diff --git a/CHANGELOG.md b/CHANGELOG.md index 21fff0eeea..3c82f886b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +## [v3.6.15](https://github.com/traefik/traefik/tree/v3.6.15) (2026-04-29) +[All Commits](https://github.com/traefik/traefik/compare/v3.6.14...v3.6.15) + +**Bug fixes:** +- **[acme]** Bump github.com/go-acme/lego/v4 to v4.35.2 ([#13043](https://github.com/traefik/traefik/pull/13043) @ldez) +- **[acme]** Bump github.com/go-acme/lego/v4 to v4.35.1 ([#13027](https://github.com/traefik/traefik/pull/13027) @ldez) +- **[middleware]** Add errorRequestHeaders option to Errors middleware ([#13034](https://github.com/traefik/traefik/pull/13034) @gndz07) +- **[k8s/ingress-nginx]** Do not require a port for ExternalName services ([#13033](https://github.com/traefik/traefik/pull/13033) @kevinpollet) +- **[server]** Bump github.com/vulcand/oxy to v2.1.0 ([#13046](https://github.com/traefik/traefik/pull/13046) @ldez) + +**Misc:** +- Make FLAGS Make variable usable ([#13009](https://github.com/traefik/traefik/pull/13009) @twz123) + +## [v2.11.44](https://github.com/traefik/traefik/tree/v2.11.44) (2026-04-29) +[All Commits](https://github.com/traefik/traefik/compare/v2.11.43...v2.11.44) + +**Bug fixes:** +- **[middleware]** Add errorRequestHeaders option to Errors middleware ([#13034](https://github.com/traefik/traefik/pull/13034) @gndz07) +- **[acme]** Bump github.com/go-acme/lego to v4.35.2 ([#13052](https://github.com/traefik/traefik/pull/13052) @mmatur) + +**Misc:** +- Make FLAGS Make variable usable ([#13009](https://github.com/traefik/traefik/pull/13009) @twz123) + ## [v3.7.0-rc.2](https://github.com/traefik/traefik/tree/v3.7.0-rc.2) (2026-04-22) [All Commits](https://github.com/traefik/traefik/compare/v3.7.0-rc.1...v3.7.0-rc.2) diff --git a/Makefile b/Makefile index 24a2b6fc94..f3473d89b5 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ generate: #? binary: Build the binary binary: generate-webui dist @echo SHA: $(VERSION) $(CODENAME) $(DATE) - CGO_ENABLED=0 GOGC=${GOGC} GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS[*]} -ldflags "-s -w \ + CGO_ENABLED=0 GOGC=${GOGC} GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS} -ldflags "-s -w \ -X github.com/traefik/traefik/v3/pkg/version.Version=$(VERSION) \ -X github.com/traefik/traefik/v3/pkg/version.Codename=$(CODENAME) \ -X github.com/traefik/traefik/v3/pkg/version.BuildDate=$(DATE)" \ diff --git a/docs/content/migrate/v3.md b/docs/content/migrate/v3.md index 3e49bcdd41..cc0aa11666 100644 --- a/docs/content/migrate/v3.md +++ b/docs/content/migrate/v3.md @@ -80,6 +80,15 @@ Note: TLSOptions for `HostRegexp` matchers remains unsupported. Use wildcard `Ho --- +## v3.6.15 + +In `v3.6.15`, a new `errorRequestHeaders` option has been added to the Errors middleware. + +By default, the behavior is unchanged: all original request headers are forwarded to the error page service. +If the error page service is in a separate trust domain, consider using `errorRequestHeaders` to restrict which headers are forwarded. + +Please check out the [Error Pages](../reference/routing-configuration/http/middlewares/errorpages.md#errorRequestHeaders) middleware documentation for more details. + ## v3.6.14 ### Kubernetes CRD: Chain middleware and `allowCrossNamespace` diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index eb525ee3b4..d57ef4bc58 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -30,6 +30,7 @@ - "traefik.http.middlewares.middleware08.digestauth.removeheader=true" - "traefik.http.middlewares.middleware08.digestauth.users=foobar, foobar" - "traefik.http.middlewares.middleware08.digestauth.usersfile=foobar" +- "traefik.http.middlewares.middleware09.errors.errorrequestheaders=foobar, foobar" - "traefik.http.middlewares.middleware09.errors.query=foobar" - "traefik.http.middlewares.middleware09.errors.service=foobar" - "traefik.http.middlewares.middleware09.errors.status=foobar, foobar" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 7707ce2b8f..f9efa7e5f0 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -193,6 +193,7 @@ status = ["foobar", "foobar"] service = "foobar" query = "foobar" + errorRequestHeaders = ["foobar", "foobar"] [http.middlewares.Middleware09.errors.statusRewrites] name0 = 42 name1 = 42 diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index 929c625a43..691b618c38 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -208,6 +208,9 @@ http: name1: 42 service: foobar query: foobar + errorRequestHeaders: + - foobar + - foobar Middleware10: forwardAuth: address: foobar diff --git a/docs/content/reference/routing-configuration/http/middlewares/errorpages.md b/docs/content/reference/routing-configuration/http/middlewares/errorpages.md index 9f95b0acd4..94a3b83887 100644 --- a/docs/content/reference/routing-configuration/http/middlewares/errorpages.md +++ b/docs/content/reference/routing-configuration/http/middlewares/errorpages.md @@ -129,3 +129,12 @@ The table below lists all the available variables and their associated values. | `{status}` | The response status code. | | `{originalStatus}` | The original response status code, if it has been modified by the `statusRewrites` option. | | `{url}` | The [escaped](https://pkg.go.dev/net/url#QueryEscape) request URL.| + +### `errorRequestHeaders` + +Defines the list of original request headers forwarded to the error page service. + +By default (`errorRequestHeaders` not set), all request headers — including authentication material such as `Authorization` and `Cookie` — are forwarded. +If the error page service is in a separate trust domain, use this option to restrict which headers cross the service boundary. + +Set to an explicit list to forward only those headers, or set to an empty list (`errorRequestHeaders: []`) to forward no headers. diff --git a/docs/content/reference/routing-configuration/other-providers/file.toml b/docs/content/reference/routing-configuration/other-providers/file.toml index 61fe202c3a..098353827e 100644 --- a/docs/content/reference/routing-configuration/other-providers/file.toml +++ b/docs/content/reference/routing-configuration/other-providers/file.toml @@ -209,6 +209,7 @@ status = ["foobar", "foobar"] service = "foobar" query = "foobar" + errorRequestHeaders = ["foobar", "foobar"] [http.middlewares.Middleware10.errors.statusRewrites] name0 = 42 name1 = 42 diff --git a/docs/content/reference/routing-configuration/other-providers/file.yaml b/docs/content/reference/routing-configuration/other-providers/file.yaml index 21ddaeaf6c..8d2f918620 100644 --- a/docs/content/reference/routing-configuration/other-providers/file.yaml +++ b/docs/content/reference/routing-configuration/other-providers/file.yaml @@ -232,6 +232,9 @@ http: name1: 42 service: foobar query: foobar + errorRequestHeaders: + - foobar + - foobar Middleware11: forwardAuth: address: foobar diff --git a/go.mod b/go.mod index 52300b37b5..94e7dff172 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/docker/go-connections v0.6.0 github.com/fatih/structs v1.1.0 github.com/fsnotify/fsnotify v1.9.0 - github.com/go-acme/lego/v4 v4.35.1 + github.com/go-acme/lego/v4 v4.35.2 github.com/go-kit/kit v0.13.0 github.com/go-kit/log v0.2.1 github.com/golang/protobuf v1.5.4 @@ -78,7 +78,7 @@ require ( github.com/unrolled/render v1.0.2 github.com/unrolled/secure v1.0.9 github.com/valyala/fasthttp v1.69.0 - github.com/vulcand/oxy/v2 v2.0.3 + github.com/vulcand/oxy/v2 v2.1.0 github.com/vulcand/predicate v1.3.0 github.com/yuin/gopher-lua v1.1.1 go.opentelemetry.io/collector/pdata v1.41.0 @@ -148,7 +148,7 @@ require ( github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect - github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect + github.com/HdrHistogram/hdrhistogram-go v1.2.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect @@ -245,7 +245,7 @@ require ( github.com/googleapis/gax-go/v2 v2.21.0 // indirect github.com/gophercloud/gophercloud v1.14.1 // indirect github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect - github.com/gravitational/trace v1.5.0 // indirect + github.com/gravitational/trace v1.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -285,7 +285,7 @@ require ( github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect github.com/magiconair/properties v1.8.10 // indirect github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect - github.com/mailgun/multibuf v0.1.2 // indirect + github.com/mailgun/multibuf v0.2.0 // indirect github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -319,7 +319,7 @@ require ( github.com/nrdcg/namesilo v0.5.0 // indirect github.com/nrdcg/nodion v0.1.0 // indirect github.com/nrdcg/oci-go-sdk/common/v1065 v1065.113.0 // indirect - github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.112.0 // indirect + github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.113.0 // indirect github.com/nrdcg/porkbun v0.4.0 // indirect github.com/nrdcg/vegadns v0.3.0 // indirect github.com/nzdjb/go-metaname v1.0.0 // indirect @@ -427,7 +427,6 @@ replace ( github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e github.com/gorilla/mux => github.com/containous/mux v0.0.0-20250523120546-41b6ec3aed59 github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 - github.com/vulcand/oxy/v2 => github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf ) // ambiguous import: found package github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http in multiple modules diff --git a/go.sum b/go.sum index b848b6ba04..32d4100124 100644 --- a/go.sum +++ b/go.sum @@ -662,8 +662,9 @@ github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/HdrHistogram/hdrhistogram-go v1.2.0 h1:XMJkDWuz6bM9Fzy7zORuVFKH7ZJY41G2q8KWhVGkNiY= +github.com/HdrHistogram/hdrhistogram-go v1.2.0/go.mod h1:CiIeGiHSd06zjX+FypuEJ5EQ07KKtxZ+8J6hszwVQig= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -1027,8 +1028,8 @@ github.com/go-acme/esa-20240910/v2 v2.48.0 h1:muSDyhjDTejxUGe3FTthCPCqRaEdYY9cG3 github.com/go-acme/esa-20240910/v2 v2.48.0/go.mod h1:shPb6hzc1rJL15IJBY8HQ4GZk4E8RC52+52twutEwIg= github.com/go-acme/jdcloud-sdk-go v1.64.0 h1:AW9j5khk8tRYbpBJPxKmqdwIqgLs2Fz3HUK3hn2YXjs= github.com/go-acme/jdcloud-sdk-go v1.64.0/go.mod h1:qc/m8HNX1Zgd7GAv2DSEinup8fwy3Ted3/VVx7LB5bU= -github.com/go-acme/lego/v4 v4.35.1 h1:xTcEBsENs4Ek5EiNpN3JXy7W5aynf5KhJ6D/HuuhXv4= -github.com/go-acme/lego/v4 v4.35.1/go.mod h1:E+4l5mPPg9dwhTz6JJptNLvtj94E2JDObI50QuFJd3s= +github.com/go-acme/lego/v4 v4.35.2 h1:uVQg+KC/yj9R2g7Q9W5wDqhvQvxV5SMu5eqFVoN5xZU= +github.com/go-acme/lego/v4 v4.35.2/go.mod h1:pX2jN5n8OphMGY1IaMjYm5DAEzguBaKRt8AvJAgJXpc= github.com/go-acme/tencentclouddnspod v1.3.24 h1:uCSiOW1EJttcnOON+MVVyVDJguFL/Q4NIGkq1CrT9p8= github.com/go-acme/tencentclouddnspod v1.3.24/go.mod h1:RKcB2wSoZncjBA0OEFj59s1ko1XDy+ZsAtk+9uMxUF0= github.com/go-acme/tencentedgdeone v1.3.38 h1:5YsVl0H4A+cwtiUqR1eZbKFdr4OWfYp2KYJopifzKyQ= @@ -1293,8 +1294,8 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/gravitational/trace v1.5.0 h1:JbeL2HDGyzgy7G72Z2hP2gExEyA6Y2p7fCiSjyZwCJw= -github.com/gravitational/trace v1.5.0/go.mod h1:dxezSkKm880IIDx+czWG8fq+pLnXjETBewMgN3jOBlg= +github.com/gravitational/trace v1.5.1 h1:CdSymAjkE1VOef+lsC5x29jX9WbgI0fBtnRqeT4Fh+c= +github.com/gravitational/trace v1.5.1/go.mod h1:sJKfJHIQ7IkG8kvYpFPEr6mj3WDEdZ0YAc7xAD8w7lw= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -1536,8 +1537,8 @@ github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailgun/multibuf v0.1.2 h1:QE9kE27lK6LFZB4aYNVtUPlWVHVCT0zpgUr2uoq/+jk= -github.com/mailgun/multibuf v0.1.2/go.mod h1:E+sUhIy69qgT6EM57kCPdUTlHnjTuxQBO/yf6af9Hes= +github.com/mailgun/multibuf v0.2.0 h1:pGhv93r0GXBVTDu6RMlA9GUQjwwoy4yspIujtaT0AOA= +github.com/mailgun/multibuf v0.2.0/go.mod h1:E+sUhIy69qgT6EM57kCPdUTlHnjTuxQBO/yf6af9Hes= github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 h1:Kg/NPZLLC3aAFr1YToMs98dbCdhootQ1hZIvZU28hAQ= github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51/go.mod h1:RYmqHbhWwIz3z9eVmQ2rx82rulEMG0t+Q1bzfc9DYN4= github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f h1:ZZYhg16XocqSKPGNQAe0aeweNtFxuedbwwb4fSlg7h4= @@ -1688,8 +1689,8 @@ github.com/nrdcg/nodion v0.1.0 h1:zLKaqTn2X0aDuBHHfyA1zFgeZfiCpmu/O9DM73okavw= github.com/nrdcg/nodion v0.1.0/go.mod h1:inbuh3neCtIWlMPZHtEpe43TmRXxHV6+hk97iCZicms= github.com/nrdcg/oci-go-sdk/common/v1065 v1065.113.0 h1:OLlJVGHkTHBCXdTGpNn5ay4DV3gOZrVLxlUM6xBQrIM= github.com/nrdcg/oci-go-sdk/common/v1065 v1065.113.0/go.mod h1:Gcs8GCaZXL3FdiDWgdnMxlOLEdRprJJnPYB22TX1jw8= -github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.112.0 h1:sQ9SfyNFj4u2kStSd2ZbsU12b4nNyROK307fb3hkoPk= -github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.112.0/go.mod h1:DaABHQaJMe64ppbXBsJPEESLxXRrbkiDfkR9JFeFowY= +github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.113.0 h1:bveOZN6gZZjjEM1T9o1TUm8de3zePyDbfuluMpaRJCE= +github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.113.0/go.mod h1:Ff6Cxm43tuGJHyltQwD3EXLs7kKpkxzqy6DGQcaiS/0= github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw= github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54= github.com/nrdcg/vegadns v0.3.0 h1:11FQMw7xVIRUWO9o5+Z/5YZhmPWlm4oxUUH3F6EVqQU= @@ -1993,8 +1994,6 @@ github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XV github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/traefik/grpc-web v0.16.0 h1:eeUWZaFg6ZU0I9dWOYE2D5qkNzRBmXzzuRlxdltascY= github.com/traefik/grpc-web v0.16.0/go.mod h1:2ttniSv7pTgBWIU2HZLokxRfFX3SA60c/DTmQQgVml4= -github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf h1:qOjmGqgXvycy0+tda6rWhTPulgQxnImwRrM1AROIvJ4= -github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf/go.mod h1:as06A23Znc9S/ilJpKqJ/UhO3Zu5JztlxVwQuKl+iZs= github.com/traefik/paerser v0.2.2 h1:cpzW/ZrQrBh3mdwD/jnp6aXASiUFKOVr6ldP+keJTcQ= github.com/traefik/paerser v0.2.2/go.mod h1:7BBDd4FANoVgaTZG+yh26jI6CA2nds7D/4VTEdIsh24= github.com/traefik/yaegi v0.16.1 h1:f1De3DVJqIDKmnasUF6MwmWv1dSEEat0wcpXhD2On3E= @@ -2034,6 +2033,8 @@ github.com/vinyldns/go-vinyldns v0.9.17 h1:hfPZfCaxcRBX6Gsgl42rLCeoal58/BH8kkvJS github.com/vinyldns/go-vinyldns v0.9.17/go.mod h1:pwWhE9K/leGDOIduVhRGvQ3ecVMHWRfEnKYUTEU3gB4= github.com/volcengine/volc-sdk-golang v1.0.242 h1:YEnYLl8mn83JCdO/X5GRDvxfxGvpUqk5j0Mj4VhwM6Y= github.com/volcengine/volc-sdk-golang v1.0.242/go.mod h1:zHJlaqiMbIB+0mcrsZPTwOb3FB7S/0MCfqlnO8R7hlM= +github.com/vulcand/oxy/v2 v2.1.0 h1:JnFb/qz+o96E6NEl4X6WSmNmcrlccPmCIyhAZLBVLWM= +github.com/vulcand/oxy/v2 v2.1.0/go.mod h1:9kY0wYBlMqrgXCZTNYCwE89NYwGGdM3sSD+w59CKMhw= github.com/vulcand/predicate v1.3.0 h1:jtNe4PHbLJ649dR7Gl+MSAzUhLGtLspAkWlSjoOiXg8= github.com/vulcand/predicate v1.3.0/go.mod h1:opzv9MetRuMNnuoPeTSWtwzjcXsxQC00/fuWzkPTn4s= github.com/vultr/govultr/v3 v3.31.0 h1:xSRqIQEnB3tjgpIOADWQOhOedDsqZj9qawW+mAoq7/8= diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index bd28f057fe..0f6666646b 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -271,6 +271,10 @@ type ErrorPage struct { // The {originalStatus} variable can be used in order to insert the upstream status code in the URL. // The {url} variable can be used in order to insert the escaped request URL. Query string `json:"query,omitempty" toml:"query,omitempty" yaml:"query,omitempty" export:"true"` + // ErrorRequestHeaders defines the list of request headers forwarded to the error page service. + // When nil (not set), all original request headers are forwarded. + // Set to an empty list to forward no headers, or list specific headers to forward only those. + ErrorRequestHeaders []string `json:"errorRequestHeaders,omitempty" toml:"errorRequestHeaders,omitempty" yaml:"errorRequestHeaders,omitempty" export:"true"` // NginxHeaders defines the headers to forward to the Error page service. // NginxHeaders option is unexposed to other providers than the IngressNGINX one. diff --git a/pkg/config/dynamic/zz_generated.deepcopy.go b/pkg/config/dynamic/zz_generated.deepcopy.go index da6a31c35b..4ea53f9d4b 100644 --- a/pkg/config/dynamic/zz_generated.deepcopy.go +++ b/pkg/config/dynamic/zz_generated.deepcopy.go @@ -381,6 +381,11 @@ func (in *ErrorPage) DeepCopyInto(out *ErrorPage) { (*out)[key] = val } } + if in.ErrorRequestHeaders != nil { + in, out := &in.ErrorRequestHeaders, &out.ErrorRequestHeaders + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.NginxHeaders != nil { in, out := &in.NginxHeaders, &out.NginxHeaders *out = new(http.Header) diff --git a/pkg/middlewares/customerrors/custom_errors.go b/pkg/middlewares/customerrors/custom_errors.go index 6eda509759..57ca141642 100644 --- a/pkg/middlewares/customerrors/custom_errors.go +++ b/pkg/middlewares/customerrors/custom_errors.go @@ -38,6 +38,7 @@ type customErrors struct { backendHandler http.Handler httpCodeRanges types.HTTPCodeRanges backendQuery string + requestHeaders []string statusRewrites []statusRewrite forwardNginxHeaders http.Header } @@ -81,6 +82,7 @@ func New(ctx context.Context, next http.Handler, config dynamic.ErrorPage, servi backendHandler: backend, httpCodeRanges: httpCodeRanges, backendQuery: config.Query, + requestHeaders: config.ErrorRequestHeaders, statusRewrites: statusRewrites, forwardNginxHeaders: ptr.Deref(config.NginxHeaders, nil), }, nil @@ -148,6 +150,16 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) { return } + if c.requestHeaders != nil { + for _, header := range c.requestHeaders { + if values := req.Header.Values(header); len(values) > 0 { + pageReq.Header[http.CanonicalHeaderKey(header)] = values + } + } + } else { + utils.CopyHeaders(pageReq.Header, req.Header) + } + if len(c.forwardNginxHeaders) > 0 { utils.CopyHeaders(pageReq.Header, c.forwardNginxHeaders) pageReq.Header.Set("X-Code", strconv.Itoa(code)) @@ -156,11 +168,7 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) { if requestID := req.Header.Get("X-Request-ID"); requestID != "" { pageReq.Header.Set("X-Request-ID", requestID) } - } else { - utils.CopyHeaders(pageReq.Header, req.Header) - } - if len(c.forwardNginxHeaders) > 0 { c.backendHandler.ServeHTTP(rw, pageReq.WithContext(req.Context())) } else { c.backendHandler.ServeHTTP(newCodeModifier(rw, code), diff --git a/pkg/middlewares/customerrors/custom_errors_test.go b/pkg/middlewares/customerrors/custom_errors_test.go index ed49cf13dd..658d1c0d5d 100644 --- a/pkg/middlewares/customerrors/custom_errors_test.go +++ b/pkg/middlewares/customerrors/custom_errors_test.go @@ -23,6 +23,7 @@ func TestHandler(t *testing.T) { backendCode int backendErrorHandler http.HandlerFunc validate func(t *testing.T, recorder *httptest.ResponseRecorder) + requestHeaders map[string]string }{ { desc: "no error", @@ -154,6 +155,60 @@ func TestHandler(t *testing.T) { assert.Contains(t, recorder.Body.String(), "My 503 page.") }, }, + { + desc: "forward all headers by default", + errorPage: &dynamic.ErrorPage{Service: "error", Query: "/test", Status: []string{"503"}}, + requestHeaders: map[string]string{ + "X-Request-Id": "trace-abc", + "Authorization": "Bearer secret", + }, + backendCode: http.StatusServiceUnavailable, + backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, r.Header.Get("X-Request-Id")) + fmt.Fprintln(w, r.Header.Get("Authorization")) + }), + validate: func(t *testing.T, recorder *httptest.ResponseRecorder) { + t.Helper() + assert.Contains(t, recorder.Body.String(), "trace-abc") + assert.Contains(t, recorder.Body.String(), "Bearer secret") + }, + }, + { + desc: "forward only allowlisted headers", + errorPage: &dynamic.ErrorPage{Service: "error", Query: "/test", Status: []string{"503"}, ErrorRequestHeaders: []string{"X-Request-Id"}}, + requestHeaders: map[string]string{ + "X-Request-Id": "trace-abc", + "Authorization": "Bearer secret", + }, + backendCode: http.StatusServiceUnavailable, + backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, r.Header.Get("X-Request-Id")) + fmt.Fprintln(w, r.Header.Get("Authorization")) + }), + validate: func(t *testing.T, recorder *httptest.ResponseRecorder) { + t.Helper() + assert.Contains(t, recorder.Body.String(), "trace-abc") + assert.NotContains(t, recorder.Body.String(), "Bearer secret") + }, + }, + { + desc: "forward no headers", + errorPage: &dynamic.ErrorPage{Service: "error", Query: "/test", Status: []string{"503"}, ErrorRequestHeaders: []string{}}, + requestHeaders: map[string]string{ + "X-Request-Id": "trace-abc", + "Authorization": "Bearer secret", + }, + backendCode: http.StatusServiceUnavailable, + backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, r.Header.Get("X-Request-Id")) + fmt.Fprintln(w, r.Header.Get("Authorization")) + }), + validate: func(t *testing.T, recorder *httptest.ResponseRecorder) { + t.Helper() + assert.NotContains(t, recorder.Body.String(), "trace-abc") + assert.NotContains(t, recorder.Body.String(), "Bearer secret") + }, + }, { desc: "nginx headers: backend status code preserved", errorPage: &dynamic.ErrorPage{ @@ -253,6 +308,9 @@ func TestHandler(t *testing.T) { require.NoError(t, err) req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost/test?foo=bar&baz=buz", nil) + for k, v := range test.requestHeaders { + req.Header.Set(k, v) + } // Client like browser and curl will issue a relative HTTP request, which not have a host and scheme in the URL. But the http.NewRequest will set them automatically. req.URL.Host = "" diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 0649aadab8..58feb28035 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v3.6.14 +# example new bugfix v3.6.15 CurrentRef = "v3.6" -PreviousRef = "v3.6.13" +PreviousRef = "v3.6.14" BaseBranch = "v3.6" -FutureCurrentRefName = "v3.6.14" +FutureCurrentRefName = "v3.6.15" ThresholdPreviousRef = 10000 ThresholdCurrentRef = 10000