Repository: traefik/traefik (language: go)

Issue:
Please disable TLS 1.0 and 1.1 by default
Using TLS 1.0 or 1.1 is considered insecure these days. It should be used only by those who really know what they're doing. For that reason, I suggest disabling TLS 1.0 and 1.1 by default.

I'm on Traefik 2.2.1.


Discussion / hints:
`tls.options.default.minVersion` should be `"VersionTLS12"` by default, IMHO.

What are the reasons to still use 1.0 and 1.1?
For now, how to disable manually using the docker options? This default is planned to be merged?
Thanks.
@dm17 add this to your dynamic configs:

```
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
```
> @dm17 add this to your dynamic configs:
> 
> ```
> tls:
>   options:
>     default:
>       minVersion: VersionTLS12
>       cipherSuites:
>         - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
>         - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
>         - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
>         - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
>         - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
>         - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
> ```

Every container needs that or just the traefik container? I.e. is this correct:
```
 image: "traefik:v2.2.8"
 tls:
   options:
     default:
       minVersion: VersionTLS12
       cipherSuites:
         - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
         - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
         - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
         - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
         - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
         - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
 restart: always
```

No, that's for the [dynamic configuration](https://docs.traefik.io/getting-started/configuration-overview/). An example:
```
$ cat traefik/traefik.dynamic.yaml
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
```
and then add that file to your traefik container

- https://docs.traefik.io/v2.2/providers/file/
- https://docs.traefik.io/v2.2/https/tls/
@heitorPB Thanks... I will consider it. I still use zero traefik.yml or treafik.toml files in my config because I wanted it to be all in the docker-compose.yml - however, several features have me considering it.
@dm17 You may want to also follow issue #5507 which is a feature request for zero config TLS options.

Fix patch:
diff --git a/docs/content/deprecation/features.md b/docs/content/deprecation/features.md
index 29b162d199..d5122707b0 100644
--- a/docs/content/deprecation/features.md
+++ b/docs/content/deprecation/features.md
@@ -2,11 +2,12 @@
 
 This page is maintained and updated periodically to reflect our roadmap and any decisions around feature deprecation.
 
-| Feature                                                       | Deprecated | End of Support | Removal |
-|---------------------------------------------------------------|------------|----------------|---------|
-| [Pilot Dashboard (Metrics)](#pilot-dashboard-metrics)         | 2.7        | 2.8            | 3.0     |
-| [Pilot Plugins](#pilot-plugins)                               | 2.7        | 2.8            | 3.0     |
-| [Consul Enterprise Namespace](#consul-enterprise-namespace)   | 2.8        | N/A            | 3.0     |
+| Feature                                                     | Deprecated | End of Support | Removal |
+|-------------------------------------------------------------|------------|----------------|---------|
+| [Pilot Dashboard (Metrics)](#pilot-dashboard-metrics)       | 2.7        | 2.8            | 3.0     |
+| [Pilot Plugins](#pilot-plugins)                             | 2.7        | 2.8            | 3.0     |
+| [Consul Enterprise Namespace](#consul-enterprise-namespace) | 2.8        | N/A            | 3.0     |
+| [TLS 1.0 and 1.1 Support](#tls-10-and-11)                   | N/A        | 2.8            | N/A     |
 
 ## Impact
 
@@ -24,3 +25,7 @@ At 2.9, a new plugin catalog home should be available, decoupled from pilot.
 
 Starting on 2.8 the `namespace` option of Consul and Consul Catalog providers is deprecated, 
 please use the `namespaces` options instead.  
+
+### TLS 1.0 and 1.1
+
+Starting on 2.8 the default TLS options will use the minimum version of TLS 1.2. Of course, it can still be overridden with custom configuration.  
diff --git a/pkg/tls/tlsmanager.go b/pkg/tls/tlsmanager.go
index 1b9c373962..73b98fc63b 100644
--- a/pkg/tls/tlsmanager.go
+++ b/pkg/tls/tlsmanager.go
@@ -27,6 +27,17 @@ const (
 var DefaultTLSOptions = Options{
 	// ensure http2 enabled
 	ALPNProtocols: []string{"h2", "http/1.1", tlsalpn01.ACMETLS1Protocol},
+	MinVersion:    "VersionTLS12",
+	CipherSuites:  getCipherSuites(),
+}
+
+func getCipherSuites() []string {
+	gsc := tls.CipherSuites()
+	ciphers := make([]string, len(gsc))
+	for idx, cs := range gsc {
+		ciphers[idx] = cs.Name
+	}
+	return ciphers
 }
 
 // Manager is the TLS option/store/configuration factory.


Test patch:
diff --git a/pkg/server/aggregator_test.go b/pkg/server/aggregator_test.go
index 8d9b0f18c1..cc45578961 100644
--- a/pkg/server/aggregator_test.go
+++ b/pkg/server/aggregator_test.go
@@ -182,13 +182,7 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) {
 			desc:  "Nil returns an empty configuration",
 			given: nil,
 			expected: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 			},
 		},
 		{
@@ -205,13 +199,7 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) {
 				},
 			},
 			expected: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 				"foo@provider-1": {
 					MinVersion: "VersionTLS12",
 				},
@@ -240,13 +228,7 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) {
 				},
 			},
 			expected: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 				"foo@provider-1": {
 					MinVersion: "VersionTLS13",
 				},
@@ -352,13 +334,7 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) {
 				},
 			},
 			expected: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 				"foo@provider-1": {
 					MinVersion: "VersionTLS12",
 				},
diff --git a/pkg/server/configurationwatcher_test.go b/pkg/server/configurationwatcher_test.go
index 11b783e586..afd886e84f 100644
--- a/pkg/server/configurationwatcher_test.go
+++ b/pkg/server/configurationwatcher_test.go
@@ -95,13 +95,7 @@ func TestNewConfigurationWatcher(t *testing.T) {
 			},
 			TLS: &dynamic.TLSConfiguration{
 				Options: map[string]tls.Options{
-					"default": {
-						ALPNProtocols: []string{
-							"h2",
-							"http/1.1",
-							"acme-tls/1",
-						},
-					},
+					"default": tls.DefaultTLSOptions,
 				},
 				Stores: map[string]tls.Store{},
 			},
@@ -238,13 +232,7 @@ func TestIgnoreTransientConfiguration(t *testing.T) {
 		},
 		TLS: &dynamic.TLSConfiguration{
 			Options: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 			},
 			Stores: map[string]tls.Store{},
 		},
@@ -408,13 +396,7 @@ func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) {
 		},
 		TLS: &dynamic.TLSConfiguration{
 			Options: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 			},
 			Stores: map[string]tls.Store{},
 		},
@@ -503,13 +485,7 @@ func TestListenProvidersIgnoreSameConfig(t *testing.T) {
 		},
 		TLS: &dynamic.TLSConfiguration{
 			Options: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 			},
 			Stores: map[string]tls.Store{},
 		},
@@ -642,13 +618,7 @@ func TestListenProvidersIgnoreIntermediateConfigs(t *testing.T) {
 		},
 		TLS: &dynamic.TLSConfiguration{
 			Options: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 			},
 			Stores: map[string]tls.Store{},
 		},
@@ -710,13 +680,7 @@ func TestListenProvidersPublishesConfigForEachProvider(t *testing.T) {
 		},
 		TLS: &dynamic.TLSConfiguration{
 			Options: map[string]tls.Options{
-				"default": {
-					ALPNProtocols: []string{
-						"h2",
-						"http/1.1",
-						"acme-tls/1",
-					},
-				},
+				"default": tls.DefaultTLSOptions,
 			},
 			Stores: map[string]tls.Store{},
 		},
diff --git a/pkg/tls/tlsmanager_test.go b/pkg/tls/tlsmanager_test.go
index f06d0ab94b..7f38532995 100644
--- a/pkg/tls/tlsmanager_test.go
+++ b/pkg/tls/tlsmanager_test.go
@@ -347,3 +347,31 @@ func TestClientAuth(t *testing.T) {
 		})
 	}
 }
+
+func TestManager_Get_DefaultValues(t *testing.T) {
+	tlsManager := NewManager()
+
+	// Ensures we won't break things for Traefik users when updating Go
+	config, _ := tlsManager.Get("default", "default")
+	assert.Equal(t, config.MinVersion, uint16(tls.VersionTLS12))
+	assert.Equal(t, config.NextProtos, []string{"h2", "http/1.1", "acme-tls/1"})
+	assert.Equal(t, config.CipherSuites, []uint16{
+		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
+		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
+		tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
+		tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
+		tls.TLS_AES_128_GCM_SHA256,
+		tls.TLS_AES_256_GCM_SHA384,
+		tls.TLS_CHACHA20_POLY1305_SHA256,
+		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+		tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+		tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+		tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+	})
+}