diff --git a/.golangci.toml b/.golangci.toml index ed8ac7b22..b1499a28e 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -107,6 +107,10 @@ "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked", "should have a package comment, unless it's in another file for this package", "SA1019: http.CloseNotifier has been deprecated", # FIXME must be fixed + "SA1019: cfg.SSLRedirect is deprecated", + "SA1019: cfg.SSLTemporaryRedirect is deprecated", + "SA1019: cfg.SSLHost is deprecated", + "SA1019: cfg.SSLForceHost is deprecated", ] [[issues.exclude-rules]] path = "(.+)_test.go" diff --git a/docs/content/middlewares/headers.md b/docs/content/middlewares/headers.md index 1c720524a..e6910f52f 100644 --- a/docs/content/middlewares/headers.md +++ b/docs/content/middlewares/headers.md @@ -133,13 +133,13 @@ http: ### Using Security Headers -Security-related headers (HSTS headers, SSL redirection, Browser XSS filter, etc) can be managed similarly to custom headers as shown above. +Security-related headers (HSTS headers, Browser XSS filter, etc) can be managed similarly to custom headers as shown above. This functionality makes it possible to easily use security features by adding headers. ```yaml tab="Docker" labels: - "traefik.http.middlewares.testHeader.headers.framedeny=true" - - "traefik.http.middlewares.testHeader.headers.sslredirect=true" + - "traefik.http.middlewares.testHeader.headers.browserxssfilter=true" ``` ```yaml tab="Kubernetes" @@ -150,32 +150,32 @@ metadata: spec: headers: frameDeny: true - sslRedirect: true + browserxssfilter: true ``` ```yaml tab="Consul Catalog" - "traefik.http.middlewares.testheader.headers.framedeny=true" -- "traefik.http.middlewares.testheader.headers.sslredirect=true" +- "traefik.http.middlewares.testheader.headers.browserxssfilter=true" ``` ```json tab="Marathon" "labels": { "traefik.http.middlewares.testheader.headers.framedeny": "true", - "traefik.http.middlewares.testheader.headers.sslredirect": "true" + "traefik.http.middlewares.testheader.headers.browserxssfilter": "true" } ``` ```yaml tab="Rancher" labels: - "traefik.http.middlewares.testheader.headers.framedeny=true" - - "traefik.http.middlewares.testheader.headers.sslredirect=true" + - "traefik.http.middlewares.testheader.headers.browserxssfilter=true" ``` ```toml tab="File (TOML)" [http.middlewares] [http.middlewares.testHeader.headers] frameDeny = true - sslRedirect = true + browserxssfilter = true ``` ```yaml tab="File (YAML)" @@ -184,7 +184,7 @@ http: testHeader: headers: frameDeny: true - sslRedirect: true + browserxssfilter: true ``` ### CORS Headers @@ -347,14 +347,26 @@ The `hostsProxyHeaders` option is a set of header keys that may hold a proxied h ### `sslRedirect` +!!! warning + + Deprecated in favor of [EntryPoint redirection](../routing/entrypoints.md#redirection) or the [RedirectScheme middleware](./redirectscheme.md). + The `sslRedirect` only allow HTTPS requests when set to `true`. ### `sslTemporaryRedirect` +!!! warning + + Deprecated in favor of [EntryPoint redirection](../routing/entrypoints.md#redirection) or the [RedirectScheme middleware](./redirectscheme.md). + Set `sslTemporaryRedirect` to `true` to force an SSL redirection using a 302 (instead of a 301). ### `sslHost` +!!! warning + + Deprecated in favor of the [RedirectRegex middleware](./redirectregex.md). + The `sslHost` option is the host name that is used to redirect HTTP requests to HTTPS. ### `sslProxyHeaders` @@ -364,6 +376,10 @@ It can be useful when using other proxies (example: `"X-Forwarded-Proto": "https ### `sslForceHost` +!!! warning + + Deprecated in favor of the [RedirectRegex middleware](./redirectregex.md). + Set `sslForceHost` to `true` and set `sslHost` to force requests to use `SSLHost` regardless of whether they already use SSL. ### `stsSeconds` diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index f4b9c8efc..be915c69c 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -386,3 +386,13 @@ Traefik now supports only v1.14+ Kubernetes clusters, which means the support of The `extensions/v1beta1` API Version should now be replaced either by `networking.k8s.io/v1beta1` or by `networking.k8s.io/v1` (as of Kubernetes v1.19+). The support of the `networking.k8s.io/v1beta1` API Version will stop in Kubernetes v1.22. + +## v2.5 to v2.6 + +### Headers middleware: ssl redirect options + +`sslRedirect`, `sslTemporaryRedirect`, `sslHost` and `sslForceHost` are deprecated in Traefik v2.5. + +For simple HTTP to HTTPS redirection, you may use [EntryPoints redirections](../routing/entrypoints.md#redirection). + +For more advanced use cases, you can use either the [RedirectScheme middleware](../middlewares/redirectscheme.md) or the [RedirectRegex middleware](../middlewares/redirectregex.md). diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml index c8feae735..739b37e80 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml @@ -319,16 +319,22 @@ spec: referrerPolicy: type: string sslForceHost: + description: 'Deprecated: use RedirectRegex instead.' type: boolean sslHost: + description: 'Deprecated: use RedirectRegex instead.' type: string sslProxyHeaders: additionalProperties: type: string type: object sslRedirect: + description: 'Deprecated: use EntryPoint redirection or RedirectScheme + instead.' type: boolean sslTemporaryRedirect: + description: 'Deprecated: use EntryPoint redirection or RedirectScheme + instead.' type: boolean stsIncludeSubdomains: type: boolean diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index 9810d3314..a86e66556 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -746,16 +746,22 @@ spec: referrerPolicy: type: string sslForceHost: + description: 'Deprecated: use RedirectRegex instead.' type: boolean sslHost: + description: 'Deprecated: use RedirectRegex instead.' type: string sslProxyHeaders: additionalProperties: type: string type: object sslRedirect: + description: 'Deprecated: use EntryPoint redirection or RedirectScheme + instead.' type: boolean sslTemporaryRedirect: + description: 'Deprecated: use EntryPoint redirection or RedirectScheme + instead.' type: boolean stsIncludeSubdomains: type: boolean diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index b931de0d4..039bd667d 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -164,27 +164,31 @@ type Headers struct { // AddVaryHeader controls if the Vary header is automatically added/updated when the AccessControlAllowOrigin is set. AddVaryHeader bool `json:"addVaryHeader,omitempty" toml:"addVaryHeader,omitempty" yaml:"addVaryHeader,omitempty" export:"true"` - AllowedHosts []string `json:"allowedHosts,omitempty" toml:"allowedHosts,omitempty" yaml:"allowedHosts,omitempty"` - HostsProxyHeaders []string `json:"hostsProxyHeaders,omitempty" toml:"hostsProxyHeaders,omitempty" yaml:"hostsProxyHeaders,omitempty" export:"true"` - SSLRedirect bool `json:"sslRedirect,omitempty" toml:"sslRedirect,omitempty" yaml:"sslRedirect,omitempty" export:"true"` - SSLTemporaryRedirect bool `json:"sslTemporaryRedirect,omitempty" toml:"sslTemporaryRedirect,omitempty" yaml:"sslTemporaryRedirect,omitempty" export:"true"` - SSLHost string `json:"sslHost,omitempty" toml:"sslHost,omitempty" yaml:"sslHost,omitempty"` - SSLProxyHeaders map[string]string `json:"sslProxyHeaders,omitempty" toml:"sslProxyHeaders,omitempty" yaml:"sslProxyHeaders,omitempty"` - SSLForceHost bool `json:"sslForceHost,omitempty" toml:"sslForceHost,omitempty" yaml:"sslForceHost,omitempty" export:"true"` - STSSeconds int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty" export:"true"` - STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty" toml:"stsIncludeSubdomains,omitempty" yaml:"stsIncludeSubdomains,omitempty" export:"true"` - STSPreload bool `json:"stsPreload,omitempty" toml:"stsPreload,omitempty" yaml:"stsPreload,omitempty" export:"true"` - ForceSTSHeader bool `json:"forceSTSHeader,omitempty" toml:"forceSTSHeader,omitempty" yaml:"forceSTSHeader,omitempty" export:"true"` - FrameDeny bool `json:"frameDeny,omitempty" toml:"frameDeny,omitempty" yaml:"frameDeny,omitempty" export:"true"` - CustomFrameOptionsValue string `json:"customFrameOptionsValue,omitempty" toml:"customFrameOptionsValue,omitempty" yaml:"customFrameOptionsValue,omitempty"` - ContentTypeNosniff bool `json:"contentTypeNosniff,omitempty" toml:"contentTypeNosniff,omitempty" yaml:"contentTypeNosniff,omitempty" export:"true"` - BrowserXSSFilter bool `json:"browserXssFilter,omitempty" toml:"browserXssFilter,omitempty" yaml:"browserXssFilter,omitempty" export:"true"` - CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty" toml:"customBrowserXSSValue,omitempty" yaml:"customBrowserXSSValue,omitempty"` - ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty" toml:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"` - PublicKey string `json:"publicKey,omitempty" toml:"publicKey,omitempty" yaml:"publicKey,omitempty"` - ReferrerPolicy string `json:"referrerPolicy,omitempty" toml:"referrerPolicy,omitempty" yaml:"referrerPolicy,omitempty" export:"true"` - FeaturePolicy string `json:"featurePolicy,omitempty" toml:"featurePolicy,omitempty" yaml:"featurePolicy,omitempty" export:"true"` - IsDevelopment bool `json:"isDevelopment,omitempty" toml:"isDevelopment,omitempty" yaml:"isDevelopment,omitempty" export:"true"` + AllowedHosts []string `json:"allowedHosts,omitempty" toml:"allowedHosts,omitempty" yaml:"allowedHosts,omitempty"` + HostsProxyHeaders []string `json:"hostsProxyHeaders,omitempty" toml:"hostsProxyHeaders,omitempty" yaml:"hostsProxyHeaders,omitempty" export:"true"` + // Deprecated: use EntryPoint redirection or RedirectScheme instead. + SSLRedirect bool `json:"sslRedirect,omitempty" toml:"sslRedirect,omitempty" yaml:"sslRedirect,omitempty" export:"true"` + // Deprecated: use EntryPoint redirection or RedirectScheme instead. + SSLTemporaryRedirect bool `json:"sslTemporaryRedirect,omitempty" toml:"sslTemporaryRedirect,omitempty" yaml:"sslTemporaryRedirect,omitempty" export:"true"` + // Deprecated: use RedirectRegex instead. + SSLHost string `json:"sslHost,omitempty" toml:"sslHost,omitempty" yaml:"sslHost,omitempty"` + SSLProxyHeaders map[string]string `json:"sslProxyHeaders,omitempty" toml:"sslProxyHeaders,omitempty" yaml:"sslProxyHeaders,omitempty"` + // Deprecated: use RedirectRegex instead. + SSLForceHost bool `json:"sslForceHost,omitempty" toml:"sslForceHost,omitempty" yaml:"sslForceHost,omitempty" export:"true"` + STSSeconds int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty" export:"true"` + STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty" toml:"stsIncludeSubdomains,omitempty" yaml:"stsIncludeSubdomains,omitempty" export:"true"` + STSPreload bool `json:"stsPreload,omitempty" toml:"stsPreload,omitempty" yaml:"stsPreload,omitempty" export:"true"` + ForceSTSHeader bool `json:"forceSTSHeader,omitempty" toml:"forceSTSHeader,omitempty" yaml:"forceSTSHeader,omitempty" export:"true"` + FrameDeny bool `json:"frameDeny,omitempty" toml:"frameDeny,omitempty" yaml:"frameDeny,omitempty" export:"true"` + CustomFrameOptionsValue string `json:"customFrameOptionsValue,omitempty" toml:"customFrameOptionsValue,omitempty" yaml:"customFrameOptionsValue,omitempty"` + ContentTypeNosniff bool `json:"contentTypeNosniff,omitempty" toml:"contentTypeNosniff,omitempty" yaml:"contentTypeNosniff,omitempty" export:"true"` + BrowserXSSFilter bool `json:"browserXssFilter,omitempty" toml:"browserXssFilter,omitempty" yaml:"browserXssFilter,omitempty" export:"true"` + CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty" toml:"customBrowserXSSValue,omitempty" yaml:"customBrowserXSSValue,omitempty"` + ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty" toml:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"` + PublicKey string `json:"publicKey,omitempty" toml:"publicKey,omitempty" yaml:"publicKey,omitempty"` + ReferrerPolicy string `json:"referrerPolicy,omitempty" toml:"referrerPolicy,omitempty" yaml:"referrerPolicy,omitempty" export:"true"` + FeaturePolicy string `json:"featurePolicy,omitempty" toml:"featurePolicy,omitempty" yaml:"featurePolicy,omitempty" export:"true"` + IsDevelopment bool `json:"isDevelopment,omitempty" toml:"isDevelopment,omitempty" yaml:"isDevelopment,omitempty" export:"true"` } // HasCustomHeadersDefined checks to see if any of the custom header elements have been set. diff --git a/pkg/middlewares/headers/headers.go b/pkg/middlewares/headers/headers.go index 39594494a..d84bbe4d3 100644 --- a/pkg/middlewares/headers/headers.go +++ b/pkg/middlewares/headers/headers.go @@ -23,6 +23,18 @@ func handleDeprecation(ctx context.Context, cfg *dynamic.Headers) { cfg.AccessControlAllowOriginList = append(cfg.AccessControlAllowOriginList, cfg.AccessControlAllowOrigin) cfg.AccessControlAllowOrigin = "" } + if cfg.SSLRedirect { + log.FromContext(ctx).Warn("SSLRedirect is deprecated, please use entrypoint redirection instead.") + } + if cfg.SSLTemporaryRedirect { + log.FromContext(ctx).Warn("SSLTemporaryRedirect is deprecated, please use entrypoint redirection instead.") + } + if cfg.SSLHost != "" { + log.FromContext(ctx).Warn("SSLHost is deprecated, please use RedirectRegex middleware instead.") + } + if cfg.SSLForceHost { + log.FromContext(ctx).Warn("SSLForceHost is deprecated, please use RedirectScheme middleware instead.") + } } type headers struct {