diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b7c5751d..282726ccc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [v2.1.9](https://github.com/containous/traefik/tree/v2.1.9) (2020-03-23) +[All Commits](https://github.com/containous/traefik/compare/v2.1.8...v2.1.9) + +**Bug fixes:** +- **[provider,sticky-session]** Fix sameSite ([#6538](https://github.com/containous/traefik/pull/6538) by [ldez](https://github.com/ldez)) +- **[server]** Force http/1.1 for upgrade ([#6554](https://github.com/containous/traefik/pull/6554) by [juliens](https://github.com/juliens)) + +**Documentation:** +- Fix tab name ([#6543](https://github.com/containous/traefik/pull/6543) by [mavimo](https://github.com/mavimo)) + ## [v2.2.0-rc4](https://github.com/containous/traefik/tree/v2.2.0-rc4) (2020-03-19) [All Commits](https://github.com/containous/traefik/compare/v2.2.0-rc3...v2.2.0-rc4) diff --git a/build.Dockerfile b/build.Dockerfile index f060e91f3..eb88c53d5 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \ && chmod +x /usr/local/bin/go-bindata # Download golangci-lint binary to bin folder in $GOPATH -RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.6 +RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.8 # Download misspell binary to bin folder in $GOPATH RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4 diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index f5986f431..7965ff1a5 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -151,6 +151,7 @@ - "traefik.http.services.service01.loadbalancer.sticky.cookie.httponly=true" - "traefik.http.services.service01.loadbalancer.sticky.cookie.name=foobar" - "traefik.http.services.service01.loadbalancer.sticky.cookie.secure=true" +- "traefik.http.services.service01.loadbalancer.sticky.cookie.samesite=foobar" - "traefik.http.services.service01.loadbalancer.server.port=foobar" - "traefik.http.services.service01.loadbalancer.server.scheme=foobar" - "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index fd35f2b1e..8691af9cb 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -43,6 +43,7 @@ name = "foobar" secure = true httpOnly = true + sameSite = "foobar" [[http.services.Service01.loadBalancer.servers]] url = "foobar" @@ -89,6 +90,7 @@ name = "foobar" secure = true httpOnly = true + sameSite = "foobar" [http.middlewares] [http.middlewares.Middleware00] [http.middlewares.Middleware00.addPrefix] diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index 432201fd7..2537abee7 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -52,6 +52,7 @@ http: name: foobar secure: true httpOnly: true + sameSite: foobar servers: - url: foobar - url: foobar @@ -90,6 +91,7 @@ http: name: foobar secure: true httpOnly: true + sameSite: foobar middlewares: Middleware00: addPrefix: diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index cbfa364c8..ccb16a95b 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -173,6 +173,7 @@ | `traefik/http/services/Service01/loadBalancer/servers/1/url` | `foobar` | | `traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly` | `true` | | `traefik/http/services/Service01/loadBalancer/sticky/cookie/name` | `foobar` | +| `traefik/http/services/Service01/loadBalancer/sticky/cookie/sameSite` | `foobar` | | `traefik/http/services/Service01/loadBalancer/sticky/cookie/secure` | `true` | | `traefik/http/services/Service02/mirroring/maxBodySize` | `42` | | `traefik/http/services/Service02/mirroring/mirrors/0/name` | `foobar` | @@ -186,6 +187,7 @@ | `traefik/http/services/Service03/weighted/services/1/weight` | `42` | | `traefik/http/services/Service03/weighted/sticky/cookie/httpOnly` | `true` | | `traefik/http/services/Service03/weighted/sticky/cookie/name` | `foobar` | +| `traefik/http/services/Service03/weighted/sticky/cookie/sameSite` | `foobar` | | `traefik/http/services/Service03/weighted/sticky/cookie/secure` | `true` | | `traefik/tcp/routers/TCPRouter0/entryPoints/0` | `foobar` | | `traefik/tcp/routers/TCPRouter0/entryPoints/1` | `foobar` | diff --git a/docs/content/reference/dynamic-configuration/marathon-labels.json b/docs/content/reference/dynamic-configuration/marathon-labels.json index 0a125f331..a6765cd25 100644 --- a/docs/content/reference/dynamic-configuration/marathon-labels.json +++ b/docs/content/reference/dynamic-configuration/marathon-labels.json @@ -148,6 +148,7 @@ "traefik.http.services.service01.loadbalancer.sticky.cookie.httponly": "true", "traefik.http.services.service01.loadbalancer.sticky.cookie.name": "foobar", "traefik.http.services.service01.loadbalancer.sticky.cookie.secure": "true", +"traefik.http.services.service01.loadbalancer.sticky.cookie.samesite": "foobar", "traefik.http.services.service01.loadbalancer.server.port": "foobar", "traefik.http.services.service01.loadbalancer.server.scheme": "foobar", "traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar", diff --git a/docs/content/routing/providers/consul-catalog.md b/docs/content/routing/providers/consul-catalog.md index 1c23218fd..425bb369e 100644 --- a/docs/content/routing/providers/consul-catalog.md +++ b/docs/content/routing/providers/consul-catalog.md @@ -233,6 +233,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 0d1016e31..44e183c63 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -366,6 +366,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 786a07432..18a462956 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -340,6 +340,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne httpOnly: true name: cookie secure: true + sameSite: none strategy: RoundRobin weight: 10 tls: # [9] diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index c222ff319..95622b002 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -290,14 +290,6 @@ which in turn will create the resulting routers, services, handlers, etc. traefik.ingress.kubernetes.io/service.sticky: "true" ``` -??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.httponly`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true" - ``` - ??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.name`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. @@ -314,6 +306,22 @@ which in turn will create the resulting routers, services, handlers, etc. traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true" ``` +??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none" + ``` + +??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.httponly`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true" + ``` + ### TLS #### Communication Between Traefik and Pods diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index d0698f775..b778e17f4 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -214,6 +214,14 @@ A Story of key & values |---------------------------------------------------------------------|--------| | `traefik/http/services/myservice/loadbalancer/sticky/cookie/secure` | `true` | +??? info "`traefik/http/services//loadbalancer/sticky/cookie/samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + | Key (Path) | Value | + |-----------------------------------------------------------------------|--------| + | `traefik/http/services/myservice/loadbalancer/sticky/cookie/samesite` | `none` | + ??? info "`traefik/http/services//loadbalancer/responseforwarding/flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. @@ -264,6 +272,12 @@ A Story of key & values |----------------------------------------------------------------------|--------| | `traefik/http/services//weighted/sticky/cookie/secure` | `true` | +??? info "`traefik/http/services//weighted/sticky/cookie/samesite`" + + | Key (Path) | Value | + |------------------------------------------------------------------------|--------| + | `traefik/http/services//weighted/sticky/cookie/samesite` | `none` | + ??? info "`traefik/http/services//weighted/sticky/cookie/httpOnly`" | Key (Path) | Value | diff --git a/docs/content/routing/providers/marathon.md b/docs/content/routing/providers/marathon.md index 79cc63461..9fbb04c7b 100644 --- a/docs/content/routing/providers/marathon.md +++ b/docs/content/routing/providers/marathon.md @@ -264,6 +264,14 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure": "true" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```json + "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite": "none" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/providers/rancher.md b/docs/content/routing/providers/rancher.md index a23a5fe2a..66d66cf5d 100644 --- a/docs/content/routing/providers/rancher.md +++ b/docs/content/routing/providers/rancher.md @@ -270,6 +270,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index 8211b0cd0..c5ab39e0b 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -182,9 +182,12 @@ On subsequent requests, to keep the session alive with the same server, the clie The default cookie name is an abbreviation of a sha1 (ex: `_1d52e`). -!!! info "Secure & HTTPOnly flags" +!!! info "Secure & HTTPOnly & SameSite flags" - By default, the affinity cookie is created without those flags. One however can change that through configuration. + By default, the affinity cookie is created without those flags. + One however can change that through configuration. + + `SameSite` can be `none`, `lax`, `strict` or empty. ??? example "Adding Stickiness -- Using the [File Provider](../../providers/file.md)" @@ -215,6 +218,7 @@ On subsequent requests, to keep the session alive with the same server, the clie name = "my_sticky_cookie_name" secure = true httpOnly = true + sameSite = "none" ``` ```yaml tab="YAML" diff --git a/go.mod b/go.mod index 1d38a1cd1..26ed7f528 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/google/go-github/v28 v28.1.1 github.com/googleapis/gnostic v0.1.0 // indirect github.com/gorilla/mux v1.7.3 - github.com/gorilla/websocket v1.4.1 + github.com/gorilla/websocket v1.4.2 github.com/hashicorp/consul/api v1.3.0 github.com/hashicorp/go-version v1.2.0 github.com/huandu/xstrings v1.2.0 // indirect @@ -81,7 +81,7 @@ require ( github.com/unrolled/render v1.0.2 github.com/unrolled/secure v1.0.7 github.com/vdemeester/shakers v0.1.0 - github.com/vulcand/oxy v1.0.0 + github.com/vulcand/oxy v1.1.0 github.com/vulcand/predicate v1.1.0 go.elastic.co/apm v1.7.0 go.elastic.co/apm/module/apmot v1.7.0 diff --git a/go.sum b/go.sum index 8a8d6a3f0..ed7a16587 100644 --- a/go.sum +++ b/go.sum @@ -377,8 +377,8 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f h1:68WxnfBzJRYktZ30fmIjGQ74RsXYLoeH2/NITPktTMY= github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -732,8 +732,8 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/shakers v0.1.0 h1:K+n9sSyUCg2ywmZkv+3c7vsYZfivcfKhMh8kRxCrONM= github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ= -github.com/vulcand/oxy v1.0.0 h1:7vL5/pjDFzHGbtBEhmlHITUi6KLH4xXTDF33/wrdRKw= -github.com/vulcand/oxy v1.0.0/go.mod h1:6EXgOAl6CRa46/2ZGcDJKf3ywJUp5WtT7vSlGSkvecI= +github.com/vulcand/oxy v1.1.0 h1:DbBijGo1+6cFqR9jarkMxasdj0lgWwrrFtue6ijek4Q= +github.com/vulcand/oxy v1.1.0/go.mod h1:ADiMYHi8gkGl2987yQIzDRoXZilANF4WtKaQ92OppKY= github.com/vulcand/predicate v1.1.0 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg= github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg= github.com/vultr/govultr v0.1.4 h1:UnNMixYFVO0p80itc8PcweoVENyo1PasfvwKhoasR9U= @@ -1119,6 +1119,7 @@ k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKf k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index dc999fa1d..9261fe637 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -113,6 +113,7 @@ type Cookie struct { Name string `json:"name,omitempty" toml:"name,omitempty" yaml:"name,omitempty"` Secure bool `json:"secure,omitempty" toml:"secure,omitempty" yaml:"secure,omitempty"` HTTPOnly bool `json:"httpOnly,omitempty" toml:"httpOnly,omitempty" yaml:"httpOnly,omitempty"` + SameSite string `json:"sameSite,omitempty" toml:"sameSite,omitempty" yaml:"sameSite,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/ingress/annotations_test.go b/pkg/provider/kubernetes/ingress/annotations_test.go index 751192d2d..9a461a720 100644 --- a/pkg/provider/kubernetes/ingress/annotations_test.go +++ b/pkg/provider/kubernetes/ingress/annotations_test.go @@ -109,6 +109,7 @@ func Test_parseServiceConfig(t *testing.T) { "traefik.ingress.kubernetes.io/service.sticky.cookie.httponly": "true", "traefik.ingress.kubernetes.io/service.sticky.cookie.name": "foobar", "traefik.ingress.kubernetes.io/service.sticky.cookie.secure": "true", + "traefik.ingress.kubernetes.io/service.sticky.cookie.samesite": "none", }, expected: &ServiceConfig{ Service: &ServiceIng{ @@ -117,6 +118,7 @@ func Test_parseServiceConfig(t *testing.T) { Name: "foobar", Secure: true, HTTPOnly: true, + SameSite: "none", }, }, ServersScheme: "protocol", diff --git a/pkg/server/service/roundtripper.go b/pkg/server/service/roundtripper.go index f232049a6..715d5d5c2 100644 --- a/pkg/server/service/roundtripper.go +++ b/pkg/server/service/roundtripper.go @@ -23,12 +23,12 @@ func (t *h2cTransportWrapper) RoundTrip(req *http.Request) (*http.Response, erro return t.Transport.RoundTrip(req) } -// createHTTPTransport creates an http.Transport configured with the Transport configuration settings. +// createRoundtripper creates an http.Roundtripper configured with the Transport configuration settings. // For the settings that can't be configured in Traefik it uses the default http.Transport settings. // An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost // in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing // behavior and backwards compatibility issues. -func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http.Transport, error) { +func createRoundtripper(transportConfiguration *static.ServersTransport) (http.RoundTripper, error) { if transportConfiguration == nil { return nil, errors.New("no transport configuration given") } @@ -66,25 +66,26 @@ func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http transport.IdleConnTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.IdleConnTimeout) } - if transportConfiguration.InsecureSkipVerify { - transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - } - - if len(transportConfiguration.RootCAs) > 0 { + if transportConfiguration.InsecureSkipVerify || len(transportConfiguration.RootCAs) > 0 { transport.TLSClientConfig = &tls.Config{ - RootCAs: createRootCACertPool(transportConfiguration.RootCAs), + InsecureSkipVerify: transportConfiguration.InsecureSkipVerify, + RootCAs: createRootCACertPool(transportConfiguration.RootCAs), } } - err := http2.ConfigureTransport(transport) + smartTransport, err := newSmartRoundTripper(transport) if err != nil { return nil, err } - return transport, nil + return smartTransport, nil } func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool { + if len(rootCAs) == 0 { + return nil + } + roots := x509.NewCertPool() for _, cert := range rootCAs { @@ -100,7 +101,7 @@ func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool { } func setupDefaultRoundTripper(conf *static.ServersTransport) http.RoundTripper { - transport, err := createHTTPTransport(conf) + transport, err := createRoundtripper(conf) if err != nil { log.WithoutContext().Errorf("Could not configure HTTP Transport, fallbacking on default transport: %v", err) return http.DefaultTransport diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go index ff5c510f4..c2288d161 100644 --- a/pkg/server/service/service.go +++ b/pkg/server/service/service.go @@ -295,8 +295,15 @@ func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, servi var cookieName string if service.Sticky != nil && service.Sticky.Cookie != nil { cookieName = cookie.GetName(service.Sticky.Cookie.Name, serviceName) - opts := roundrobin.CookieOptions{HTTPOnly: service.Sticky.Cookie.HTTPOnly, Secure: service.Sticky.Cookie.Secure} + + opts := roundrobin.CookieOptions{ + HTTPOnly: service.Sticky.Cookie.HTTPOnly, + Secure: service.Sticky.Cookie.Secure, + SameSite: convertSameSite(service.Sticky.Cookie.SameSite), + } + options = append(options, roundrobin.EnableStickySession(roundrobin.NewStickySessionWithOptions(cookieName, opts))) + logger.Debugf("Sticky session cookie name: %v", cookieName) } @@ -332,3 +339,16 @@ func (m *Manager) upsertServers(ctx context.Context, lb healthcheck.BalancerHand } return nil } + +func convertSameSite(sameSite string) http.SameSite { + switch sameSite { + case "none": + return http.SameSiteNoneMode + case "lax": + return http.SameSiteLaxMode + case "strict": + return http.SameSiteStrictMode + default: + return 0 + } +} diff --git a/pkg/server/service/smart_roundtripper.go b/pkg/server/service/smart_roundtripper.go new file mode 100644 index 000000000..9a3028720 --- /dev/null +++ b/pkg/server/service/smart_roundtripper.go @@ -0,0 +1,38 @@ +package service + +import ( + "net/http" + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2" +) + +func newSmartRoundTripper(transport *http.Transport) (http.RoundTripper, error) { + transportHTTP1 := transport.Clone() + + err := http2.ConfigureTransport(transport) + if err != nil { + return nil, err + } + + return &smartRoundTripper{ + http2: transport, + http: transportHTTP1, + }, nil +} + +type smartRoundTripper struct { + http2 *http.Transport + http *http.Transport +} + +// smartRoundTripper implements RoundTrip while making sure that HTTP/2 is not used +// with protocols that start with a Connection Upgrade, such as SPDY or Websocket. +func (m *smartRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + // If we have a connection upgrade, we don't use HTTP/2 + if httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") { + return m.http.RoundTrip(req) + } + + return m.http2.RoundTrip(req) +}