From 7c430e5c9de5305b2f58dce77cdf50eeba944a25 Mon Sep 17 00:00:00 2001 From: Daniel Tomcej Date: Wed, 12 Feb 2020 11:06:04 -0600 Subject: [PATCH] Allow PreferServerCipherSuites as a TLS Option --- docs/content/https/tls.md | 33 +++++++++++++++++++ .../reference/dynamic-configuration/file.toml | 2 ++ .../reference/dynamic-configuration/file.yaml | 2 ++ .../kubernetes-crd-resource.yml | 24 ++++++++++++++ .../dynamic-configuration/kubernetes-crd.yml | 24 ++++++++++++++ .../reference/dynamic-configuration/kv-ref.md | 2 ++ .../crd/fixtures/tcp/with_tls_options.yml | 2 +- .../crd/fixtures/with_tls_options.yml | 1 + pkg/provider/kubernetes/crd/kubernetes.go | 3 +- .../kubernetes/crd/kubernetes_test.go | 6 ++-- .../crd/traefik/v1alpha1/tlsoption.go | 13 ++++---- pkg/tls/tls.go | 13 ++++---- pkg/tls/tlsmanager.go | 3 ++ 13 files changed, 112 insertions(+), 16 deletions(-) diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index b06073349..6804636c2 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -347,6 +347,39 @@ spec: sniStrict: true ``` +### Prefer Server Cipher Suites + +This option allows the server to choose its most preferred cipher suite instead of the client's. +Please note that this is enabled automatically when `minVersion` or `maxVersion` are set. + +```toml tab="File (TOML)" +# Dynamic configuration + +[tls.options] + [tls.options.default] + preferServerCipherSuites = true +``` + +```yaml tab="File (YAML)" +# Dynamic configuration + +tls: + options: + default: + preferServerCipherSuites: true +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.containo.us/v1alpha1 +kind: TLSOption +metadata: + name: default + namespace: default + +spec: + preferServerCipherSuites: true +``` + ### Client Authentication (mTLS) Traefik supports mutual authentication, through the `clientAuth` section. diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 9ba59ad5a..8cba1cbe1 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -357,6 +357,7 @@ cipherSuites = ["foobar", "foobar"] curvePreferences = ["foobar", "foobar"] sniStrict = true + preferServerCipherSuites = true [tls.options.Options0.clientAuth] caFiles = ["foobar", "foobar"] clientAuthType = "foobar" @@ -366,6 +367,7 @@ cipherSuites = ["foobar", "foobar"] curvePreferences = ["foobar", "foobar"] sniStrict = true + preferServerCipherSuites = true [tls.options.Options1.clientAuth] caFiles = ["foobar", "foobar"] clientAuthType = "foobar" diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index 50ca3898e..e88da86e6 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -397,6 +397,7 @@ tls: - foobar clientAuthType: foobar sniStrict: true + preferServerCipherSuites: true Options1: minVersion: foobar maxVersion: foobar @@ -412,6 +413,7 @@ tls: - foobar clientAuthType: foobar sniStrict: true + preferServerCipherSuites: true stores: Store0: defaultCertificate: diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml index 7c755da06..04b9d0f74 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml @@ -155,3 +155,27 @@ spec: options: name: myTLSOption namespace: default + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: TLSOption +metadata: + name: tlsoption + namespace: default + +spec: + minVersion: foobar + maxVersion: foobar + cipherSuites: + - foobar + - foobar + curvePreferences: + - foobar + - foobar + clientAuth: + caFiles: + - foobar + - foobar + clientAuthType: foobar + sniStrict: true + preferServerCipherSuites: true diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd.yml index 62916b201..01fede4fc 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd.yml @@ -230,3 +230,27 @@ spec: options: name: myTLSOption namespace: default + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: TLSOption +metadata: + name: tlsoption + namespace: default + +spec: + minVersion: foobar + maxVersion: foobar + cipherSuites: + - foobar + - foobar + curvePreferences: + - foobar + - foobar + clientAuth: + caFiles: + - foobar + - foobar + clientAuthType: foobar + sniStrict: true + preferServerCipherSuites: true diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index c661f2e4f..d7aaba381 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -233,6 +233,7 @@ | `traefik/tls/options/Options0/curvePreferences/1` | `foobar` | | `traefik/tls/options/Options0/maxVersion` | `foobar` | | `traefik/tls/options/Options0/minVersion` | `foobar` | +| `traefik/tls/options/Options0/preferServerCipherSuites` | `true` | | `traefik/tls/options/Options0/sniStrict` | `true` | | `traefik/tls/options/Options1/cipherSuites/0` | `foobar` | | `traefik/tls/options/Options1/cipherSuites/1` | `foobar` | @@ -243,6 +244,7 @@ | `traefik/tls/options/Options1/curvePreferences/1` | `foobar` | | `traefik/tls/options/Options1/maxVersion` | `foobar` | | `traefik/tls/options/Options1/minVersion` | `foobar` | +| `traefik/tls/options/Options1/preferServerCipherSuites` | `true` | | `traefik/tls/options/Options1/sniStrict` | `true` | | `traefik/tls/stores/Store0/defaultCertificate/certFile` | `foobar` | | `traefik/tls/stores/Store0/defaultCertificate/keyFile` | `foobar` | diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml index c68d3900a..6f0c80143 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml @@ -35,7 +35,7 @@ spec: - secretCA1 - secretCA2 clientAuthType: VerifyClientCertIfGiven - + preferServerCipherSuites: true --- apiVersion: v1 kind: Secret diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml index 93ec20239..a5dd706b8 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml @@ -35,6 +35,7 @@ spec: - secretCA1 - secretCA2 clientAuthType: VerifyClientCertIfGiven + preferServerCipherSuites: true --- apiVersion: traefik.containo.us/v1alpha1 diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index c4ff55019..98d4c2336 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -501,7 +501,8 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options CAFiles: clientCAs, ClientAuthType: tlsOption.Spec.ClientAuth.ClientAuthType, }, - SniStrict: tlsOption.Spec.SniStrict, + SniStrict: tlsOption.Spec.SniStrict, + PreferServerCipherSuites: tlsOption.Spec.PreferServerCipherSuites, } } return tlsOptions diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index cfee54b7c..0bb8ce165 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -423,7 +423,8 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, ClientAuthType: "VerifyClientCertIfGiven", }, - SniStrict: true, + SniStrict: true, + PreferServerCipherSuites: true, }, }, }, @@ -1896,7 +1897,8 @@ func TestLoadIngressRoutes(t *testing.T) { }, ClientAuthType: "VerifyClientCertIfGiven", }, - SniStrict: true, + SniStrict: true, + PreferServerCipherSuites: true, }, }, }, diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go index 36f7f89f3..ed0e0df62 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go @@ -19,12 +19,13 @@ type TLSOption struct { // TLSOptionSpec configures TLS for an entry point type TLSOptionSpec struct { - MinVersion string `json:"minVersion,omitempty"` - MaxVersion string `json:"maxVersion,omitempty"` - CipherSuites []string `json:"cipherSuites,omitempty"` - CurvePreferences []string `json:"curvePreferences,omitempty"` - ClientAuth ClientAuth `json:"clientAuth,omitempty"` - SniStrict bool `json:"sniStrict,omitempty"` + MinVersion string `json:"minVersion,omitempty"` + MaxVersion string `json:"maxVersion,omitempty"` + CipherSuites []string `json:"cipherSuites,omitempty"` + CurvePreferences []string `json:"curvePreferences,omitempty"` + ClientAuth ClientAuth `json:"clientAuth,omitempty"` + SniStrict bool `json:"sniStrict,omitempty"` + PreferServerCipherSuites bool `json:"preferServerCipherSuites,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index 36342dc39..f4014d6bd 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -16,12 +16,13 @@ type ClientAuth struct { // Options configures TLS for an entry point type Options struct { - MinVersion string `json:"minVersion,omitempty" toml:"minVersion,omitempty" yaml:"minVersion,omitempty" export:"true"` - MaxVersion string `json:"maxVersion,omitempty" toml:"maxVersion,omitempty" yaml:"maxVersion,omitempty" export:"true"` - CipherSuites []string `json:"cipherSuites,omitempty" toml:"cipherSuites,omitempty" yaml:"cipherSuites,omitempty"` - CurvePreferences []string `json:"curvePreferences,omitempty" toml:"curvePreferences,omitempty" yaml:"curvePreferences,omitempty"` - ClientAuth ClientAuth `json:"clientAuth,omitempty" toml:"clientAuth,omitempty" yaml:"clientAuth,omitempty"` - SniStrict bool `json:"sniStrict,omitempty" toml:"sniStrict,omitempty" yaml:"sniStrict,omitempty" export:"true"` + MinVersion string `json:"minVersion,omitempty" toml:"minVersion,omitempty" yaml:"minVersion,omitempty" export:"true"` + MaxVersion string `json:"maxVersion,omitempty" toml:"maxVersion,omitempty" yaml:"maxVersion,omitempty" export:"true"` + CipherSuites []string `json:"cipherSuites,omitempty" toml:"cipherSuites,omitempty" yaml:"cipherSuites,omitempty"` + CurvePreferences []string `json:"curvePreferences,omitempty" toml:"curvePreferences,omitempty" yaml:"curvePreferences,omitempty"` + ClientAuth ClientAuth `json:"clientAuth,omitempty" toml:"clientAuth,omitempty" yaml:"clientAuth,omitempty"` + SniStrict bool `json:"sniStrict,omitempty" toml:"sniStrict,omitempty" yaml:"sniStrict,omitempty" export:"true"` + PreferServerCipherSuites bool `json:"preferServerCipherSuites,omitempty" toml:"preferServerCipherSuites,omitempty" yaml:"preferServerCipherSuites,omitempty" export:"true"` } // +k8s:deepcopy-gen=true diff --git a/pkg/tls/tlsmanager.go b/pkg/tls/tlsmanager.go index 6e81a2fdb..d2c30b96a 100644 --- a/pkg/tls/tlsmanager.go +++ b/pkg/tls/tlsmanager.go @@ -219,6 +219,9 @@ func buildTLSConfig(tlsOption Options) (*tls.Config, error) { } } + // Set PreferServerCipherSuites. + conf.PreferServerCipherSuites = tlsOption.PreferServerCipherSuites + // Set the minimum TLS version if set in the config if minConst, exists := MinVersion[tlsOption.MinVersion]; exists { conf.PreferServerCipherSuites = true