diff options
author | Valery Piashchynski <[email protected]> | 2020-08-27 11:07:02 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2020-08-27 11:07:02 +0300 |
commit | e736440450b7828913e7a7c24881b7159b07dbfb (patch) | |
tree | 2aec33a75bfcbb35bbe2d925e5e754a8ff2c6c2b /service | |
parent | 090feef263a7d6aa967d37c05efcf7f565efac89 (diff) | |
parent | 88b394324165e3e16253c27552b0d4d7d6628a81 (diff) |
Merge branch 'master' into patch-1
Diffstat (limited to 'service')
-rw-r--r-- | service/http/service.go | 74 | ||||
-rw-r--r-- | service/metrics/service.go | 71 | ||||
-rw-r--r-- | service/reload/watcher_test.go | 8 |
3 files changed, 137 insertions, 16 deletions
diff --git a/service/http/service.go b/service/http/service.go index b260008c..25a10064 100644 --- a/service/http/service.go +++ b/service/http/service.go @@ -6,6 +6,13 @@ import ( "crypto/x509" "errors" "fmt" + "io/ioutil" + "net/http" + "net/http/fcgi" + "net/url" + "strings" + "sync" + "github.com/sirupsen/logrus" "github.com/spiral/roadrunner" "github.com/spiral/roadrunner/service/env" @@ -14,12 +21,7 @@ import ( "github.com/spiral/roadrunner/util" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" - "io/ioutil" - "net/http" - "net/http/fcgi" - "net/url" - "strings" - "sync" + "golang.org/x/sys/cpu" ) const ( @@ -264,7 +266,7 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { } if s.https != nil && r.TLS != nil { - w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains") + w.Header().Add("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") } r = attributes.Init(r) @@ -310,11 +312,67 @@ func (s *Service) appendRootCa() error { // Init https server func (s *Service) initSSL() *http.Server { + var topCipherSuites []uint16 + var defaultCipherSuitesTLS13 []uint16 + + hasGCMAsmAMD64 := cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ + hasGCMAsmARM64 := cpu.ARM64.HasAES && cpu.ARM64.HasPMULL + // Keep in sync with crypto/aes/cipher_s390x.go. + hasGCMAsmS390X := cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) + + hasGCMAsm := hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X + + if hasGCMAsm { + // If AES-GCM hardware is provided then prioritise AES-GCM + // cipher suites. + topCipherSuites = []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + } + defaultCipherSuitesTLS13 = []uint16{ + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_CHACHA20_POLY1305_SHA256, + tls.TLS_AES_256_GCM_SHA384, + } + } else { + // Without AES-GCM hardware, we put the ChaCha20-Poly1305 + // cipher suites first. + topCipherSuites = []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_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + } + defaultCipherSuitesTLS13 = []uint16{ + tls.TLS_CHACHA20_POLY1305_SHA256, + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_AES_256_GCM_SHA384, + } + } + + DefaultCipherSuites := make([]uint16, 0, 22) + DefaultCipherSuites = append(DefaultCipherSuites, topCipherSuites...) + DefaultCipherSuites = append(DefaultCipherSuites, defaultCipherSuitesTLS13...) + server := &http.Server{ Addr: s.tlsAddr(s.cfg.Address, true), Handler: s, TLSConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, + CurvePreferences: []tls.CurveID{ + tls.CurveP256, + tls.CurveP384, + tls.CurveP521, + tls.X25519, + }, + CipherSuites: DefaultCipherSuites, + MinVersion: tls.VersionTLS12, + PreferServerCipherSuites: true, }, } s.throw(EventInitSSL, server) diff --git a/service/metrics/service.go b/service/metrics/service.go index 0b667f2d..4656ae04 100644 --- a/service/metrics/service.go +++ b/service/metrics/service.go @@ -4,14 +4,17 @@ package metrics import ( "context" + "crypto/tls" "fmt" + "net/http" + "sync" + "time" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/sirupsen/logrus" "github.com/spiral/roadrunner/service/rpc" - "net/http" - "sync" - "time" + "golang.org/x/sys/cpu" ) const ( @@ -81,14 +84,74 @@ func (s *Service) Serve() error { } s.mu.Lock() + + var topCipherSuites []uint16 + var defaultCipherSuitesTLS13 []uint16 + + hasGCMAsmAMD64 := cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ + hasGCMAsmARM64 := cpu.ARM64.HasAES && cpu.ARM64.HasPMULL + // Keep in sync with crypto/aes/cipher_s390x.go. + hasGCMAsmS390X := cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) + + hasGCMAsm := hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X + + if hasGCMAsm { + // If AES-GCM hardware is provided then prioritise AES-GCM + // cipher suites. + topCipherSuites = []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + } + defaultCipherSuitesTLS13 = []uint16{ + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_CHACHA20_POLY1305_SHA256, + tls.TLS_AES_256_GCM_SHA384, + } + } else { + // Without AES-GCM hardware, we put the ChaCha20-Poly1305 + // cipher suites first. + topCipherSuites = []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_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + } + defaultCipherSuitesTLS13 = []uint16{ + tls.TLS_CHACHA20_POLY1305_SHA256, + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_AES_256_GCM_SHA384, + } + } + + DefaultCipherSuites := make([]uint16, 0, 22) + DefaultCipherSuites = append(DefaultCipherSuites, topCipherSuites...) + DefaultCipherSuites = append(DefaultCipherSuites, defaultCipherSuitesTLS13...) + s.http = &http.Server{ Addr: s.cfg.Address, - Handler: promhttp.HandlerFor(s.registry, promhttp.HandlerOpts{}, ), + Handler: promhttp.HandlerFor(s.registry, promhttp.HandlerOpts{}), IdleTimeout: time.Hour * 24, ReadTimeout: time.Minute * 60, MaxHeaderBytes: maxHeaderSize, ReadHeaderTimeout: time.Minute * 60, WriteTimeout: time.Minute * 60, + TLSConfig: &tls.Config{ + CurvePreferences: []tls.CurveID{ + tls.CurveP256, + tls.CurveP384, + tls.CurveP521, + tls.X25519, + }, + CipherSuites: DefaultCipherSuites, + MinVersion: tls.VersionTLS12, + PreferServerCipherSuites: true, + }, } s.mu.Unlock() diff --git a/service/reload/watcher_test.go b/service/reload/watcher_test.go index 391f6bb9..9683d2de 100644 --- a/service/reload/watcher_test.go +++ b/service/reload/watcher_test.go @@ -246,7 +246,7 @@ func Test_Recursive_Support(t *testing.T) { } }() - nestedDir, err := ioutil.TempDir(tempDir, "/nested") + nestedDir, err := ioutil.TempDir(tempDir, "nested") if err != nil { t.Fatal(err) } @@ -368,7 +368,7 @@ func Test_Filter_Directory(t *testing.T) { go limitTime(time.Second*10, t.Name(), c) - nestedDir, err := ioutil.TempDir(tempDir, "/nested") + nestedDir, err := ioutil.TempDir(tempDir, "nested") if err != nil { t.Fatal(err) } @@ -470,7 +470,7 @@ func Test_Copy_Directory(t *testing.T) { c <- struct{}{} }() - nestedDir, err := ioutil.TempDir(tempDir, "/nested") + nestedDir, err := ioutil.TempDir(tempDir, "nested") if err != nil { t.Fatal(err) } @@ -535,7 +535,7 @@ func Test_Copy_Directory(t *testing.T) { go func() { go func() { - err2 := copyDir(nestedDir, filepath.Join(tempDir, "/copyTo")) + err2 := copyDir(nestedDir, filepath.Join(tempDir, "copyTo")) if err2 != nil { panic(err2) } |