diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b7c5751d..650a05a7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,145 @@ +## [v2.2.1](https://github.com/containous/traefik/tree/v2.2.1) (2020-04-29) +[All Commits](https://github.com/containous/traefik/compare/v2.2.0...v2.2.1) + +**Bug fixes:** +- **[acme]** Update go-acme/lego to v3.6.0 ([#6727](https://github.com/containous/traefik/pull/6727) by [ldez](https://github.com/ldez)) +- **[consulcatalog]** Normalize default names for ConsulCatalog. ([#6593](https://github.com/containous/traefik/pull/6593) by [ldez](https://github.com/ldez)) +- **[internal]** Change the default priority on the router created by the redirect. ([#6588](https://github.com/containous/traefik/pull/6588) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/ingress]** Delete an unnecessary warning log ([#6624](https://github.com/containous/traefik/pull/6624) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[middleware]** ratelimit: do not default to ipstrategy too early ([#6713](https://github.com/containous/traefik/pull/6713) by [mpl](https://github.com/mpl)) +- **[rancher,webui]** It's just the one TLS, actually. ([#6606](https://github.com/containous/traefik/pull/6606) by [RealOrangeOne](https://github.com/RealOrangeOne)) +- **[server]** Fix case-sensitive header Sec-Websocket-Version ([#6698](https://github.com/containous/traefik/pull/6698) by [tbrandstetter](https://github.com/tbrandstetter)) +- **[udp]** fix: consider UDP when checking for empty config ([#6683](https://github.com/containous/traefik/pull/6683) by [nrwiersma](https://github.com/nrwiersma)) +- **[websocket]** FIx wS heAder ([#6660](https://github.com/containous/traefik/pull/6660) by [mmatur](https://github.com/mmatur)) +- **[websocket]** Manage case for all Websocket headers ([#6705](https://github.com/containous/traefik/pull/6705) by [mmatur](https://github.com/mmatur)) +- **[webui]** Disable distribution of the WebUI as PWA ([#6717](https://github.com/containous/traefik/pull/6717) by [SantoDE](https://github.com/SantoDE)) +- **[webui]** Add polling for getOverview in toolbar ([#6611](https://github.com/containous/traefik/pull/6611) by [lukashass](https://github.com/lukashass)) + +**Documentation:** +- **[api]** Fix documentation about api.insecure defaults ([#6671](https://github.com/containous/traefik/pull/6671) by [thisismydesign](https://github.com/thisismydesign)) +- **[docker,k8s,k8s/ingress,marathon,rancher,sticky-session]** fix: cookie documentation. ([#6745](https://github.com/containous/traefik/pull/6745) by [ldez](https://github.com/ldez)) +- **[file]** Edit code indentation for correct alignment ([#6691](https://github.com/containous/traefik/pull/6691) by [fbruetting](https://github.com/fbruetting)) +- **[healthcheck,k8s,k8s/crd]** Add note about health check in kubernetes ([#6647](https://github.com/containous/traefik/pull/6647) by [mmatur](https://github.com/mmatur)) +- **[k8s,k8s/crd]** docs: Update kubernetes-crd-resource.yml ([#6741](https://github.com/containous/traefik/pull/6741) by [rdxmb](https://github.com/rdxmb)) +- **[k8s,k8s/crd]** doc: improve CRD documentation. ([#6681](https://github.com/containous/traefik/pull/6681) by [ldez](https://github.com/ldez)) +- **[k8s/crd]** doc: add apiVersion for "kind: Middleware" ([#6734](https://github.com/containous/traefik/pull/6734) by [yuyicai](https://github.com/yuyicai)) +- **[k8s/helm]** Update the documentation for helm chart ([#6744](https://github.com/containous/traefik/pull/6744) by [mmatur](https://github.com/mmatur)) +- **[k8s]** Add sentence about the resource namespace and middleware ([#6719](https://github.com/containous/traefik/pull/6719) by [SantoDE](https://github.com/SantoDE)) +- **[kv]** fix KV service docs for http:url and tcp:address ([#6720](https://github.com/containous/traefik/pull/6720) by [bryfry](https://github.com/bryfry)) +- **[logs]** Add Access log chapter for migration v1->v2 ([#6689](https://github.com/containous/traefik/pull/6689) by [MartinKoerner](https://github.com/MartinKoerner)) +- **[middleware]** Update headers.md ([#6675](https://github.com/containous/traefik/pull/6675) by [jamct](https://github.com/jamct)) +- **[middleware]** Doc middleware compress content type ([#6738](https://github.com/containous/traefik/pull/6738) by [rtribotte](https://github.com/rtribotte)) +- **[tracing]** Add link to tracing with elastic ([#6673](https://github.com/containous/traefik/pull/6673) by [collinmutembei](https://github.com/collinmutembei)) +- Added missing text `a yaml file` in Configuration ([#6663](https://github.com/containous/traefik/pull/6663) by [fsoedjede](https://github.com/fsoedjede)) +- Fix typos in the documentation ([#6650](https://github.com/containous/traefik/pull/6650) by [SuperSandro2000](https://github.com/SuperSandro2000)) +- Fix documentation ([#6648](https://github.com/containous/traefik/pull/6648) by [mmatur](https://github.com/mmatur)) +- Fix bad address syntax in Global HTTP to HTTPS redirection v2 TOML ([#6619](https://github.com/containous/traefik/pull/6619) by [Beetix](https://github.com/Beetix)) +- Doc Fix for 2.2 Redirects ([#6595](https://github.com/containous/traefik/pull/6595) by [ajschmidt8](https://github.com/ajschmidt8)) + +## [v2.2.0](https://github.com/containous/traefik/tree/v2.2.0) (2020-03-25) +[All Commits](https://github.com/containous/traefik/compare/v2.1.0-rc1...v2.2.0) + +**Enhancements:** +- **[acme,middleware,tls]** Entry point redirection and default routers configuration ([#6417](https://github.com/containous/traefik/pull/6417) by [ldez](https://github.com/ldez)) +- **[consul,etcd,kv,redis,zk]** Add KV store providers (dynamic configuration only) ([#5899](https://github.com/containous/traefik/pull/5899) by [ldez](https://github.com/ldez)) +- **[consulcatalog,docker,marathon,rancher,udp]** Add UDP in providers with labels ([#6327](https://github.com/containous/traefik/pull/6327) by [juliens](https://github.com/juliens)) +- **[docker]** Fix traefik behavior when network_mode is host ([#5698](https://github.com/containous/traefik/pull/5698) by [FuNK3Y](https://github.com/FuNK3Y)) +- **[docker]** Support SSH connection to Docker ([#5969](https://github.com/containous/traefik/pull/5969) by [sh7dm](https://github.com/sh7dm)) +- **[healthcheck]** Do not follow redirects for the health check URLs ([#5147](https://github.com/containous/traefik/pull/5147) by [coder-hugo](https://github.com/coder-hugo)) +- **[k8s,k8s/crd,udp]** Add UDP support in kubernetesCRD provider ([#6348](https://github.com/containous/traefik/pull/6348) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[k8s,k8s/crd]** Add TLSStores to Kubernetes CRD ([#6270](https://github.com/containous/traefik/pull/6270) by [dtomcej](https://github.com/dtomcej)) +- **[k8s,k8s/crd]** Add namespace attribute on IngressRouteTCP service ([#6085](https://github.com/containous/traefik/pull/6085) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[k8s,k8s/ingress]** Support 'networking.k8s.io/v1beta1' ingress apiVersion ([#6171](https://github.com/containous/traefik/pull/6171) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/ingress]** Update deprecated function call in k8s providers ([#5241](https://github.com/containous/traefik/pull/5241) by [Wagum](https://github.com/Wagum)) +- **[k8s,k8s/ingress]** Add Ingress annotations support ([#6160](https://github.com/containous/traefik/pull/6160) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/ingress]** systematically call updateIngressStatus ([#6148](https://github.com/containous/traefik/pull/6148) by [mpl](https://github.com/mpl)) +- **[logs,middleware]** Rename the non-exposed field "count" to "size" ([#6048](https://github.com/containous/traefik/pull/6048) by [sylr](https://github.com/sylr)) +- **[logs,middleware]** Add http request scheme to logger ([#6226](https://github.com/containous/traefik/pull/6226) by [valtlfelipe](https://github.com/valtlfelipe)) +- **[logs]** Decrease log level for client related error ([#6204](https://github.com/containous/traefik/pull/6204) by [sylr](https://github.com/sylr)) +- **[metrics]** Add metrics about TLS ([#6255](https://github.com/containous/traefik/pull/6255) by [sylr](https://github.com/sylr)) +- **[middleware]** Add period for rate limiter middleware ([#6055](https://github.com/containous/traefik/pull/6055) by [mpl](https://github.com/mpl)) +- **[middleware]** Let metrics libs handle the atomicity ([#5738](https://github.com/containous/traefik/pull/5738) by [sylr](https://github.com/sylr)) +- **[middleware]** Rework access control origin configuration ([#5996](https://github.com/containous/traefik/pull/5996) by [dtomcej](https://github.com/dtomcej)) +- **[middleware]** Add serial number certificate to forward headers ([#5915](https://github.com/containous/traefik/pull/5915) by [dkijkuit](https://github.com/dkijkuit)) +- **[rancher]** Duration order consistency when multiplying number by time unit ([#5885](https://github.com/containous/traefik/pull/5885) by [maxifom](https://github.com/maxifom)) +- **[server,udp]** UDP support ([#6172](https://github.com/containous/traefik/pull/6172) by [mpl](https://github.com/mpl)) +- **[service]** Use EDF schedule algorithm for WeightedRoundRobin ([#6206](https://github.com/containous/traefik/pull/6206) by [pkumza](https://github.com/pkumza)) +- **[service]** Support mirroring request body ([#6080](https://github.com/containous/traefik/pull/6080) by [dmitriyminer](https://github.com/dmitriyminer)) +- **[tls]** Allow PreferServerCipherSuites as a TLS Option ([#6248](https://github.com/containous/traefik/pull/6248) by [dtomcej](https://github.com/dtomcej)) +- **[tracing]** Update APM client. ([#6152](https://github.com/containous/traefik/pull/6152) by [ldez](https://github.com/ldez)) +- **[tracing]** Elastic APM tracer implementation ([#5870](https://github.com/containous/traefik/pull/5870) by [amine7536](https://github.com/amine7536)) +- **[udp,webui]** WebUI: add udp pages ([#6313](https://github.com/containous/traefik/pull/6313) by [matthieuh](https://github.com/matthieuh)) +- **[webui]** Web UI: Polling on tables ([#5909](https://github.com/containous/traefik/pull/5909) by [matthieuh](https://github.com/matthieuh)) +- **[webui]** Proxy API to Traefik in dev mode ([#5980](https://github.com/containous/traefik/pull/5980) by [sh7dm](https://github.com/sh7dm)) +- **[webui]** Web UI: Table infinite scroll ([#5875](https://github.com/containous/traefik/pull/5875) by [matthieuh](https://github.com/matthieuh)) +- **[webui]** Web UI: Take off logic from generic table component ([#5910](https://github.com/containous/traefik/pull/5910) by [matthieuh](https://github.com/matthieuh)) +- **[webui]** Add dark theme for Web UI ([#6036](https://github.com/containous/traefik/pull/6036) by [sh7dm](https://github.com/sh7dm)) +- Update dependencies ([#6359](https://github.com/containous/traefik/pull/6359) by [ldez](https://github.com/ldez)) + +**Bug fixes:** +- **[acme]** Update go-acme/lego to v3.5.0 ([#6491](https://github.com/containous/traefik/pull/6491) by [ldez](https://github.com/ldez)) +- **[authentication,middleware]** digest auth: use RequireAuthStale when appropriate ([#6569](https://github.com/containous/traefik/pull/6569) by [mpl](https://github.com/mpl)) +- **[file]** Revert "Allow fsnotify to reload config files on k8s (or symlinks)" ([#6416](https://github.com/containous/traefik/pull/6416) by [juliens](https://github.com/juliens)) +- **[internal]** Fix entry point redirect behavior ([#6512](https://github.com/containous/traefik/pull/6512) by [ldez](https://github.com/ldez)) +- **[internal]** Router entry points on reload. ([#6444](https://github.com/containous/traefik/pull/6444) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/crd]** Improve kubernetes external name service support ([#6428](https://github.com/containous/traefik/pull/6428) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/ingress]** fix: Ingress TLS support ([#6504](https://github.com/containous/traefik/pull/6504) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/ingress]** Improvement of the unique name of the router for Ingress. ([#6325](https://github.com/containous/traefik/pull/6325) by [ldez](https://github.com/ldez)) +- **[kv,redis]** Update valkeyrie to fix the support of Redis. ([#6291](https://github.com/containous/traefik/pull/6291) by [ldez](https://github.com/ldez)) +- **[kv]** fix: KV flaky tests. ([#6300](https://github.com/containous/traefik/pull/6300) by [ldez](https://github.com/ldez)) +- **[etcd,kv]** fix: etcd provider name. ([#6212](https://github.com/containous/traefik/pull/6212) by [ldez](https://github.com/ldez)) +- **[middleware]** fix: period field name. ([#6549](https://github.com/containous/traefik/pull/6549) by [ldez](https://github.com/ldez)) +- **[middleware]** fix: custom Host header. ([#6502](https://github.com/containous/traefik/pull/6502) by [ldez](https://github.com/ldez)) +- **[server,udp]** udp: replace concurrently reset timer with ticker ([#6498](https://github.com/containous/traefik/pull/6498) by [mpl](https://github.com/mpl)) +- **[server]** Drop traefik from default entry points. ([#6477](https://github.com/containous/traefik/pull/6477) by [ldez](https://github.com/ldez)) +- **[server]** fix: use MaxInt32. ([#5845](https://github.com/containous/traefik/pull/5845) by [ldez](https://github.com/ldez)) +- **[tracing]** Disable default APM tracer. ([#6410](https://github.com/containous/traefik/pull/6410) by [ldez](https://github.com/ldez)) +- **[udp]** Add missing generated element for UDP. ([#6309](https://github.com/containous/traefik/pull/6309) by [ldez](https://github.com/ldez)) +- **[udp]** Build all UDP services on an entrypoint ([#6329](https://github.com/containous/traefik/pull/6329) by [juliens](https://github.com/juliens)) + +**Documentation:** +- **[authentication,middleware]** docs: terminology, replace 'encoded' by 'hashed' ([#6478](https://github.com/containous/traefik/pull/6478) by [debovema](https://github.com/debovema)) +- **[acme]** Doc: fix wrong name of config format ([#6519](https://github.com/containous/traefik/pull/6519) by [Nek-](https://github.com/Nek-)) +- **[docker]** Fix example values for swarmModeRefreshSeconds ([#6460](https://github.com/containous/traefik/pull/6460) by [skjnldsv](https://github.com/skjnldsv)) +- **[k8s,k8s/crd,sticky-session]** docs: clarify multi-levels stickiness ([#6475](https://github.com/containous/traefik/pull/6475) by [mpl](https://github.com/mpl)) +- **[k8s,k8s/crd]** doc: fix terminationDelay word case. ([#6532](https://github.com/containous/traefik/pull/6532) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/crd]** Update the k8s CRD documentation ([#6426](https://github.com/containous/traefik/pull/6426) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[k8s,k8s/ingress]** Improve documentation for kubernetes ingress configuration ([#6440](https://github.com/containous/traefik/pull/6440) by [rtribotte](https://github.com/rtribotte)) +- **[k8s/helm]** Update traefik install documentation ([#6466](https://github.com/containous/traefik/pull/6466) by [mmatur](https://github.com/mmatur)) +- **[provider]** Update supported providers list. ([#6190](https://github.com/containous/traefik/pull/6190) by [ldez](https://github.com/ldez)) +- **[tcp,tls]** Specify passthrough for TCP/TLS in its own section ([#6459](https://github.com/containous/traefik/pull/6459) by [mpl](https://github.com/mpl)) +- doc: Use neutral domains. ([#6471](https://github.com/containous/traefik/pull/6471) by [ldez](https://github.com/ldez)) +- doc: fix typo. ([#6472](https://github.com/containous/traefik/pull/6472) by [ldez](https://github.com/ldez)) +- Improve ping documentation. ([#6476](https://github.com/containous/traefik/pull/6476) by [ldez](https://github.com/ldez)) +- Remove @dduportal from the maintainers team ([#6464](https://github.com/containous/traefik/pull/6464) by [emilevauge](https://github.com/emilevauge)) +- Fix wrong copy/pasted with service name warning ([#6510](https://github.com/containous/traefik/pull/6510) by [Nek-](https://github.com/Nek-)) +- Update migration documentation ([#6447](https://github.com/containous/traefik/pull/6447) by [ldez](https://github.com/ldez)) +- Update version references. ([#6434](https://github.com/containous/traefik/pull/6434) by [ldez](https://github.com/ldez)) +- Fix broken documentation link ([#6430](https://github.com/containous/traefik/pull/6430) by [pbek](https://github.com/pbek)) + +**Misc:** +- **[rancher]** Stop using fork of go-rancher-metadata ([#6469](https://github.com/containous/traefik/pull/6469) by [ibuildthecloud](https://github.com/ibuildthecloud)) +- Merge current v2.1 branch into v2.2 ([#6564](https://github.com/containous/traefik/pull/6564) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into v2.2 ([#6525](https://github.com/containous/traefik/pull/6525) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into v2.2 ([#6516](https://github.com/containous/traefik/pull/6516) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#6429](https://github.com/containous/traefik/pull/6429) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#6409](https://github.com/containous/traefik/pull/6409) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#6302](https://github.com/containous/traefik/pull/6302) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#6216](https://github.com/containous/traefik/pull/6216) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#6138](https://github.com/containous/traefik/pull/6138) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#6004](https://github.com/containous/traefik/pull/6004) by [ldez](https://github.com/ldez)) +- Merge current v2.1 branch into master ([#5933](https://github.com/containous/traefik/pull/5933) by [ldez](https://github.com/ldez)) + +## [v2.1.9](https://github.com/containous/traefik/tree/v2.1.9) (2020-03-23) +[All Commits](https://github.com/containous/traefik/compare/v2.1.8...v2.1.9) + +**Bug fixes:** +- **[provider,sticky-session]** Fix sameSite ([#6538](https://github.com/containous/traefik/pull/6538) by [ldez](https://github.com/ldez)) +- **[server]** Force http/1.1 for upgrade ([#6554](https://github.com/containous/traefik/pull/6554) by [juliens](https://github.com/juliens)) + +**Documentation:** +- Fix tab name ([#6543](https://github.com/containous/traefik/pull/6543) by [mavimo](https://github.com/mavimo)) + ## [v2.2.0-rc4](https://github.com/containous/traefik/tree/v2.2.0-rc4) (2020-03-19) [All Commits](https://github.com/containous/traefik/compare/v2.2.0-rc3...v2.2.0-rc4) diff --git a/build.Dockerfile b/build.Dockerfile index f060e91f3..eb88c53d5 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \ && chmod +x /usr/local/bin/go-bindata # Download golangci-lint binary to bin folder in $GOPATH -RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.6 +RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.8 # Download misspell binary to bin folder in $GOPATH RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4 diff --git a/docs/content/getting-started/install-traefik.md b/docs/content/getting-started/install-traefik.md index 27ad69246..fa24837ac 100644 --- a/docs/content/getting-started/install-traefik.md +++ b/docs/content/getting-started/install-traefik.md @@ -78,20 +78,53 @@ helm install traefik traefik/traefik The values are not (yet) documented, but are self-explanatory: you can look at the [default `values.yaml`](https://github.com/containous/traefik-helm-chart/blob/master/traefik/values.yaml) file to explore possibilities. + You can also set Traefik command line flags using `additionalArguments`. Example of installation with logging set to `DEBUG`: ```bash tab="Using Helm CLI" helm install --namespace=traefik-v2 \ - --set="logs.loglevel=DEBUG" \ + --set="additionalArguments={--logs.level=DEBUG}" \ traefik traefik/traefik ``` ```yml tab="With a custom values file" # File custom-values.yml ## Install with "helm install --values=./custom-values.yml traefik traefik/traefik - logs: - loglevel: DEBUG + additionalArguments: + - "--log.level=DEBUG" ``` + +### Exposing the Traefik dashboard + +This HelmChart does not expose the Traefik dashboard by default, for security concerns. +Thus, there are multiple ways to expose the dashboard. +For instance, the dashboard access could be achieved through a port-forward : + +```shell +kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000 +``` + +Accessible with the url: http://127.0.0.1:9000/dashboard/ + +Another way would be to apply your own configuration, for instance, +by defining and applying an IngressRoute CRD (`kubectl apply -f dashboard.yaml`): + +```yaml +# dashboard.yaml +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: dashboard +spec: + entryPoints: + - web + routes: + - match: Host(`traefik.localhost`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`)) + kind: Rule + services: + - name: api@internal + kind: TraefikService +``` ## Use the Binary Distribution diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index 773a0739a..95d0b8306 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -288,6 +288,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used | [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | | [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | | [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) | +| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) | | [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | | [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | | [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | diff --git a/docs/content/middlewares/compress.md b/docs/content/middlewares/compress.md index 35282da6c..cf62f119b 100644 --- a/docs/content/middlewares/compress.md +++ b/docs/content/middlewares/compress.md @@ -64,6 +64,9 @@ http: * The `Accept-Encoding` request header contains `gzip`. * The response is not already compressed, i.e. the `Content-Encoding` response header is not already set. + If Content-Type header is not defined, or empty, the compress middleware will automatically [detect](https://mimesniff.spec.whatwg.org/) a content type. + It will also set accordingly the `Content-Type` header with the detected MIME type. + ## Configuration Options ### `excludedContentTypes` diff --git a/docs/content/middlewares/contenttype.md b/docs/content/middlewares/contenttype.md index b92c272be..85ed8782f 100644 --- a/docs/content/middlewares/contenttype.md +++ b/docs/content/middlewares/contenttype.md @@ -21,6 +21,9 @@ This middleware exists to enable the correct behavior until at least the default is still to automatically set the `Content-Type` header. Therefore, given the default value of the `autoDetect` option (false), simply enabling this middleware for a router switches the router's behavior. + + The scope of the Content-Type middleware is the MIME type detection done by the core of Traefik (the server part). + Therefore, it has no effect against any other `Content-Type` header modifications (e.g.: in another middleware such as compress). ## Configuration Examples diff --git a/docs/content/middlewares/headers.md b/docs/content/middlewares/headers.md index 18bed41c2..cd9072a0c 100644 --- a/docs/content/middlewares/headers.md +++ b/docs/content/middlewares/headers.md @@ -322,7 +322,7 @@ The `accessControlExposeHeaders` indicates which headers are safe to expose to t ### `accessControlMaxAge` -The `accessControlMaxAge` indicates how long a preflight request can be cached. +The `accessControlMaxAge` indicates how long (in seconds) a preflight request can be cached. ### `addVaryHeader` diff --git a/docs/content/migration/v1-to-v2.md b/docs/content/migration/v1-to-v2.md index 6fbfeeb24..2a7006add 100644 --- a/docs/content/migration/v1-to-v2.md +++ b/docs/content/migration/v1-to-v2.md @@ -50,7 +50,7 @@ Then any router can refer to an instance of the wanted middleware. traefik.ingress.kubernetes.io/rule-type: PathPrefix spec: rules: - - host: test.locahost + - host: test.localhost http: paths: - path: /test @@ -370,13 +370,13 @@ To apply a redirection: ## static configuration [entryPoints.web] - address = 80 + address = ":80" [entryPoints.web.http.redirections.entryPoint] to = "websecure" scheme = "https" [entryPoints.websecure] - address = 443 + address = ":443" ``` ```yaml tab="File (YAML)" @@ -609,6 +609,7 @@ with the path `/admin` stripped, e.g. to `http://:/`. In this case, yo middlewares: - name: admin-stripprefix --- + apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: admin-stripprefix @@ -799,6 +800,13 @@ There is no more log configuration at the root level. --log.format=json ``` +## Access Logs + +Access Logs are configured in the same way as before. + +But all request headers are now filtered out by default in Traefik v2. +So during migration, you might want to consider enabling some needed fields (see [access log configuration](../observability/access-logs.md)). + ## Tracing Traefik v2 retains OpenTracing support. The `backend` root option from the v1 is gone, you just have to set your [tracing configuration](../observability/tracing/overview.md). diff --git a/docs/content/observability/tracing/overview.md b/docs/content/observability/tracing/overview.md index 8098cd0ea..1471209e9 100644 --- a/docs/content/observability/tracing/overview.md +++ b/docs/content/observability/tracing/overview.md @@ -7,13 +7,14 @@ The tracing system allows developers to visualize call flows in their infrastruc Traefik uses OpenTracing, an open standard designed for distributed tracing. -Traefik supports five tracing backends: +Traefik supports six tracing backends: - [Jaeger](./jaeger.md) - [Zipkin](./zipkin.md) - [Datadog](./datadog.md) - [Instana](./instana.md) - [Haystack](./haystack.md) +- [Elastic](./elastic.md) ## Configuration diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index 9f1c7e3ab..dc6a0b0c6 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -47,22 +47,22 @@ You can write one of these mutually exclusive configuration elements: middlewares = ["my-basic-auth"] service = "service-foo" rule = "Path(`/foo`)" - - # Add the middleware - [http.middlewares] - [http.middlewares.my-basic-auth.basicAuth] - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] - usersFile = "etc/traefik/.htpasswd" - - # Add the service - [http.services] - [http.services.service-foo] - [http.services.service-foo.loadBalancer] - [[http.services.service-foo.loadBalancer.servers]] - url = "http://foo/" - [[http.services.service-foo.loadBalancer.servers]] - url = "http://bar/" + + # Add the middleware + [http.middlewares] + [http.middlewares.my-basic-auth.basicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] + usersFile = "etc/traefik/.htpasswd" + + # Add the service + [http.services] + [http.services.service-foo] + [http.services.service-foo.loadBalancer] + [[http.services.service-foo.loadBalancer.servers]] + url = "http://foo/" + [[http.services.service-foo.loadBalancer.servers]] + url = "http://bar/" ``` ```yaml tab="YAML" diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index cbdbae76c..32538a861 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -173,7 +173,7 @@ Array of namespaces to watch. ### `labelselector` -_Optional,Default: empty (process all Ingresses)_ +_Optional,Default: empty (process all resources)_ ```toml tab="File (TOML)" [providers.kubernetesCRD] @@ -192,8 +192,8 @@ providers: --providers.kubernetescrd.labelselector="A and not B" ``` -By default, Traefik processes all Ingress objects in the configured namespaces. -A label selector can be defined to filter on specific Ingress objects only. +By default, Traefik processes all resource objects in the configured namespaces. +A label selector can be defined to filter on specific resource objects only. See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details. @@ -218,10 +218,10 @@ providers: --providers.kubernetescrd.ingressclass=traefik-internal ``` -Value of `kubernetes.io/ingress.class` annotation that identifies Ingress objects to be processed. +Value of `kubernetes.io/ingress.class` annotation that identifies resource objects to be processed. -If the parameter is non-empty, only Ingresses containing an annotation with the same value are processed. -Otherwise, Ingresses missing the annotation, having an empty value, or the value `traefik` are processed. +If the parameter is non-empty, only resources containing an annotation with the same value are processed. +Otherwise, resources missing the annotation, having an empty value, or the value `traefik` are processed. ### `throttleDuration` diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index f5986f431..6a02d09e5 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -147,10 +147,11 @@ - "traefik.http.services.service01.loadbalancer.healthcheck.followredirects=true" - "traefik.http.services.service01.loadbalancer.passhostheader=true" - "traefik.http.services.service01.loadbalancer.responseforwarding.flushinterval=foobar" -- "traefik.http.services.service01.loadbalancer.sticky=true" +- "traefik.http.services.service01.loadbalancer.sticky.cookie=true" - "traefik.http.services.service01.loadbalancer.sticky.cookie.httponly=true" - "traefik.http.services.service01.loadbalancer.sticky.cookie.name=foobar" - "traefik.http.services.service01.loadbalancer.sticky.cookie.secure=true" +- "traefik.http.services.service01.loadbalancer.sticky.cookie.samesite=foobar" - "traefik.http.services.service01.loadbalancer.server.port=foobar" - "traefik.http.services.service01.loadbalancer.server.scheme=foobar" - "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index fd35f2b1e..8691af9cb 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -43,6 +43,7 @@ name = "foobar" secure = true httpOnly = true + sameSite = "foobar" [[http.services.Service01.loadBalancer.servers]] url = "foobar" @@ -89,6 +90,7 @@ name = "foobar" secure = true httpOnly = true + sameSite = "foobar" [http.middlewares] [http.middlewares.Middleware00] [http.middlewares.Middleware00.addPrefix] diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index 432201fd7..2537abee7 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -52,6 +52,7 @@ http: name: foobar secure: true httpOnly: true + sameSite: foobar servers: - url: foobar - url: foobar @@ -90,6 +91,7 @@ http: name: foobar secure: true httpOnly: true + sameSite: foobar middlewares: Middleware00: addPrefix: diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml index 0a9a98bd7..ae7752036 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml @@ -91,21 +91,11 @@ spec: services: - name: s1 port: 80 - healthCheck: - path: /health - host: baz.com - intervalSeconds: 7 - timeoutSeconds: 60 # strategy defines the load balancing strategy between the servers. It defaults # to Round Robin, and for now only Round Robin is supported anyway. strategy: RoundRobin - name: s2 port: 433 - healthCheck: - path: /health - host: baz.com - intervalSeconds: 7 - timeoutSeconds: 60 - match: PathPrefix(`/misc`) services: - name: s3 @@ -133,7 +123,7 @@ spec: tls: secretName: supersecret options: - name: myTLSOption + name: my-tls-option namespace: default --- @@ -155,7 +145,7 @@ spec: secretName: foosecret passthrough: false options: - name: myTLSOption + name: my-tls-option namespace: default --- diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index cbfa364c8..ccb16a95b 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -173,6 +173,7 @@ | `traefik/http/services/Service01/loadBalancer/servers/1/url` | `foobar` | | `traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly` | `true` | | `traefik/http/services/Service01/loadBalancer/sticky/cookie/name` | `foobar` | +| `traefik/http/services/Service01/loadBalancer/sticky/cookie/sameSite` | `foobar` | | `traefik/http/services/Service01/loadBalancer/sticky/cookie/secure` | `true` | | `traefik/http/services/Service02/mirroring/maxBodySize` | `42` | | `traefik/http/services/Service02/mirroring/mirrors/0/name` | `foobar` | @@ -186,6 +187,7 @@ | `traefik/http/services/Service03/weighted/services/1/weight` | `42` | | `traefik/http/services/Service03/weighted/sticky/cookie/httpOnly` | `true` | | `traefik/http/services/Service03/weighted/sticky/cookie/name` | `foobar` | +| `traefik/http/services/Service03/weighted/sticky/cookie/sameSite` | `foobar` | | `traefik/http/services/Service03/weighted/sticky/cookie/secure` | `true` | | `traefik/tcp/routers/TCPRouter0/entryPoints/0` | `foobar` | | `traefik/tcp/routers/TCPRouter0/entryPoints/1` | `foobar` | diff --git a/docs/content/reference/dynamic-configuration/marathon-labels.json b/docs/content/reference/dynamic-configuration/marathon-labels.json index 0a125f331..f869a0099 100644 --- a/docs/content/reference/dynamic-configuration/marathon-labels.json +++ b/docs/content/reference/dynamic-configuration/marathon-labels.json @@ -145,9 +145,11 @@ "traefik.http.services.service01.loadbalancer.healthcheck.followredirects": "true", "traefik.http.services.service01.loadbalancer.passhostheader": "true", "traefik.http.services.service01.loadbalancer.responseforwarding.flushinterval": "foobar", +"traefik.http.services.service01.loadbalancer.sticky.cookie": "true", "traefik.http.services.service01.loadbalancer.sticky.cookie.httponly": "true", "traefik.http.services.service01.loadbalancer.sticky.cookie.name": "foobar", "traefik.http.services.service01.loadbalancer.sticky.cookie.secure": "true", +"traefik.http.services.service01.loadbalancer.sticky.cookie.samesite": "foobar", "traefik.http.services.service01.loadbalancer.server.port": "foobar", "traefik.http.services.service01.loadbalancer.server.scheme": "foobar", "traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar", diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 4d63cc971..aed610b9a 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -106,13 +106,13 @@ HTTP configuration. Default middlewares for the routers linked to the entry point. `--entrypoints..http.redirections.entrypoint.permanent`: -Applied a permanent redirection. Defaults to true. (Default: ```true```) +Applies a permanent redirection. (Default: ```true```) `--entrypoints..http.redirections.entrypoint.priority`: -Priority of the generated router. Defaults to 1. (Default: ```1```) +Priority of the generated router. (Default: ```2147483647```) `--entrypoints..http.redirections.entrypoint.scheme`: -Scheme used for the redirection. Defaults to https. (Default: ```https```) +Scheme used for the redirection. (Default: ```https```) `--entrypoints..http.redirections.entrypoint.to`: Targeted entry point of the redirection. diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 6800f51f9..2228bec10 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -106,13 +106,13 @@ HTTP configuration. Default middlewares for the routers linked to the entry point. `TRAEFIK_ENTRYPOINTS__HTTP_REDIRECTIONS_ENTRYPOINT_PERMANENT`: -Applied a permanent redirection. Defaults to true. (Default: ```true```) +Applies a permanent redirection. (Default: ```true```) `TRAEFIK_ENTRYPOINTS__HTTP_REDIRECTIONS_ENTRYPOINT_PRIORITY`: -Priority of the generated router. Defaults to 1. (Default: ```1```) +Priority of the generated router. (Default: ```2147483647```) `TRAEFIK_ENTRYPOINTS__HTTP_REDIRECTIONS_ENTRYPOINT_SCHEME`: -Scheme used for the redirection. Defaults to https. (Default: ```https```) +Scheme used for the redirection. (Default: ```https```) `TRAEFIK_ENTRYPOINTS__HTTP_REDIRECTIONS_ENTRYPOINT_TO`: Targeted entry point of the redirection. diff --git a/docs/content/routing/entrypoints.md b/docs/content/routing/entrypoints.md index 86078163d..52290000e 100644 --- a/docs/content/routing/entrypoints.md +++ b/docs/content/routing/entrypoints.md @@ -91,7 +91,7 @@ and whether to listen for TCP or UDP. ### General EntryPoints are part of the [static configuration](../getting-started/configuration-overview.md#the-static-configuration). -You can define them using a toml file, CLI arguments, or a key-value store. +They can be defined by using a file (TOML or YAML) or CLI arguments. ??? info "See the complete reference for the list of available options" @@ -569,7 +569,7 @@ This whole section is dedicated to options, keyed by entry point, that will appl ```bash tab="CLI" --entrypoints.web.address=:80 --entrypoints.web.http.redirections.entryPoint.to=websecure - --entrypoints.web.http.redirections.entryPoint.https=true + --entrypoints.web.http.redirections.entryPoint.scheme=https --entrypoints.websecure.address=:443 ``` diff --git a/docs/content/routing/providers/consul-catalog.md b/docs/content/routing/providers/consul-catalog.md index 1c23218fd..425bb369e 100644 --- a/docs/content/routing/providers/consul-catalog.md +++ b/docs/content/routing/providers/consul-catalog.md @@ -233,6 +233,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 0d1016e31..46fa35f66 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -334,12 +334,12 @@ you'd add the label `traefik.http.services..loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true" ``` -??? info "`traefik.http.services..loadbalancer.sticky`" +??? info "`traefik.http.services..loadbalancer.sticky.cookie`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky=true" + - "traefik.http.services.myservice.loadbalancer.sticky.cookie=true" ``` ??? info "`traefik.http.services..loadbalancer.sticky.cookie.httponly`" @@ -366,6 +366,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index f3d5ad360..f07d50573 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -340,6 +340,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne httpOnly: true name: cookie secure: true + sameSite: none strategy: RoundRobin weight: 10 tls: # [9] @@ -617,10 +618,12 @@ Register the `Middleware` [kind](../../reference/dynamic-configuration/kubernete !!! 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](../../middlewares/overview.md#provider-namespace), - when the definition of the 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. + 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](../../middlewares/overview.md#provider-namespace), + when the definition of the 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 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). @@ -1086,7 +1089,7 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube - name: foo # [5] port: 8080 # [6] weight: 10 # [7] - TerminationDelay: 400 # [8] + terminationDelay: 400 # [8] tls: # [9] secretName: supersecret # [10] options: # [11] @@ -1110,7 +1113,7 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube | [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/) | | [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). | +| [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] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration | | [10] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | | [11] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | @@ -1139,11 +1142,11 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube services: - name: foo port: 8080 - TerminationDelay: 400 + terminationDelay: 400 weight: 10 - name: bar port: 8081 - TerminationDelay: 500 + terminationDelay: 500 weight: 10 tls: certResolver: foo diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index c222ff319..95622b002 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -290,14 +290,6 @@ which in turn will create the resulting routers, services, handlers, etc. traefik.ingress.kubernetes.io/service.sticky: "true" ``` -??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.httponly`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true" - ``` - ??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.name`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. @@ -314,6 +306,22 @@ which in turn will create the resulting routers, services, handlers, etc. traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true" ``` +??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none" + ``` + +??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.httponly`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true" + ``` + ### TLS #### Communication Between Traefik and Pods diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index d0698f775..c3bd4cdac 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -106,17 +106,9 @@ A Story of key & values See [servers](../services/index.md#servers) for more information. - | Key (Path) | Value | - |-----------------------------------------------------------------|--------| - | `traefik/http/services/myservice/loadbalancer/servers/0/scheme` | `http` | - -??? info "`traefik/http/services//loadbalancer/servers//scheme`" - - Overrides the default scheme. - - | Key (Path) | Value | - |-----------------------------------------------------------------|--------| - | `traefik/http/services/myservice/loadbalancer/servers/0/scheme` | `http` | + | Key (Path) | Value | + |-----------------------------------------------------------------|-----------------------------------------| + | `traefik/http/services/myservice/loadbalancer/servers/0/url` | `http://:/` | ??? info "`traefik/http/services//loadbalancer/passhostheader`" @@ -214,6 +206,14 @@ A Story of key & values |---------------------------------------------------------------------|--------| | `traefik/http/services/myservice/loadbalancer/sticky/cookie/secure` | `true` | +??? info "`traefik/http/services//loadbalancer/sticky/cookie/samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + | Key (Path) | Value | + |-----------------------------------------------------------------------|--------| + | `traefik/http/services/myservice/loadbalancer/sticky/cookie/samesite` | `none` | + ??? info "`traefik/http/services//loadbalancer/responseforwarding/flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. @@ -264,6 +264,12 @@ A Story of key & values |----------------------------------------------------------------------|--------| | `traefik/http/services//weighted/sticky/cookie/secure` | `true` | +??? info "`traefik/http/services//weighted/sticky/cookie/samesite`" + + | Key (Path) | Value | + |------------------------------------------------------------------------|--------| + | `traefik/http/services//weighted/sticky/cookie/samesite` | `none` | + ??? info "`traefik/http/services//weighted/sticky/cookie/httpOnly`" | Key (Path) | Value | @@ -367,9 +373,9 @@ You can declare TCP Routers and/or Services using KV. See [servers](../services/index.md#servers) for more information. - | Key (Path) | Value | - |-------------------------------------------------------------------|--------| - | `traefik/tcp/services/mytcpservice/loadbalancer/servers/0/scheme` | `http` | + | Key (Path) | Value | + |--------------------------------------------------------------------|------------------| + | `traefik/tcp/services/mytcpservice/loadbalancer/servers/0/address` | `xx.xx.xx.xx:xx` | ??? info "`traefik/tcp/services//loadbalancer/terminationdelay`" diff --git a/docs/content/routing/providers/marathon.md b/docs/content/routing/providers/marathon.md index 79cc63461..ccb0a068e 100644 --- a/docs/content/routing/providers/marathon.md +++ b/docs/content/routing/providers/marathon.md @@ -232,12 +232,12 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects": "true" ``` -??? info "`traefik.http.services..loadbalancer.sticky`" +??? info "`traefik.http.services..loadbalancer.sticky.cookie`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. ```json - "traefik.http.services.myservice.loadbalancer.sticky": "true" + "traefik.http.services.myservice.loadbalancer.sticky.cookie": "true" ``` ??? info "`traefik.http.services..loadbalancer.sticky.cookie.httponly`" @@ -264,6 +264,14 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure": "true" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```json + "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite": "none" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/providers/rancher.md b/docs/content/routing/providers/rancher.md index a23a5fe2a..377856115 100644 --- a/docs/content/routing/providers/rancher.md +++ b/docs/content/routing/providers/rancher.md @@ -238,12 +238,12 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true" ``` -??? info "`traefik.http.services..loadbalancer.sticky`" +??? info "`traefik.http.services..loadbalancer.sticky.cookie`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky=true" + - "traefik.http.services.myservice.loadbalancer.sticky.cookie=true" ``` ??? info "`traefik.http.services..loadbalancer.sticky.cookie.httponly`" @@ -270,6 +270,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index 077c2df25..bba559dc9 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -235,8 +235,8 @@ The table below lists all the available matchers: | ```Host(`example.com`, ...)``` | Check if the request domain targets one of the given `domains`. | | ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Check if the request domain matches the given `regexp`. | | ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) | -| ```Path(`/path`, `/articles/{category}/{id:[0-9]+}`, ...)``` | Match exact request path. It accepts a sequence of literal and regular expression paths. | -| ```PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)``` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. | +| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. It accepts a sequence of literal and regular expression paths. | +| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. | | ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. | !!! important "Regexp Syntax" diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index 8211b0cd0..7a85a0039 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -182,9 +182,12 @@ On subsequent requests, to keep the session alive with the same server, the clie The default cookie name is an abbreviation of a sha1 (ex: `_1d52e`). -!!! info "Secure & HTTPOnly flags" +!!! info "Secure & HTTPOnly & SameSite flags" - By default, the affinity cookie is created without those flags. One however can change that through configuration. + By default, the affinity cookie is created without those flags. + One however can change that through configuration. + + `SameSite` can be `none`, `lax`, `strict` or empty. ??? example "Adding Stickiness -- Using the [File Provider](../../providers/file.md)" @@ -215,6 +218,7 @@ On subsequent requests, to keep the session alive with the same server, the clie name = "my_sticky_cookie_name" secure = true httpOnly = true + sameSite = "none" ``` ```yaml tab="YAML" @@ -330,6 +334,12 @@ Below are the available options for the health check mechanism: Traefik keeps monitoring the health of unhealthy servers. If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balacer rotation pool. +!!! warning "Health check in Kubernetes" + + The Traefik health check is not available for `kubernetesCRD` and `kubernetesIngress` providers because Kubernetes + already has a health check mechanism. + Unhealthy pods will be removed by kubernetes. (cf [liveness documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request)) + ??? example "Custom Interval & Timeout -- Using the [File Provider](../../providers/file.md)" ```toml tab="TOML" diff --git a/docs/content/user-guides/docker-compose/acme-dns/index.md b/docs/content/user-guides/docker-compose/acme-dns/index.md index aa6124f0d..2383234c2 100644 --- a/docs/content/user-guides/docker-compose/acme-dns/index.md +++ b/docs/content/user-guides/docker-compose/acme-dns/index.md @@ -131,7 +131,7 @@ The point is to manage those secret files by another mean, and read them from th !!! Note You could store those secrets anywhere on the server, - just make sure to use the proper path for the `file` directive fo the secrets definition in the `docker-compose.yml` file. + just make sure to use the proper path for the `file` directive for the secrets definition in the `docker-compose.yml` file. - Use this `docker-compose.yml` file: diff --git a/go.mod b/go.mod index 1d38a1cd1..b2e0472c8 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/fatih/structs v1.1.0 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 - github.com/go-acme/lego/v3 v3.5.0 + github.com/go-acme/lego/v3 v3.6.0 github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.9.0 github.com/gogo/protobuf v1.3.0 // indirect @@ -44,7 +44,7 @@ require ( github.com/google/go-github/v28 v28.1.1 github.com/googleapis/gnostic v0.1.0 // indirect github.com/gorilla/mux v1.7.3 - github.com/gorilla/websocket v1.4.1 + github.com/gorilla/websocket v1.4.2 github.com/hashicorp/consul/api v1.3.0 github.com/hashicorp/go-version v1.2.0 github.com/huandu/xstrings v1.2.0 // indirect @@ -75,13 +75,12 @@ require ( github.com/stretchr/testify v1.5.1 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/tinylib/msgp v1.0.2 // indirect - github.com/transip/gotransip v5.8.2+incompatible // indirect github.com/uber/jaeger-client-go v2.22.1+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible github.com/unrolled/render v1.0.2 github.com/unrolled/secure v1.0.7 github.com/vdemeester/shakers v0.1.0 - github.com/vulcand/oxy v1.0.0 + github.com/vulcand/oxy v1.1.0 github.com/vulcand/predicate v1.1.0 go.elastic.co/apm v1.7.0 go.elastic.co/apm/module/apmot v1.7.0 @@ -104,7 +103,7 @@ replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.2020020422 // Containous forks replace ( - github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20180112153951-65b0cdae8d7f + github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a github.com/gorilla/mux => github.com/containous/mux v0.0.0-20181024131434-c33f32e26898 github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 diff --git a/go.sum b/go.sum index 8a8d6a3f0..88e768cda 100644 --- a/go.sum +++ b/go.sum @@ -105,9 +105,8 @@ github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.8 h1:6rJvj+NXjjauunLeS7uGy891F github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.8/go.mod h1:aVvklgKsPENRkl29bNwrHISa1F+YLGTHArMxZMBqWM8= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee h1:NYqDBPkhVYt68W3yoGoRRi32i3MLx2ey7SFkJ1v/UI0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.112 h1:E273ePcLllLIBGg5BHr3T0Fp1BJTvUyh5Y57ziSy81w= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.112/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -120,7 +119,6 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/aws/aws-sdk-go v1.16.23/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.0 h1:ilfJN/vJtFo1XDFxB2YMBYGeOvGZl6Qow17oyD4+Z9A= github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -162,8 +160,8 @@ github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd h1:0n+lFLh5zU0l6K github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd/go.mod h1:BbQgeDS5i0tNvypwEoF1oNjOJw8knRAE1DnVvjDstcQ= github.com/containous/check v0.0.0-20170915194414-ca0bf163426a h1:8esAQaPKjfntQR1bag/mAOvWJd5HqSX5nsa+0KT63zo= github.com/containous/check v0.0.0-20170915194414-ca0bf163426a/go.mod h1:eQOqZ7GoFsLxI7jFKLs7+Nv2Rm1x4FyK8d2NV+yGjwQ= -github.com/containous/go-http-auth v0.4.1-0.20180112153951-65b0cdae8d7f h1:AgXgJSqQmsiNFW268OGe/y7Mn4jiCWaMUk05qser3Bo= -github.com/containous/go-http-auth v0.4.1-0.20180112153951-65b0cdae8d7f/go.mod h1:dCmRGidPSLagL8D/2u7yIO6Y/8D/yuYX9EdKrnrhpCA= +github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e h1:D+uTEzDZc1Fhmd0Pq06c+O9+KkAyExw0eVmu/NOqaHU= +github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e/go.mod h1:s8kLgBQolDbsJOPVIGCEEv9zGAKUUf/685Gi0Qqg8z8= github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 h1:aPspFRO6b94To3gl4yTDOEtpjFwXI7V2W+z0JcNljQ4= github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595/go.mod h1:+lHFbEasIiQVGzhVDVw/cn0ZaOzde2OwNncp1NhXV4c= github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba h1:PhR03pep+5eO/9BSvCY9RyG8rjogB3uYS4X/WBYNTT8= @@ -183,8 +181,8 @@ github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pq github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpu/goacmedns v0.0.1 h1:GeIU5chKys9zmHgOAgP+bstRaLqcGQ6HJh/hLw9hrus= -github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok= +github.com/cpu/goacmedns v0.0.2 h1:hYAgjnPu7HogTgb8trqQouR/RrBgXq1TPBgmxbK9eRA= +github.com/cpu/goacmedns v0.0.2/go.mod h1:4MipLkI+qScwqtVxcNO6okBhbgRrr7/tKXUSgSL0teQ= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -261,8 +259,8 @@ github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLy github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-acme/lego/v3 v3.5.0 h1:/0+NJQK+hNwRznhCi+19lbEa4xufhe7wJZOVd5j486s= -github.com/go-acme/lego/v3 v3.5.0/go.mod h1:TXodhTGOiWEqXDdgrzBoCtJ5R4L9lfOE68CTM0KGkT0= +github.com/go-acme/lego/v3 v3.6.0 h1:Rv0MrX3DpVp9Xg77yR7x+PCksLLph3Ut/69/9Kim8ac= +github.com/go-acme/lego/v3 v3.6.0/go.mod h1:sB/T7hfyz0HYIBvPmz/C8jIaxF6scbbiGKTzbQ22V6A= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -377,8 +375,8 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f h1:68WxnfBzJRYktZ30fmIjGQ74RsXYLoeH2/NITPktTMY= github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -670,7 +668,6 @@ github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec h1:6ncX5ko6B9L github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -714,9 +711,8 @@ github.com/tinylib/msgp v1.0.2 h1:DfdQrzQa7Yh2es9SuLkixqxuXS2SxsdYn0KbdrOGWD8= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY= -github.com/transip/gotransip v5.8.2+incompatible h1:aNJhw/w/3QBqFcHAIPz1ytoK5FexeMzbUCGrrhWr3H0= -github.com/transip/gotransip v5.8.2+incompatible/go.mod h1:uacMoJVmrfOcscM4Bi5NVg708b7c6rz2oDTWqa7i2Ic= +github.com/transip/gotransip/v6 v6.0.2 h1:rOCMY607PYF+YvMHHtJt7eZRd0mx/uhyz6dsXWPmn+4= +github.com/transip/gotransip/v6 v6.0.2/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= @@ -732,8 +728,8 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/shakers v0.1.0 h1:K+n9sSyUCg2ywmZkv+3c7vsYZfivcfKhMh8kRxCrONM= github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ= -github.com/vulcand/oxy v1.0.0 h1:7vL5/pjDFzHGbtBEhmlHITUi6KLH4xXTDF33/wrdRKw= -github.com/vulcand/oxy v1.0.0/go.mod h1:6EXgOAl6CRa46/2ZGcDJKf3ywJUp5WtT7vSlGSkvecI= +github.com/vulcand/oxy v1.1.0 h1:DbBijGo1+6cFqR9jarkMxasdj0lgWwrrFtue6ijek4Q= +github.com/vulcand/oxy v1.1.0/go.mod h1:ADiMYHi8gkGl2987yQIzDRoXZilANF4WtKaQ92OppKY= github.com/vulcand/predicate v1.1.0 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg= github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg= github.com/vultr/govultr v0.1.4 h1:UnNMixYFVO0p80itc8PcweoVENyo1PasfvwKhoasR9U= @@ -796,6 +792,8 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww= +golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1119,6 +1117,7 @@ k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKf k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index dc999fa1d..d422797d5 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -103,7 +103,7 @@ func (w *WRRService) SetDefaults() { // Sticky holds the sticky configuration. type Sticky struct { - Cookie *Cookie `json:"cookie,omitempty" toml:"cookie,omitempty" yaml:"cookie,omitempty"` + Cookie *Cookie `json:"cookie,omitempty" toml:"cookie,omitempty" yaml:"cookie,omitempty" label:"allowEmpty"` } // +k8s:deepcopy-gen=true @@ -113,6 +113,7 @@ type Cookie struct { Name string `json:"name,omitempty" toml:"name,omitempty" yaml:"name,omitempty"` Secure bool `json:"secure,omitempty" toml:"secure,omitempty" yaml:"secure,omitempty"` HTTPOnly bool `json:"httpOnly,omitempty" toml:"httpOnly,omitempty" yaml:"httpOnly,omitempty"` + SameSite string `json:"sameSite,omitempty" toml:"sameSite,omitempty" yaml:"sameSite,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index e01480e97..cba305a77 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -286,13 +286,6 @@ type InFlightReq struct { SourceCriterion *SourceCriterion `json:"sourceCriterion,omitempty" toml:"sourceCriterion,omitempty" yaml:"sourceCriterion,omitempty"` } -// SetDefaults Default values for a InFlightReq. -func (i *InFlightReq) SetDefaults() { - i.SourceCriterion = &SourceCriterion{ - RequestHost: true, - } -} - // +k8s:deepcopy-gen=true // PassTLSClientCert holds the TLS client cert headers configuration. @@ -304,8 +297,8 @@ type PassTLSClientCert struct { // +k8s:deepcopy-gen=true // SourceCriterion defines what criterion is used to group requests as originating from a common source. -// The precedence order is IPStrategy, then RequestHeaderName. // If none are set, the default is to use the request's remote address field. +// All fields are mutually exclusive. type SourceCriterion struct { IPStrategy *IPStrategy `json:"ipStrategy" toml:"ipStrategy, omitempty"` RequestHeaderName string `json:"requestHeaderName,omitempty" toml:"requestHeaderName,omitempty" yaml:"requestHeaderName,omitempty"` @@ -321,12 +314,15 @@ type RateLimit struct { // The rate is actually defined by dividing Average by Period. So for a rate below 1req/s, // one needs to define a Period larger than a second. Average int64 `json:"average,omitempty" toml:"average,omitempty" yaml:"average,omitempty"` + // Period, in combination with Average, defines the actual maximum rate, such as: // r = Average / Period. It defaults to a second. - Period types.Duration + Period types.Duration `json:"period,omitempty" toml:"period,omitempty" yaml:"period,omitempty"` + // Burst is the maximum number of requests allowed to arrive in the same arbitrarily small period of time. // It defaults to 1. - Burst int64 `json:"burst,omitempty" toml:"burst,omitempty" yaml:"burst,omitempty"` + Burst int64 `json:"burst,omitempty" toml:"burst,omitempty" yaml:"burst,omitempty"` + SourceCriterion *SourceCriterion `json:"sourceCriterion,omitempty" toml:"sourceCriterion,omitempty" yaml:"sourceCriterion,omitempty"` } @@ -334,9 +330,6 @@ type RateLimit struct { func (r *RateLimit) SetDefaults() { r.Burst = 1 r.Period = types.Duration(time.Second) - r.SourceCriterion = &SourceCriterion{ - IPStrategy: &IPStrategy{}, - } } // +k8s:deepcopy-gen=true diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index f8378ae2e..1c0e030ca 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -2,6 +2,7 @@ package static import ( "fmt" + "math" "strings" "github.com/containous/traefik/v2/pkg/types" @@ -61,16 +62,16 @@ type Redirections struct { // RedirectEntryPoint is the definition of an entry point redirection. type RedirectEntryPoint struct { To string `description:"Targeted entry point of the redirection." json:"to,omitempty" toml:"to,omitempty" yaml:"to,omitempty"` - Scheme string `description:"Scheme used for the redirection. Defaults to https." json:"https,omitempty" toml:"https,omitempty" yaml:"https,omitempty"` - Permanent bool `description:"Applied a permanent redirection. Defaults to true." json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty"` - Priority int `description:"Priority of the generated router. Defaults to 1." json:"priority,omitempty" toml:"priority,omitempty" yaml:"priority,omitempty"` + Scheme string `description:"Scheme used for the redirection." json:"https,omitempty" toml:"https,omitempty" yaml:"https,omitempty"` + Permanent bool `description:"Applies a permanent redirection." json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty"` + Priority int `description:"Priority of the generated router." json:"priority,omitempty" toml:"priority,omitempty" yaml:"priority,omitempty"` } // SetDefaults sets the default values. func (r *RedirectEntryPoint) SetDefaults() { r.Scheme = "https" r.Permanent = true - r.Priority = 1 + r.Priority = math.MaxInt32 } // TLSConfig is the default TLS configuration for all the routers associated to the concerned entry point. diff --git a/pkg/middlewares/auth/basic_auth.go b/pkg/middlewares/auth/basic_auth.go index ee857d05a..e03fb3f6a 100644 --- a/pkg/middlewares/auth/basic_auth.go +++ b/pkg/middlewares/auth/basic_auth.go @@ -49,7 +49,8 @@ func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAu if len(authConfig.Realm) > 0 { realm = authConfig.Realm } - ba.auth = goauth.NewBasicAuthenticator(realm, ba.secretBasic) + + ba.auth = &goauth.BasicAuth{Realm: realm, Secrets: ba.secretBasic} return ba, nil } diff --git a/pkg/middlewares/auth/digest_auth.go b/pkg/middlewares/auth/digest_auth.go index 0a43d45c1..70d1306ef 100644 --- a/pkg/middlewares/auth/digest_auth.go +++ b/pkg/middlewares/auth/digest_auth.go @@ -61,29 +61,38 @@ func (d *digestAuth) GetTracingInformation() (string, ext.SpanKindEnum) { func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { logger := log.FromContext(middlewares.GetLoggerCtx(req.Context(), d.name, digestTypeName)) - if username, _ := d.auth.CheckAuth(req); username == "" { + username, authinfo := d.auth.CheckAuth(req) + if username == "" { + if authinfo != nil && *authinfo == "stale" { + logger.Debug("Digest authentication failed, possibly because out of order requests") + tracing.SetErrorWithEvent(req, "Digest authentication failed, possibly because out of order requests") + d.auth.RequireAuthStale(rw, req) + return + } + logger.Debug("Digest authentication failed") tracing.SetErrorWithEvent(req, "Digest authentication failed") d.auth.RequireAuth(rw, req) - } else { - logger.Debug("Digest authentication succeeded") - req.URL.User = url.User(username) - - logData := accesslog.GetLogData(req) - if logData != nil { - logData.Core[accesslog.ClientUsername] = username - } - - if d.headerField != "" { - req.Header[d.headerField] = []string{username} - } - - if d.removeHeader { - logger.Debug("Removing the Authorization header") - req.Header.Del(authorizationHeader) - } - d.next.ServeHTTP(rw, req) + return } + + logger.Debug("Digest authentication succeeded") + req.URL.User = url.User(username) + + logData := accesslog.GetLogData(req) + if logData != nil { + logData.Core[accesslog.ClientUsername] = username + } + + if d.headerField != "" { + req.Header[d.headerField] = []string{username} + } + + if d.removeHeader { + logger.Debug("Removing the Authorization header") + req.Header.Del(authorizationHeader) + } + d.next.ServeHTTP(rw, req) } func (d *digestAuth) secretDigest(user, realm string) string { diff --git a/pkg/middlewares/extractor.go b/pkg/middlewares/extractor.go index 75b700523..1a886bfad 100644 --- a/pkg/middlewares/extractor.go +++ b/pkg/middlewares/extractor.go @@ -13,7 +13,20 @@ import ( // GetSourceExtractor returns the SourceExtractor function corresponding to the given sourceMatcher. // It defaults to a RemoteAddrStrategy IPStrategy if need be. +// It returns an error if more than one source criterion is provided. func GetSourceExtractor(ctx context.Context, sourceMatcher *dynamic.SourceCriterion) (utils.SourceExtractor, error) { + if sourceMatcher != nil { + if sourceMatcher.IPStrategy != nil && sourceMatcher.RequestHeaderName != "" { + return nil, errors.New("iPStrategy and RequestHeaderName are mutually exclusive") + } + if sourceMatcher.IPStrategy != nil && sourceMatcher.RequestHost { + return nil, errors.New("iPStrategy and RequestHost are mutually exclusive") + } + if sourceMatcher.RequestHeaderName != "" && sourceMatcher.RequestHost { + return nil, errors.New("requestHost and RequestHeaderName are mutually exclusive") + } + } + if sourceMatcher == nil || sourceMatcher.IPStrategy == nil && sourceMatcher.RequestHeaderName == "" && !sourceMatcher.RequestHost { diff --git a/pkg/middlewares/inflightreq/inflight_req.go b/pkg/middlewares/inflightreq/inflight_req.go index 4be488bd8..8856858a6 100644 --- a/pkg/middlewares/inflightreq/inflight_req.go +++ b/pkg/middlewares/inflightreq/inflight_req.go @@ -23,6 +23,7 @@ type inFlightReq struct { } // New creates a max request middleware. +// If no source criterion is provided in the config, it defaults to RequestHost. func New(ctx context.Context, next http.Handler, config dynamic.InFlightReq, name string) (http.Handler, error) { ctxLog := log.With(ctx, log.Str(log.MiddlewareName, name), log.Str(log.MiddlewareType, typeName)) log.FromContext(ctxLog).Debug("Creating middleware") diff --git a/pkg/middlewares/ratelimiter/rate_limiter_test.go b/pkg/middlewares/ratelimiter/rate_limiter_test.go index 7d9213db3..c0f4be1b2 100644 --- a/pkg/middlewares/ratelimiter/rate_limiter_test.go +++ b/pkg/middlewares/ratelimiter/rate_limiter_test.go @@ -22,6 +22,8 @@ func TestNewRateLimiter(t *testing.T) { config dynamic.RateLimit expectedMaxDelay time.Duration expectedSourceIP string + requestHeader string + expectedError string }{ { desc: "maxDelay computation", @@ -48,6 +50,29 @@ func TestNewRateLimiter(t *testing.T) { }, expectedSourceIP: "127.0.0.1", }, + { + desc: "SourceCriterion in config is respected", + config: dynamic.RateLimit{ + Average: 200, + Burst: 10, + SourceCriterion: &dynamic.SourceCriterion{ + RequestHeaderName: "Foo", + }, + }, + requestHeader: "bar", + }, + { + desc: "SourceCriteria are mutually exclusive", + config: dynamic.RateLimit{ + Average: 200, + Burst: 10, + SourceCriterion: &dynamic.SourceCriterion{ + IPStrategy: &dynamic.IPStrategy{}, + RequestHeaderName: "Foo", + }, + }, + expectedError: "iPStrategy and RequestHeaderName are mutually exclusive", + }, } for _, test := range testCases { @@ -58,7 +83,11 @@ func TestNewRateLimiter(t *testing.T) { next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}) h, err := New(context.Background(), next, test.config, "rate-limiter") - require.NoError(t, err) + if test.expectedError != "" { + assert.EqualError(t, err, test.expectedError) + } else { + require.NoError(t, err) + } rtl, _ := h.(*rateLimiter) if test.expectedMaxDelay != 0 { @@ -77,6 +106,19 @@ func TestNewRateLimiter(t *testing.T) { assert.NoError(t, err) assert.Equal(t, test.expectedSourceIP, ip) } + if test.requestHeader != "" { + extractor, ok := rtl.sourceMatcher.(utils.ExtractorFunc) + require.True(t, ok, "Not an ExtractorFunc") + + req := http.Request{ + Header: map[string][]string{ + test.config.SourceCriterion.RequestHeaderName: {test.requestHeader}, + }, + } + hd, _, err := extractor(&req) + assert.NoError(t, err) + assert.Equal(t, test.requestHeader, hd) + } }) } } diff --git a/pkg/provider/consulcatalog/config.go b/pkg/provider/consulcatalog/config.go index a69c942e4..679600880 100644 --- a/pkg/provider/consulcatalog/config.go +++ b/pkg/provider/consulcatalog/config.go @@ -18,8 +18,8 @@ func (p *Provider) buildConfiguration(ctx context.Context, items []itemData) *dy configurations := make(map[string]*dynamic.Configuration) for _, item := range items { - svcName := item.Node + "-" + item.Name + "-" + item.ID - ctxSvc := log.With(ctx, log.Str("serviceName", svcName)) + svcName := provider.Normalize(item.Node + "-" + item.Name + "-" + item.ID) + ctxSvc := log.With(ctx, log.Str(log.ServiceName, svcName)) if !p.keepContainer(ctxSvc, item) { continue @@ -77,7 +77,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, items []itemData) *dy Labels: item.Labels, } - provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, item.Name, p.defaultRuleTpl, model) + provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, provider.Normalize(item.Name), p.defaultRuleTpl, model) configurations[svcName] = confFromLabel } @@ -118,7 +118,7 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, item itemDa lb := &dynamic.TCPServersLoadBalancer{} lb.SetDefaults() - configuration.Services[item.Name] = &dynamic.TCPService{ + configuration.Services[provider.Normalize(item.Name)] = &dynamic.TCPService{ LoadBalancer: lb, } } @@ -140,7 +140,7 @@ func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, item itemDa lb := &dynamic.UDPServersLoadBalancer{} - configuration.Services[item.Name] = &dynamic.UDPService{ + configuration.Services[provider.Normalize(item.Name)] = &dynamic.UDPService{ LoadBalancer: lb, } } @@ -163,7 +163,7 @@ func (p *Provider) buildServiceConfiguration(ctx context.Context, item itemData, lb := &dynamic.ServersLoadBalancer{} lb.SetDefaults() - configuration.Services[item.Name] = &dynamic.Service{ + configuration.Services[provider.Normalize(item.Name)] = &dynamic.Service{ LoadBalancer: lb, } } diff --git a/pkg/provider/consulcatalog/config_test.go b/pkg/provider/consulcatalog/config_test.go index 69d4d7818..732fe9dcc 100644 --- a/pkg/provider/consulcatalog/config_test.go +++ b/pkg/provider/consulcatalog/config_test.go @@ -284,7 +284,7 @@ func Test_buildConfiguration(t *testing.T) { { ID: "Test", Node: "Node1", - Name: "Test", + Name: "dev/Test", Labels: map[string]string{}, Address: "127.0.0.1", Port: "80", @@ -302,14 +302,14 @@ func Test_buildConfiguration(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", + "dev-Test": { + Service: "dev-Test", + Rule: "Host(`dev-Test.traefik.wtf`)", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "Test": { + "dev-Test": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1003,9 +1003,6 @@ func Test_buildConfiguration(t *testing.T) { "Middleware1": { InFlightReq: &dynamic.InFlightReq{ Amount: 42, - SourceCriterion: &dynamic.SourceCriterion{ - RequestHost: true, - }, }, }, }, @@ -1055,9 +1052,6 @@ func Test_buildConfiguration(t *testing.T) { "Middleware1": { InFlightReq: &dynamic.InFlightReq{ Amount: 42, - SourceCriterion: &dynamic.SourceCriterion{ - RequestHost: true, - }, }, }, }, diff --git a/pkg/provider/docker/config_test.go b/pkg/provider/docker/config_test.go index 1617bbd8b..c49594d1b 100644 --- a/pkg/provider/docker/config_test.go +++ b/pkg/provider/docker/config_test.go @@ -1301,9 +1301,6 @@ func Test_buildConfiguration(t *testing.T) { "Middleware1": { InFlightReq: &dynamic.InFlightReq{ Amount: 42, - SourceCriterion: &dynamic.SourceCriterion{ - RequestHost: true, - }, }, }, }, @@ -1372,9 +1369,6 @@ func Test_buildConfiguration(t *testing.T) { "Middleware1": { InFlightReq: &dynamic.InFlightReq{ Amount: 42, - SourceCriterion: &dynamic.SourceCriterion{ - RequestHost: true, - }, }, }, }, diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go index 9cc3face3..0f3ba4f8b 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go @@ -69,7 +69,6 @@ type LoadBalancerSpec struct { // and therefore should only be specified when Name references a Kubernetes Service. Port int32 `json:"port"` Scheme string `json:"scheme,omitempty"` - HealthCheck *HealthCheck `json:"healthCheck,omitempty"` Strategy string `json:"strategy,omitempty"` PassHostHeader *bool `json:"passHostHeader,omitempty"` ResponseForwarding *dynamic.ResponseForwarding `json:"responseForwarding,omitempty"` @@ -90,16 +89,6 @@ type MiddlewareRef struct { Namespace string `json:"namespace"` } -// HealthCheck is the HealthCheck definition. -type HealthCheck struct { - Path string `json:"path"` - Host string `json:"host,omitempty"` - Scheme string `json:"scheme"` - IntervalSeconds int64 `json:"intervalSeconds"` - TimeoutSeconds int64 `json:"timeoutSeconds"` - Headers map[string]string `json:"headers"` -} - // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 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 69473f773..d7ac29e4f 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go @@ -188,29 +188,6 @@ func (in *ForwardAuth) DeepCopy() *ForwardAuth { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HealthCheck) DeepCopyInto(out *HealthCheck) { - *out = *in - if in.Headers != nil { - in, out := &in.Headers, &out.Headers - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheck. -func (in *HealthCheck) DeepCopy() *HealthCheck { - if in == nil { - return nil - } - out := new(HealthCheck) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRoute) DeepCopyInto(out *IngressRoute) { *out = *in @@ -493,11 +470,6 @@ func (in *LoadBalancerSpec) DeepCopyInto(out *LoadBalancerSpec) { *out = new(dynamic.Sticky) (*in).DeepCopyInto(*out) } - if in.HealthCheck != nil { - in, out := &in.HealthCheck, &out.HealthCheck - *out = new(HealthCheck) - (*in).DeepCopyInto(*out) - } if in.PassHostHeader != nil { in, out := &in.PassHostHeader, &out.PassHostHeader *out = new(bool) diff --git a/pkg/provider/kubernetes/ingress/annotations_test.go b/pkg/provider/kubernetes/ingress/annotations_test.go index 751192d2d..9a461a720 100644 --- a/pkg/provider/kubernetes/ingress/annotations_test.go +++ b/pkg/provider/kubernetes/ingress/annotations_test.go @@ -109,6 +109,7 @@ func Test_parseServiceConfig(t *testing.T) { "traefik.ingress.kubernetes.io/service.sticky.cookie.httponly": "true", "traefik.ingress.kubernetes.io/service.sticky.cookie.name": "foobar", "traefik.ingress.kubernetes.io/service.sticky.cookie.secure": "true", + "traefik.ingress.kubernetes.io/service.sticky.cookie.samesite": "none", }, expected: &ServiceConfig{ Service: &ServiceIng{ @@ -117,6 +118,7 @@ func Test_parseServiceConfig(t *testing.T) { Name: "foobar", Secure: true, HTTPOnly: true, + SameSite: "none", }, }, ServersScheme: "protocol", diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations_service.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations_service.yml index e0de9f321..c3eaf80d3 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations_service.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations_service.yml @@ -9,7 +9,7 @@ metadata: traefik.ingress.kubernetes.io/foo: bar traefik.ingress.kubernetes.io/service.serversscheme: protocol traefik.ingress.kubernetes.io/service.passhostheader: "true" - traefik.ingress.kubernetes.io/service.sticky: "true" + traefik.ingress.kubernetes.io/service.sticky.cookie: "true" traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true" traefik.ingress.kubernetes.io/service.sticky.cookie.name: foobar traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true" diff --git a/pkg/provider/marathon/config_test.go b/pkg/provider/marathon/config_test.go index cb553b47c..d8862e78e 100644 --- a/pkg/provider/marathon/config_test.go +++ b/pkg/provider/marathon/config_test.go @@ -686,9 +686,6 @@ func TestBuildConfiguration(t *testing.T) { "Middleware1": { InFlightReq: &dynamic.InFlightReq{ Amount: 42, - SourceCriterion: &dynamic.SourceCriterion{ - RequestHost: true, - }, }, }, }, diff --git a/pkg/server/configurationwatcher.go b/pkg/server/configurationwatcher.go index 8bca826cf..3434e727a 100644 --- a/pkg/server/configurationwatcher.go +++ b/pkg/server/configurationwatcher.go @@ -241,10 +241,14 @@ func isEmptyConfiguration(conf *dynamic.Configuration) bool { if conf.HTTP == nil { conf.HTTP = &dynamic.HTTPConfiguration{} } + if conf.UDP == nil { + conf.UDP = &dynamic.UDPConfiguration{} + } httpEmpty := conf.HTTP.Routers == nil && conf.HTTP.Services == nil && conf.HTTP.Middlewares == nil tlsEmpty := conf.TLS == nil || conf.TLS.Certificates == nil && conf.TLS.Stores == nil && conf.TLS.Options == nil tcpEmpty := conf.TCP.Routers == nil && conf.TCP.Services == nil + udpEmpty := conf.UDP.Routers == nil && conf.UDP.Services == nil - return httpEmpty && tlsEmpty && tcpEmpty + return httpEmpty && tlsEmpty && tcpEmpty && udpEmpty } diff --git a/pkg/server/service/proxy.go b/pkg/server/service/proxy.go index d6fdfcb8e..3c7da58ac 100644 --- a/pkg/server/service/proxy.go +++ b/pkg/server/service/proxy.go @@ -62,10 +62,19 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar } // Even if the websocket RFC says that headers should be case-insensitive, - // some servers need Sec-WebSocket-Key to be case-sensitive. + // some servers need Sec-WebSocket-Key, Sec-WebSocket-Extensions, Sec-WebSocket-Accept, + // Sec-WebSocket-Protocol and Sec-WebSocket-Version to be case-sensitive. // https://tools.ietf.org/html/rfc6455#page-20 outReq.Header["Sec-WebSocket-Key"] = outReq.Header["Sec-Websocket-Key"] + outReq.Header["Sec-WebSocket-Extensions"] = outReq.Header["Sec-Websocket-Extensions"] + outReq.Header["Sec-WebSocket-Accept"] = outReq.Header["Sec-Websocket-Accept"] + outReq.Header["Sec-WebSocket-Protocol"] = outReq.Header["Sec-Websocket-Protocol"] + outReq.Header["Sec-WebSocket-Version"] = outReq.Header["Sec-Websocket-Version"] delete(outReq.Header, "Sec-Websocket-Key") + delete(outReq.Header, "Sec-Websocket-Extensions") + delete(outReq.Header, "Sec-Websocket-Accept") + delete(outReq.Header, "Sec-Websocket-Protocol") + delete(outReq.Header, "Sec-Websocket-Version") }, Transport: defaultRoundTripper, FlushInterval: time.Duration(flushInterval), diff --git a/pkg/server/service/roundtripper.go b/pkg/server/service/roundtripper.go index f232049a6..715d5d5c2 100644 --- a/pkg/server/service/roundtripper.go +++ b/pkg/server/service/roundtripper.go @@ -23,12 +23,12 @@ func (t *h2cTransportWrapper) RoundTrip(req *http.Request) (*http.Response, erro return t.Transport.RoundTrip(req) } -// createHTTPTransport creates an http.Transport configured with the Transport configuration settings. +// createRoundtripper creates an http.Roundtripper configured with the Transport configuration settings. // For the settings that can't be configured in Traefik it uses the default http.Transport settings. // An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost // in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing // behavior and backwards compatibility issues. -func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http.Transport, error) { +func createRoundtripper(transportConfiguration *static.ServersTransport) (http.RoundTripper, error) { if transportConfiguration == nil { return nil, errors.New("no transport configuration given") } @@ -66,25 +66,26 @@ func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http transport.IdleConnTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.IdleConnTimeout) } - if transportConfiguration.InsecureSkipVerify { - transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - } - - if len(transportConfiguration.RootCAs) > 0 { + if transportConfiguration.InsecureSkipVerify || len(transportConfiguration.RootCAs) > 0 { transport.TLSClientConfig = &tls.Config{ - RootCAs: createRootCACertPool(transportConfiguration.RootCAs), + InsecureSkipVerify: transportConfiguration.InsecureSkipVerify, + RootCAs: createRootCACertPool(transportConfiguration.RootCAs), } } - err := http2.ConfigureTransport(transport) + smartTransport, err := newSmartRoundTripper(transport) if err != nil { return nil, err } - return transport, nil + return smartTransport, nil } func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool { + if len(rootCAs) == 0 { + return nil + } + roots := x509.NewCertPool() for _, cert := range rootCAs { @@ -100,7 +101,7 @@ func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool { } func setupDefaultRoundTripper(conf *static.ServersTransport) http.RoundTripper { - transport, err := createHTTPTransport(conf) + transport, err := createRoundtripper(conf) if err != nil { log.WithoutContext().Errorf("Could not configure HTTP Transport, fallbacking on default transport: %v", err) return http.DefaultTransport diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go index ff5c510f4..c2288d161 100644 --- a/pkg/server/service/service.go +++ b/pkg/server/service/service.go @@ -295,8 +295,15 @@ func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, servi var cookieName string if service.Sticky != nil && service.Sticky.Cookie != nil { cookieName = cookie.GetName(service.Sticky.Cookie.Name, serviceName) - opts := roundrobin.CookieOptions{HTTPOnly: service.Sticky.Cookie.HTTPOnly, Secure: service.Sticky.Cookie.Secure} + + opts := roundrobin.CookieOptions{ + HTTPOnly: service.Sticky.Cookie.HTTPOnly, + Secure: service.Sticky.Cookie.Secure, + SameSite: convertSameSite(service.Sticky.Cookie.SameSite), + } + options = append(options, roundrobin.EnableStickySession(roundrobin.NewStickySessionWithOptions(cookieName, opts))) + logger.Debugf("Sticky session cookie name: %v", cookieName) } @@ -332,3 +339,16 @@ func (m *Manager) upsertServers(ctx context.Context, lb healthcheck.BalancerHand } return nil } + +func convertSameSite(sameSite string) http.SameSite { + switch sameSite { + case "none": + return http.SameSiteNoneMode + case "lax": + return http.SameSiteLaxMode + case "strict": + return http.SameSiteStrictMode + default: + return 0 + } +} diff --git a/pkg/server/service/smart_roundtripper.go b/pkg/server/service/smart_roundtripper.go new file mode 100644 index 000000000..9a3028720 --- /dev/null +++ b/pkg/server/service/smart_roundtripper.go @@ -0,0 +1,38 @@ +package service + +import ( + "net/http" + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2" +) + +func newSmartRoundTripper(transport *http.Transport) (http.RoundTripper, error) { + transportHTTP1 := transport.Clone() + + err := http2.ConfigureTransport(transport) + if err != nil { + return nil, err + } + + return &smartRoundTripper{ + http2: transport, + http: transportHTTP1, + }, nil +} + +type smartRoundTripper struct { + http2 *http.Transport + http *http.Transport +} + +// smartRoundTripper implements RoundTrip while making sure that HTTP/2 is not used +// with protocols that start with a Connection Upgrade, such as SPDY or Websocket. +func (m *smartRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + // If we have a connection upgrade, we don't use HTTP/2 + if httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") { + return m.http.RoundTrip(req) + } + + return m.http2.RoundTrip(req) +} diff --git a/traefik.sample.toml b/traefik.sample.toml index 1f664ac93..cb2cb4c40 100644 --- a/traefik.sample.toml +++ b/traefik.sample.toml @@ -98,9 +98,9 @@ # Enable the API in insecure mode # # Optional - # Default: true + # Default: false # - # insecure = false + # insecure = true # Enabled Dashboard # diff --git a/webui/package.json b/webui/package.json index 423cc8e66..87f79b181 100644 --- a/webui/package.json +++ b/webui/package.json @@ -9,10 +9,10 @@ "transfer": "node dev/scripts/transfer.js", "lint": "eslint --ext .js,.vue src", "test-unit": "mocha-webpack --mode=production './src/**/*.spec.js'", - "dev": "export APP_ENV='development' && quasar dev -m pwa", - "build-quasar": "quasar build -m pwa", + "dev": "export APP_ENV='development' && quasar dev", + "build-quasar": "quasar build", "build-staging": "export NODE_ENV='production' && export APP_ENV='development' && npm run build-quasar", - "build": "export NODE_ENV='production' && export APP_ENV='production' && npm run build-quasar && npm run transfer pwa", + "build": "export NODE_ENV='production' && export APP_ENV='production' && npm run build-quasar && npm run transfer spa", "build:nc": "npm run build" }, "dependencies": { diff --git a/webui/readme.md b/webui/readme.md index ca205bcef..4e58abf12 100644 --- a/webui/readme.md +++ b/webui/readme.md @@ -4,7 +4,7 @@ Access to Traefik Web UI, ex: http://localhost:8080 ## Interface -Traefik Web UI provide 2 types of informations: +Traefik Web UI provide 2 types of information: - Providers with their backends and frontends information. - Health of the web server. diff --git a/webui/src/components/_commons/PanelTLS.vue b/webui/src/components/_commons/PanelTLS.vue index 5bfd1c5a8..eb25e0985 100644 --- a/webui/src/components/_commons/PanelTLS.vue +++ b/webui/src/components/_commons/PanelTLS.vue @@ -70,7 +70,7 @@ empty empty -
There are no
TLS configured
+
There is no
TLS configured
diff --git a/webui/src/components/_commons/ToolBar.vue b/webui/src/components/_commons/ToolBar.vue index 9a1cb9f05..b508d09c2 100644 --- a/webui/src/components/_commons/ToolBar.vue +++ b/webui/src/components/_commons/ToolBar.vue @@ -21,7 +21,9 @@ export default { name: 'ToolBar', data () { return { - loadingOverview: true + loadingOverview: true, + intervalRefresh: null, + intervalRefreshTime: 5000 } }, computed: { @@ -65,8 +67,10 @@ export default { }, created () { this.refreshAll() + this.intervalRefresh = setInterval(this.onGetAll, this.intervalRefreshTime) }, beforeDestroy () { + clearInterval(this.intervalRefresh) this.$store.commit('core/getOverviewClear') } }