Browse Source

issue #193 - added TLS 1.3 support for Go 1.13 or higher. (#203)

- adds TLS 1.3 and new cipher-suites as config options
- remove SSLv3 and the TLS_FALLBACK_SCSV ciphersuite from the sample configuration
- removes SSLv3 and the TLS_FALLBACK_SCSV ciphersuite when building with Go 1.14 or above
- remove Go 1.10 and Go 1.9 from Travis CI tests, add Go 1.13
Flashmob 5 years ago
parent
commit
de9b608138
9 changed files with 47 additions and 17 deletions
  1. 1 2
      .travis.yml
  2. 1 1
      README.md
  3. 9 6
      config.go
  4. 4 4
      goguerrilla.conf.sample
  5. 1 1
      guerrilla.go
  6. 2 2
      server.go
  7. 1 1
      server_test.go
  8. 15 0
      tls_go1.13.go
  9. 13 0
      tls_go1.14.go

+ 1 - 2
.travis.yml

@@ -1,10 +1,9 @@
 language: go
 sudo: false
 go:
-  - 1.9
-  - 1.10.x
   - 1.11.x
   - 1.12.x
+  - 1.13.x
   - master
 
 cache:

+ 1 - 1
README.md

@@ -270,7 +270,7 @@ Using Nginx as a proxy
 
 For such purposes as load balancing, terminating TLS early,
  or supporting SSL versions not supported by Go (highly not recommended if you
- want to use older SSL versions), 
+ want to use older TLS/SSL versions), 
  it is possible to [use NGINX as a proxy](https://github.com/flashmob/go-guerrilla/wiki/Using-Nginx-as-a-proxy).
 
 

+ 9 - 6
config.go

@@ -98,9 +98,13 @@ type ServerTLSConfig struct {
 // https://golang.org/pkg/crypto/tls/#pkg-constants
 // Ciphers introduced before Go 1.7 are listed here,
 // ciphers since Go 1.8, see tls_go1.8.go
+// ....... since Go 1.13, see tls_go1.13.go
 var TLSCiphers = map[string]uint16{
 
-	// // Note: Generally avoid using CBC unless for compatibility
+	// Note: Generally avoid using CBC unless for compatibility
+	// The following ciphersuites are not configurable for TLS 1.3
+	// see tls_go1.13.go for a list of ciphersuites always used in TLS 1.3
+
 	"TLS_RSA_WITH_3DES_EDE_CBC_SHA":        tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
 	"TLS_RSA_WITH_AES_128_CBC_SHA":         tls.TLS_RSA_WITH_AES_128_CBC_SHA,
 	"TLS_RSA_WITH_AES_256_CBC_SHA":         tls.TLS_RSA_WITH_AES_256_CBC_SHA,
@@ -120,13 +124,12 @@ var TLSCiphers = map[string]uint16{
 	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":   tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 	"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
 
-	// Include to prevent downgrade attacks
-	"TLS_FALLBACK_SCSV": tls.TLS_FALLBACK_SCSV,
+	// see tls_go1.13 for new TLS 1.3 ciphersuites
+	// Note that TLS 1.3 ciphersuites are not configurable
 }
 
 // https://golang.org/pkg/crypto/tls/#pkg-constants
 var TLSProtocols = map[string]uint16{
-	"ssl3.0": tls.VersionSSL30,
 	"tls1.0": tls.VersionTLS10,
 	"tls1.1": tls.VersionTLS11,
 	"tls1.2": tls.VersionTLS12,
@@ -174,7 +177,7 @@ func (c *AppConfig) Load(jsonBytes []byte) error {
 		}
 	}
 
-	// read the timestamps for the ssl keys, to determine if they need to be reloaded
+	// read the timestamps for the TLS keys, to determine if they need to be reloaded
 	for i := 0; i < len(c.Servers); i++ {
 		if err := c.Servers[i].loadTlsKeyTimestamps(); err != nil {
 			return err
@@ -404,7 +407,7 @@ func (sc *ServerConfig) emitChangeEvents(oldServer *ServerConfig, app Guerrilla)
 	}
 }
 
-// Loads in timestamps for the ssl keys
+// Loads in timestamps for the TLS keys
 func (sc *ServerConfig) loadTlsKeyTimestamps() error {
 	var statErr = func(iface string, err error) error {
 		return fmt.Errorf(

+ 4 - 4
goguerrilla.conf.sample

@@ -31,8 +31,8 @@
                 "tls_always_on":false,
                 "private_key_file":"/path/to/pem/file/test.com.key",
                 "public_key_file":"/path/to/pem/file/test.com.crt",
-                "protocols" : ["ssl3.0", "tls1.2"],
-                "ciphers" : ["TLS_FALLBACK_SCSV", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"],
+                "protocols" : ["tls1.0", "tls1.2"],
+                "ciphers" : ["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"],
                 "curves" : ["P256", "P384", "P521", "X25519"],
                 "client_auth_type" : "NoClientCert"
             }
@@ -50,8 +50,8 @@
                 "public_key_file":"/path/to/pem/file/test.com.crt",
                  "start_tls_on":false,
                  "tls_always_on":true,
-                 "protocols" : ["ssl3.0", "tls1.2"],
-                 "ciphers" : ["TLS_FALLBACK_SCSV", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"],
+                 "protocols" : ["tls1.0", "tls1.2"],
+                 "ciphers" : ["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"],
                  "curves" : ["P256", "P384", "P521", "X25519"],
                  "client_auth_type" : "NoClientCert"
             }

+ 1 - 1
guerrilla.go

@@ -320,7 +320,7 @@ func (g *guerrilla) subscribeEvents() {
 	// TLS changes
 	events[EventConfigServerTLSConfig] = serverEvent(func(sc *ServerConfig) {
 		if server, err := g.findServer(sc.ListenInterface); err == nil {
-			if err := server.configureSSL(); err == nil {
+			if err := server.configureTLS(); err == nil {
 				g.mainlog().Infof("Server [%s] new TLS configuration loaded", sc.ListenInterface)
 			} else {
 				g.mainlog().WithError(err).Errorf("Server [%s] failed to load the new TLS configuration", sc.ListenInterface)

+ 2 - 2
server.go

@@ -113,13 +113,13 @@ func newServer(sc *ServerConfig, b backends.Backend, mainlog log.Logger) (*serve
 	}
 	server.setConfig(sc)
 	server.setTimeout(sc.Timeout)
-	if err := server.configureSSL(); err != nil {
+	if err := server.configureTLS(); err != nil {
 		return server, err
 	}
 	return server, nil
 }
 
-func (s *server) configureSSL() error {
+func (s *server) configureTLS() error {
 	sConfig := s.configStore.Load().(ServerConfig)
 	if sConfig.TLS.AlwaysOn || sConfig.TLS.StartTLSOn {
 		cert, err := tls.LoadX509KeyPair(sConfig.TLS.PublicKeyFile, sConfig.TLS.PrivateKeyFile)

+ 1 - 1
server_test.go

@@ -222,7 +222,7 @@ func TestTLSConfig(t *testing.T) {
 			Protocols:      []string{"tls1.0", "tls1.2"},
 		},
 	})
-	if err := s.configureSSL(); err != nil {
+	if err := s.configureTLS(); err != nil {
 		t.Error(err)
 	}
 

+ 15 - 0
tls_go1.13.go

@@ -0,0 +1,15 @@
+// +build go1.13
+
+package guerrilla
+
+import "crypto/tls"
+
+// TLS 1.3 was introduced in go 1.12 as an option and enabled for production in go 1.13
+// release notes: https://golang.org/doc/go1.12#tls_1_3
+func init() {
+	TLSProtocols["tls1.3"] = tls.VersionTLS13
+
+	TLSCiphers["TLS_AES_128_GCM_SHA256"] = tls.TLS_AES_128_GCM_SHA256
+	TLSCiphers["TLS_AES_256_GCM_SHA384"] = tls.TLS_AES_256_GCM_SHA384
+	TLSCiphers["TLS_CHACHA20_POLY1305_SHA256"] = tls.TLS_CHACHA20_POLY1305_SHA256
+}

+ 13 - 0
tls_go1.14.go

@@ -0,0 +1,13 @@
+// +build !go1.14
+
+package guerrilla
+
+import "crypto/tls"
+
+func init() {
+
+	TLSProtocols["ssl3.0"] = tls.VersionSSL30 // deprecated since GO 1.13, removed 1.14
+
+	// Include to prevent downgrade attacks (SSLv3 only, deprecated in Go 1.13)
+	TLSCiphers["TLS_FALLBACK_SCSV"] = tls.TLS_FALLBACK_SCSV
+}