diff options
author | Krasimir Angelov <kangelov@gitlab.com> | 2019-05-16 12:48:38 +0300 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2019-05-16 12:48:38 +0300 |
commit | 0d97132056ac751d2841e35466225fbff6ad727e (patch) | |
tree | 1f9cd9f7b4369cf457d56a74fe24eb5e1a273c42 | |
parent | 656dfa25f02513e2b0c489ca88887f10a72299e6 (diff) |
Disable 3DES and other insecure cipher suites
Supported cipher suites:
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Closes https://gitlab.com/gitlab-org/gitlab-pages/issues/150.
-rw-r--r-- | acceptance_test.go | 68 | ||||
-rw-r--r-- | app.go | 2 | ||||
-rw-r--r-- | app_config.go | 1 | ||||
-rw-r--r-- | helpers_test.go | 12 | ||||
-rw-r--r-- | main.go | 3 | ||||
-rw-r--r-- | server.go | 15 |
6 files changed, 99 insertions, 2 deletions
diff --git a/acceptance_test.go b/acceptance_test.go index 55a83881..f68b31ef 100644 --- a/acceptance_test.go +++ b/acceptance_test.go @@ -1057,3 +1057,71 @@ func TestAccessControl(t *testing.T) { }) } } + +func TestAcceptsSupportedCiphers(t *testing.T) { + skipUnlessEnabled(t) + teardown := RunPagesProcess(t, *pagesBinary, listeners, "") + defer teardown() + + ciphers := []uint16{ + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + } + client, cleanup := ClientWithCiphers(ciphers) + defer cleanup() + + rsp, err := client.Get(httpsListener.URL("/")) + + if rsp != nil { + rsp.Body.Close() + } + + require.NoError(t, err) +} + +func TestRejectsUnsupportedCiphers(t *testing.T) { + skipUnlessEnabled(t) + teardown := RunPagesProcess(t, *pagesBinary, listeners, "") + defer teardown() + + ciphers := []uint16{ + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + } + client, cleanup := ClientWithCiphers(ciphers) + defer cleanup() + + rsp, err := client.Get(httpsListener.URL("/")) + + if rsp != nil { + rsp.Body.Close() + } + + require.Error(t, err) + require.Nil(t, rsp) +} + +func TestEnableInsecureCiphers(t *testing.T) { + skipUnlessEnabled(t) + teardown := RunPagesProcess(t, *pagesBinary, listeners, "", "-insecure-ciphers") + defer teardown() + + ciphers := []uint16{ + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + } + client, cleanup := ClientWithCiphers(ciphers) + defer cleanup() + + rsp, err := client.Get(httpsListener.URL("/")) + + if rsp != nil { + rsp.Body.Close() + } + + require.NoError(t, err) +} @@ -258,7 +258,7 @@ func (a *theApp) Run() { wg.Add(1) go func(fd uintptr) { defer wg.Done() - err := listenAndServeTLS(fd, a.RootCertificate, a.RootKey, a.ServeHTTP, a.ServeTLS, a.HTTP2, limiter) + err := listenAndServeTLS(fd, a.RootCertificate, a.RootKey, a.ServeHTTP, a.ServeTLS, a.HTTP2, a.InsecureCiphers, limiter) if err != nil { fatal(err) } diff --git a/app_config.go b/app_config.go index 9ff26b6b..b2b885f9 100644 --- a/app_config.go +++ b/app_config.go @@ -17,6 +17,7 @@ type appConfig struct { ListenMetrics uintptr ListenAdminUnix uintptr ListenAdminHTTPS uintptr + InsecureCiphers bool HTTP2 bool RedirectHTTP bool diff --git a/helpers_test.go b/helpers_test.go index bf61b7a4..2e565300 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -329,6 +329,18 @@ func GetRedirectPageWithCookie(t *testing.T, spec ListenSpec, host, urlsuffix st return TestHTTPSClient.Transport.RoundTrip(req) } +func ClientWithCiphers(ciphers []uint16) (*http.Client, func()) { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: TestCertPool, + CipherSuites: ciphers, + }, + } + client := &http.Client{Transport: tr} + + return client, tr.CloseIdleConnections +} + func waitForRoundtrips(t *testing.T, listeners []ListenSpec, timeout time.Duration) { nListening := 0 start := time.Now() @@ -51,6 +51,7 @@ var ( clientSecret = flag.String("auth-client-secret", "", "GitLab application Client Secret") redirectURI = flag.String("auth-redirect-uri", "", "GitLab application redirect URI") maxConns = flag.Uint("max-conns", 5000, "Limit on the number of concurrent connections to the HTTP, HTTPS or proxy listeners") + insecureCiphers = flag.Bool("insecure-ciphers", false, "Use default list of cipher suites, may contain insecure ones like 3DES and RC4") disableCrossOriginRequests = flag.Bool("disable-cross-origin-requests", false, "Disable cross-origin requests") @@ -82,6 +83,7 @@ func configFromFlags() appConfig { config.LogFormat = *logFormat config.LogVerbose = *logVerbose config.MaxConns = int(*maxConns) + config.InsecureCiphers = *insecureCiphers for _, file := range []struct { contents *[]byte @@ -194,6 +196,7 @@ func appMain() { "default-config-filename": flag.DefaultConfigFlagname, "disable-cross-origin-requests": *disableCrossOriginRequests, "domain": config.Domain, + "insecure-ciphers": config.InsecureCiphers, "listen-http": strings.Join(listenHTTP, ","), "listen-https": strings.Join(listenHTTPS, ","), "listen-proxy": strings.Join(listenProxy, ","), @@ -25,6 +25,15 @@ type keepAliveSetter interface { SetKeepAlivePeriod(time.Duration) error } +var preferredCipherSuites = []uint16{ + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, +} + func (ln *keepAliveListener) Accept() (net.Conn, error) { conn, err := ln.Listener.Accept() if err != nil { @@ -65,7 +74,7 @@ func listenAndServe(fd uintptr, handler http.HandlerFunc, useHTTP2 bool, tlsConf return server.Serve(&keepAliveListener{l}) } -func listenAndServeTLS(fd uintptr, cert, key []byte, handler http.HandlerFunc, tlsHandler tlsHandlerFunc, useHTTP2 bool, limiter *netutil.Limiter) error { +func listenAndServeTLS(fd uintptr, cert, key []byte, handler http.HandlerFunc, tlsHandler tlsHandlerFunc, useHTTP2 bool, insecureCiphers bool, limiter *netutil.Limiter) error { certificate, err := tls.X509KeyPair(cert, key) if err != nil { return err @@ -76,5 +85,9 @@ func listenAndServeTLS(fd uintptr, cert, key []byte, handler http.HandlerFunc, t tlsConfig.Certificates = []tls.Certificate{ certificate, } + if !insecureCiphers { + tlsConfig.PreferServerCipherSuites = true + tlsConfig.CipherSuites = preferredCipherSuites + } return listenAndServe(fd, handler, useHTTP2, tlsConfig, limiter) } |