Rework the hsts related test file

This commit is contained in:
Sandor Szombat 2020-02-20 16:29:55 +01:00
parent 57fcbdfb73
commit 1906832bc5

View file

@ -37,158 +37,211 @@ var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers)", f
f.UpdateNginxConfigMapData("use-forwarded-headers", "false") f.UpdateNginxConfigMapData("use-forwarded-headers", "false")
}) })
ginkgo.It("should configure TLS protocol", func() { ginkgo.Context("should configure TLS protocol", func() {
sslCiphers := "ssl-ciphers" var (
sslProtocols := "ssl-protocols" sslCiphers string
sslProtocols string
testCiphers string
tlsConfig *tls.Config
)
// Two ciphers supported by each of TLSv1.2 and TLSv1. ginkgo.BeforeEach(func() {
// https://www.openssl.org/docs/man1.1.0/apps/ciphers.html - "CIPHER SUITE NAMES" sslCiphers = "ssl-ciphers"
testCiphers := "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA" sslProtocols = "ssl-protocols"
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil)) // Two ciphers supported by each of TLSv1.2 and TLSv1.
tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet, // https://www.openssl.org/docs/man1.1.0/apps/ciphers.html - "CIPHER SUITE NAMES"
ing.Spec.TLS[0].Hosts, testCiphers = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA"
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig) ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil))
tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
ing.Spec.TLS[0].Hosts,
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
ginkgo.By("setting cipher suite") framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig)
f.UpdateNginxConfigMapData(sslCiphers, testCiphers) })
f.WaitForNginxConfiguration( ginkgo.It("setting cipher suite", func() {
func(cfg string) bool { f.UpdateNginxConfigMapData(sslCiphers, testCiphers)
return strings.Contains(cfg, fmt.Sprintf("ssl_ciphers '%s';", testCiphers))
f.WaitForNginxConfiguration(
func(cfg string) bool {
return strings.Contains(cfg, fmt.Sprintf("ssl_ciphers '%s';", testCiphers))
})
resp := f.HTTPTestClientWithTLSConfig(tlsConfig).
GET("/").
WithURL(f.GetURL(framework.HTTPS)).
WithHeader("Host", host).
Expect().
Status(http.StatusOK).
Raw()
assert.Equal(ginkgo.GinkgoT(), int(resp.TLS.Version), tls.VersionTLS12)
assert.Equal(ginkgo.GinkgoT(), resp.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
})
ginkgo.It("enforcing TLS v1.0", func() {
f.SetNginxConfigMapData(map[string]string{
sslCiphers: testCiphers,
sslProtocols: "TLSv1",
}) })
resp := f.HTTPTestClientWithTLSConfig(tlsConfig). f.WaitForNginxConfiguration(
GET("/"). func(cfg string) bool {
WithURL(f.GetURL(framework.HTTPS)). return strings.Contains(cfg, "ssl_protocols TLSv1;")
WithHeader("Host", host). })
Expect().
Status(http.StatusOK).
Raw()
assert.Equal(ginkgo.GinkgoT(), int(resp.TLS.Version), tls.VersionTLS12) resp := f.HTTPTestClientWithTLSConfig(tlsConfig).
assert.Equal(ginkgo.GinkgoT(), resp.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) GET("/").
WithURL(f.GetURL(framework.HTTPS)).
WithHeader("Host", host).
Expect().
Status(http.StatusOK).
Raw()
ginkgo.By("enforcing TLS v1.0") assert.Equal(ginkgo.GinkgoT(), int(resp.TLS.Version), tls.VersionTLS10)
f.UpdateNginxConfigMapData(sslProtocols, "TLSv1") assert.Equal(ginkgo.GinkgoT(), resp.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
})
})
f.WaitForNginxConfiguration( ginkgo.Context("should configure HSTS policy header", func() {
func(cfg string) bool { var (
return strings.Contains(cfg, "ssl_protocols TLSv1;") tlsConfig *tls.Config
hstsMaxAge string
hstsIncludeSubdomains string
hstsPreload string
)
ginkgo.BeforeEach(func() {
hstsMaxAge = "hsts-max-age"
hstsIncludeSubdomains = "hsts-include-subdomains"
hstsPreload = "hsts-preload"
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil))
tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
ing.Spec.TLS[0].Hosts,
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig)
})
ginkgo.It("setting max-age parameter", func() {
f.UpdateNginxConfigMapData(hstsMaxAge, "86400")
f.WaitForNginxConfiguration(func(server string) bool {
return strings.Contains(server, fmt.Sprintf(`hsts_max_age = 86400,`))
}) })
resp = f.HTTPTestClientWithTLSConfig(tlsConfig). f.HTTPTestClientWithTLSConfig(tlsConfig).
GET("/"). GET("/").
WithURL(f.GetURL(framework.HTTPS)). WithURL(f.GetURL(framework.HTTPS)).
WithHeader("Host", host). WithHeader("Host", host).
Expect(). Expect().
Status(http.StatusOK). Status(http.StatusOK).
Raw() Header("Strict-Transport-Security").Equal("max-age=86400; includeSubDomains")
})
ginkgo.It("setting includeSubDomains parameter", func() {
f.SetNginxConfigMapData(map[string]string{
hstsMaxAge: "86400",
hstsIncludeSubdomains: "false",
})
f.WaitForNginxConfiguration(func(server string) bool {
return strings.Contains(server, fmt.Sprintf(`hsts_include_subdomains = false,`))
})
f.HTTPTestClientWithTLSConfig(tlsConfig).
GET("/").
WithURL(f.GetURL(framework.HTTPS)).
WithHeader("Host", host).
Expect().
Status(http.StatusOK).
Header("Strict-Transport-Security").Equal("max-age=86400")
})
ginkgo.It("setting preload parameter", func() {
f.SetNginxConfigMapData(map[string]string{
hstsMaxAge: "86400",
hstsPreload: "true",
hstsIncludeSubdomains: "false",
})
f.WaitForNginxConfiguration(func(server string) bool {
return strings.Contains(server, fmt.Sprintf(`hsts_preload = true,`))
})
f.HTTPTestClientWithTLSConfig(tlsConfig).
GET("/").
WithURL(f.GetURL(framework.HTTPS)).
WithHeader("Host", host).
Expect().
Status(http.StatusOK).
Header("Strict-Transport-Security").Equal("max-age=86400; preload")
})
ginkgo.It("overriding what's set from the upstream", func() {
f.SetNginxConfigMapData(map[string]string{
hstsMaxAge: "86400",
hstsPreload: "true",
hstsIncludeSubdomains: "false",
})
// we can not use gorequest here because it flattens the duplicate headers
// and specifically in case of Strict-Transport-Security it ignore extra headers
// intead of concatenating, rightfully. And I don't know of any API it provides for getting raw headers.
curlCmd := fmt.Sprintf("curl -I -k --fail --silent --resolve settings-tls:443:127.0.0.1 https://settings-tls/%v", "?hsts=true")
output, err := f.ExecIngressPod(curlCmd)
assert.Nil(ginkgo.GinkgoT(), err)
assert.Contains(ginkgo.GinkgoT(), output, "strict-transport-security: max-age=86400; preload")
// this is what the upstream sets
assert.NotContains(ginkgo.GinkgoT(), output, "strict-transport-security: max-age=3600; preload")
})
assert.Equal(ginkgo.GinkgoT(), int(resp.TLS.Version), tls.VersionTLS10)
assert.Equal(ginkgo.GinkgoT(), resp.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
}) })
ginkgo.It("should configure HSTS policy header", func() { ginkgo.Context("ports or X-Forwarded-Host check during HTTP tp HTTPS redirection", func() {
hstsMaxAge := "hsts-max-age" ginkgo.It("should not use ports during the HTTP to HTTPS redirection", func() {
hstsIncludeSubdomains := "hsts-include-subdomains" ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil))
hstsPreload := "hsts-preload" tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
ing.Spec.TLS[0].Hosts,
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil)) framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig)
tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
ing.Spec.TLS[0].Hosts,
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig) f.HTTPTestClient().
GET("/").
WithHeader("Host", host).
Expect().
Status(http.StatusPermanentRedirect).
Header("Location").Equal(fmt.Sprintf("https://%v/", host))
})
ginkgo.By("setting max-age parameter") ginkgo.It("should not use ports or X-Forwarded-Host during the HTTP to HTTPS redirection", func() {
f.UpdateNginxConfigMapData(hstsMaxAge, "86400") f.UpdateNginxConfigMapData("use-forwarded-headers", "true")
f.HTTPTestClientWithTLSConfig(tlsConfig). ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil))
GET("/"). tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
WithURL(f.GetURL(framework.HTTPS)). ing.Spec.TLS[0].Hosts,
WithHeader("Host", host). ing.Spec.TLS[0].SecretName,
Expect(). ing.Namespace)
Status(http.StatusOK). assert.Nil(ginkgo.GinkgoT(), err)
Header("Strict-Transport-Security").Equal("max-age=86400; includeSubDomains")
ginkgo.By("setting includeSubDomains parameter") framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig)
f.UpdateNginxConfigMapData(hstsIncludeSubdomains, "false")
f.HTTPTestClientWithTLSConfig(tlsConfig). f.HTTPTestClient().
GET("/"). GET("/").
WithURL(f.GetURL(framework.HTTPS)). WithHeader("Host", host).
WithHeader("Host", host). WithHeader("X-Forwarded-Host", "example.com:80").
Expect(). Expect().
Status(http.StatusOK). Status(http.StatusPermanentRedirect).
Header("Strict-Transport-Security").Equal("max-age=86400") Header("Location").Equal("https://example.com/")
})
ginkgo.By("setting preload parameter")
f.UpdateNginxConfigMapData(hstsPreload, "true")
f.HTTPTestClientWithTLSConfig(tlsConfig).
GET("/").
WithURL(f.GetURL(framework.HTTPS)).
WithHeader("Host", host).
Expect().
Status(http.StatusOK).
Header("Strict-Transport-Security").Equal("max-age=86400; preload")
ginkgo.By("overriding what's set from the upstream")
// we can not use gorequest here because it flattens the duplicate headers
// and specifically in case of Strict-Transport-Security it ignore extra headers
// intead of concatenating, rightfully. And I don't know of any API it provides for getting raw headers.
curlCmd := fmt.Sprintf("curl -I -k --fail --silent --resolve settings-tls:443:127.0.0.1 https://settings-tls/%v", "?hsts=true")
output, err := f.ExecIngressPod(curlCmd)
assert.Nil(ginkgo.GinkgoT(), err)
assert.Contains(ginkgo.GinkgoT(), output, "strict-transport-security: max-age=86400; preload")
// this is what the upstream sets
assert.NotContains(ginkgo.GinkgoT(), output, "strict-transport-security: max-age=3600; preload")
}) })
ginkgo.It("should not use ports during the HTTP to HTTPS redirection", func() {
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil))
tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
ing.Spec.TLS[0].Hosts,
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig)
f.HTTPTestClient().
GET("/").
WithHeader("Host", host).
Expect().
Status(http.StatusPermanentRedirect).
Header("Location").Equal(fmt.Sprintf("https://%v/", host))
})
ginkgo.It("should not use ports or X-Forwarded-Host during the HTTP to HTTPS redirection", func() {
f.UpdateNginxConfigMapData("use-forwarded-headers", "true")
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil))
tlsConfig, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
ing.Spec.TLS[0].Hosts,
ing.Spec.TLS[0].SecretName,
ing.Namespace)
assert.Nil(ginkgo.GinkgoT(), err)
framework.WaitForTLS(f.GetURL(framework.HTTPS), tlsConfig)
f.HTTPTestClient().
GET("/").
WithHeader("Host", host).
WithHeader("X-Forwarded-Host", "example.com:80").
Expect().
Status(http.StatusPermanentRedirect).
Header("Location").Equal("https://example.com/")
})
}) })