diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 10538f069..fc7e03b27 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,11 +3,11 @@ PLEASE READ THIS MESSAGE. Documentation fixes or enhancements: - for Traefik v1: use branch v1.7 -- for Traefik v2: use branch v2.4 +- for Traefik v2: use branch v2.5 Bug fixes: - for Traefik v1: use branch v1.7 -- for Traefik v2: use branch v2.4 +- for Traefik v2: use branch v2.5 Enhancements: - for Traefik v1: we only accept bug fixes diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8fb5a867d..d0cde427c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -6,7 +6,7 @@ on: - '*' env: - GO_VERSION: 1.16 + GO_VERSION: 1.17 CGO_ENABLED: 0 PRE_TARGET: "" diff --git a/.github/workflows/experimental.yaml b/.github/workflows/experimental.yaml new file mode 100644 index 000000000..2b002a484 --- /dev/null +++ b/.github/workflows/experimental.yaml @@ -0,0 +1,37 @@ +name: Build experimental image on branch + +on: + push: + branches: + - master + - v* + +jobs: + + experimental: + if: github.repository == 'traefik/traefik' + name: Build experimental image on branch + runs-on: ubuntu-20.04 + + steps: + + # https://github.com/marketplace/actions/checkout + - name: Check out code + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Branch name + run: echo ${GITHUB_REF##*/} + + - name: Build docker experimental image + run: docker build -t traefik/traefik:experimental-${GITHUB_REF##*/} -f exp.Dockerfile . + + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Push to Docker Hub + run: docker push traefik/traefik:experimental-${GITHUB_REF##*/} diff --git a/.github/workflows/test-unit.yaml b/.github/workflows/test-unit.yaml index e2829a248..9583a37da 100644 --- a/.github/workflows/test-unit.yaml +++ b/.github/workflows/test-unit.yaml @@ -6,7 +6,7 @@ on: - '*' env: - GO_VERSION: 1.16 + GO_VERSION: 1.17 PRE_TARGET: "" jobs: diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index eb3379d2a..4bf9abf12 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -6,7 +6,7 @@ on: - '*' env: - GO_VERSION: 1.16 + GO_VERSION: 1.17 GOLANGCI_LINT_VERSION: v1.41.1 MISSSPELL_VERSION: v0.3.4 PRE_TARGET: "" diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 058f375da..0210c1ffa 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -19,7 +19,7 @@ global_job_config: prologue: commands: - curl -sSfL https://raw.githubusercontent.com/ldez/semgo/master/godownloader.sh | sudo sh -s -- -b "/usr/local/bin" - - sudo semgo go1.16 + - sudo semgo go1.17 - export "GOPATH=$(go env GOPATH)" - export "SEMAPHORE_GIT_DIR=${GOPATH}/src/github.com/traefik/${SEMAPHORE_PROJECT_NAME}" - export "PATH=${GOPATH}/bin:${PATH}" @@ -73,6 +73,10 @@ blocks: run: when: "tag =~ '.*'" task: + agent: + machine: + type: e1-standard-8 + os_image: ubuntu1804 secrets: - name: traefik env_vars: diff --git a/CHANGELOG.md b/CHANGELOG.md index 633f4eeb8..2eafa3f9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,146 @@ +## [v2.5.1](https://github.com/traefik/traefik/tree/v2.5.1) (2021-08-20) +[All Commits](https://github.com/traefik/traefik/compare/v2.5.0...v2.5.1) + +**Bug fixes:** +- **[middleware,http3]** Conditional CloseNotify in header middleware ([#8374](https://github.com/traefik/traefik/pull/8374) by [juliens](https://github.com/juliens)) +- **[tls,tcp,k8s/crd,k8s]** Makes ALPN protocols configurable ([#8383](https://github.com/traefik/traefik/pull/8383) by [rtribotte](https://github.com/rtribotte)) + +**Documentation:** +- **[k8s]** Adds MiddlewareTCP CRD documentation ([#8369](https://github.com/traefik/traefik/pull/8369) by [perosb](https://github.com/perosb)) +- **[middleware]** Adds ContentType to middleware's overview table ([#8350](https://github.com/traefik/traefik/pull/8350) by [euidong](https://github.com/euidong)) + +## [v2.5.0](https://github.com/traefik/traefik/tree/v2.5.0) (2021-08-17) +[All Commits](https://github.com/traefik/traefik/compare/v2.4.0-rc1...v2.5.0) + +**Enhancements:** +- **[consulcatalog]** Add Support for Consul Connect ([#7407](https://github.com/traefik/traefik/pull/7407) by [Gufran](https://github.com/Gufran)) +- Update Go version ([#8355](https://github.com/traefik/traefik/pull/8355) by [mpl](https://github.com/mpl)) +- **[file]** Update sprig to v3.2.0 ([#7746](https://github.com/traefik/traefik/pull/7746) by [sirlatrom](https://github.com/sirlatrom)) +- **[healthcheck]** Healthcheck: add support at the load-balancers of services level ([#8057](https://github.com/traefik/traefik/pull/8057) by [mpl](https://github.com/mpl)) +- **[http3]** Upgrade github.com/lucas-clemente/quic-go ([#8076](https://github.com/traefik/traefik/pull/8076) by [sylr](https://github.com/sylr)) +- **[http3]** Add HTTP3 support (experimental) ([#7724](https://github.com/traefik/traefik/pull/7724) by [juliens](https://github.com/juliens)) +- **[k8s,k8s/gatewayapi]** Add wildcard hostname rule to kubernetes gateway ([#7963](https://github.com/traefik/traefik/pull/7963) by [jberger](https://github.com/jberger)) +- **[k8s,k8s/gatewayapi]** Add support for TCPRoute and TLSRoute ([#8054](https://github.com/traefik/traefik/pull/8054) by [tomMoulard](https://github.com/tomMoulard)) +- **[k8s,k8s/gatewayapi]** Allow crossprovider service reference ([#7774](https://github.com/traefik/traefik/pull/7774) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[k8s/crd,k8s]** Add named port support to Kubernetes IngressRoute CRDs ([#7668](https://github.com/traefik/traefik/pull/7668) by [Cirrith](https://github.com/Cirrith)) +- **[k8s/crd,k8s]** Improve kubernetes external name service support for UDP ([#7773](https://github.com/traefik/traefik/pull/7773) by [kevinpollet](https://github.com/kevinpollet)) +- **[k8s/crd,k8s]** Upgrade the CRD version from apiextensions.k8s.io/v1beta1 to apiextensions.k8s.io/v1 ([#7815](https://github.com/traefik/traefik/pull/7815) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[k8s/ingress,k8s/crd,k8s]** Ignore empty endpoint changes ([#7646](https://github.com/traefik/traefik/pull/7646) by [hensur](https://github.com/hensur)) +- **[k8s/ingress,k8s]** Upgrade Ingress Handling to work with networkingv1/Ingress ([#7549](https://github.com/traefik/traefik/pull/7549) by [SantoDE](https://github.com/SantoDE)) +- **[k8s/ingress,k8s]** Filter ingress class resources by name ([#7915](https://github.com/traefik/traefik/pull/7915) by [tomMoulard](https://github.com/tomMoulard)) +- **[k8s/ingress,k8s]** Add k8s provider option to create services without endpoints ([#7593](https://github.com/traefik/traefik/pull/7593) by [Lucaber](https://github.com/Lucaber)) +- **[k8s/ingress,k8s]** Upgrade IngressClass to use v1 over v1Beta on Kube 1.19+ ([#8089](https://github.com/traefik/traefik/pull/8089) by [SantoDE](https://github.com/SantoDE)) +- **[k8s/ingress,k8s]** Add ServersTransport annotation to k8s ingress provider ([#8084](https://github.com/traefik/traefik/pull/8084) by [wdullaer](https://github.com/wdullaer)) +- **[logs,middleware]** Add TLS version and cipher to the accessLog ([#7478](https://github.com/traefik/traefik/pull/7478) by [na4ma4](https://github.com/na4ma4)) +- **[metrics]** Add TLS certs expiration metric ([#6924](https://github.com/traefik/traefik/pull/6924) by [sylr](https://github.com/sylr)) +- **[metrics]** Allow to define datadogs metrics endpoint with env vars ([#7968](https://github.com/traefik/traefik/pull/7968) by [sylr](https://github.com/sylr)) +- **[middleware,metrics]** Add router metrics ([#7510](https://github.com/traefik/traefik/pull/7510) by [jorge07](https://github.com/jorge07)) +- **[middleware,tcp]** Add TCP Middlewares support ([#7813](https://github.com/traefik/traefik/pull/7813) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Removes headers middleware options ([#8161](https://github.com/traefik/traefik/pull/8161) by [tomMoulard](https://github.com/tomMoulard)) +- **[middleware]** Headers: add `permissionsPolicy` and deprecate `featurePolicy` ([#8200](https://github.com/traefik/traefik/pull/8200) by [WLun001](https://github.com/WLun001)) +- **[middleware]** Deprecates ssl redirect headers middleware options ([#8160](https://github.com/traefik/traefik/pull/8160) by [tomMoulard](https://github.com/tomMoulard)) +- **[plugins]** Local private plugins. ([#8224](https://github.com/traefik/traefik/pull/8224) by [ldez](https://github.com/ldez)) +- **[provider,plugins]** Add plugin's support for provider ([#7794](https://github.com/traefik/traefik/pull/7794) by [ldez](https://github.com/ldez)) +- **[rules]** Support not in rules definition ([#8164](https://github.com/traefik/traefik/pull/8164) by [juliens](https://github.com/juliens)) +- **[rules]** Add routing IP rule matcher ([#8169](https://github.com/traefik/traefik/pull/8169) by [tomMoulard](https://github.com/tomMoulard)) +- **[server]** Improve host name resolution for TCP proxy ([#7971](https://github.com/traefik/traefik/pull/7971) by [H-M-H](https://github.com/H-M-H)) +- **[server]** Add ability to disable HTTP/2 in dynamic config ([#7645](https://github.com/traefik/traefik/pull/7645) by [jcuzzi](https://github.com/jcuzzi)) +- **[sticky-session]** Add a mechanism to format the sticky cookie value ([#8103](https://github.com/traefik/traefik/pull/8103) by [tomMoulard](https://github.com/tomMoulard)) +- **[tls]** Mutualize TLS version and cipher code ([#7779](https://github.com/traefik/traefik/pull/7779) by [rtribotte](https://github.com/rtribotte)) +- **[tls,k8s/crd,k8s]** Improve CA certificate loading from kubernetes secret ([#7789](https://github.com/traefik/traefik/pull/7789) by [rio](https://github.com/rio)) +- **[tls]** Do not build a default certificate for ACME challenges store ([#7833](https://github.com/traefik/traefik/pull/7833) by [rkojedzinszky](https://github.com/rkojedzinszky)) +- **[tracing]** Use Datadog tracer environment variables to setup default config ([#7721](https://github.com/traefik/traefik/pull/7721) by [GianOrtiz](https://github.com/GianOrtiz)) +- **[tracing]** Update Elastic APM from 1.7.0 to 1.11.0 ([#8187](https://github.com/traefik/traefik/pull/8187) by [afitzek](https://github.com/afitzek)) +- **[tracing]** Override jaeger configuration with env variables ([#8198](https://github.com/traefik/traefik/pull/8198) by [mmatur](https://github.com/mmatur)) +- **[udp]** Add udp timeout configuration ([#6982](https://github.com/traefik/traefik/pull/6982) by [Lindenk](https://github.com/Lindenk)) + +**Bug fixes:** +- **[k8s,k8s/gatewayapi]** Update Gateway API version to v0.3.0 ([#8253](https://github.com/traefik/traefik/pull/8253) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[k8s]** Kubernetes: detect changes for resources other than endpoints ([#8313](https://github.com/traefik/traefik/pull/8313) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Library change for compress middleware to increase performance ([#8245](https://github.com/traefik/traefik/pull/8245) by [tomMoulard](https://github.com/tomMoulard)) +- **[plugins]** Update yaegi to v0.9.21 ([#8285](https://github.com/traefik/traefik/pull/8285) by [ldez](https://github.com/ldez)) +- **[plugins]** Downgrade yaegi to v0.9.19 ([#8282](https://github.com/traefik/traefik/pull/8282) by [ldez](https://github.com/ldez)) +- **[webui]** Fix dashboard to display middleware details ([#8284](https://github.com/traefik/traefik/pull/8284) by [tomMoulard](https://github.com/tomMoulard)) +- **[webui]** Fix dashboard title for TCP middlewares ([#8339](https://github.com/traefik/traefik/pull/8339) by [mschneider82](https://github.com/mschneider82)) +- **[k8s]** Remove logging of changed object with cast ([#8128](https://github.com/traefik/traefik/pull/8128) by [hensur](https://github.com/hensur)) + +**Documentation:** +- Fix KV reference documentation ([#8280](https://github.com/traefik/traefik/pull/8280) by [rtribotte](https://github.com/rtribotte)) +- Fix migration guide ([#8269](https://github.com/traefik/traefik/pull/8269) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Update generated and reference doc for plugins ([#8236](https://github.com/traefik/traefik/pull/8236) by [tomMoulard](https://github.com/tomMoulard)) +- **[k8s/crd]** Fix: regenerate crd ([#8114](https://github.com/traefik/traefik/pull/8114) by [tomMoulard](https://github.com/tomMoulard)) +- **[k8s]** Clarify doc for ingressclass name in k8s 1.18+ ([#7944](https://github.com/traefik/traefik/pull/7944) by [tomMoulard](https://github.com/tomMoulard)) +- Update documentation references ([#8202](https://github.com/traefik/traefik/pull/8202) by [rtribotte](https://github.com/rtribotte)) + +**Misc:** +- Merge current v2.4 into v2.5 ([#8333](https://github.com/traefik/traefik/pull/8333) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into v2.5 ([#8325](https://github.com/traefik/traefik/pull/8325) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into v2.5 ([#8314](https://github.com/traefik/traefik/pull/8314) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into v2.5 ([#8296](https://github.com/traefik/traefik/pull/8296) by [tomMoulard](https://github.com/tomMoulard)) +- Merge current v2.4 into v2.5 ([#8287](https://github.com/traefik/traefik/pull/8287) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into v2.5 ([#8281](https://github.com/traefik/traefik/pull/8281) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into v2.5 ([#8263](https://github.com/traefik/traefik/pull/8263) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#8232](https://github.com/traefik/traefik/pull/8232) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#8210](https://github.com/traefik/traefik/pull/8210) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#8105](https://github.com/traefik/traefik/pull/8105) by [tomMoulard](https://github.com/tomMoulard)) +- Merge current v2.4 into master ([#8087](https://github.com/traefik/traefik/pull/8087) by [tomMoulard](https://github.com/tomMoulard)) +- Merge current v2.4 into master ([#8068](https://github.com/traefik/traefik/pull/8068) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into master ([#8058](https://github.com/traefik/traefik/pull/8058) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into master ([#8024](https://github.com/traefik/traefik/pull/8024) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into master ([#7969](https://github.com/traefik/traefik/pull/7969) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into master ([#7921](https://github.com/traefik/traefik/pull/7921) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#7901](https://github.com/traefik/traefik/pull/7901) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#7859](https://github.com/traefik/traefik/pull/7859) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into master ([#7795](https://github.com/traefik/traefik/pull/7795) by [kevinpollet](https://github.com/kevinpollet)) +- Merge current v2.4 into master ([#8221](https://github.com/traefik/traefik/pull/8221) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#7781](https://github.com/traefik/traefik/pull/7781) by [kevinpollet](https://github.com/kevinpollet)) +- Merge current v2.4 into master ([#7766](https://github.com/traefik/traefik/pull/7766) by [ldez](https://github.com/ldez)) +- Merge current v2.4 into master ([#7761](https://github.com/traefik/traefik/pull/7761) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into master ([#7748](https://github.com/traefik/traefik/pull/7748) by [kevinpollet](https://github.com/kevinpollet)) +- Merge current v2.4 into master ([#7728](https://github.com/traefik/traefik/pull/7728) by [mmatur](https://github.com/mmatur)) + + +## [v2.4.14](https://github.com/traefik/traefik/tree/v2.4.14) (2021-08-16) +[All Commits](https://github.com/traefik/traefik/compare/v2.4.13...v2.4.14) + +**Bug fixes:** +- **[k8s/crd,k8s]** Avoid unauthorized middleware cross namespace reference ([#8322](https://github.com/traefik/traefik/pull/8322) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[kv]** Remove unwanted trailing slash in key ([#8335](https://github.com/traefik/traefik/pull/8335) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[middleware]** Redirect: fix comparison when explicit port request and implicit redirect port ([#8348](https://github.com/traefik/traefik/pull/8348) by [tcolgate](https://github.com/tcolgate)) + +**Documentation:** +- **[kv]** Fix a router's entryPoint definition example for KV provider ([#8357](https://github.com/traefik/traefik/pull/8357) by [avtion](https://github.com/avtion)) + +## [v2.5.0-rc6](https://github.com/traefik/traefik/tree/v2.5.0-rc6) (2021-08-13) +[All Commits](https://github.com/traefik/traefik/compare/v2.5.0-rc5...v2.5.0-rc6) + +**Enhancements:** +- Update Go version ([#8355](https://github.com/traefik/traefik/pull/8355) by [mpl](https://github.com/mpl)) + +**Misc:** +- Merge current v2.4 into v2.5 ([#8333](https://github.com/traefik/traefik/pull/8333) by [jbdoumenjou](https://github.com/jbdoumenjou)) + +## [v2.5.0-rc5](https://github.com/traefik/traefik/tree/v2.5.0-rc5) (2021-08-03) +[All Commits](https://github.com/traefik/traefik/compare/v2.5.0-rc3...v2.5.0-rc5) + +**Bug fixes:** +- **[k8s]** Kubernetes: detect changes for resources other than endpoints ([#8313](https://github.com/traefik/traefik/pull/8313) by [rtribotte](https://github.com/rtribotte)) + +**Misc:** +- Merge current v2.4 into v2.5 ([#8325](https://github.com/traefik/traefik/pull/8325) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Merge current v2.4 into v2.5 ([#8314](https://github.com/traefik/traefik/pull/8314) by [rtribotte](https://github.com/rtribotte)) +- Merge current v2.4 into v2.5 ([#8296](https://github.com/traefik/traefik/pull/8296) by [tomMoulard](https://github.com/tomMoulard)) + +## [v2.5.0-rc4](https://github.com/traefik/traefik/tree/v2.5.0-rc4) (2021-08-03) + +Release canceled. + +## [v2.4.13](https://github.com/traefik/traefik/tree/v2.4.13) (2021-07-30) +[All Commits](https://github.com/traefik/traefik/compare/v2.4.12...v2.4.13) + +**Bug fixes:** +- **[authentication,middleware]** Remove hop-by-hop headers defined in connection header before some middleware ([#8319](https://github.com/traefik/traefik/pull/8319) by [ldez](https://github.com/ldez)) + ## [v2.4.12](https://github.com/traefik/traefik/tree/v2.4.12) (2021-07-26) [All Commits](https://github.com/traefik/traefik/compare/v2.4.11...v2.4.12) diff --git a/build.Dockerfile b/build.Dockerfile index 4c34406e7..cd9c84c98 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.16-alpine +FROM golang:1.17-alpine RUN apk --update upgrade \ && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ diff --git a/docs/check.Dockerfile b/docs/check.Dockerfile index 925a9ae4d..53b914c66 100644 --- a/docs/check.Dockerfile +++ b/docs/check.Dockerfile @@ -1,5 +1,5 @@ -FROM alpine:3.13 as alpine +FROM alpine:3.14 as alpine RUN apk --no-cache --no-progress add \ libcurl \ diff --git a/docs/content/getting-started/install-traefik.md b/docs/content/getting-started/install-traefik.md index 81ab71463..e82168f8e 100644 --- a/docs/content/getting-started/install-traefik.md +++ b/docs/content/getting-started/install-traefik.md @@ -11,8 +11,8 @@ You can install Traefik with the following flavors: Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with one sample configuration file: -* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.4/traefik.sample.yml) -* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.4/traefik.sample.toml) +* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.5/traefik.sample.yml) +* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.5/traefik.sample.toml) ```bash docker run -d -p 8080:8080 -p 80:80 \ diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index ae3584b8b..cff442cab 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -399,6 +399,47 @@ spec: preferServerCipherSuites: true ``` +### ALPN Protocols + +_Optional, Default="h2, http/1.1, acme-tls/1"_ + +This option allows to specify the list of supported application level protocols for the TLS handshake, +in order of preference. +If the client supports ALPN, the selected protocol will be one from this list, +and the connection will fail if there is no mutually supported protocol. + +```yaml tab="File (YAML)" +# Dynamic configuration + +tls: + options: + default: + alpnProtocols: + - http/1.1 + - h2 +``` + +```toml tab="File (TOML)" +# Dynamic configuration + +[tls.options] + [tls.options.default] + alpnProtocols = ["http/1.1", "h2"] +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.containo.us/v1alpha1 +kind: TLSOption +metadata: + name: default + namespace: default + +spec: + alpnProtocols: + - http/1.1 + - h2 +``` + ### Client Authentication (mTLS) Traefik supports mutual authentication, through the `clientAuth` section. diff --git a/docs/content/middlewares/http/overview.md b/docs/content/middlewares/http/overview.md index 67a18b895..50692ae5e 100644 --- a/docs/content/middlewares/http/overview.md +++ b/docs/content/middlewares/http/overview.md @@ -126,24 +126,25 @@ http: | Middleware | Purpose | Area | |-------------------------------------------|---------------------------------------------------|-----------------------------| -| [AddPrefix](addprefix.md) | Add a Path Prefix | Path Modifier | -| [BasicAuth](basicauth.md) | Basic auth mechanism | Security, Authentication | +| [AddPrefix](addprefix.md) | Adds a Path Prefix | Path Modifier | +| [BasicAuth](basicauth.md) | Adds Basic Authentication | Security, Authentication | | [Buffering](buffering.md) | Buffers the request/response | Request Lifecycle | -| [Chain](chain.md) | Combine multiple pieces of middleware | Middleware tool | -| [CircuitBreaker](circuitbreaker.md) | Stop calling unhealthy services | Request Lifecycle | -| [Compress](compress.md) | Compress the response | Content Modifier | +| [Chain](chain.md) | Combines multiple pieces of middleware | Misc | +| [CircuitBreaker](circuitbreaker.md) | Prevents calling unhealthy services | Request Lifecycle | +| [Compress](compress.md) | Compresses the response | Content Modifier | +| [ContentType](contenttype.md) | Handles Content-Type auto-detection | Misc | | [DigestAuth](digestauth.md) | Adds Digest Authentication | Security, Authentication | -| [Errors](errorpages.md) | Define custom error pages | Request Lifecycle | -| [ForwardAuth](forwardauth.md) | Authentication delegation | Security, Authentication | -| [Headers](headers.md) | Add / Update headers | Security | -| [IPWhiteList](ipwhitelist.md) | Limit the allowed client IPs | Security, Request lifecycle | -| [InFlightReq](inflightreq.md) | Limit the number of simultaneous connections | Security, Request lifecycle | -| [PassTLSClientCert](passtlsclientcert.md) | Adding Client Certificates in a Header | Security | -| [RateLimit](ratelimit.md) | Limit the call frequency | Security, Request lifecycle | -| [RedirectScheme](redirectscheme.md) | Redirect easily the client elsewhere | Request lifecycle | -| [RedirectRegex](redirectregex.md) | Redirect the client elsewhere | Request lifecycle | -| [ReplacePath](replacepath.md) | Change the path of the request | Path Modifier | -| [ReplacePathRegex](replacepathregex.md) | Change the path of the request | Path Modifier | -| [Retry](retry.md) | Automatically retry the request in case of errors | Request lifecycle | -| [StripPrefix](stripprefix.md) | Change the path of the request | Path Modifier | -| [StripPrefixRegex](stripprefixregex.md) | Change the path of the request | Path Modifier | +| [Errors](errorpages.md) | Defines custom error pages | Request Lifecycle | +| [ForwardAuth](forwardauth.md) | Delegates Authentication | Security, Authentication | +| [Headers](headers.md) | Adds / Updates headers | Security | +| [IPWhiteList](ipwhitelist.md) | Limits the allowed client IPs | Security, Request lifecycle | +| [InFlightReq](inflightreq.md) | Limits the number of simultaneous connections | Security, Request lifecycle | +| [PassTLSClientCert](passtlsclientcert.md) | Adds Client Certificates in a Header | Security | +| [RateLimit](ratelimit.md) | Limits the call frequency | Security, Request lifecycle | +| [RedirectScheme](redirectscheme.md) | Redirects based on scheme | Request lifecycle | +| [RedirectRegex](redirectregex.md) | Redirects based on regex | Request lifecycle | +| [ReplacePath](replacepath.md) | Changes the path of the request | Path Modifier | +| [ReplacePathRegex](replacepathregex.md) | Changes the path of the request | Path Modifier | +| [Retry](retry.md) | Automatically retries in case of error | Request lifecycle | +| [StripPrefix](stripprefix.md) | Changes the path of the request | Path Modifier | +| [StripPrefixRegex](stripprefixregex.md) | Changes the path of the request | Path Modifier | diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index 4aa9b6202..778abc3d6 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -409,3 +409,9 @@ For more advanced use cases, you can use either the [RedirectScheme middleware]( ### Headers middleware: accessControlAllowOrigin `accessControlAllowOrigin` is no longer supported in Traefik v2.5. + +### X.509 CommonName Deprecation Bis + +Following up on the deprecation started [previously](#x509-commonname-deprecation), +as the `x509ignoreCN=0` value for the `GODEBUG` is [deprecated in Go 1.17](https://tip.golang.org/doc/go1.17#crypto/x509), +the legacy behavior related to the CommonName field can not be enabled at all anymore. diff --git a/docs/content/providers/kubernetes-gateway.md b/docs/content/providers/kubernetes-gateway.md index 1cd115f4e..bc38cbb40 100644 --- a/docs/content/providers/kubernetes-gateway.md +++ b/docs/content/providers/kubernetes-gateway.md @@ -73,17 +73,17 @@ This provider is proposed as an experimental feature and partially supports the The Kubernetes Gateway API project provides several guides on how to use the APIs. These guides can help you to go further than the example above. -The [getting started guide](https://gateway-api.sigs.k8s.io/guides/getting-started/) details how to install the CRDs from their repository. +The [getting started guide](https://gateway-api.sigs.k8s.io/v1alpha1/guides/getting-started/) details how to install the CRDs from their repository. !!! note "" - Keep in mind that the Traefik Gateway provider only supports the `v0.3.0`. + Keep in mind that the Traefik Gateway provider only supports the `v0.3.0` (v1alpha1). For now, the Traefik Gateway Provider can be used while following the below guides: -* [Simple Gateway](https://gateway-api.sigs.k8s.io/guides/simple-gateway/) -* [HTTP routing](https://gateway-api.sigs.k8s.io/guides/http-routing/) -* [TLS](https://gateway-api.sigs.k8s.io/guides/tls/) +* [Simple Gateway](https://gateway-api.sigs.k8s.io/v1alpha1/guides/simple-gateway/) +* [HTTP routing](https://gateway-api.sigs.k8s.io/v1alpha1/guides/http-routing/) +* [TLS](https://gateway-api.sigs.k8s.io/v1alpha1/guides/tls/) ## Resource Configuration diff --git a/docs/content/providers/kubernetes-ingress.md b/docs/content/providers/kubernetes-ingress.md index c3a3a86c9..aa47da890 100644 --- a/docs/content/providers/kubernetes-ingress.md +++ b/docs/content/providers/kubernetes-ingress.md @@ -490,4 +490,4 @@ providers: ### Further To learn more about the various aspects of the Ingress specification that Traefik supports, -many examples of Ingresses definitions are located in the test [examples](https://github.com/traefik/traefik/tree/v2.4/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository. +many examples of Ingresses definitions are located in the test [examples](https://github.com/traefik/traefik/tree/v2.5/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository. diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index a7ac27b77..e521e20b1 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -422,6 +422,7 @@ curvePreferences = ["foobar", "foobar"] sniStrict = true preferServerCipherSuites = true + alpnProtocols = ["foobar", "foobar"] [tls.options.Options0.clientAuth] caFiles = ["foobar", "foobar"] clientAuthType = "foobar" @@ -432,6 +433,7 @@ curvePreferences = ["foobar", "foobar"] sniStrict = true preferServerCipherSuites = true + alpnProtocols = ["foobar", "foobar"] [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 3a124cbfe..8a4dc1aca 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -471,6 +471,9 @@ tls: clientAuthType: foobar sniStrict: true preferServerCipherSuites: true + alpnProtocols: + - foobar + - foobar Options1: minVersion: foobar maxVersion: foobar @@ -487,6 +490,9 @@ tls: clientAuthType: foobar sniStrict: true preferServerCipherSuites: true + alpnProtocols: + - foobar + - foobar stores: Store0: defaultCertificate: diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml index 3ec900d5f..69a939498 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -2,6 +2,7 @@ --8<-- "content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml" --8<-- "content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml" --8<-- "content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_middlewaretcps.yaml" --8<-- "content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml" --8<-- "content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml" --8<-- "content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml" diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml index 4b9bb5562..d86a2dd67 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml @@ -194,6 +194,9 @@ spec: clientAuthType: RequireAndVerifyClientCert sniStrict: true preferServerCipherSuites: true + alpnProtocols: + - foobar + - foobar --- apiVersion: traefik.containo.us/v1alpha1 diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index d06c339e0..5921510ee 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -275,6 +275,8 @@ | `traefik/tls/certificates/1/keyFile` | `foobar` | | `traefik/tls/certificates/1/stores/0` | `foobar` | | `traefik/tls/certificates/1/stores/1` | `foobar` | +| `traefik/tls/options/Options0/alpnProtocols/0` | `foobar` | +| `traefik/tls/options/Options0/alpnProtocols/1` | `foobar` | | `traefik/tls/options/Options0/cipherSuites/0` | `foobar` | | `traefik/tls/options/Options0/cipherSuites/1` | `foobar` | | `traefik/tls/options/Options0/clientAuth/caFiles/0` | `foobar` | @@ -286,6 +288,8 @@ | `traefik/tls/options/Options0/minVersion` | `foobar` | | `traefik/tls/options/Options0/preferServerCipherSuites` | `true` | | `traefik/tls/options/Options0/sniStrict` | `true` | +| `traefik/tls/options/Options1/alpnProtocols/0` | `foobar` | +| `traefik/tls/options/Options1/alpnProtocols/1` | `foobar` | | `traefik/tls/options/Options1/cipherSuites/0` | `foobar` | | `traefik/tls/options/Options1/cipherSuites/1` | `foobar` | | `traefik/tls/options/Options1/clientAuth/caFiles/0` | `foobar` | diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml index e18585a9b..86e9beb7c 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml @@ -36,6 +36,10 @@ spec: spec: description: TLSOptionSpec configures TLS for an entry point. properties: + alpnProtocols: + items: + type: string + type: array cipherSuites: items: type: string diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 965f9db0f..4db55f7f2 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -295,9 +295,10 @@ You can find an excerpt of the available custom resources in the table below: | Kind | Purpose | Concept Behind | |--------------------------------------------|--------------------------------------------------------------------|----------------------------------------------------------------| | [IngressRoute](#kind-ingressroute) | HTTP Routing | [HTTP router](../routers/index.md#configuring-http-routers) | -| [Middleware](#kind-middleware) | Tweaks the HTTP requests before they are sent to your service | [HTTP Middlewares](../../middlewares/overview.md) | +| [Middleware](#kind-middleware) | Tweaks the HTTP requests before they are sent to your service | [HTTP Middlewares](../../middlewares/http/overview.md) | | [TraefikService](#kind-traefikservice) | Abstraction for HTTP loadbalancing/mirroring | [HTTP service](../services/index.md#configuring-http-services) | | [IngressRouteTCP](#kind-ingressroutetcp) | TCP Routing | [TCP router](../routers/index.md#configuring-tcp-routers) | +| [MiddlewareTCP](#kind-middlewaretcp) | Tweaks the TCP requests before they are sent to your service | [TCP Middlewares](../../middlewares/tcp/overview.md) | | [IngressRouteUDP](#kind-ingressrouteudp) | UDP Routing | [UDP router](../routers/index.md#configuring-udp-routers) | | [TLSOptions](#kind-tlsoption) | Allows to configure some parameters of the TLS connection | [TLSOptions](../../https/tls.md#tls-options) | | [TLSStores](#kind-tlsstore) | Allows to configure the default TLS store | [TLSStores](../../https/tls.md#certificates-stores) | @@ -580,7 +581,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne ### Kind: `Middleware` -`Middleware` is the CRD implementation of a [Traefik middleware](../../middlewares/overview.md). +`Middleware` is the CRD implementation of a [Traefik middleware](../../middlewares/http/overview.md). Register the `Middleware` [kind](../../reference/dynamic-configuration/kubernetes-crd.md#definitions) in the Kubernetes cluster before creating `Middleware` objects or referencing middlewares in the [`IngressRoute`](#kind-ingressroute) objects. @@ -628,7 +629,7 @@ Register the `Middleware` [kind](../../reference/dynamic-configuration/kubernete Additionally, when you want to reference a Middleware from the CRD Provider, you have to append the namespace of the resource in the resource-name as Traefik appends the namespace internally automatically. -More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md). +More information about available middlewares in the dedicated [middlewares section](../../middlewares/http/overview.md). ### Kind: `TraefikService` @@ -1088,25 +1089,28 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube - footcp routes: # [2] - match: HostSNI(`*`) # [3] - services: # [4] - - name: foo # [5] - port: 8080 # [6] - weight: 10 # [7] - terminationDelay: 400 # [8] - proxyProtocol: # [9] - version: 1 # [10] - tls: # [11] - secretName: supersecret # [12] - options: # [13] - name: opt # [14] - namespace: default # [15] - certResolver: foo # [16] - domains: # [17] - - main: example.net # [18] - sans: # [19] + middlewares: + - name: middleware1 # [4] + namespace: default # [5] + services: # [6] + - name: foo # [7] + port: 8080 # [8] + weight: 10 # [9] + terminationDelay: 400 # [10] + proxyProtocol: # [11] + version: 1 # [12] + tls: # [13] + secretName: supersecret # [14] + options: # [15] + name: opt # [16] + namespace: default # [17] + certResolver: foo # [18] + domains: # [19] + - main: example.net # [20] + sans: # [21] - a.example.net - b.example.net - passthrough: false # [20] + passthrough: false # [22] ``` | Ref | Attribute | Purpose | @@ -1114,23 +1118,25 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube | [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names | | [2] | `routes` | List of routes | | [3] | `routes[n].match` | Defines the [rule](../routers/index.md#rule_1) corresponding to an underlying router | -| [4] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) | -| [5] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) | -| [6] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | -| [7] | `services[n].weight` | Defines the weight to apply to the server load balancing | -| [8] | `services[n].terminationDelay` | corresponds to the deadline that the proxy sets, after one of its connected peers indicates it has closed the writing capability of its connection, to close the reading capability as well, hence fully terminating the connection. It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed). | -| [9] | `proxyProtocol` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) configuration | -| [10] | `version` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) version | -| [11] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration | -| [12] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | -| [13] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | -| [14] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | -| [15] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | -| [16] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) | -| [17] | `tls.domains` | List of [domains](../routers/index.md#domains_1) | -| [18] | `domains[n].main` | Defines the main domain name | -| [19] | `domains[n].sans` | List of SANs (alternative domains) | -| [20] | `tls.passthrough` | If `true`, delegates the TLS termination to the backend | +| [4] | `middlewares[n].name` | Defines the [MiddlewareTCP](#kind-middlewaretcp) name | +| [5] | `middlewares[n].namespace` | Defines the [MiddlewareTCP](#kind-middlewaretcp) namespace | +| [6] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) | +| [7] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) | +| [8] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | +| [9] | `services[n].weight` | Defines the weight to apply to the server load balancing | +| [10] | `services[n].terminationDelay` | corresponds to the deadline that the proxy sets, after one of its connected peers indicates it has closed the writing capability of its connection, to close the reading capability as well, hence fully terminating the connection. It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed). | +| [11] | `proxyProtocol` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) configuration | +| [12] | `version` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) version | +| [13] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration | +| [14] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | +| [15] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | +| [16] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | +| [17] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | +| [18] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) | +| [19] | `tls.domains` | List of [domains](../routers/index.md#domains_1) | +| [20] | `domains[n].main` | Defines the main domain name | +| [21] | `domains[n].sans` | List of SANs (alternative domains) | +| [22] | `tls.passthrough` | If `true`, delegates the TLS termination to the backend | ??? example "Declaring an IngressRouteTCP" @@ -1265,6 +1271,57 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube - port: 80 ``` +### Kind: `MiddlewareTCP` + +`MiddlewareTCP` is the CRD implementation of a [Traefik TCP middleware](../../middlewares/tcp/overview.md). + +Register the `MiddlewareTCP` [kind](../../reference/dynamic-configuration/kubernetes-crd.md#definitions) in the Kubernetes cluster before creating `MiddlewareTCP` objects or referencing TCP middlewares in the [`IngressRouteTCP`](#kind-ingressroutetcp) objects. + +??? "Declaring and Referencing a MiddlewareTCP " + + ```yaml tab="Middleware" + apiVersion: traefik.containo.us/v1alpha1 + kind: MiddlewareTCP + metadata: + name: ipwhitelist + spec: + ipWhiteList: + sourceRange: + - 127.0.0.1/32 + - 192.168.1.7 + ``` + + ```yaml tab="IngressRoute" + apiVersion: traefik.containo.us/v1alpha1 + kind: IngressRoute + metadata: + name: ingressroutebar + + spec: + entryPoints: + - web + routes: + - match: Host(`example.com`) && PathPrefix(`/whitelist`) + kind: Rule + services: + - name: whoami + port: 80 + middlewares: + - name: ipwhitelist + namespace: foo + ``` + +!!! important "Cross-provider namespace" + + As Kubernetes also has its own notion of namespace, one should not confuse the kubernetes namespace of a resource + (in the reference to the middleware) with the [provider namespace](../../providers/overview.md#provider-namespace), + when the definition of the TCP middleware comes from another provider. + In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored. + Additionally, when you want to reference a MiddlewareTCP from the CRD Provider, + you have to append the namespace of the resource in the resource-name as Traefik appends the namespace internally automatically. + +More information about available TCP middlewares in the dedicated [middlewares section](../../middlewares/tcp/overview.md). + ### Kind `IngressRouteUDP` `IngressRouteUDP` is the CRD implementation of a [Traefik UDP router](../routers/index.md#configuring-udp-routers). @@ -1449,6 +1506,8 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre - secret-ca2 clientAuthType: VerifyClientCertIfGiven # [7] sniStrict: true # [8] + alpnProtocols: # [9] + - foobar ``` | Ref | Attribute | Purpose | @@ -1461,6 +1520,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre | [6] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. | | [7] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert` | | [8] | `sniStrict` | if `true`, Traefik won't allow connections from clients connections that do not specify a server_name extension | +| [9] | `alpnProtocols` | List of supported [application level protocols](../../https/tls.md#alpn-protocols) for the TLS handshake, in order of preference. | !!! info "CA Secret" diff --git a/docs/content/routing/providers/kubernetes-gateway.md b/docs/content/routing/providers/kubernetes-gateway.md index 6cdd578a3..97a857eb9 100644 --- a/docs/content/routing/providers/kubernetes-gateway.md +++ b/docs/content/routing/providers/kubernetes-gateway.md @@ -35,16 +35,16 @@ You can find an excerpt of the supported Kubernetes Gateway API resources in the | Kind | Purpose | Concept Behind | |------------------------------------|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------| -| [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass) | -| [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway) | -| [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/api-types/httproute) | -| [TCPRoute](#kind-tcproute) | Allows mapping TCP requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/concepts/api-overview/#httptcpfooroute) | -| [TLSRoute](#kind-tlsroute) | Allows mapping TLS requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/concepts/api-overview/#httptcpfooroute) | +| [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/v1alpha1/api-types/gatewayclass) | +| [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/v1alpha1/api-types/gateway) | +| [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha1/api-types/httproute) | +| [TCPRoute](#kind-tcproute) | Allows mapping TCP requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/concepts/api-overview/#tcproute-and-udproute)| +| [TLSRoute](#kind-tlsroute) | Allows mapping TLS requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/concepts/api-overview/#tcproute-and-udproute)| ### Kind: `GatewayClass` `GatewayClass` is cluster-scoped resource defined by the infrastructure provider. This resource represents a class of Gateways that can be instantiated. -More details on the GatewayClass [official documentation](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/). +More details on the GatewayClass [official documentation](https://gateway-api.sigs.k8s.io/v1alpha1/api-types/gatewayclass/). The `GatewayClass` should be declared by the infrastructure provider, otherwise please register the `GatewayClass` [definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the Kubernetes cluster before @@ -67,7 +67,7 @@ creating `GatewayClass` objects. A `Gateway` is 1:1 with the life cycle of the configuration of infrastructure. When a user creates a Gateway, some load balancing infrastructure is provisioned or configured by the GatewayClass controller. -More details on the Gateway [official documentation](https://gateway-api.sigs.k8s.io/api-types/gateway/). +More details on the Gateway [official documentation](https://gateway-api.sigs.k8s.io/v1alpha1/api-types/gateway/). Register the `Gateway` [definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the Kubernetes cluster before creating `Gateway` objects. diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index 2276f04df..34ca6d38f 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -28,8 +28,8 @@ A Story of key & values | Key (Path) | Value | |-----------------------------------------------|-------------| - | `traefik.http.routers.myrouter.entrypoints/0` | `web` | - | `traefik.http.routers.myrouter.entrypoints/1` | `websecure` | + | `traefik/http/routers/myrouter/entrypoints/0` | `web` | + | `traefik/http/routers/myrouter/entrypoints/1` | `websecure` | ??? info "`traefik/http/routers//middlewares`" diff --git a/docs/docs.Dockerfile b/docs/docs.Dockerfile index 177e3f9cc..ee10a5302 100644 --- a/docs/docs.Dockerfile +++ b/docs/docs.Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:3.14 ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.local/bin diff --git a/docs/requirements.txt b/docs/requirements.txt index 1ea1cf557..c9c00839c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -mkdocs==1.1 +mkdocs==1.2.2 pymdown-extensions==7.0 mkdocs-bootswatch==1.0 mkdocs-traefiklabs>=100.0.7 diff --git a/exp.Dockerfile b/exp.Dockerfile index 318f8c95f..4d7bd5cca 100644 --- a/exp.Dockerfile +++ b/exp.Dockerfile @@ -12,7 +12,7 @@ RUN npm install RUN npm run build # BUILD -FROM golang:1.16-alpine as gobuild +FROM golang:1.17-alpine as gobuild RUN apk --update upgrade \ && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ @@ -38,7 +38,7 @@ COPY --from=webui /src/static/ /go/src/github.com/traefik/traefik/static/ RUN ./script/make.sh generate binary ## IMAGE -FROM alpine:3.10 +FROM alpine:3.14 RUN apk --no-cache --no-progress add bash curl ca-certificates tzdata \ && update-ca-certificates \ diff --git a/go.mod b/go.mod index 44c2a25a6..3e416d9d6 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/go-acme/lego/v4 v4.4.0 github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea - github.com/golang/protobuf v1.4.3 + github.com/golang/protobuf v1.5.2 github.com/google/go-github/v28 v28.1.1 github.com/gorilla/mux v1.7.3 github.com/gorilla/websocket v1.4.2 @@ -48,7 +48,7 @@ require ( github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807 github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591 - github.com/lucas-clemente/quic-go v0.20.1 + github.com/lucas-clemente/quic-go v0.22.0 github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f github.com/miekg/dns v1.1.43 github.com/mitchellh/copystructure v1.0.0 @@ -73,7 +73,7 @@ require ( github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/tinylib/msgp v1.0.2 // indirect github.com/traefik/paerser v0.1.4 - github.com/traefik/yaegi v0.9.21 + github.com/traefik/yaegi v0.9.23 github.com/uber/jaeger-client-go v2.29.1+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible github.com/unrolled/render v1.0.2 @@ -84,9 +84,10 @@ require ( go.elastic.co/apm v1.11.0 go.elastic.co/apm/module/apmot v1.11.0 golang.org/x/mod v0.4.2 - golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 + golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 + golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba - golang.org/x/tools v0.1.0 + golang.org/x/tools v0.1.1 google.golang.org/grpc v1.27.1 gopkg.in/DataDog/dd-trace-go.v1 v1.19.0 gopkg.in/fsnotify.v1 v1.4.7 diff --git a/go.sum b/go.sum index 806eb5978..dc2de8bd3 100644 --- a/go.sum +++ b/go.sum @@ -403,6 +403,8 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= @@ -436,8 +438,8 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -452,8 +454,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= @@ -467,8 +471,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= @@ -738,8 +743,8 @@ github.com/liquidweb/liquidweb-go v1.6.3/go.mod h1:SuXXp+thr28LnjEw18AYtWwIbWMHS github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20= github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI= -github.com/lucas-clemente/quic-go v0.20.1 h1:hb5m76V8QS/8Nw/suHvXqo3BMHAozvIkcnzpJdpanSk= -github.com/lucas-clemente/quic-go v0.20.1/go.mod h1:fZq/HUDIM+mW6X6wtzORjC0E/WDBMKe5Hf9bgjISwLk= +github.com/lucas-clemente/quic-go v0.22.0 h1:o8NIiHaavjoHe6z8Bqm6fw7g0YIP6AFKMYer+oNxInA= +github.com/lucas-clemente/quic-go v0.22.0/go.mod h1:vF5M1XqhBAHgbjKcJOXY3JZz3GP0T3FQhz/uyOUS38Q= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -758,10 +763,13 @@ github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-15 v0.1.4 h1:RehYMOyRW8hPVEja1KBVsFVNSm35Jj9Mvs5yNoZZ28A= github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-16 v0.1.3 h1:XEZ1xGorVy9u+lJq+WXNE+hiqRYLNvJGYmwfwKQN2gU= -github.com/marten-seemann/qtls-go1-16 v0.1.3/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-15 v0.1.5 h1:Ci4EIUN6Rlb+D6GmLdej/bCQ4nPYNtVXQB+xjiXE1nk= +github.com/marten-seemann/qtls-go1-15 v0.1.5/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco= +github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1 h1:/rpmWuGvceLwwWuaKPdjpR4JJEUH0tq64/I3hvzaNLM= +github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -866,8 +874,9 @@ github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= github.com/nrdcg/porkbun v0.1.1 h1:gxVzQYfFUGXhnBax/aVugoE3OIBAdHgrJgyMPyY5Sjo= github.com/nrdcg/porkbun v0.1.1/go.mod h1:JWl/WKnguWos4mjfp4YizvvToigk9qpQwrodOk+CPoA= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -881,16 +890,19 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= @@ -1138,8 +1150,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/traefik/paerser v0.1.4 h1:/IXjV04Gf6di51H8Jl7jyS3OylsLjIasrwXIIwj1aT8= github.com/traefik/paerser v0.1.4/go.mod h1:FIdQ4Y92ulQUGSeZgxchtBKEcLw1o551PMNg9PoIq/4= -github.com/traefik/yaegi v0.9.21 h1:Ar123+dawjSKTUqkhWF5q7pCeR3Ei0V5070teAZxnQ0= -github.com/traefik/yaegi v0.9.21/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk= +github.com/traefik/yaegi v0.9.23 h1:QM2DZCZZJBwAxiST2JhHnL1yze2XkeNZcnUPlB+2fCE= +github.com/traefik/yaegi v0.9.23/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk= github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE= github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= @@ -1193,6 +1205,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.elastic.co/apm v1.11.0 h1:uJyt6nCW9880sZhfl1tB//Jy/5TadNoAd8edRUtgb3w= go.elastic.co/apm v1.11.0/go.mod h1:qoOSi09pnzJDh5fKnfY7bPmQgl8yl2tULdOu03xhui0= go.elastic.co/apm/module/apmhttp v1.11.0 h1:k/MjK0y2aLOXumoM8jcWXqxvIFlMS4U8Bn9cMUPdVX0= @@ -1347,8 +1360,10 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1433,12 +1448,15 @@ golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= @@ -1511,9 +1529,11 @@ golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200513154647-78b527d18275/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1598,8 +1618,10 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/DataDog/dd-trace-go.v1 v1.19.0 h1:aFSFd6oDMdvPYiToGqTv7/ERA6QrPhGaXSuueRCaM88= gopkg.in/DataDog/dd-trace-go.v1 v1.19.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index 543bb577a..d425c38d0 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.1 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null name: ingressroutes.traefik.containo.us spec: @@ -202,7 +202,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.1 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null name: ingressroutetcps.traefik.containo.us spec: @@ -362,7 +362,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.1 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null name: ingressrouteudps.traefik.containo.us spec: @@ -1212,6 +1212,10 @@ spec: spec: description: TLSOptionSpec configures TLS for an entry point. properties: + alpnProtocols: + items: + type: string + type: array cipherSuites: items: type: string diff --git a/integration/retry_test.go b/integration/retry_test.go index e55dc10c1..47a51f44b 100644 --- a/integration/retry_test.go +++ b/integration/retry_test.go @@ -64,7 +64,7 @@ func (s *RetrySuite) TestRetryBackoff(c *check.C) { response, err := http.Get("http://127.0.0.1:8000/") duration := time.Since(start) // test case delays: 500 + 700 + 1000ms with randomization. It should be safely > 1500ms - minAllowed := time.Millisecond * 1500 + minAllowed := time.Millisecond * 1400 c.Assert(err, checker.IsNil) c.Assert(response.StatusCode, checker.Equals, http.StatusOK) diff --git a/pkg/config/kv/kv_node.go b/pkg/config/kv/kv_node.go index ef1571c1e..229525ef6 100644 --- a/pkg/config/kv/kv_node.go +++ b/pkg/config/kv/kv_node.go @@ -24,7 +24,7 @@ func DecodeToNode(pairs []*store.KVPair, rootName string, filters ...string) (*p return nil, fmt.Errorf("invalid label root %s", rootName) } - split := strings.Split(pair.Key[len(rootName)+1:], "/") + split := strings.FieldsFunc(pair.Key[len(rootName)+1:], func(c rune) bool { return c == '/' }) parts := []string{rootName} for _, fragment := range split { diff --git a/pkg/config/kv/kv_test.go b/pkg/config/kv/kv_test.go index c94da1bce..f7c0d7ed9 100644 --- a/pkg/config/kv/kv_test.go +++ b/pkg/config/kv/kv_test.go @@ -28,6 +28,7 @@ func TestDecode(t *testing.T) { "traefik/fieldf/Test2": "B", "traefik/fieldg/0/name": "A", "traefik/fieldg/1/name": "B", + "traefik/fieldh/": "foo", }, expected: &sample{ FieldA: "bar", @@ -45,6 +46,7 @@ func TestDecode(t *testing.T) { {Name: "A"}, {Name: "B"}, }, + FieldH: "foo", }, }, { @@ -61,6 +63,7 @@ func TestDecode(t *testing.T) { "foo/bar/traefik/fieldf/Test2": "B", "foo/bar/traefik/fieldg/0/name": "A", "foo/bar/traefik/fieldg/1/name": "B", + "foo/bar/traefik/fieldh/": "foo", }, expected: &sample{ FieldA: "bar", @@ -78,6 +81,7 @@ func TestDecode(t *testing.T) { {Name: "A"}, {Name: "B"}, }, + FieldH: "foo", }, }, } @@ -107,6 +111,7 @@ type sample struct { } `label:"allowEmpty"` FieldF map[string]string FieldG []sub + FieldH string } type sub struct { diff --git a/pkg/ip/checker_test.go b/pkg/ip/checker_test.go index 0e7a5c6fd..da2f07861 100644 --- a/pkg/ip/checker_test.go +++ b/pkg/ip/checker_test.go @@ -27,6 +27,12 @@ func TestIsAuthorized(t *testing.T) { remoteAddr: "1.2.3.1:123", authorized: true, }, + { + desc: "octal ip in remoteAddr", + whiteList: []string{"127.2.3.4/24"}, + remoteAddr: "0127.2.3.1:123", + authorized: false, + }, } for _, test := range testCases { diff --git a/pkg/middlewares/auth/forward.go b/pkg/middlewares/auth/forward.go index ed9e7d2ef..df1895f09 100644 --- a/pkg/middlewares/auth/forward.go +++ b/pkg/middlewares/auth/forward.go @@ -15,6 +15,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v2/pkg/middlewares/connectionheader" "github.com/traefik/traefik/v2/pkg/tracing" "github.com/vulcand/oxy/forward" "github.com/vulcand/oxy/utils" @@ -89,7 +90,7 @@ func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAu fa.authResponseHeadersRegex = re } - return fa, nil + return connectionheader.Remover(fa), nil } func (fa *forwardAuth) GetTracingInformation() (string, ext.SpanKindEnum) { diff --git a/pkg/middlewares/connectionheader/connectionheader.go b/pkg/middlewares/connectionheader/connectionheader.go new file mode 100644 index 000000000..b7a64910a --- /dev/null +++ b/pkg/middlewares/connectionheader/connectionheader.go @@ -0,0 +1,46 @@ +package connectionheader + +import ( + "net/http" + "net/textproto" + "strings" + + "golang.org/x/net/http/httpguts" +) + +const ( + connectionHeader = "Connection" + upgradeHeader = "Upgrade" +) + +// Remover removes hop-by-hop headers listed in the "Connection" header. +// See RFC 7230, section 6.1. +func Remover(next http.Handler) http.HandlerFunc { + return func(rw http.ResponseWriter, req *http.Request) { + var reqUpType string + if httpguts.HeaderValuesContainsToken(req.Header[connectionHeader], upgradeHeader) { + reqUpType = req.Header.Get(upgradeHeader) + } + + removeConnectionHeaders(req.Header) + + if reqUpType != "" { + req.Header.Set(connectionHeader, upgradeHeader) + req.Header.Set(upgradeHeader, reqUpType) + } else { + req.Header.Del(connectionHeader) + } + + next.ServeHTTP(rw, req) + } +} + +func removeConnectionHeaders(h http.Header) { + for _, f := range h[connectionHeader] { + for _, sf := range strings.Split(f, ",") { + if sf = textproto.TrimString(sf); sf != "" { + h.Del(sf) + } + } + } +} diff --git a/pkg/middlewares/connectionheader/connectionheader_test.go b/pkg/middlewares/connectionheader/connectionheader_test.go new file mode 100644 index 000000000..7ee047bd0 --- /dev/null +++ b/pkg/middlewares/connectionheader/connectionheader_test.go @@ -0,0 +1,71 @@ +package connectionheader + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRemover(t *testing.T) { + testCases := []struct { + desc string + reqHeaders map[string]string + expected http.Header + }{ + { + desc: "simple remove", + reqHeaders: map[string]string{ + "Foo": "bar", + connectionHeader: "foo", + }, + expected: http.Header{}, + }, + { + desc: "remove and Upgrade", + reqHeaders: map[string]string{ + upgradeHeader: "test", + "Foo": "bar", + connectionHeader: "Upgrade,foo", + }, + expected: http.Header{ + upgradeHeader: []string{"test"}, + connectionHeader: []string{"Upgrade"}, + }, + }, + { + desc: "no remove", + reqHeaders: map[string]string{ + "Foo": "bar", + connectionHeader: "fii", + }, + expected: http.Header{ + "Foo": []string{"bar"}, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}) + + h := Remover(next) + + req := httptest.NewRequest(http.MethodGet, "https://localhost", nil) + + for k, v := range test.reqHeaders { + req.Header.Set(k, v) + } + + rw := httptest.NewRecorder() + + h.ServeHTTP(rw, req) + + assert.Equal(t, test.expected, req.Header) + }) + } +} diff --git a/pkg/middlewares/headers/headers.go b/pkg/middlewares/headers/headers.go index 5ed9f2807..503944f24 100644 --- a/pkg/middlewares/headers/headers.go +++ b/pkg/middlewares/headers/headers.go @@ -10,6 +10,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v2/pkg/middlewares/connectionheader" "github.com/traefik/traefik/v2/pkg/tracing" ) @@ -68,11 +69,12 @@ func New(ctx context.Context, next http.Handler, cfg dynamic.Headers, name strin if hasCustomHeaders || hasCorsHeaders { logger.Debugf("Setting up customHeaders/Cors from %v", cfg) - var err error - handler, err = NewHeader(nextHandler, cfg) + h, err := NewHeader(nextHandler, cfg) if err != nil { return nil, err } + + handler = connectionheader.Remover(h) } return &headers{ diff --git a/pkg/middlewares/headers/responsewriter.go b/pkg/middlewares/headers/responsewriter.go index 39a171dc2..15201b1fd 100644 --- a/pkg/middlewares/headers/responsewriter.go +++ b/pkg/middlewares/headers/responsewriter.go @@ -22,13 +22,18 @@ type responseModifier struct { } // modifier can be nil. -func newResponseModifier(w http.ResponseWriter, r *http.Request, modifier func(*http.Response) error) *responseModifier { - return &responseModifier{ +func newResponseModifier(w http.ResponseWriter, r *http.Request, modifier func(*http.Response) error) http.ResponseWriter { + rm := &responseModifier{ req: r, rw: w, modifier: modifier, code: http.StatusOK, } + + if _, ok := w.(http.CloseNotifier); ok { + return responseModifierWithCloseNotify{responseModifier: rm} + } + return rm } func (r *responseModifier) WriteHeader(code int) { @@ -93,7 +98,11 @@ func (r *responseModifier) Flush() { } } -// CloseNotify implements http.CloseNotifier. -func (r *responseModifier) CloseNotify() <-chan bool { - return r.rw.(http.CloseNotifier).CloseNotify() +type responseModifierWithCloseNotify struct { + *responseModifier +} + +// CloseNotify implements http.CloseNotifier. +func (r *responseModifierWithCloseNotify) CloseNotify() <-chan bool { + return r.responseModifier.rw.(http.CloseNotifier).CloseNotify() } diff --git a/pkg/middlewares/redirect/redirect.go b/pkg/middlewares/redirect/redirect.go index e58422315..d2783d1bc 100644 --- a/pkg/middlewares/redirect/redirect.go +++ b/pkg/middlewares/redirect/redirect.go @@ -4,13 +4,17 @@ import ( "net/http" "net/url" "regexp" - "strings" "github.com/opentracing/opentracing-go/ext" "github.com/traefik/traefik/v2/pkg/tracing" "github.com/vulcand/oxy/utils" ) +const ( + schemeHTTP = "http" + schemeHTTPS = "https" +) + type redirect struct { next http.Handler regex *regexp.Regexp @@ -18,10 +22,11 @@ type redirect struct { permanent bool errHandler utils.ErrorHandler name string + rawURL func(*http.Request) string } // New creates a Redirect middleware. -func newRedirect(next http.Handler, regex, replacement string, permanent bool, name string) (http.Handler, error) { +func newRedirect(next http.Handler, regex, replacement string, permanent bool, rawURL func(*http.Request) string, name string) (http.Handler, error) { re, err := regexp.Compile(regex) if err != nil { return nil, err @@ -34,6 +39,7 @@ func newRedirect(next http.Handler, regex, replacement string, permanent bool, n errHandler: utils.DefaultHandler, next: next, name: name, + rawURL: rawURL, }, nil } @@ -42,7 +48,7 @@ func (r *redirect) GetTracingInformation() (string, ext.SpanKindEnum) { } func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - oldURL := rawURL(req) + oldURL := r.rawURL(req) // If the Regexp doesn't match, skip to the next handler. if !r.regex.MatchString(oldURL) { @@ -98,33 +104,3 @@ func (m *moveHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { http.Error(rw, err.Error(), http.StatusInternalServerError) } } - -func rawURL(req *http.Request) string { - scheme := "http" - host := req.Host - port := "" - uri := req.RequestURI - - schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` - re, _ := regexp.Compile(schemeRegex) - if re.Match([]byte(req.RequestURI)) { - match := re.FindStringSubmatch(req.RequestURI) - scheme = match[1] - - if len(match[2]) > 0 { - host = match[2] - } - - if len(match[3]) > 0 { - port = match[3] - } - - uri = match[4] - } - - if req.TLS != nil { - scheme = "https" - } - - return strings.Join([]string{scheme, "://", host, port, uri}, "") -} diff --git a/pkg/middlewares/redirect/redirect_regex.go b/pkg/middlewares/redirect/redirect_regex.go index c4a6918c9..f26b5e3d4 100644 --- a/pkg/middlewares/redirect/redirect_regex.go +++ b/pkg/middlewares/redirect/redirect_regex.go @@ -3,6 +3,8 @@ package redirect import ( "context" "net/http" + "regexp" + "strings" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" @@ -19,5 +21,35 @@ func NewRedirectRegex(ctx context.Context, next http.Handler, conf dynamic.Redir logger.Debug("Creating middleware") logger.Debugf("Setting up redirection from %s to %s", conf.Regex, conf.Replacement) - return newRedirect(next, conf.Regex, conf.Replacement, conf.Permanent, name) + return newRedirect(next, conf.Regex, conf.Replacement, conf.Permanent, rawURL, name) +} + +func rawURL(req *http.Request) string { + scheme := schemeHTTP + host := req.Host + port := "" + uri := req.RequestURI + + schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` + re, _ := regexp.Compile(schemeRegex) + if re.Match([]byte(req.RequestURI)) { + match := re.FindStringSubmatch(req.RequestURI) + scheme = match[1] + + if len(match[2]) > 0 { + host = match[2] + } + + if len(match[3]) > 0 { + port = match[3] + } + + uri = match[4] + } + + if req.TLS != nil { + scheme = schemeHTTPS + } + + return strings.Join([]string{scheme, "://", host, port, uri}, "") } diff --git a/pkg/middlewares/redirect/redirect_scheme.go b/pkg/middlewares/redirect/redirect_scheme.go index e83b20136..36bcb25fd 100644 --- a/pkg/middlewares/redirect/redirect_scheme.go +++ b/pkg/middlewares/redirect/redirect_scheme.go @@ -3,7 +3,10 @@ package redirect import ( "context" "errors" + "net" "net/http" + "regexp" + "strings" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" @@ -26,9 +29,47 @@ func NewRedirectScheme(ctx context.Context, next http.Handler, conf dynamic.Redi } port := "" - if len(conf.Port) > 0 && !(conf.Scheme == "http" && conf.Port == "80" || conf.Scheme == "https" && conf.Port == "443") { + if len(conf.Port) > 0 && !(conf.Scheme == schemeHTTP && conf.Port == "80" || conf.Scheme == schemeHTTPS && conf.Port == "443") { port = ":" + conf.Port } - return newRedirect(next, schemeRedirectRegex, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, name) + return newRedirect(next, schemeRedirectRegex, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, rawURLScheme, name) +} + +func rawURLScheme(req *http.Request) string { + scheme := schemeHTTP + host, port, err := net.SplitHostPort(req.Host) + if err != nil { + host = req.Host + } else { + port = ":" + port + } + uri := req.RequestURI + + schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` + re, _ := regexp.Compile(schemeRegex) + if re.Match([]byte(req.RequestURI)) { + match := re.FindStringSubmatch(req.RequestURI) + scheme = match[1] + + if len(match[2]) > 0 { + host = match[2] + } + + if len(match[3]) > 0 { + port = match[3] + } + + uri = match[4] + } + + if req.TLS != nil { + scheme = schemeHTTPS + } + + if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" || port == "" { + port = "" + } + + return strings.Join([]string{scheme, "://", host, port, uri}, "") } diff --git a/pkg/middlewares/redirect/redirect_scheme_test.go b/pkg/middlewares/redirect/redirect_scheme_test.go index 4b38ec8e9..710a681ee 100644 --- a/pkg/middlewares/redirect/redirect_scheme_test.go +++ b/pkg/middlewares/redirect/redirect_scheme_test.go @@ -127,8 +127,18 @@ func TestRedirectSchemeHandler(t *testing.T) { Port: "80", }, url: "http://foo:80", - expectedURL: "http://foo", - expectedStatus: http.StatusFound, + expectedURL: "http://foo:80", + expectedStatus: http.StatusOK, + }, + { + desc: "to HTTPS 443", + config: dynamic.RedirectScheme{ + Scheme: "https", + Port: "443", + }, + url: "https://foo:443", + expectedURL: "https://foo:443", + expectedStatus: http.StatusOK, }, { desc: "HTTP to wss", @@ -248,6 +258,7 @@ func TestRedirectSchemeHandler(t *testing.T) { if test.method != "" { method = test.method } + req := httptest.NewRequest(method, test.url, nil) for k, v := range test.headers { diff --git a/pkg/middlewares/tracing/status_code.go b/pkg/middlewares/tracing/status_code.go index 9cec2e16c..f0c57f81f 100644 --- a/pkg/middlewares/tracing/status_code.go +++ b/pkg/middlewares/tracing/status_code.go @@ -11,6 +11,15 @@ type statusCodeRecoder interface { Status() int } +// newStatusCodeRecoder returns an initialized statusCodeRecoder. +func newStatusCodeRecoder(rw http.ResponseWriter, status int) statusCodeRecoder { + recorder := &statusCodeWithoutCloseNotify{rw, status} + if _, ok := rw.(http.CloseNotifier); ok { + return &statusCodeWithCloseNotify{recorder} + } + return recorder +} + type statusCodeWithoutCloseNotify struct { http.ResponseWriter status int @@ -46,12 +55,3 @@ type statusCodeWithCloseNotify struct { func (s *statusCodeWithCloseNotify) CloseNotify() <-chan bool { return s.ResponseWriter.(http.CloseNotifier).CloseNotify() } - -// newStatusCodeRecoder returns an initialized statusCodeRecoder. -func newStatusCodeRecoder(rw http.ResponseWriter, status int) statusCodeRecoder { - recorder := &statusCodeWithoutCloseNotify{rw, status} - if _, ok := rw.(http.CloseNotifier); ok { - return &statusCodeWithCloseNotify{recorder} - } - return recorder -} diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml index aaed4a1d8..25a2ac448 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml @@ -28,6 +28,15 @@ spec: port: 80 middlewares: - name: test-errorpage + - match: Host(`foo.com`) && PathPrefix(`/bur`) + kind: Rule + priority: 12 + services: + - name: whoami + namespace: default + port: 80 + middlewares: + - name: cross-ns-stripprefix@kubernetescrd --- apiVersion: traefik.containo.us/v1alpha1 diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index dcb37ae8a..4dd1d208d 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -703,6 +703,12 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options id = tlsOption.Name nsDefault = append(nsDefault, tlsOption.Namespace) } + + alpnProtocols := tls.DefaultTLSOptions.ALPNProtocols + if len(tlsOption.Spec.ALPNProtocols) > 0 { + alpnProtocols = tlsOption.Spec.ALPNProtocols + } + tlsOptions[id] = tls.Options{ MinVersion: tlsOption.Spec.MinVersion, MaxVersion: tlsOption.Spec.MaxVersion, @@ -714,6 +720,7 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options }, SniStrict: tlsOption.Spec.SniStrict, PreferServerCipherSuites: tlsOption.Spec.PreferServerCipherSuites, + ALPNProtocols: alpnProtocols, } } diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index 3f969d7e8..ba32bba33 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -147,13 +147,23 @@ func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace str var mds []string for _, mi := range middlewares { - if strings.Contains(mi.Name, providerNamespaceSeparator) { + name := mi.Name + + if !p.AllowCrossNamespace && strings.HasSuffix(mi.Name, providerNamespaceSeparator+providerName) { + // Since we are not able to know if another namespace is in the name (namespace-name@kubernetescrd), + // if the provider namespace kubernetescrd is used, + // we don't allow this format to avoid cross namespace references. + return nil, fmt.Errorf("invalid reference to middleware %s: with crossnamespace disallowed, the namespace field needs to be explicitly specified", mi.Name) + } + + if strings.Contains(name, providerNamespaceSeparator) { if len(mi.Namespace) > 0 { log.FromContext(ctx). WithField(log.MiddlewareName, mi.Name). Warnf("namespace %q is ignored in cross-provider context", mi.Namespace) } - mds = append(mds, mi.Name) + + mds = append(mds, name) continue } @@ -166,7 +176,7 @@ func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace str ns = mi.Namespace } - mds = append(mds, makeID(ns, mi.Name)) + mds = append(mds, makeID(ns, name)) } return mds, nil diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 504e317da..c02f9889d 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -616,6 +616,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, SniStrict: true, PreferServerCipherSuites: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -678,6 +683,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { ClientAuthType: "VerifyClientCertIfGiven", }, SniStrict: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -739,6 +749,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { ClientAuthType: "VerifyClientCertIfGiven", }, SniStrict: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -789,6 +804,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Options: map[string]tls.Options{ "default-foo": { MinVersion: "VersionTLS12", + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -839,6 +859,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Options: map[string]tls.Options{ "default-foo": { MinVersion: "VersionTLS12", + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -2539,6 +2564,11 @@ func TestLoadIngressRoutes(t *testing.T) { }, SniStrict: true, PreferServerCipherSuites: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -2648,6 +2678,11 @@ func TestLoadIngressRoutes(t *testing.T) { }, SniStrict: true, PreferServerCipherSuites: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -2716,6 +2751,11 @@ func TestLoadIngressRoutes(t *testing.T) { ClientAuthType: "VerifyClientCertIfGiven", }, SniStrict: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -2779,6 +2819,11 @@ func TestLoadIngressRoutes(t *testing.T) { ClientAuthType: "VerifyClientCertIfGiven", }, SniStrict: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -2831,6 +2876,11 @@ func TestLoadIngressRoutes(t *testing.T) { Options: map[string]tls.Options{ "default-foo": { MinVersion: "VersionTLS12", + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -2883,6 +2933,11 @@ func TestLoadIngressRoutes(t *testing.T) { Options: map[string]tls.Options{ "default-foo": { MinVersion: "VersionTLS12", + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, }, @@ -4313,6 +4368,13 @@ func TestCrossNamespace(t *testing.T) { Priority: 12, Middlewares: []string{"default-test-errorpage"}, }, + "default-test-crossnamespace-route-a1963878aac7331b7950": { + EntryPoints: []string{"foo"}, + Service: "default-test-crossnamespace-route-a1963878aac7331b7950", + Rule: "Host(`foo.com`) && PathPrefix(`/bur`)", + Priority: 12, + Middlewares: []string{"cross-ns-stripprefix@kubernetescrd"}, + }, }, Middlewares: map[string]*dynamic.Middleware{ "cross-ns-stripprefix": { @@ -4369,6 +4431,19 @@ func TestCrossNamespace(t *testing.T) { PassHostHeader: Bool(true), }, }, + "default-test-crossnamespace-route-a1963878aac7331b7950": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: Bool(true), + }, + }, }, ServersTransports: map[string]*dynamic.ServersTransport{}, }, diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go index 52eb84a48..9faf2d61c 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go @@ -27,6 +27,7 @@ type TLSOptionSpec struct { ClientAuth ClientAuth `json:"clientAuth,omitempty"` SniStrict bool `json:"sniStrict,omitempty"` PreferServerCipherSuites bool `json:"preferServerCipherSuites,omitempty"` + ALPNProtocols []string `json:"alpnProtocols,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go index 05b41d74c..b0a17ce4c 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go @@ -1327,6 +1327,11 @@ func (in *TLSOptionSpec) DeepCopyInto(out *TLSOptionSpec) { copy(*out, *in) } in.ClientAuth.DeepCopyInto(&out.ClientAuth) + if in.ALPNProtocols != nil { + in, out := &in.ALPNProtocols, &out.ALPNProtocols + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/provider/kubernetes/gateway/kubernetes.go b/pkg/provider/kubernetes/gateway/kubernetes.go index 5a9bd0f9b..5bea3a6af 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes.go +++ b/pkg/provider/kubernetes/gateway/kubernetes.go @@ -417,7 +417,7 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * } if tlsModeType == v1alpha1.TLSModePassthrough && listener.TLS.CertificateRef != nil { - // https://gateway-api.sigs.k8s.io/guides/tls/ + // https://gateway-api.sigs.k8s.io/v1alpha1/guides/tls/ logger.Warnf("In case of Passthrough TLS mode, no TLS settings take effect as the TLS session from the client is NOT terminated at the Gateway") } @@ -900,7 +900,7 @@ func hostRule(httpRouteSpec v1alpha1.HTTPRouteSpec) (string, error) { continue } - // https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.Hostname + // https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.Hostname if !strings.HasPrefix(host, "*.") || wildcard > 1 { return "", fmt.Errorf("invalid rule: %q", host) } diff --git a/pkg/provider/kubernetes/k8s/event_handler.go b/pkg/provider/kubernetes/k8s/event_handler.go index 155c01253..92b450bec 100644 --- a/pkg/provider/kubernetes/k8s/event_handler.go +++ b/pkg/provider/kubernetes/k8s/event_handler.go @@ -48,12 +48,10 @@ func objChanged(oldObj, newObj interface{}) bool { } if _, ok := oldObj.(*corev1.Endpoints); ok { - if endpointsChanged(oldObj.(*corev1.Endpoints), newObj.(*corev1.Endpoints)) { - return true - } + return endpointsChanged(oldObj.(*corev1.Endpoints), newObj.(*corev1.Endpoints)) } - return false + return true } func endpointsChanged(a, b *corev1.Endpoints) bool { diff --git a/pkg/provider/kubernetes/k8s/event_handler_test.go b/pkg/provider/kubernetes/k8s/event_handler_test.go index a2bbfb0c5..8f75ebbd2 100644 --- a/pkg/provider/kubernetes/k8s/event_handler_test.go +++ b/pkg/provider/kubernetes/k8s/event_handler_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -60,6 +61,33 @@ func Test_detectChanges(t *testing.T) { }, }, }, + { + name: "Ingress With same version", + oldObj: &v1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "1", + }, + }, + newObj: &v1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "1", + }, + }, + }, + { + name: "Ingress With different version", + oldObj: &v1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "1", + }, + }, + newObj: &v1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "2", + }, + }, + want: true, + }, { name: "With same annotations", oldObj: &corev1.Endpoints{ diff --git a/pkg/provider/kv/kv_test.go b/pkg/provider/kv/kv_test.go index a04093f18..ff3f941fd 100644 --- a/pkg/provider/kv/kv_test.go +++ b/pkg/provider/kv/kv_test.go @@ -848,6 +848,11 @@ func Test_buildConfiguration(t *testing.T) { ClientAuthType: "foobar", }, SniStrict: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, "Options1": { MinVersion: "foobar", @@ -868,6 +873,11 @@ func Test_buildConfiguration(t *testing.T) { ClientAuthType: "foobar", }, SniStrict: true, + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, }, }, Stores: map[string]tls.Store{ diff --git a/pkg/server/aggregator_test.go b/pkg/server/aggregator_test.go index 70cce8820..8d9b0f18c 100644 --- a/pkg/server/aggregator_test.go +++ b/pkg/server/aggregator_test.go @@ -182,7 +182,13 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) { desc: "Nil returns an empty configuration", given: nil, expected: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, }, }, { @@ -199,7 +205,13 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) { }, }, expected: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, "foo@provider-1": { MinVersion: "VersionTLS12", }, @@ -228,7 +240,13 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) { }, }, expected: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, "foo@provider-1": { MinVersion: "VersionTLS13", }, @@ -334,7 +352,13 @@ func Test_mergeConfiguration_tlsOptions(t *testing.T) { }, }, expected: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, "foo@provider-1": { MinVersion: "VersionTLS12", }, diff --git a/pkg/server/configurationwatcher_test.go b/pkg/server/configurationwatcher_test.go index 276b6bc83..7b885cd22 100644 --- a/pkg/server/configurationwatcher_test.go +++ b/pkg/server/configurationwatcher_test.go @@ -76,7 +76,13 @@ func TestNewConfigurationWatcher(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, }, Stores: map[string]tls.Store{}, }, @@ -236,7 +242,13 @@ func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, }, Stores: map[string]tls.Store{}, }, @@ -292,7 +304,13 @@ func TestListenProvidersPublishesConfigForEachProvider(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ - "default": {}, + "default": { + ALPNProtocols: []string{ + "h2", + "http/1.1", + "acme-tls/1", + }, + }, }, Stores: map[string]tls.Store{}, }, diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index 8e2e3f884..d23370000 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -23,6 +23,13 @@ type Options struct { 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"` + ALPNProtocols []string `json:"alpnProtocols,omitempty" toml:"alpnProtocols,omitempty" yaml:"alpnProtocols,omitempty" export:"true"` +} + +// SetDefaults sets the default values for an Options struct. +func (o *Options) SetDefaults() { + // ensure http2 enabled + o.ALPNProtocols = DefaultTLSOptions.ALPNProtocols } // +k8s:deepcopy-gen=true diff --git a/pkg/tls/tlsmanager.go b/pkg/tls/tlsmanager.go index 2ac87a161..35ba50fac 100644 --- a/pkg/tls/tlsmanager.go +++ b/pkg/tls/tlsmanager.go @@ -24,7 +24,10 @@ const ( ) // DefaultTLSOptions the default TLS options. -var DefaultTLSOptions = Options{} +var DefaultTLSOptions = Options{ + // ensure http2 enabled + ALPNProtocols: []string{"h2", "http/1.1", tlsalpn01.ACMETLS1Protocol}, +} // Manager is the TLS option/store/configuration factory. type Manager struct { @@ -230,10 +233,9 @@ func buildCertificateStore(ctx context.Context, tlsStore Store, storename string // creates a TLS config that allows terminating HTTPS for multiple domains using SNI. func buildTLSConfig(tlsOption Options) (*tls.Config, error) { - conf := &tls.Config{} - - // ensure http2 enabled - conf.NextProtos = []string{"h2", "http/1.1", tlsalpn01.ACMETLS1Protocol} + conf := &tls.Config{ + NextProtos: tlsOption.ALPNProtocols, + } if len(tlsOption.ClientAuth.CAFiles) > 0 { pool := x509.NewCertPool() diff --git a/pkg/tls/zz_generated.deepcopy.go b/pkg/tls/zz_generated.deepcopy.go index 0025fb9f8..c4dbf9b3c 100644 --- a/pkg/tls/zz_generated.deepcopy.go +++ b/pkg/tls/zz_generated.deepcopy.go @@ -85,6 +85,11 @@ func (in *Options) DeepCopyInto(out *Options) { copy(*out, *in) } in.ClientAuth.DeepCopyInto(&out.ClientAuth) + if in.ALPNProtocols != nil { + in, out := &in.ALPNProtocols, &out.ALPNProtocols + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 0e924afaa..5cf4da4f8 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 v2.4.12 -CurrentRef = "v2.4" -PreviousRef = "v2.4.11" -BaseBranch = "v2.4" -FutureCurrentRefName = "v2.4.12" +# example new bugfix v2.5.1 +CurrentRef = "v2.5" +PreviousRef = "v2.5.0" +BaseBranch = "v2.5" +FutureCurrentRefName = "v2.5.1" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 diff --git a/script/gcg/traefik-final-release-part1.toml b/script/gcg/traefik-final-release-part1.toml index a255763ab..1bb718499 100644 --- a/script/gcg/traefik-final-release-part1.toml +++ b/script/gcg/traefik-final-release-part1.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example final release of v2.4.0 -CurrentRef = "v2.4" -PreviousRef = "v2.4.0-rc1" -BaseBranch = "v2.4" -FutureCurrentRefName = "v2.4.0" +# example final release of v2.5.0 +CurrentRef = "v2.5" +PreviousRef = "v2.5.0-rc1" +BaseBranch = "v2.5" +FutureCurrentRefName = "v2.5.0" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 diff --git a/script/gcg/traefik-final-release-part2.toml b/script/gcg/traefik-final-release-part2.toml index 67b3edbea..eebb26dfb 100644 --- a/script/gcg/traefik-final-release-part2.toml +++ b/script/gcg/traefik-final-release-part2.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example final release of v2.4.0 -CurrentRef = "v2.4.0-rc1" -PreviousRef = "v2.3.0-rc1" +# example final release of v2.5.0 +CurrentRef = "v2.5.0-rc1" +PreviousRef = "v2.4.0-rc1" BaseBranch = "master" -FutureCurrentRefName = "v2.4.0-rc1" +FutureCurrentRefName = "v2.5.0-rc1" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 diff --git a/script/gcg/traefik-rc-new.toml b/script/gcg/traefik-rc-new.toml index e9f153b67..682b8dec8 100644 --- a/script/gcg/traefik-rc-new.toml +++ b/script/gcg/traefik-rc-new.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example RC2 of v2.5.0 +# example RC6 of v2.5.0 CurrentRef = "v2.5" -PreviousRef = "v2.5.0-rc2" +PreviousRef = "v2.5.0-rc5" BaseBranch = "v2.5" -FutureCurrentRefName = "v2.5.0-rc3" +FutureCurrentRefName = "v2.5.0-rc6" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 diff --git a/webui/src/pages/_commons/RouterDetail.vue b/webui/src/pages/_commons/RouterDetail.vue index 2e95d0d18..16455f25c 100644 --- a/webui/src/pages/_commons/RouterDetail.vue +++ b/webui/src/pages/_commons/RouterDetail.vue @@ -46,7 +46,7 @@
-
HTTP Middlewares
+
{{ middlewareType }}
@@ -187,6 +187,9 @@ export default { hasTLSConfiguration () { return this.routerByName.item.tls }, + middlewareType () { + return this.$route.meta.protocol.toUpperCase() + ' Middlewares' + }, routerType () { return this.$route.meta.protocol.toUpperCase() + ' Router' },