mirror of
				https://github.com/containous/traefik.git
				synced 2025-11-03 08:23:51 +03:00 
			
		
		
		
	Compare commits
	
		
			169 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					f9e9e11035 | ||
| 
						 | 
					772c9ca4d5 | ||
| 
						 | 
					208d0fa471 | ||
| 
						 | 
					9f72b6d1d5 | ||
| 
						 | 
					29ef007917 | ||
| 
						 | 
					590a0d67bb | ||
| 
						 | 
					74ad83f05a | ||
| 
						 | 
					d707c8ba93 | ||
| 
						 | 
					640eb62ca1 | ||
| 
						 | 
					216710864e | ||
| 
						 | 
					226f20b626 | ||
| 
						 | 
					151be83bce | ||
| 
						 | 
					d1a8c7fa78 | ||
| 
						 | 
					254dc38c3d | ||
| 
						 | 
					24d084d7e6 | ||
| 
						 | 
					df5f530058 | ||
| 
						 | 
					753d173965 | ||
| 
						 | 
					ffd1f122de | ||
| 
						 | 
					f98b57fdf4 | ||
| 
						 | 
					2d37f08864 | ||
| 
						 | 
					a7dbcc282c | ||
| 
						 | 
					f4f62e7fb3 | ||
| 
						 | 
					4cae8bcb10 | ||
| 
						 | 
					bee370ec6b | ||
| 
						 | 
					f1d016b893 | ||
| 
						 | 
					4defbbe848 | ||
| 
						 | 
					f397342f16 | ||
| 
						 | 
					989a59cc29 | ||
| 
						 | 
					c5b71592c8 | ||
| 
						 | 
					9de3129a55 | ||
| 
						 | 
					40ab1f325c | ||
| 
						 | 
					73e0561610 | ||
| 
						 | 
					0a89cccdc0 | ||
| 
						 | 
					b102e6de5a | ||
| 
						 | 
					2064a6f805 | ||
| 
						 | 
					72e2ddff98 | ||
| 
						 | 
					7db41967c6 | ||
| 
						 | 
					a8680a8719 | ||
| 
						 | 
					7e11fa1193 | ||
| 
						 | 
					489b5a6150 | ||
| 
						 | 
					8027e8ee23 | ||
| 
						 | 
					d35d5bd2e8 | ||
| 
						 | 
					8e47bdedc6 | ||
| 
						 | 
					51419a9235 | ||
| 
						 | 
					32fd52c698 | ||
| 
						 | 
					468e4ebd98 | ||
| 
						 | 
					92a57384a4 | ||
| 
						 | 
					2067a433cd | ||
| 
						 | 
					16f1f851cc | ||
| 
						 | 
					8e992c7cfb | ||
| 
						 | 
					9da0bcf3aa | ||
| 
						 | 
					51287d9316 | ||
| 
						 | 
					29307fe9fa | ||
| 
						 | 
					52772c9642 | ||
| 
						 | 
					8f135fdb0a | ||
| 
						 | 
					7722a41270 | ||
| 
						 | 
					cd11b1aab4 | ||
| 
						 | 
					e7564d4cf8 | ||
| 
						 | 
					cc130fb673 | ||
| 
						 | 
					4106cf647b | ||
| 
						 | 
					8a1c3510ea | ||
| 
						 | 
					787b0a3ac7 | ||
| 
						 | 
					a6d86cdddb | ||
| 
						 | 
					9559a56011 | ||
| 
						 | 
					07e8042192 | ||
| 
						 | 
					edd8e36dcc | ||
| 
						 | 
					e291dcb8d1 | ||
| 
						 | 
					de6e365b74 | ||
| 
						 | 
					98a5e08553 | ||
| 
						 | 
					ba44619828 | ||
| 
						 | 
					86d700c845 | ||
| 
						 | 
					b2f11afcc2 | ||
| 
						 | 
					cfb356c68e | ||
| 
						 | 
					266f5d18a8 | ||
| 
						 | 
					305af43fb9 | ||
| 
						 | 
					30545808d9 | ||
| 
						 | 
					358f125a58 | ||
| 
						 | 
					57ae9a80d5 | ||
| 
						 | 
					e32c021f16 | ||
| 
						 | 
					0db2a9aadd | ||
| 
						 | 
					4f4dab3ca5 | ||
| 
						 | 
					eaee39e534 | ||
| 
						 | 
					d85eb0495c | ||
| 
						 | 
					8aa618775d | ||
| 
						 | 
					f6b7e333be | ||
| 
						 | 
					108d9dbb3f | ||
| 
						 | 
					2a1fa32950 | ||
| 
						 | 
					ee7aa77833 | ||
| 
						 | 
					fcc4cab614 | ||
| 
						 | 
					1206cd52fc | ||
| 
						 | 
					5cdba752a4 | ||
| 
						 | 
					b48ea1e173 | ||
| 
						 | 
					373040f552 | ||
| 
						 | 
					443902a0f0 | ||
| 
						 | 
					9eb02d9b03 | ||
| 
						 | 
					2eb651645d | ||
| 
						 | 
					630571fdc8 | ||
| 
						 | 
					00fc43ebce | ||
| 
						 | 
					6d906fa4c8 | ||
| 
						 | 
					6a4c7796e3 | ||
| 
						 | 
					67704e333d | ||
| 
						 | 
					76c9cea856 | ||
| 
						 | 
					0366fb9bc2 | ||
| 
						 | 
					5fed947eaa | ||
| 
						 | 
					c289279d24 | ||
| 
						 | 
					418dca1113 | ||
| 
						 | 
					ed293e3058 | ||
| 
						 | 
					40bb0cd879 | ||
| 
						 | 
					32f5e0df8f | ||
| 
						 | 
					40b8a93930 | ||
| 
						 | 
					b52b0f58b9 | ||
| 
						 | 
					0016db0856 | ||
| 
						 | 
					5aeca4507e | ||
| 
						 | 
					11bfb49e65 | ||
| 
						 | 
					d0cdb5608f | ||
| 
						 | 
					8bb8ad5e02 | ||
| 
						 | 
					b488d8365c | ||
| 
						 | 
					e2bd7b45d1 | ||
| 
						 | 
					c8ea2ce703 | ||
| 
						 | 
					7d1edcd735 | ||
| 
						 | 
					9660c31d3d | ||
| 
						 | 
					37ac19583a | ||
| 
						 | 
					ca60c52199 | ||
| 
						 | 
					9cddf5616a | ||
| 
						 | 
					f8ba843ad2 | ||
| 
						 | 
					e598d6bcca | ||
| 
						 | 
					52ec0e8d34 | ||
| 
						 | 
					13c32dee11 | ||
| 
						 | 
					6db120fd8e | ||
| 
						 | 
					b6b3a9ed7f | ||
| 
						 | 
					b5a4d0797a | ||
| 
						 | 
					9ec2887494 | ||
| 
						 | 
					94de6eb7f2 | ||
| 
						 | 
					0e643f06a3 | ||
| 
						 | 
					4db0dd9a7f | ||
| 
						 | 
					ee19e66aba | ||
| 
						 | 
					16ed13ba6f | ||
| 
						 | 
					8f5e972843 | ||
| 
						 | 
					4b70ff82b9 | ||
| 
						 | 
					1468e1f697 | ||
| 
						 | 
					7a963e75fd | ||
| 
						 | 
					9203ba5f95 | ||
| 
						 | 
					302849282c | ||
| 
						 | 
					2a227fa4c7 | ||
| 
						 | 
					31b80683c8 | ||
| 
						 | 
					6aa040ad9f | ||
| 
						 | 
					617de78d14 | ||
| 
						 | 
					44605731dc | ||
| 
						 | 
					9d26839e54 | ||
| 
						 | 
					7a93bcc869 | ||
| 
						 | 
					0840fd0f96 | ||
| 
						 | 
					4a5f5440d7 | ||
| 
						 | 
					479ee9af49 | ||
| 
						 | 
					ef6c1fac4b | ||
| 
						 | 
					53201b65b0 | ||
| 
						 | 
					9cb4d56c03 | ||
| 
						 | 
					f25ebc7e3d | ||
| 
						 | 
					4c25cda55f | ||
| 
						 | 
					18962b61d6 | ||
| 
						 | 
					d0aa993661 | ||
| 
						 | 
					df688dba0e | ||
| 
						 | 
					69585c58cd | ||
| 
						 | 
					b889b0191c | ||
| 
						 | 
					9b0586cba7 | ||
| 
						 | 
					a20f5bda0b | ||
| 
						 | 
					28d5731b87 | ||
| 
						 | 
					66486eacdc | ||
| 
						 | 
					2b82ed054c | ||
| 
						 | 
					cd6f0c0ded | 
							
								
								
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@@ -1 +1 @@
 | 
			
		||||
# vendor/github.com/xenolf/lego/providers/dns/cloudxns/cloudxns.go eol=crlf
 | 
			
		||||
# vendor/github.com/go-acme/lego/providers/dns/cloudxns/cloudxns.go eol=crlf
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,15 +1,17 @@
 | 
			
		||||
/dist
 | 
			
		||||
/autogen/genstatic/gen.go
 | 
			
		||||
.idea/
 | 
			
		||||
.intellij/
 | 
			
		||||
*.iml
 | 
			
		||||
/traefik
 | 
			
		||||
/traefik.toml
 | 
			
		||||
/static/
 | 
			
		||||
/webui/.tmp/
 | 
			
		||||
.vscode/
 | 
			
		||||
.DS_Store
 | 
			
		||||
/static/
 | 
			
		||||
/autogen/genstatic/gen.go
 | 
			
		||||
/webui/.tmp/
 | 
			
		||||
/examples/acme/acme.json
 | 
			
		||||
/site/
 | 
			
		||||
/docs/site/
 | 
			
		||||
/traefik.toml
 | 
			
		||||
/dist
 | 
			
		||||
/traefik
 | 
			
		||||
*.log
 | 
			
		||||
*.exe
 | 
			
		||||
.DS_Store
 | 
			
		||||
/examples/acme/acme.json
 | 
			
		||||
cover.out
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								.semaphoreci/golang.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								.semaphoreci/golang.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
curl -O https://dl.google.com/go/go1.12.linux-amd64.tar.gz
 | 
			
		||||
 | 
			
		||||
tar -xvf go1.12.linux-amd64.tar.gz
 | 
			
		||||
rm -rf go1.12.linux-amd64.tar.gz
 | 
			
		||||
 | 
			
		||||
sudo mkdir -p /usr/local/golang/1.12/go
 | 
			
		||||
sudo mv go /usr/local/golang/1.12/
 | 
			
		||||
 | 
			
		||||
sudo rm /usr/local/bin/go
 | 
			
		||||
sudo chmod +x /usr/local/golang/1.12/go/bin/go
 | 
			
		||||
sudo ln -s /usr/local/golang/1.12/go/bin/go /usr/local/bin/go
 | 
			
		||||
 | 
			
		||||
export GOROOT="/usr/local/golang/1.12/go"
 | 
			
		||||
export GOTOOLDIR="/usr/local/golang/1.12/go/pkg/tool/linux_amd64"
 | 
			
		||||
 | 
			
		||||
go version
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
export DOCKER_VERSION=17.03.1
 | 
			
		||||
export DOCKER_VERSION=18.09.7
 | 
			
		||||
 | 
			
		||||
source .semaphoreci/vars
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -13,6 +13,7 @@ env:
 | 
			
		||||
    - VERSION: $TRAVIS_TAG
 | 
			
		||||
    - CODENAME: maroilles
 | 
			
		||||
    - N_MAKE_JOBS: 2
 | 
			
		||||
    - DOCS_VERIFY_SKIP: true
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
- echo "Skipping tests... (Tests are executed on SemaphoreCI)"
 | 
			
		||||
@@ -30,9 +31,8 @@ before_deploy:
 | 
			
		||||
        make -j${N_MAKE_JOBS} crossbinary-parallel;
 | 
			
		||||
        tar cfz dist/traefik-${VERSION}.src.tar.gz --exclude-vcs --exclude dist .;
 | 
			
		||||
      fi;
 | 
			
		||||
      curl -sI https://github.com/containous/structor/releases/latest | grep -Fi Location  | tr -d '\r' | sed "s/tag/download/g" | awk -F " " '{ print $2 "/structor_linux-amd64"}' | wget --output-document=$GOPATH/bin/structor -i -;
 | 
			
		||||
      chmod +x $GOPATH/bin/structor;
 | 
			
		||||
      structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/master/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/containous/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/containous/structor/master/requirements-override.txt" --exp-branch=master --debug;
 | 
			
		||||
      curl -sfL https://raw.githubusercontent.com/containous/structor/master/godownloader.sh | bash -s -- -b "${GOPATH}/bin" ${STRUCTOR_VERSION}
 | 
			
		||||
      structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/containous/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/containous/structor/master/requirements-override.txt" --exp-branch=master --force-edit-url --debug;
 | 
			
		||||
    fi
 | 
			
		||||
deploy:
 | 
			
		||||
  - provider: releases
 | 
			
		||||
@@ -49,11 +49,6 @@ deploy:
 | 
			
		||||
    on:
 | 
			
		||||
      repo: containous/traefik
 | 
			
		||||
      tags: true
 | 
			
		||||
  - provider: script
 | 
			
		||||
    script: sh script/deploy-docker.sh
 | 
			
		||||
    skip_cleanup: true
 | 
			
		||||
    on:
 | 
			
		||||
      repo: containous/traefik
 | 
			
		||||
  - provider: pages
 | 
			
		||||
    edge: false
 | 
			
		||||
    github_token: ${GITHUB_TOKEN}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										247
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										247
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,248 @@
 | 
			
		||||
# Change Log
 | 
			
		||||
 | 
			
		||||
## [v1.7.19](https://github.com/containous/traefik/tree/v1.7.19) (2019-10-25)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.18...v1.7.19)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[k8s,k8s/ingress]** Add functions to support precise float compute of weight ([#5663](https://github.com/containous/traefik/pull/5663) by [rmrfself](https://github.com/rmrfself))
 | 
			
		||||
- **[middleware]** Fix Location response header http to https when SSL ([#5574](https://github.com/containous/traefik/pull/5574) by [elielgoncalves](https://github.com/elielgoncalves))
 | 
			
		||||
- **[tls]** Allow Default Certificate to work on macOS 10.15 ([#5662](https://github.com/containous/traefik/pull/5662) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[k8s]** Update DaemonSet apiVersion ([#5682](https://github.com/containous/traefik/pull/5682) by [ialidzhikov](https://github.com/ialidzhikov))
 | 
			
		||||
 | 
			
		||||
## [v1.7.18](https://github.com/containous/traefik/tree/v1.7.18) (2019-09-23)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.17...v1.7.18)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[go,security]** This version is compiled with [Go 1.12.10](https://groups.google.com/d/msg/golang-announce/cszieYyuL9Q/g4Z7pKaqAgAJ), which fixes a vulnerability in previous versions. See the [CVE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16276) about it for more details.
 | 
			
		||||
 | 
			
		||||
## [v1.7.17](https://github.com/containous/traefik/tree/v1.7.17) (2019-09-23)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.16...v1.7.17)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[logs,middleware]** Avoid closing stdout when the accesslog handler is closed ([#5459](https://github.com/containous/traefik/pull/5459) by [nrwiersma](https://github.com/nrwiersma))
 | 
			
		||||
- **[middleware]** Actually send header and code during WriteHeader, if needed ([#5404](https://github.com/containous/traefik/pull/5404) by [mpl](https://github.com/mpl))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[k8s]** Add note clarifying client certificate header ([#5362](https://github.com/containous/traefik/pull/5362) by [bradjones1](https://github.com/bradjones1))
 | 
			
		||||
- **[webui]** Update docs links. ([#5412](https://github.com/containous/traefik/pull/5412) by [ldez](https://github.com/ldez))
 | 
			
		||||
- Update Traefik image version. ([#5399](https://github.com/containous/traefik/pull/5399) by [ldez](https://github.com/ldez))
 | 
			
		||||
 | 
			
		||||
## [v1.7.16](https://github.com/containous/traefik/tree/v1.7.16) (2019-09-13)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.15...v1.7.16)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[middleware,websocket]** implement Flusher and Hijacker for codeCatcher ([#5376](https://github.com/containous/traefik/pull/5376) by [mpl](https://github.com/mpl))
 | 
			
		||||
 | 
			
		||||
## [v1.7.15](https://github.com/containous/traefik/tree/v1.7.15) (2019-09-12)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.14...v1.7.15)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[authentication,k8s/ingress]** Kubernetes support for Auth.HeaderField ([#5235](https://github.com/containous/traefik/pull/5235) by [ErikWegner](https://github.com/ErikWegner))
 | 
			
		||||
- **[k8s,k8s/ingress]** Finish kubernetes throttling refactoring ([#5269](https://github.com/containous/traefik/pull/5269) by [mpl](https://github.com/mpl))
 | 
			
		||||
- **[k8s]** Throttle Kubernetes config refresh ([#4716](https://github.com/containous/traefik/pull/4716) by [benweissmann](https://github.com/benweissmann))
 | 
			
		||||
- **[k8s]** Fix wrong handling of insecure tls auth forward ingress annotation ([#5319](https://github.com/containous/traefik/pull/5319) by [majkrzak](https://github.com/majkrzak))
 | 
			
		||||
- **[middleware]** error pages: do not buffer response when it's not an error ([#5285](https://github.com/containous/traefik/pull/5285) by [mpl](https://github.com/mpl))
 | 
			
		||||
- **[tls]** Consider default cert domain in certificate store ([#5353](https://github.com/containous/traefik/pull/5353) by [nrwiersma](https://github.com/nrwiersma))
 | 
			
		||||
- **[tls]** Add TLS minversion constraint ([#5356](https://github.com/containous/traefik/pull/5356) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** Update Acme doc - Vultr Wildcard & Root ([#5320](https://github.com/containous/traefik/pull/5320) by [ddymko](https://github.com/ddymko))
 | 
			
		||||
- **[consulcatalog]** Typo in basic auth usersFile label consul-catalog ([#5230](https://github.com/containous/traefik/pull/5230) by [pitan](https://github.com/pitan))
 | 
			
		||||
- **[logs]** Improve Access Logs Documentation page ([#5238](https://github.com/containous/traefik/pull/5238) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
 | 
			
		||||
## [v1.7.14](https://github.com/containous/traefik/tree/v1.7.14) (2019-08-14)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.13...v1.7.14)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- Update to go1.12.8 ([#5201](https://github.com/containous/traefik/pull/5201) by [ldez](https://github.com/ldez)). HTTP/2 Denial of Service [CVE-2019-9512](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9512) and [CVE-2019-9514](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9514)
 | 
			
		||||
- **[server]** Make hijackConnectionTracker.Close thread safe ([#5194](https://github.com/containous/traefik/pull/5194) by [jlevesy](https://github.com/jlevesy))
 | 
			
		||||
 | 
			
		||||
## [v1.7.13](https://github.com/containous/traefik/tree/v1.7.13) (2019-08-07)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.12...v1.7.13)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** Update lego ([#5166](https://github.com/containous/traefik/pull/5166) by [dabeck](https://github.com/dabeck))
 | 
			
		||||
- **[consulcatalog]** warning should not be a fail status ([#4537](https://github.com/containous/traefik/pull/4537) by [saez0pub](https://github.com/saez0pub))
 | 
			
		||||
- **[docker]** Update docker api version ([#4909](https://github.com/containous/traefik/pull/4909) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- **[dynamodb]** Use dynamodbav tags to override json tags. ([#5002](https://github.com/containous/traefik/pull/5002) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[healthcheck]** Wrr loadbalancer honors old weight on recovered servers ([#5051](https://github.com/containous/traefik/pull/5051) by [DougWagner](https://github.com/DougWagner))
 | 
			
		||||
- **[k8s]** Check for multiport services on Global Backend Ingress ([#5021](https://github.com/containous/traefik/pull/5021) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- **[logs]** Allows logs to use local time zone instead of UTC ([#4954](https://github.com/containous/traefik/pull/4954) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
- **[middleware]** Clear TLS client headers if TLSMutualAuth is optional ([#4963](https://github.com/containous/traefik/pull/4963) by [stffabi](https://github.com/stffabi))
 | 
			
		||||
- **[tls]** Add missing KeyUsages for default generated certificate ([#5150](https://github.com/containous/traefik/pull/5150) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** Fixed doc link for AlibabaCloud ([#5109](https://github.com/containous/traefik/pull/5109) by [ddymko](https://github.com/ddymko))
 | 
			
		||||
- **[docker]** Add example for CLI ([#5131](https://github.com/containous/traefik/pull/5131) by [alvarezbruned](https://github.com/alvarezbruned))
 | 
			
		||||
- **[docker]** Use the latest stable version of traefik in the docs ([#4927](https://github.com/containous/traefik/pull/4927) by [kolaente](https://github.com/kolaente))
 | 
			
		||||
- **[logs]** Update documentation to clarify the default format for logs ([#4953](https://github.com/containous/traefik/pull/4953) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
- **[rancher]** Add remarks about Rancher 2 ([#4999](https://github.com/containous/traefik/pull/4999) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[tls]** Fixes the TLS Mutual Authentication documentation ([#5085](https://github.com/containous/traefik/pull/5085) by [jbdoumenjou](https://github.com/jbdoumenjou))
 | 
			
		||||
- Format YAML example on user guide ([#5067](https://github.com/containous/traefik/pull/5067) by [gurayyildirim](https://github.com/gurayyildirim))
 | 
			
		||||
- Update Slack support channel references to Discourse community forum ([#5014](https://github.com/containous/traefik/pull/5014) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
- Updating Service Fabric documentation ([#5160](https://github.com/containous/traefik/pull/5160) by [gheibia](https://github.com/gheibia))
 | 
			
		||||
- Improve API / Dashboard wording in documentation ([#4929](https://github.com/containous/traefik/pull/4929) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
 | 
			
		||||
## [v1.7.12](https://github.com/containous/traefik/tree/v1.7.12) (2019-05-29)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.11...v1.7.12)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** Allow SANs for wildcards domain. ([#4821](https://github.com/containous/traefik/pull/4821) by [vizv](https://github.com/vizv))
 | 
			
		||||
- **[acme]** fix: update lego. ([#4910](https://github.com/containous/traefik/pull/4910) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[api,authentication]** Remove authentication hashes from API ([#4918](https://github.com/containous/traefik/pull/4918) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[consul]** Enhance KV logs. ([#4877](https://github.com/containous/traefik/pull/4877) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[k8s]** Fix kubernetes template for backend responseforwarding flushinterval setting ([#4901](https://github.com/containous/traefik/pull/4901) by [ravilr](https://github.com/ravilr))
 | 
			
		||||
- **[metrics]** Upgraded DataDog tracing library to 1.13.0 ([#4878](https://github.com/containous/traefik/pull/4878) by [aantono](https://github.com/aantono))
 | 
			
		||||
- **[server]** Add missing callback on close of hijacked connections ([#4900](https://github.com/containous/traefik/pull/4900) by [ravilr](https://github.com/ravilr))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[docker]** Docs: Troubleshooting help for Docker Swarm labels ([#4751](https://github.com/containous/traefik/pull/4751) by [gregberns](https://github.com/gregberns))
 | 
			
		||||
- **[logs]** Adds a log fields documentation. ([#4890](https://github.com/containous/traefik/pull/4890) by [ldez](https://github.com/ldez))
 | 
			
		||||
 | 
			
		||||
## [v1.7.11](https://github.com/containous/traefik/tree/v1.7.11) (2019-04-26)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.10...v1.7.11)
 | 
			
		||||
 | 
			
		||||
**Enhancements:**
 | 
			
		||||
- **[k8s,k8s/ingress]** Enhance k8s tests maintainability ([#4696](https://github.com/containous/traefik/pull/4696) by [ldez](https://github.com/ldez))
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** fix: update lego. ([#4800](https://github.com/containous/traefik/pull/4800) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[authentication,middleware]** Forward all header values from forward auth response ([#4515](https://github.com/containous/traefik/pull/4515) by [ctas582](https://github.com/ctas582))
 | 
			
		||||
- **[cluster]** Remove usage of github.com/satori/go.uuid ([#4722](https://github.com/containous/traefik/pull/4722) by [aaslamin](https://github.com/aaslamin))
 | 
			
		||||
- **[kv]** Enhance KV client error management ([#4819](https://github.com/containous/traefik/pull/4819) by [jbdoumenjou](https://github.com/jbdoumenjou))
 | 
			
		||||
- **[tls]** Improve log message about redundant TLS certificate ([#4765](https://github.com/containous/traefik/pull/4765) by [mpl](https://github.com/mpl))
 | 
			
		||||
- **[tracing]** Update zipkin-go-opentracing. ([#4720](https://github.com/containous/traefik/pull/4720) by [ldez](https://github.com/ldez))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** Documentation Update: Hosting.de wildcard support tested ([#4747](https://github.com/containous/traefik/pull/4747) by [martinhoefling](https://github.com/martinhoefling))
 | 
			
		||||
- **[acme]** Update Wildcard Domain documentation ([#4682](https://github.com/containous/traefik/pull/4682) by [DWSR](https://github.com/DWSR))
 | 
			
		||||
- **[middleware]** Keep consistent order ([#4690](https://github.com/containous/traefik/pull/4690) by [maxifom](https://github.com/maxifom))
 | 
			
		||||
 | 
			
		||||
## [v1.7.10](https://github.com/containous/traefik/tree/v1.7.10) (2019-03-28)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.9...v1.7.10)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** fix: update lego. ([#4670](https://github.com/containous/traefik/pull/4670) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[acme]** Migrate to go-acme/lego. ([#4577](https://github.com/containous/traefik/pull/4577) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[authentication,middleware]** Reorder Auth and TLSClientHeaders middleware ([#4557](https://github.com/containous/traefik/pull/4557) by [tomberek](https://github.com/tomberek))
 | 
			
		||||
- **[k8s/ingress]** Support external name service on global default backend ([#4564](https://github.com/containous/traefik/pull/4564) by [kippandrew](https://github.com/kippandrew))
 | 
			
		||||
- **[k8s/ingress]** Loop through service ports for global backend ([#4486](https://github.com/containous/traefik/pull/4486) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- **[k8s]** Add entrypoints prefix in kubernetes frontend/backend id  ([#4679](https://github.com/containous/traefik/pull/4679) by [juliens](https://github.com/juliens))
 | 
			
		||||
- **[websocket]** Exclude websocket connections from Average Response Time ([#4313](https://github.com/containous/traefik/pull/4313) by [siyu6974](https://github.com/siyu6974))
 | 
			
		||||
- **[middleware]** Added support for configuring trace headers for DataDog tracing ([#4516](https://github.com/containous/traefik/pull/4516) by [aantono](https://github.com/aantono))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** Add _FILE Environment Variable Documentation ([#4643](https://github.com/containous/traefik/pull/4643) by [dargmuesli](https://github.com/dargmuesli))
 | 
			
		||||
- **[docker]** Add TraefikEE as security workaround ([#4606](https://github.com/containous/traefik/pull/4606) by [emilevauge](https://github.com/emilevauge))
 | 
			
		||||
 | 
			
		||||
## [v1.7.9](https://github.com/containous/traefik/tree/v1.7.9) (2019-02-11)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.8...v1.7.9)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** Updates of Lego. ([#4480](https://github.com/containous/traefik/pull/4480) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[k8s]** app-root on non-explicit path include "/" in the redirect ([#4458](https://github.com/containous/traefik/pull/4458) by [doctori](https://github.com/doctori))
 | 
			
		||||
- **[middleware]** Missing trailers with retry ([#4442](https://github.com/containous/traefik/pull/4442) by [juliens](https://github.com/juliens))
 | 
			
		||||
- **[rancher]** Handle errors when working with rancher ([#4378](https://github.com/containous/traefik/pull/4378) by [apsifly](https://github.com/apsifly))
 | 
			
		||||
- **[servicefabric]** Add support for specifying the name of the endpoint. ([#4479](https://github.com/containous/traefik/pull/4479) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[tls]** insecureSkipVerify for the passTLSCert transport ([#4438](https://github.com/containous/traefik/pull/4438) by [jbdoumenjou](https://github.com/jbdoumenjou))
 | 
			
		||||
- **[tracing]** Add Tracing Header Context Name option for Jaeger ([#4459](https://github.com/containous/traefik/pull/4459) by [gadoor](https://github.com/gadoor))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[metrics]** Update default value of buckets for Prometheus ([#4468](https://github.com/containous/traefik/pull/4468) by [adam-golab](https://github.com/adam-golab))
 | 
			
		||||
- **[rules]** Fixes the display of the associativity rules. ([#4478](https://github.com/containous/traefik/pull/4478) by [ldez](https://github.com/ldez))
 | 
			
		||||
- Fixed curl example ([#4471](https://github.com/containous/traefik/pull/4471) by [rgarrigue](https://github.com/rgarrigue))
 | 
			
		||||
 | 
			
		||||
## [v1.7.8](https://github.com/containous/traefik/tree/v1.7.8) (2019-01-29)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.7...v1.7.8)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** Updates lego. ([#4428](https://github.com/containous/traefik/pull/4428) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[acme]** Updates lego. ([#4376](https://github.com/containous/traefik/pull/4376) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[docker]** Fixes docker swarm mode refresh second for KV. ([#4420](https://github.com/containous/traefik/pull/4420) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[ecs]** Generic awsvpc support, not just Fargate ([#4360](https://github.com/containous/traefik/pull/4360) by [maartenvanderhoef](https://github.com/maartenvanderhoef))
 | 
			
		||||
- **[ecs]** Cache exising task definitions to avoid rate limiting ([#4177](https://github.com/containous/traefik/pull/4177) by [hwhelan-CB](https://github.com/hwhelan-CB))
 | 
			
		||||
- **[tls]** Check for dynamic tls updates on configuration preload ([#4022](https://github.com/containous/traefik/pull/4022) by [ffilippopoulos](https://github.com/ffilippopoulos))
 | 
			
		||||
- **[tracing]** Support Datadog tracer priority sampling ([#4359](https://github.com/containous/traefik/pull/4359) by [jcassee](https://github.com/jcassee))
 | 
			
		||||
- Update to Go 1.11.5 [CVE-2019-6486](https://nvd.nist.gov/vuln/detail/CVE-2019-6486)
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** More detailed info about Google Cloud DNS. ([#4395](https://github.com/containous/traefik/pull/4395) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[acme]** Tested wildcard ACME challenge with DNSimple ([#4384](https://github.com/containous/traefik/pull/4384) by [tstackhouse](https://github.com/tstackhouse))
 | 
			
		||||
- **[docker]** Note about quotes for entrypoint definition with docker-compose ([#4390](https://github.com/containous/traefik/pull/4390) by [Dragnucs](https://github.com/Dragnucs))
 | 
			
		||||
- **[k8s]** Allow Træfik to update Ingress status ([#4397](https://github.com/containous/traefik/pull/4397) by [rbq](https://github.com/rbq))
 | 
			
		||||
- **[k8s]** Minor formatting fixes ([#4394](https://github.com/containous/traefik/pull/4394) by [dbirks](https://github.com/dbirks))
 | 
			
		||||
- **[metrics]** Missing information about statistics parameter ([#4393](https://github.com/containous/traefik/pull/4393) by [decima](https://github.com/decima))
 | 
			
		||||
- **[rules]** Route priorities: document minimum priority value ([#4374](https://github.com/containous/traefik/pull/4374) by [tw-360vier](https://github.com/tw-360vier))
 | 
			
		||||
- Removed repeated entryPoints.http from grpc.md ([#4370](https://github.com/containous/traefik/pull/4370) by [ishaanbahal](https://github.com/ishaanbahal))
 | 
			
		||||
- Happy 2019 ([#4367](https://github.com/containous/traefik/pull/4367) by [emilevauge](https://github.com/emilevauge))
 | 
			
		||||
 | 
			
		||||
**Misc:**
 | 
			
		||||
- Assert that test timeout service is ready. ([#4398](https://github.com/containous/traefik/pull/4398) by [timoreimann](https://github.com/timoreimann))
 | 
			
		||||
 | 
			
		||||
## [v1.7.7](https://github.com/containous/traefik/tree/v1.7.7) (2019-01-08)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.6...v1.7.7)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** Update Lego ([#4277](https://github.com/containous/traefik/pull/4277) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[k8s]** Check for watched namespace before getting kubernetes objects ([#4327](https://github.com/containous/traefik/pull/4327) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- **[k8s]** Allow empty path with App-root annotation ([#4326](https://github.com/containous/traefik/pull/4326) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- **[k8s]** kubernetes: sort and uniq TLS secrets ([#4307](https://github.com/containous/traefik/pull/4307) by [zarqman](https://github.com/zarqman))
 | 
			
		||||
- **[k8s]** Skip TLS section with no secret in Kubernetes ingress ([#4340](https://github.com/containous/traefik/pull/4340) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- **[middleware,consul,consulcatalog,docker,ecs,k8s,marathon,mesos,rancher]** Add Pass TLS Cert Issuer and Domain Component ([#4298](https://github.com/containous/traefik/pull/4298) by [jbdoumenjou](https://github.com/jbdoumenjou))
 | 
			
		||||
- **[middleware]** Retry middleware : store headers per attempts and propagate them when responding. ([#4299](https://github.com/containous/traefik/pull/4299) by [jlevesy](https://github.com/jlevesy))
 | 
			
		||||
- **[middleware]** Redirection status codes for methods different than GET ([#4116](https://github.com/containous/traefik/pull/4116) by [r--w](https://github.com/r--w))
 | 
			
		||||
- Test and exit for jq error before domain loop ([#4347](https://github.com/containous/traefik/pull/4347) by [muhlemmer](https://github.com/muhlemmer))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** Letsencrypt - Add info on httpreq format ([#4355](https://github.com/containous/traefik/pull/4355) by [goetas](https://github.com/goetas))
 | 
			
		||||
- **[docker]** Update broken link for Docker service constraints ([#4289](https://github.com/containous/traefik/pull/4289) by [clrech](https://github.com/clrech))
 | 
			
		||||
- **[middleware]** Add extractorfunc values ([#4351](https://github.com/containous/traefik/pull/4351) by [hsmade](https://github.com/hsmade))
 | 
			
		||||
- **[provider]** Rephrase the `traefik.backend` definition in documentation ([#4317](https://github.com/containous/traefik/pull/4317) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
- Harden Traefik systemd service ([#4302](https://github.com/containous/traefik/pull/4302) by [jacksgt](https://github.com/jacksgt))
 | 
			
		||||
 | 
			
		||||
## [v1.7.6](https://github.com/containous/traefik/tree/v1.7.6) (2018-12-07)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.5...v1.7.6)
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[consulcatalog]** Fix label segmentation when using custom prefix ([#4272](https://github.com/containous/traefik/pull/4272) by [hsmade](https://github.com/hsmade))
 | 
			
		||||
- Update to Go 1.11.3 [CVE-2018-16875](https://nvd.nist.gov/vuln/detail/CVE-2018-16875)
 | 
			
		||||
 | 
			
		||||
## [v1.7.5](https://github.com/containous/traefik/tree/v1.7.5) (2018-12-03)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.4...v1.7.5)
 | 
			
		||||
 | 
			
		||||
**Enhancements:**
 | 
			
		||||
- **[docker]** [docker backend] - Add config flag to set refreshSeconds for swarmmode ticker ([#4105](https://github.com/containous/traefik/pull/4105) by [WTFKr0](https://github.com/WTFKr0))
 | 
			
		||||
- **[k8s]** Support canary weight for external name service ([#4135](https://github.com/containous/traefik/pull/4135) by [yue9944882](https://github.com/yue9944882))
 | 
			
		||||
 | 
			
		||||
**Bug fixes:**
 | 
			
		||||
- **[acme]** Fix ACME spec and Cloudflare. ([#4201](https://github.com/containous/traefik/pull/4201) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[authentication,middleware]** Remove X-Forwarded-Uri and X-Forwarded-Method from untrusted IP ([#4036](https://github.com/containous/traefik/pull/4036) by [stffabi](https://github.com/stffabi))
 | 
			
		||||
- **[authentication,middleware]** Allow usersFile comments ([#4159](https://github.com/containous/traefik/pull/4159) by [thde](https://github.com/thde))
 | 
			
		||||
- **[authentication]** Fix partial declaration of authentication. ([#4212](https://github.com/containous/traefik/pull/4212) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[docker]** Verify ctx when we send configuration message in docker provider ([#4185](https://github.com/containous/traefik/pull/4185) by [juliens](https://github.com/juliens))
 | 
			
		||||
- **[ecs]** Filter ECS tasks by LastStatus before adding to list of service tasks ([#4255](https://github.com/containous/traefik/pull/4255) by [hwhelan-CB](https://github.com/hwhelan-CB))
 | 
			
		||||
- **[healthcheck]** Query params in health check ([#4188](https://github.com/containous/traefik/pull/4188) by [mmatur](https://github.com/mmatur))
 | 
			
		||||
- **[metrics]** Upgraded DD APM library ([#4189](https://github.com/containous/traefik/pull/4189) by [aantono](https://github.com/aantono))
 | 
			
		||||
- **[middleware]** Fix ssl force host secure middleware ([#4138](https://github.com/containous/traefik/pull/4138) by [mmatur](https://github.com/mmatur))
 | 
			
		||||
- **[oxy]** Fix unannonced trailers problem when body is empty ([#4258](https://github.com/containous/traefik/pull/4258) by [juliens](https://github.com/juliens))
 | 
			
		||||
- **[provider,server]** Log configuration errors from providers and keeps listening ([#4230](https://github.com/containous/traefik/pull/4230) by [geraldcroes](https://github.com/geraldcroes))
 | 
			
		||||
- **[tls]** Implement Case-insensitive SNI matching ([#4132](https://github.com/containous/traefik/pull/4132) by [dtomcej](https://github.com/dtomcej))
 | 
			
		||||
- Use ParseInt instead of Atoi for parsing durations ([#4263](https://github.com/containous/traefik/pull/4263) by [mmatur](https://github.com/mmatur))
 | 
			
		||||
 | 
			
		||||
**Documentation:**
 | 
			
		||||
- **[acme]** ACME DNS provider is called `acme-dns` ([#4166](https://github.com/containous/traefik/pull/4166) by [robsdedude](https://github.com/robsdedude))
 | 
			
		||||
- **[docker]** Add a "Security Consideration" section in the Docker's backend section of the documentation ([#4225](https://github.com/containous/traefik/pull/4225) by [dduportal](https://github.com/dduportal))
 | 
			
		||||
- **[docker]** Clarify swarm loadbalancer documentation ([#4194](https://github.com/containous/traefik/pull/4194) by [jlevesy](https://github.com/jlevesy))
 | 
			
		||||
- **[docker]** Fix spelling in comment ([#4169](https://github.com/containous/traefik/pull/4169) by [giocomai](https://github.com/giocomai))
 | 
			
		||||
- **[docker]** Update swarm mode endpoint ([#4208](https://github.com/containous/traefik/pull/4208) by [siyu6974](https://github.com/siyu6974))
 | 
			
		||||
- **[k8s]** Include an explicit list of kubernetes protocol annotations in docs. ([#4170](https://github.com/containous/traefik/pull/4170) by [shanna](https://github.com/shanna))
 | 
			
		||||
- **[k8s]** Improve kubernetes TLS user guide ([#4175](https://github.com/containous/traefik/pull/4175) by [mterring](https://github.com/mterring))
 | 
			
		||||
- **[k8s]** frame-deny should be set to true to enable the header ([#4171](https://github.com/containous/traefik/pull/4171) by [swestcott](https://github.com/swestcott))
 | 
			
		||||
- **[rules]** Matcher associativity rule. ([#4244](https://github.com/containous/traefik/pull/4244) by [ldez](https://github.com/ldez))
 | 
			
		||||
- Documentation: Rename "admin panel" to "dashboard ([#4156](https://github.com/containous/traefik/pull/4156) by [thernstig](https://github.com/thernstig))
 | 
			
		||||
 | 
			
		||||
## [v1.7.4](https://github.com/containous/traefik/tree/v1.7.4) (2018-10-30)
 | 
			
		||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.3...v1.7.4)
 | 
			
		||||
 | 
			
		||||
@@ -1018,7 +1261,7 @@
 | 
			
		||||
- **[acme,tls]** Rename TLSConfigurations to TLS. ([#2744](https://github.com/containous/traefik/pull/2744) by [ldez](https://github.com/ldez))
 | 
			
		||||
- **[acme,provider,docker,tls]** Make the TLS certificates management dynamic. ([#2233](https://github.com/containous/traefik/pull/2233) by [nmengin](https://github.com/nmengin))
 | 
			
		||||
- **[acme]** Add Let's Encrypt HTTP Challenge ([#2701](https://github.com/containous/traefik/pull/2701) by [Juliens](https://github.com/Juliens))
 | 
			
		||||
- **[acme]** Update github.com/xenolf/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
 | 
			
		||||
- **[acme]** Update github.com/go-acme/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
 | 
			
		||||
- **[api,healthcheck,metrics,provider,webui]** Split Web into API/Dashboard, ping, metric and Rest Provider ([#2335](https://github.com/containous/traefik/pull/2335) by [Juliens](https://github.com/Juliens))
 | 
			
		||||
- **[authentication]** Pass through certain forward auth negative response headers ([#2127](https://github.com/containous/traefik/pull/2127) by [wheresmysocks](https://github.com/wheresmysocks))
 | 
			
		||||
- **[cluster,consul,file]** Add file to storeconfig ([#2419](https://github.com/containous/traefik/pull/2419) by [emilevauge](https://github.com/emilevauge))
 | 
			
		||||
@@ -1297,7 +1540,7 @@
 | 
			
		||||
 | 
			
		||||
**Enhancements:**
 | 
			
		||||
- **[acme,provider,docker,tls]** Make the TLS certificates management dynamic. ([#2233](https://github.com/containous/traefik/pull/2233) by [nmengin](https://github.com/nmengin))
 | 
			
		||||
- **[acme]** Update github.com/xenolf/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
 | 
			
		||||
- **[acme]** Update github.com/go-acme/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
 | 
			
		||||
- **[api,healthcheck,metrics,provider,webui]** Split Web into API/Dashboard, ping, metric and Rest Provider ([#2335](https://github.com/containous/traefik/pull/2335) by [Juliens](https://github.com/Juliens))
 | 
			
		||||
- **[authentication]** Pass through certain forward auth negative response headers ([#2127](https://github.com/containous/traefik/pull/2127) by [wheresmysocks](https://github.com/wheresmysocks))
 | 
			
		||||
- **[cluster,consul,file]** Add file to storeconfig ([#2419](https://github.com/containous/traefik/pull/2419) by [emilevauge](https://github.com/emilevauge))
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ You need to run the `binary` target. This will create binaries for Linux platfor
 | 
			
		||||
$ make binary
 | 
			
		||||
docker build -t "traefik-dev:no-more-godep-ever" -f build.Dockerfile .
 | 
			
		||||
Sending build context to Docker daemon 295.3 MB
 | 
			
		||||
Step 0 : FROM golang:1.11-alpine
 | 
			
		||||
Step 0 : FROM golang:1.12-alpine
 | 
			
		||||
 ---> 8c6473912976
 | 
			
		||||
Step 1 : RUN go get github.com/golang/dep/cmd/dep
 | 
			
		||||
[...]
 | 
			
		||||
@@ -87,7 +87,7 @@ If you happen to update the provider templates (in `/templates`), you need to ru
 | 
			
		||||
 | 
			
		||||
[dep](https://github.com/golang/dep) is not required for building; however, it is necessary to modify dependencies (i.e., add, update, or remove third-party packages)
 | 
			
		||||
 | 
			
		||||
You need to use [dep](https://github.com/golang/dep) >= O.4.1.
 | 
			
		||||
You need to use [dep](https://github.com/golang/dep) >= 0.5.0.
 | 
			
		||||
 | 
			
		||||
If you want to add a dependency, use `dep ensure -add` to have [dep](https://github.com/golang/dep) put it into the vendor folder and update the dep manifest/lock files (`Gopkg.toml` and `Gopkg.lock`, respectively).
 | 
			
		||||
 | 
			
		||||
@@ -158,7 +158,7 @@ Integration tests must be run from the `integration/` directory and require the
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
The [documentation site](http://docs.traefik.io/) is built with [mkdocs](http://mkdocs.org/)
 | 
			
		||||
The [documentation site](https://docs.traefik.io/v1.7/) is built with [mkdocs](https://mkdocs.org/)
 | 
			
		||||
 | 
			
		||||
### Building Documentation
 | 
			
		||||
 | 
			
		||||
@@ -236,6 +236,14 @@ $ make docs-clean docs-verify
 | 
			
		||||
...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Please note that verification can be disabled by setting the environment variable `DOCS_VERIFY_SKIP` to `true`:
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
DOCS_VERIFY_SKIP=true make docs-verify
 | 
			
		||||
...
 | 
			
		||||
DOCS_LINT_SKIP is true: no linting done.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## How to Write a Good Issue
 | 
			
		||||
 | 
			
		||||
Please keep in mind that the GitHub issue tracker is not intended as a general support forum, but for reporting bugs and feature requests.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1248
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1248
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										70
									
								
								Gopkg.toml
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								Gopkg.toml
									
									
									
									
									
								
							@@ -19,6 +19,11 @@
 | 
			
		||||
#  name = "github.com/x/y"
 | 
			
		||||
#  version = "2.4.0"
 | 
			
		||||
 | 
			
		||||
[prune]
 | 
			
		||||
  non-go = true
 | 
			
		||||
  go-tests = true
 | 
			
		||||
  unused-packages = true
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/ArthurHlt/go-eureka-client"
 | 
			
		||||
@@ -31,6 +36,10 @@
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/BurntSushi/ty"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/Masterminds/sprig"
 | 
			
		||||
  version = "2.19.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/NYTimes/gziphandler"
 | 
			
		||||
@@ -40,6 +49,11 @@
 | 
			
		||||
  name = "github.com/abbot/go-http-auth"
 | 
			
		||||
  source = "github.com/containous/go-http-auth"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/thoas/stats"
 | 
			
		||||
  # related to https://github.com/thoas/stats/pull/32
 | 
			
		||||
  revision = "4975baf6a358ed3ddaa42133996e1959f96c9300"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/armon/go-proxyproto"
 | 
			
		||||
@@ -49,12 +63,12 @@
 | 
			
		||||
  version = "1.13.11"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/cenk/backoff"
 | 
			
		||||
  version = "v2.1.1"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/containous/flaeg"
 | 
			
		||||
  version = "1.3.0"
 | 
			
		||||
  version = "1.4.1"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
@@ -66,7 +80,7 @@
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/containous/traefik-extra-service-fabric"
 | 
			
		||||
  version = "1.3.0"
 | 
			
		||||
  version = "v1.5.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/coreos/go-systemd"
 | 
			
		||||
@@ -112,8 +126,8 @@
 | 
			
		||||
  version = "1.3.7"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/jjcollinge/servicefabric"
 | 
			
		||||
  revision = "8eebe170fa1ba25d3dfb928b3f86a7313b13b9fe"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
@@ -123,18 +137,6 @@
 | 
			
		||||
  name = "github.com/mesosphere/mesos-dns"
 | 
			
		||||
  source = "https://github.com/containous/mesos-dns.git"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/mitchellh/copystructure"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/mitchellh/hashstructure"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/mitchellh/mapstructure"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/opentracing/opentracing-go"
 | 
			
		||||
  version = "1.0.2"
 | 
			
		||||
@@ -148,10 +150,6 @@
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/ryanuber/go-glob"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/satori/go.uuid"
 | 
			
		||||
  version = "1.1.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/stvp/go-udp-testing"
 | 
			
		||||
@@ -162,7 +160,7 @@
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/uber/jaeger-client-go"
 | 
			
		||||
  version = "2.9.0"
 | 
			
		||||
  version = "2.15.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/uber/jaeger-lib"
 | 
			
		||||
@@ -181,9 +179,12 @@
 | 
			
		||||
  name = "github.com/vulcand/oxy"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  name = "github.com/xenolf/lego"
 | 
			
		||||
#  version = "1.0.0"
 | 
			
		||||
  name = "github.com/go-acme/lego"
 | 
			
		||||
  version = "2.7.2"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/golang/protobuf"
 | 
			
		||||
  version = "v1.3.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "google.golang.org/grpc"
 | 
			
		||||
@@ -249,18 +250,25 @@
 | 
			
		||||
  revision = "7e6055773c5137efbeb3bd2410d705fe10ab6bfd"
 | 
			
		||||
 | 
			
		||||
[[override]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  version = "v1.1.1"
 | 
			
		||||
  name = "github.com/miekg/dns"
 | 
			
		||||
 | 
			
		||||
[prune]
 | 
			
		||||
  non-go = true
 | 
			
		||||
  go-tests = true
 | 
			
		||||
  unused-packages = true
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/patrickmn/go-cache"
 | 
			
		||||
  version = "2.1.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "gopkg.in/DataDog/dd-trace-go.v1"
 | 
			
		||||
  version = "1.0.0"
 | 
			
		||||
  version = "1.13.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/google/uuid"
 | 
			
		||||
  version = "0.2.0"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/shopspring/decimal"
 | 
			
		||||
  revision = "f1972eb1d1f519e2e5f4b51f2dea765e8c93a130"
 | 
			
		||||
 | 
			
		||||
[[override]]
 | 
			
		||||
  name = "contrib.go.opencensus.io/exporter/ocagent"
 | 
			
		||||
  version = "0.4.12"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Makefile
									
									
									
									
									
								
							@@ -23,6 +23,7 @@ TRAEFIK_IMAGE := $(if $(REPONAME),$(REPONAME),"containous/traefik")
 | 
			
		||||
INTEGRATION_OPTS := $(if $(MAKE_DOCKER_HOST),-e "DOCKER_HOST=$(MAKE_DOCKER_HOST)", -e "TEST_CONTAINER=1" -v "/var/run/docker.sock:/var/run/docker.sock")
 | 
			
		||||
TRAEFIK_DOC_IMAGE := traefik-docs
 | 
			
		||||
TRAEFIK_DOC_VERIFY_IMAGE := $(TRAEFIK_DOC_IMAGE)-verify
 | 
			
		||||
DOCS_VERIFY_SKIP ?= false
 | 
			
		||||
 | 
			
		||||
DOCKER_BUILD_ARGS := $(if $(DOCKER_VERSION), "--build-arg=DOCKER_VERSION=$(DOCKER_VERSION)",)
 | 
			
		||||
DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)"
 | 
			
		||||
@@ -75,7 +76,7 @@ test-integration: build ## run the integration tests
 | 
			
		||||
	TEST_HOST=1 ./script/make.sh test-integration
 | 
			
		||||
 | 
			
		||||
validate: build  ## validate code, vendor and autogen
 | 
			
		||||
	$(DOCKER_RUN_TRAEFIK) ./script/make.sh validate-gofmt validate-govet validate-golint validate-misspell validate-vendor validate-autogen
 | 
			
		||||
	$(DOCKER_RUN_TRAEFIK) ./script/make.sh validate-gofmt validate-golint validate-misspell validate-vendor validate-autogen
 | 
			
		||||
 | 
			
		||||
build: dist
 | 
			
		||||
	docker build $(DOCKER_BUILD_ARGS) -t "$(TRAEFIK_DEV_IMAGE)" -f build.Dockerfile .
 | 
			
		||||
@@ -104,8 +105,12 @@ docs: docs-image
 | 
			
		||||
docs-build: site
 | 
			
		||||
 | 
			
		||||
docs-verify: site
 | 
			
		||||
	docker build -t $(TRAEFIK_DOC_VERIFY_IMAGE) ./script/docs-verify-docker-image ## Build Validator image
 | 
			
		||||
	docker run --rm -v $(CURDIR):/app $(TRAEFIK_DOC_VERIFY_IMAGE) ## Check for dead links and w3c compliance
 | 
			
		||||
ifeq ($(DOCS_VERIFY_SKIP),false)
 | 
			
		||||
	docker build -t $(TRAEFIK_DOC_VERIFY_IMAGE) ./script/docs-verify-docker-image
 | 
			
		||||
	docker run --rm -v $(CURDIR):/app $(TRAEFIK_DOC_VERIFY_IMAGE)
 | 
			
		||||
else
 | 
			
		||||
	@echo "DOCS_LINT_SKIP is true: no linting done."
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
site: docs-image
 | 
			
		||||
	docker run  $(DOCKER_RUN_DOC_OPTS) $(TRAEFIK_DOC_IMAGE) mkdocs build
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								README.md
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
[](https://semaphoreci.com/containous/traefik)
 | 
			
		||||
[](https://docs.traefik.io)
 | 
			
		||||
[](https://docs.traefik.io/v1.7)
 | 
			
		||||
[](http://goreportcard.com/report/containous/traefik)
 | 
			
		||||
[](https://microbadger.com/images/traefik)
 | 
			
		||||
[](https://github.com/containous/traefik/blob/master/LICENSE.md)
 | 
			
		||||
@@ -70,22 +70,22 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t
 | 
			
		||||
 | 
			
		||||
## Supported Backends
 | 
			
		||||
 | 
			
		||||
- [Docker](https://docs.traefik.io/configuration/backends/docker) / [Swarm mode](https://docs.traefik.io/configuration/backends/docker#docker-swarm-mode)
 | 
			
		||||
- [Kubernetes](https://docs.traefik.io/configuration/backends/kubernetes)
 | 
			
		||||
- [Mesos](https://docs.traefik.io/configuration/backends/mesos) / [Marathon](https://docs.traefik.io/configuration/backends/marathon)
 | 
			
		||||
- [Rancher](https://docs.traefik.io/configuration/backends/rancher) (API, Metadata)
 | 
			
		||||
- [Azure Service Fabric](https://docs.traefik.io/configuration/backends/servicefabric)
 | 
			
		||||
- [Consul Catalog](https://docs.traefik.io/configuration/backends/consulcatalog)
 | 
			
		||||
- [Consul](https://docs.traefik.io/configuration/backends/consul) / [Etcd](https://docs.traefik.io/configuration/backends/etcd) / [Zookeeper](https://docs.traefik.io/configuration/backends/zookeeper) / [BoltDB](https://docs.traefik.io/configuration/backends/boltdb)
 | 
			
		||||
- [Eureka](https://docs.traefik.io/configuration/backends/eureka)
 | 
			
		||||
- [Amazon ECS](https://docs.traefik.io/configuration/backends/ecs)
 | 
			
		||||
- [Amazon DynamoDB](https://docs.traefik.io/configuration/backends/dynamodb)
 | 
			
		||||
- [File](https://docs.traefik.io/configuration/backends/file)
 | 
			
		||||
- [Rest](https://docs.traefik.io/configuration/backends/rest)
 | 
			
		||||
- [Docker](https://docs.traefik.io/v1.7/configuration/backends/docker) / [Swarm mode](https://docs.traefik.io/v1.7/configuration/backends/docker#docker-swarm-mode)
 | 
			
		||||
- [Kubernetes](https://docs.traefik.io/v1.7/configuration/backends/kubernetes)
 | 
			
		||||
- [Mesos](https://docs.traefik.io/v1.7/configuration/backends/mesos) / [Marathon](https://docs.traefik.io/v1.7/configuration/backends/marathon)
 | 
			
		||||
- [Rancher](https://docs.traefik.io/v1.7/configuration/backends/rancher) (API, Metadata)
 | 
			
		||||
- [Azure Service Fabric](https://docs.traefik.io/v1.7/configuration/backends/servicefabric)
 | 
			
		||||
- [Consul Catalog](https://docs.traefik.io/v1.7/configuration/backends/consulcatalog)
 | 
			
		||||
- [Consul](https://docs.traefik.io/v1.7/configuration/backends/consul) / [Etcd](https://docs.traefik.io/v1.7/configuration/backends/etcd) / [Zookeeper](https://docs.traefik.io/v1.7/configuration/backends/zookeeper) / [BoltDB](https://docs.traefik.io/v1.7/configuration/backends/boltdb)
 | 
			
		||||
- [Eureka](https://docs.traefik.io/v1.7/configuration/backends/eureka)
 | 
			
		||||
- [Amazon ECS](https://docs.traefik.io/v1.7/configuration/backends/ecs)
 | 
			
		||||
- [Amazon DynamoDB](https://docs.traefik.io/v1.7/configuration/backends/dynamodb)
 | 
			
		||||
- [File](https://docs.traefik.io/v1.7/configuration/backends/file)
 | 
			
		||||
- [Rest](https://docs.traefik.io/v1.7/configuration/backends/rest)
 | 
			
		||||
 | 
			
		||||
## Quickstart
 | 
			
		||||
 | 
			
		||||
To get your hands on Traefik, you can use the [5-Minute Quickstart](http://docs.traefik.io/#the-traefik-quickstart-using-docker) in our documentation (you will need Docker).
 | 
			
		||||
To get your hands on Traefik, you can use the [5-Minute Quickstart](http://docs.traefik.io/v1.7/#the-traefik-quickstart-using-docker) in our documentation (you will need Docker).
 | 
			
		||||
 | 
			
		||||
Alternatively, if you don't want to install anything on your computer, you can try Traefik online in this great [Katacoda tutorial](https://www.katacoda.com/courses/traefik/deploy-load-balancer) that shows how to load balance requests between multiple Docker containers. 
 | 
			
		||||
 | 
			
		||||
@@ -100,7 +100,7 @@ You can access the simple HTML frontend of Traefik.
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
You can find the complete documentation at [https://docs.traefik.io](https://docs.traefik.io).
 | 
			
		||||
You can find the complete documentation at [https://docs.traefik.io/v1.7](https://docs.traefik.io/v1.7).
 | 
			
		||||
A collection of contributions around Traefik can be found at [https://awesome.traefik.io](https://awesome.traefik.io).
 | 
			
		||||
 | 
			
		||||
## Support
 | 
			
		||||
@@ -113,13 +113,13 @@ If you need commercial support, please contact [Containo.us](https://containo.us
 | 
			
		||||
 | 
			
		||||
## Download
 | 
			
		||||
 | 
			
		||||
- Grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
 | 
			
		||||
- Grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v1.7/traefik.sample.toml):
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
./traefik --configFile=traefik.toml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Or use the official tiny Docker image and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
 | 
			
		||||
- Or use the official tiny Docker image and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v1.7/traefik.sample.toml):
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
 | 
			
		||||
@@ -133,7 +133,7 @@ git clone https://github.com/containous/traefik
 | 
			
		||||
 | 
			
		||||
## Introductory Videos
 | 
			
		||||
 | 
			
		||||
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at [GopherCon 2017](https://gophercon.com/).
 | 
			
		||||
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at GopherCon 2017.
 | 
			
		||||
You will learn Traefik basics in less than 10 minutes.
 | 
			
		||||
 | 
			
		||||
[](https://www.youtube.com/watch?v=RgudiksfL-k)
 | 
			
		||||
 
 | 
			
		||||
@@ -17,15 +17,16 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
	acmeprovider "github.com/containous/traefik/provider/acme"
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/xenolf/lego/acme"
 | 
			
		||||
	"github.com/go-acme/lego/certcrypto"
 | 
			
		||||
	"github.com/go-acme/lego/registration"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Account is used to store lets encrypt registration info
 | 
			
		||||
type Account struct {
 | 
			
		||||
	Email              string
 | 
			
		||||
	Registration       *acme.RegistrationResource
 | 
			
		||||
	Registration       *registration.Resource
 | 
			
		||||
	PrivateKey         []byte
 | 
			
		||||
	KeyType            acme.KeyType
 | 
			
		||||
	KeyType            certcrypto.KeyType
 | 
			
		||||
	DomainsCertificate DomainsCertificates
 | 
			
		||||
	ChallengeCerts     map[string]*ChallengeCert
 | 
			
		||||
	HTTPChallenge      map[string]map[string][]byte
 | 
			
		||||
@@ -100,7 +101,7 @@ func (a *Account) GetEmail() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetRegistration returns lets encrypt registration resource
 | 
			
		||||
func (a *Account) GetRegistration() *acme.RegistrationResource {
 | 
			
		||||
func (a *Account) GetRegistration() *registration.Resource {
 | 
			
		||||
	return a.Registration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										106
									
								
								acme/acme.go
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								acme/acme.go
									
									
									
									
									
								
							@@ -27,14 +27,19 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/containous/traefik/version"
 | 
			
		||||
	"github.com/eapache/channels"
 | 
			
		||||
	"github.com/go-acme/lego/certificate"
 | 
			
		||||
	"github.com/go-acme/lego/challenge"
 | 
			
		||||
	"github.com/go-acme/lego/challenge/dns01"
 | 
			
		||||
	"github.com/go-acme/lego/challenge/http01"
 | 
			
		||||
	"github.com/go-acme/lego/lego"
 | 
			
		||||
	legolog "github.com/go-acme/lego/log"
 | 
			
		||||
	"github.com/go-acme/lego/providers/dns"
 | 
			
		||||
	"github.com/go-acme/lego/registration"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"github.com/xenolf/lego/acme"
 | 
			
		||||
	legolog "github.com/xenolf/lego/log"
 | 
			
		||||
	"github.com/xenolf/lego/providers/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// OSCPMustStaple enables OSCP stapling as from https://github.com/xenolf/lego/issues/270
 | 
			
		||||
	// OSCPMustStaple enables OSCP stapling as from https://github.com/go-acme/lego/issues/270
 | 
			
		||||
	OSCPMustStaple = false
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -57,7 +62,7 @@ type ACME struct {
 | 
			
		||||
	DelayDontCheckDNS     flaeg.Duration              `description:"(Deprecated) Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` // Deprecated
 | 
			
		||||
	ACMELogging           bool                        `description:"Enable debug logging of ACME actions."`
 | 
			
		||||
	OverrideCertificates  bool                        `description:"Enable to override certificates in key-value store when using storeconfig"`
 | 
			
		||||
	client                *acme.Client
 | 
			
		||||
	client                *lego.Client
 | 
			
		||||
	store                 cluster.Store
 | 
			
		||||
	challengeHTTPProvider *challengeHTTPProvider
 | 
			
		||||
	challengeTLSProvider  *challengeTLSProvider
 | 
			
		||||
@@ -70,8 +75,6 @@ type ACME struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *ACME) init() error {
 | 
			
		||||
	acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
 | 
			
		||||
 | 
			
		||||
	if a.ACMELogging {
 | 
			
		||||
		legolog.Logger = fmtlog.New(log.WriterLevel(logrus.InfoLevel), "legolog: ", 0)
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -89,7 +92,7 @@ func (a *ACME) init() error {
 | 
			
		||||
// AddRoutes add routes on internal router
 | 
			
		||||
func (a *ACME) AddRoutes(router *mux.Router) {
 | 
			
		||||
	router.Methods(http.MethodGet).
 | 
			
		||||
		Path(acme.HTTP01ChallengePath("{token}")).
 | 
			
		||||
		Path(http01.ChallengePath("{token}")).
 | 
			
		||||
		Handler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
 | 
			
		||||
			if a.challengeHTTPProvider == nil {
 | 
			
		||||
				rw.WriteHeader(http.StatusNotFound)
 | 
			
		||||
@@ -222,7 +225,7 @@ func (a *ACME) leadershipListener(elected bool) error {
 | 
			
		||||
			// New users will need to register; be sure to save it
 | 
			
		||||
			log.Debug("Register...")
 | 
			
		||||
 | 
			
		||||
			reg, err := a.client.Register(true)
 | 
			
		||||
			reg, err := a.client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
@@ -367,7 +370,7 @@ func (a *ACME) renewCertificates() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *ACME) renewACMECertificate(certificateResource *DomainsCertificate) (*Certificate, error) {
 | 
			
		||||
	renewedCert, err := a.client.RenewCertificate(acme.CertificateResource{
 | 
			
		||||
	renewedCert, err := a.client.Certificate.Renew(certificate.Resource{
 | 
			
		||||
		Domain:        certificateResource.Certificate.Domain,
 | 
			
		||||
		CertURL:       certificateResource.Certificate.CertURL,
 | 
			
		||||
		CertStableURL: certificateResource.Certificate.CertStableURL,
 | 
			
		||||
@@ -416,28 +419,19 @@ func (a *ACME) storeRenewedCertificate(certificateResource *DomainsCertificate,
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dnsOverrideDelay(delay flaeg.Duration) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	if delay > 0 {
 | 
			
		||||
		log.Debugf("Delaying %d rather than validating DNS propagation", delay)
 | 
			
		||||
		acme.PreCheckDNS = func(_, _ string) (bool, error) {
 | 
			
		||||
			time.Sleep(time.Duration(delay))
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
	} else if delay < 0 {
 | 
			
		||||
		err = fmt.Errorf("invalid negative DelayBeforeCheck: %d", delay)
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
 | 
			
		||||
func (a *ACME) buildACMEClient(account *Account) (*lego.Client, error) {
 | 
			
		||||
	log.Debug("Building ACME client...")
 | 
			
		||||
	caServer := "https://acme-v02.api.letsencrypt.org/directory"
 | 
			
		||||
	if len(a.CAServer) > 0 {
 | 
			
		||||
		caServer = a.CAServer
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client, err := acme.NewClient(caServer, account, account.KeyType)
 | 
			
		||||
	config := lego.NewConfig(account)
 | 
			
		||||
	config.CADirURL = caServer
 | 
			
		||||
	config.Certificate.KeyType = account.KeyType
 | 
			
		||||
	config.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
 | 
			
		||||
 | 
			
		||||
	client, err := lego.NewClient(config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -446,22 +440,23 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
 | 
			
		||||
	if a.DNSChallenge != nil && len(a.DNSChallenge.Provider) > 0 {
 | 
			
		||||
		log.Debugf("Using DNS Challenge provider: %s", a.DNSChallenge.Provider)
 | 
			
		||||
 | 
			
		||||
		err = dnsOverrideDelay(a.DNSChallenge.DelayBeforeCheck)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		acmeprovider.SetRecursiveNameServers(a.DNSChallenge.Resolvers)
 | 
			
		||||
		acmeprovider.SetPropagationCheck(a.DNSChallenge.DisablePropagationCheck)
 | 
			
		||||
 | 
			
		||||
		var provider acme.ChallengeProvider
 | 
			
		||||
		var provider challenge.Provider
 | 
			
		||||
		provider, err = dns.NewDNSChallengeProviderByName(a.DNSChallenge.Provider)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSALPN01})
 | 
			
		||||
		err = client.SetChallengeProvider(acme.DNS01, provider)
 | 
			
		||||
		err = client.Challenge.SetDNS01Provider(provider,
 | 
			
		||||
			dns01.CondOption(len(a.DNSChallenge.Resolvers) > 0, dns01.AddRecursiveNameservers(a.DNSChallenge.Resolvers)),
 | 
			
		||||
			dns01.CondOption(a.DNSChallenge.DisablePropagationCheck || a.DNSChallenge.DelayBeforeCheck > 0,
 | 
			
		||||
				dns01.AddPreCheck(func(_, _ string) (bool, error) {
 | 
			
		||||
					if a.DNSChallenge.DelayBeforeCheck > 0 {
 | 
			
		||||
						log.Debugf("Delaying %d rather than validating DNS propagation now.", a.DNSChallenge.DelayBeforeCheck)
 | 
			
		||||
						time.Sleep(time.Duration(a.DNSChallenge.DelayBeforeCheck))
 | 
			
		||||
					}
 | 
			
		||||
					return true, nil
 | 
			
		||||
				})),
 | 
			
		||||
		)
 | 
			
		||||
		return client, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -469,17 +464,16 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
 | 
			
		||||
	if a.HTTPChallenge != nil && len(a.HTTPChallenge.EntryPoint) > 0 {
 | 
			
		||||
		log.Debug("Using HTTP Challenge provider.")
 | 
			
		||||
 | 
			
		||||
		client.ExcludeChallenges([]acme.Challenge{acme.DNS01, acme.TLSALPN01})
 | 
			
		||||
		a.challengeHTTPProvider = &challengeHTTPProvider{store: a.store}
 | 
			
		||||
		err = client.SetChallengeProvider(acme.HTTP01, a.challengeHTTPProvider)
 | 
			
		||||
		err = client.Challenge.SetHTTP01Provider(a.challengeHTTPProvider)
 | 
			
		||||
		return client, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TLS Challenge
 | 
			
		||||
	if a.TLSChallenge != nil {
 | 
			
		||||
		log.Debug("Using TLS Challenge provider.")
 | 
			
		||||
		client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.DNS01})
 | 
			
		||||
		err = client.SetChallengeProvider(acme.TLSALPN01, a.challengeTLSProvider)
 | 
			
		||||
 | 
			
		||||
		err = client.Challenge.SetTLSALPN01Provider(a.challengeTLSProvider)
 | 
			
		||||
		return client, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -551,7 +545,7 @@ func (a *ACME) LoadCertificateForDomains(domains []string) {
 | 
			
		||||
		a.addResolvingDomains(uncheckedDomains)
 | 
			
		||||
		defer a.removeResolvingDomains(uncheckedDomains)
 | 
			
		||||
 | 
			
		||||
		certificate, err := a.getDomainsCertificates(uncheckedDomains)
 | 
			
		||||
		cert, err := a.getDomainsCertificates(uncheckedDomains)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Errorf("Error getting ACME certificates %+v : %v", uncheckedDomains, err)
 | 
			
		||||
			return
 | 
			
		||||
@@ -570,7 +564,7 @@ func (a *ACME) LoadCertificateForDomains(domains []string) {
 | 
			
		||||
			domain = types.Domain{Main: uncheckedDomains[0]}
 | 
			
		||||
		}
 | 
			
		||||
		account = object.(*Account)
 | 
			
		||||
		_, err = account.DomainsCertificate.addCertificateForDomains(certificate, domain)
 | 
			
		||||
		_, err = account.DomainsCertificate.addCertificateForDomains(cert, domain)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Errorf("Error adding ACME certificates %+v : %v", uncheckedDomains, err)
 | 
			
		||||
			return
 | 
			
		||||
@@ -698,7 +692,7 @@ func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) {
 | 
			
		||||
	var cleanDomains []string
 | 
			
		||||
	for _, domain := range domains {
 | 
			
		||||
		canonicalDomain := types.CanonicalDomain(domain)
 | 
			
		||||
		cleanDomain := acme.UnFqdn(canonicalDomain)
 | 
			
		||||
		cleanDomain := dns01.UnFqdn(canonicalDomain)
 | 
			
		||||
		if canonicalDomain != cleanDomain {
 | 
			
		||||
			log.Warnf("FQDN detected, please remove the trailing dot: %s", canonicalDomain)
 | 
			
		||||
		}
 | 
			
		||||
@@ -708,18 +702,24 @@ func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) {
 | 
			
		||||
	log.Debugf("Loading ACME certificates %s...", cleanDomains)
 | 
			
		||||
	bundle := true
 | 
			
		||||
 | 
			
		||||
	certificate, err := a.client.ObtainCertificate(cleanDomains, bundle, nil, OSCPMustStaple)
 | 
			
		||||
	request := certificate.ObtainRequest{
 | 
			
		||||
		Domains:    cleanDomains,
 | 
			
		||||
		Bundle:     bundle,
 | 
			
		||||
		MustStaple: OSCPMustStaple,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cert, err := a.client.Certificate.Obtain(request)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("cannot obtain certificates: %+v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log.Debugf("Loaded ACME certificates %s", cleanDomains)
 | 
			
		||||
	return &Certificate{
 | 
			
		||||
		Domain:        certificate.Domain,
 | 
			
		||||
		CertURL:       certificate.CertURL,
 | 
			
		||||
		CertStableURL: certificate.CertStableURL,
 | 
			
		||||
		PrivateKey:    certificate.PrivateKey,
 | 
			
		||||
		Certificate:   certificate.Certificate,
 | 
			
		||||
		Domain:        cert.Domain,
 | 
			
		||||
		CertURL:       cert.CertURL,
 | 
			
		||||
		CertStableURL: cert.CertStableURL,
 | 
			
		||||
		PrivateKey:    cert.PrivateKey,
 | 
			
		||||
		Certificate:   cert.Certificate,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -751,12 +751,6 @@ func (a *ACME) getValidDomains(domains []string, wildcardAllowed bool) ([]string
 | 
			
		||||
			return nil, fmt.Errorf("unable to generate a wildcard certificate for domain %q : ACME does not allow '*.*' wildcard domain", strings.Join(domains, ","))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, san := range domains[1:] {
 | 
			
		||||
		if strings.HasPrefix(san, "*") {
 | 
			
		||||
			return nil, fmt.Errorf("unable to generate a certificate for domains %q: SANs can not be a wildcard domain", strings.Join(domains, ","))
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	domains = fun.Map(types.CanonicalDomain, domains).([]string)
 | 
			
		||||
	return domains, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/tls/generate"
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
	"github.com/xenolf/lego/acme"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestDomainsSet(t *testing.T) {
 | 
			
		||||
@@ -258,39 +257,10 @@ func TestRemoveDuplicates(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNoPreCheckOverride(t *testing.T) {
 | 
			
		||||
	acme.PreCheckDNS = nil // Irreversable - but not expecting real calls into this during testing process
 | 
			
		||||
	err := dnsOverrideDelay(0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("Error in dnsOverrideDelay :%v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if acme.PreCheckDNS != nil {
 | 
			
		||||
		t.Error("Unexpected change to acme.PreCheckDNS when leaving DNS verification as is.")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSillyPreCheckOverride(t *testing.T) {
 | 
			
		||||
	err := dnsOverrideDelay(-5)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Error("Missing expected error in dnsOverrideDelay!")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPreCheckOverride(t *testing.T) {
 | 
			
		||||
	acme.PreCheckDNS = nil // Irreversable - but not expecting real calls into this during testing process
 | 
			
		||||
	err := dnsOverrideDelay(5)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("Error in dnsOverrideDelay :%v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if acme.PreCheckDNS == nil {
 | 
			
		||||
		t.Error("No change to acme.PreCheckDNS when meant to be adding enforcing override function.")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestAcmeClientCreation(t *testing.T) {
 | 
			
		||||
	acme.PreCheckDNS = nil // Irreversable - but not expecting real calls into this during testing process
 | 
			
		||||
	// Lengthy setup to avoid external web requests - oh for easier golang testing!
 | 
			
		||||
	account := &Account{Email: "f@f"}
 | 
			
		||||
 | 
			
		||||
	account.PrivateKey, _ = base64.StdEncoding.DecodeString(`
 | 
			
		||||
MIIBPAIBAAJBAMp2Ni92FfEur+CAvFkgC12LT4l9D53ApbBpDaXaJkzzks+KsLw9zyAxvlrfAyTCQ
 | 
			
		||||
7tDnEnIltAXyQ0uOFUUdcMCAwEAAQJAK1FbipATZcT9cGVa5x7KD7usytftLW14heQUPXYNV80r/3
 | 
			
		||||
@@ -298,8 +268,9 @@ lmnpvjL06dffRpwkYeN8DATQF/QOcy3NNNGDw/4QIhAPAKmiZFxA/qmRXsuU8Zhlzf16WrNZ68K64
 | 
			
		||||
asn/h3qZrAiEA1+wFR3WXCPIolOvd7AHjfgcTKQNkoMPywU4FYUNQ1AkCIQDv8yk0qPjckD6HVCPJ
 | 
			
		||||
llJh9MC0svjevGtNlxJoE3lmEQIhAKXy1wfZ32/XtcrnENPvi6lzxI0T94X7s5pP3aCoPPoJAiEAl
 | 
			
		||||
cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
 | 
			
		||||
 | 
			
		||||
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		w.Write([]byte(`{
 | 
			
		||||
		_, err := w.Write([]byte(`{
 | 
			
		||||
  "GPHhmRVEDas": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
 | 
			
		||||
  "keyChange": "https://foo/acme/key-change",
 | 
			
		||||
  "meta": {
 | 
			
		||||
@@ -310,9 +281,20 @@ cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
 | 
			
		||||
  "newOrder": "https://foo/acme/new-order",
 | 
			
		||||
  "revokeCert": "https://foo/acme/revoke-cert"
 | 
			
		||||
}`))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
		}
 | 
			
		||||
	}))
 | 
			
		||||
	defer ts.Close()
 | 
			
		||||
	a := ACME{DNSChallenge: &acmeprovider.DNSChallenge{Provider: "manual", DelayBeforeCheck: 10}, CAServer: ts.URL}
 | 
			
		||||
 | 
			
		||||
	a := ACME{
 | 
			
		||||
		CAServer: ts.URL,
 | 
			
		||||
		DNSChallenge: &acmeprovider.DNSChallenge{
 | 
			
		||||
			Provider:                "manual",
 | 
			
		||||
			DelayBeforeCheck:        10,
 | 
			
		||||
			DisablePropagationCheck: true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client, err := a.buildACMEClient(account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -321,9 +303,6 @@ cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
 | 
			
		||||
	if client == nil {
 | 
			
		||||
		t.Error("No client from buildACMEClient!")
 | 
			
		||||
	}
 | 
			
		||||
	if acme.PreCheckDNS == nil {
 | 
			
		||||
		t.Error("No change to acme.PreCheckDNS when meant to be adding enforcing override function.")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestAcme_getUncheckedCertificates(t *testing.T) {
 | 
			
		||||
@@ -440,12 +419,12 @@ func TestAcme_getValidDomain(t *testing.T) {
 | 
			
		||||
			expectedDomains: []string{"*.traefik.wtf", "traefik.wtf"},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:            "unexpected SANs",
 | 
			
		||||
			desc:            "wildcard SANs",
 | 
			
		||||
			domains:         []string{"*.traefik.wtf", "*.acme.wtf"},
 | 
			
		||||
			dnsChallenge:    &acmeprovider.DNSChallenge{},
 | 
			
		||||
			wildcardAllowed: true,
 | 
			
		||||
			expectedErr:     "unable to generate a certificate for domains \"*.traefik.wtf,*.acme.wtf\": SANs can not be a wildcard domain",
 | 
			
		||||
			expectedDomains: nil,
 | 
			
		||||
			expectedErr:     "",
 | 
			
		||||
			expectedDomains: []string{"*.traefik.wtf", "*.acme.wtf"},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, test := range testCases {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,10 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/cluster"
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
	"github.com/containous/traefik/safe"
 | 
			
		||||
	"github.com/xenolf/lego/acme"
 | 
			
		||||
	"github.com/go-acme/lego/challenge"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ acme.ChallengeProviderTimeout = (*challengeHTTPProvider)(nil)
 | 
			
		||||
var _ challenge.ProviderTimeout = (*challengeHTTPProvider)(nil)
 | 
			
		||||
 | 
			
		||||
type challengeHTTPProvider struct {
 | 
			
		||||
	store cluster.Store
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,11 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/cluster"
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
	"github.com/containous/traefik/safe"
 | 
			
		||||
	"github.com/xenolf/lego/acme"
 | 
			
		||||
	"github.com/go-acme/lego/challenge"
 | 
			
		||||
	"github.com/go-acme/lego/challenge/tlsalpn01"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ acme.ChallengeProviderTimeout = (*challengeTLSProvider)(nil)
 | 
			
		||||
var _ challenge.ProviderTimeout = (*challengeTLSProvider)(nil)
 | 
			
		||||
 | 
			
		||||
type challengeTLSProvider struct {
 | 
			
		||||
	store cluster.Store
 | 
			
		||||
@@ -113,7 +114,7 @@ func (c *challengeTLSProvider) Timeout() (timeout, interval time.Duration) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func tlsALPN01ChallengeCert(domain, keyAuth string) (*ChallengeCert, error) {
 | 
			
		||||
	tempCertPEM, rsaPrivPEM, err := acme.TLSALPNChallengeBlocks(domain, keyAuth)
 | 
			
		||||
	tempCertPEM, rsaPrivPEM, err := tlsalpn01.ChallengeBlocks(domain, keyAuth)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/safe"
 | 
			
		||||
	traefiktls "github.com/containous/traefik/tls"
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	assetfs "github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	"github.com/thoas/stats"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/containous/mux"
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
	"github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	assetfs "github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DashboardHandler expose dashboard routes
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/safe"
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/containous/traefik/version"
 | 
			
		||||
	"github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	assetfs "github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	thoas_stats "github.com/thoas/stats"
 | 
			
		||||
	"github.com/unrolled/render"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -236,6 +236,18 @@ var _templatesConsul_catalogTmpl = []byte(`[backends]
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Subject }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."frontend-{{ $service.ServiceName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -719,6 +731,18 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Issuer }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -1055,6 +1079,18 @@ var _templatesEcsTmpl = []byte(`[backends]
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Issuer }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -1280,7 +1316,7 @@ var _templatesKubernetesTmpl = []byte(`[backends]
 | 
			
		||||
 | 
			
		||||
    {{if $backend.ResponseForwarding }}
 | 
			
		||||
    [backends."{{ $backendName }}".responseForwarding]
 | 
			
		||||
      flushInterval = "{{ $backend.responseForwarding.FlushInterval }}"
 | 
			
		||||
      flushInterval = "{{ $backend.ResponseForwarding.FlushInterval }}"
 | 
			
		||||
    {{end}}
 | 
			
		||||
 | 
			
		||||
    [backends."{{ $backendName }}".loadBalancer]
 | 
			
		||||
@@ -1329,7 +1365,9 @@ var _templatesKubernetesTmpl = []byte(`[backends]
 | 
			
		||||
 | 
			
		||||
    {{if $frontend.Auth }}
 | 
			
		||||
    [frontends."{{ $frontendName }}".auth]
 | 
			
		||||
      headerField = "X-WebAuth-User"
 | 
			
		||||
      {{if $frontend.Auth.HeaderField }}
 | 
			
		||||
      headerField = "{{ $frontend.Auth.HeaderField }}"
 | 
			
		||||
      {{end}}
 | 
			
		||||
 | 
			
		||||
      {{if $frontend.Auth.Basic }}
 | 
			
		||||
      [frontends."{{ $frontendName }}".auth.basic]
 | 
			
		||||
@@ -1422,6 +1460,18 @@ var _templatesKubernetesTmpl = []byte(`[backends]
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Subject }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -1609,6 +1659,18 @@ var _templatesKvTmpl = []byte(`[backends]
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Subject }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -1985,6 +2047,18 @@ var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }}
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Subject }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -2305,6 +2379,18 @@ var _templatesMesosTmpl = []byte(`[backends]
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Subject }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
@@ -2678,6 +2764,18 @@ var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }}
 | 
			
		||||
          organization = {{ $subject.Organization }}
 | 
			
		||||
          commonName = {{ $subject.CommonName }}
 | 
			
		||||
          serialNumber = {{ $subject.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $subject.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
        {{ $issuer := $infos.Subject }}
 | 
			
		||||
        {{if $issuer }}
 | 
			
		||||
        [frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
 | 
			
		||||
          country = {{ $issuer.Country }}
 | 
			
		||||
          province = {{ $issuer.Province }}
 | 
			
		||||
          locality = {{ $issuer.Locality }}
 | 
			
		||||
          organization = {{ $issuer.Organization }}
 | 
			
		||||
          commonName = {{ $issuer.CommonName }}
 | 
			
		||||
          serialNumber = {{ $issuer.SerialNumber }}
 | 
			
		||||
          domainComponent = {{ $issuer.DomainComponent }}
 | 
			
		||||
        {{end}}
 | 
			
		||||
      {{end}}
 | 
			
		||||
    {{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,21 @@
 | 
			
		||||
FROM golang:1.11-alpine
 | 
			
		||||
FROM golang:1.12-alpine
 | 
			
		||||
 | 
			
		||||
RUN apk --update upgrade \
 | 
			
		||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar \
 | 
			
		||||
&& rm -rf /var/cache/apk/*
 | 
			
		||||
    && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
 | 
			
		||||
    && update-ca-certificates \
 | 
			
		||||
    && rm -rf /var/cache/apk/*
 | 
			
		||||
 | 
			
		||||
RUN go get github.com/containous/go-bindata/... \
 | 
			
		||||
&& go get golang.org/x/lint/golint \
 | 
			
		||||
&& go get github.com/kisielk/errcheck \
 | 
			
		||||
RUN go get golang.org/x/lint/golint \
 | 
			
		||||
&& go get github.com/client9/misspell/cmd/misspell
 | 
			
		||||
 | 
			
		||||
# Which docker version to test on
 | 
			
		||||
ARG DOCKER_VERSION=17.03.2
 | 
			
		||||
ARG DEP_VERSION=0.4.1
 | 
			
		||||
ARG DOCKER_VERSION=18.09.7
 | 
			
		||||
ARG DEP_VERSION=0.5.1
 | 
			
		||||
 | 
			
		||||
# Download go-bindata binary to bin folder in $GOPATH
 | 
			
		||||
RUN mkdir -p /usr/local/bin \
 | 
			
		||||
    && curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \
 | 
			
		||||
    && chmod +x /usr/local/bin/go-bindata
 | 
			
		||||
 | 
			
		||||
# Download dep binary to bin folder in $GOPATH
 | 
			
		||||
RUN mkdir -p /usr/local/bin \
 | 
			
		||||
@@ -20,7 +24,7 @@ RUN mkdir -p /usr/local/bin \
 | 
			
		||||
 | 
			
		||||
# Download docker
 | 
			
		||||
RUN mkdir -p /usr/local/bin \
 | 
			
		||||
    && curl -fL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}-ce.tgz \
 | 
			
		||||
    && curl -fL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz \
 | 
			
		||||
    | tar -xzC /usr/local/bin --transform 's#^.+/##x'
 | 
			
		||||
 | 
			
		||||
WORKDIR /go/src/github.com/containous/traefik
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/job"
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
	"github.com/containous/traefik/safe"
 | 
			
		||||
	"github.com/satori/go.uuid"
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Metadata stores Object plus metadata
 | 
			
		||||
@@ -125,7 +125,7 @@ func (d *Datastore) reload() error {
 | 
			
		||||
 | 
			
		||||
// Begin creates a transaction with the KV store.
 | 
			
		||||
func (d *Datastore) Begin() (Transaction, Object, error) {
 | 
			
		||||
	id := uuid.NewV4().String()
 | 
			
		||||
	id := uuid.New().String()
 | 
			
		||||
	log.Debugf("Transaction %s begins", id)
 | 
			
		||||
	remoteLock, err := d.kv.NewLock(d.lockKey, &store.LockOptions{TTL: 20 * time.Second, Value: []byte(id)})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/containous/flaeg"
 | 
			
		||||
	"github.com/containous/traefik-extra-service-fabric"
 | 
			
		||||
	servicefabric "github.com/containous/traefik-extra-service-fabric"
 | 
			
		||||
	"github.com/containous/traefik/api"
 | 
			
		||||
	"github.com/containous/traefik/configuration"
 | 
			
		||||
	"github.com/containous/traefik/middlewares/accesslog"
 | 
			
		||||
@@ -46,6 +46,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
 | 
			
		||||
	defaultDocker.ExposedByDefault = true
 | 
			
		||||
	defaultDocker.Endpoint = "unix:///var/run/docker.sock"
 | 
			
		||||
	defaultDocker.SwarmMode = false
 | 
			
		||||
	defaultDocker.SwarmModeRefreshSeconds = 15
 | 
			
		||||
 | 
			
		||||
	// default File
 | 
			
		||||
	var defaultFile file.Provider
 | 
			
		||||
@@ -110,6 +111,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
 | 
			
		||||
	defaultConsulCatalog.Prefix = "traefik"
 | 
			
		||||
	defaultConsulCatalog.FrontEndRule = "Host:{{.ServiceName}}.{{.Domain}}"
 | 
			
		||||
	defaultConsulCatalog.Stale = false
 | 
			
		||||
	defaultConsulCatalog.StrictChecks = true
 | 
			
		||||
 | 
			
		||||
	// default Etcd
 | 
			
		||||
	var defaultEtcd etcd.Provider
 | 
			
		||||
@@ -223,10 +225,11 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
 | 
			
		||||
		ServiceName:   "traefik",
 | 
			
		||||
		SpanNameLimit: 0,
 | 
			
		||||
		Jaeger: &jaeger.Config{
 | 
			
		||||
			SamplingServerURL:  "http://localhost:5778/sampling",
 | 
			
		||||
			SamplingType:       "const",
 | 
			
		||||
			SamplingParam:      1.0,
 | 
			
		||||
			LocalAgentHostPort: "127.0.0.1:6831",
 | 
			
		||||
			SamplingServerURL:      "http://localhost:5778/sampling",
 | 
			
		||||
			SamplingType:           "const",
 | 
			
		||||
			SamplingParam:          1.0,
 | 
			
		||||
			LocalAgentHostPort:     "127.0.0.1:6831",
 | 
			
		||||
			TraceContextHeaderName: "uber-trace-id",
 | 
			
		||||
		},
 | 
			
		||||
		Zipkin: &zipkin.Config{
 | 
			
		||||
			HTTPEndpoint: "http://localhost:9411/api/v1/spans",
 | 
			
		||||
@@ -238,6 +241,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
 | 
			
		||||
			LocalAgentHostPort: "localhost:8126",
 | 
			
		||||
			GlobalTag:          "",
 | 
			
		||||
			Debug:              false,
 | 
			
		||||
			PrioritySampling:   false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/containous/traefik/version"
 | 
			
		||||
	"github.com/coreos/go-systemd/daemon"
 | 
			
		||||
	"github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	assetfs "github.com/elazarl/go-bindata-assetfs"
 | 
			
		||||
	"github.com/ogier/pflag"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"github.com/vulcand/oxy/roundrobin"
 | 
			
		||||
@@ -352,14 +352,14 @@ func stats(globalConfiguration *configuration.GlobalConfiguration) {
 | 
			
		||||
Stats collection is enabled.
 | 
			
		||||
Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.
 | 
			
		||||
Help us improve Traefik by leaving this feature on :)
 | 
			
		||||
More details on: https://docs.traefik.io/basics/#collected-data
 | 
			
		||||
More details on: https://docs.traefik.io/v1.7/basics/#collected-data
 | 
			
		||||
`)
 | 
			
		||||
		collect(globalConfiguration)
 | 
			
		||||
	} else {
 | 
			
		||||
		log.Info(`
 | 
			
		||||
Stats collection is disabled.
 | 
			
		||||
Help us improve Traefik by turning this feature on :)
 | 
			
		||||
More details on: https://docs.traefik.io/basics/#collected-data
 | 
			
		||||
More details on: https://docs.traefik.io/v1.7/basics/#collected-data
 | 
			
		||||
`)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/containous/flaeg"
 | 
			
		||||
	"github.com/containous/traefik-extra-service-fabric"
 | 
			
		||||
	servicefabric "github.com/containous/traefik-extra-service-fabric"
 | 
			
		||||
	"github.com/containous/traefik/acme"
 | 
			
		||||
	"github.com/containous/traefik/api"
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
@@ -33,8 +33,9 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/provider/zk"
 | 
			
		||||
	"github.com/containous/traefik/tls"
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/go-acme/lego/challenge/dns01"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	lego "github.com/xenolf/lego/acme"
 | 
			
		||||
	jaegercli "github.com/uber/jaeger-client-go"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -211,6 +212,12 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Thanks to SSLv3 being enabled by mistake in golang 1.12,
 | 
			
		||||
		// If no minVersion is set, apply TLS1.0 as the minimum.
 | 
			
		||||
		if entryPoint.TLS != nil && len(entryPoint.TLS.MinVersion) == 0 {
 | 
			
		||||
			entryPoint.TLS.MinVersion = "VersionTLS10"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if entryPoint.TLS != nil && entryPoint.TLS.DefaultCertificate == nil && len(entryPoint.TLS.Certificates) > 0 {
 | 
			
		||||
			log.Infof("No tls.defaultCertificate given for %s: using the first item in tls.certificates as a fallback.", entryPointName)
 | 
			
		||||
			entryPoint.TLS.DefaultCertificate = &entryPoint.TLS.Certificates[0]
 | 
			
		||||
@@ -235,6 +242,10 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
 | 
			
		||||
		} else {
 | 
			
		||||
			gc.Docker.TemplateVersion = 2
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if gc.Docker.SwarmModeRefreshSeconds <= 0 {
 | 
			
		||||
			gc.Docker.SwarmModeRefreshSeconds = 15
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if gc.Marathon != nil {
 | 
			
		||||
@@ -331,10 +342,11 @@ func (gc *GlobalConfiguration) initTracing() {
 | 
			
		||||
		case jaeger.Name:
 | 
			
		||||
			if gc.Tracing.Jaeger == nil {
 | 
			
		||||
				gc.Tracing.Jaeger = &jaeger.Config{
 | 
			
		||||
					SamplingServerURL:  "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:       "const",
 | 
			
		||||
					SamplingParam:      1.0,
 | 
			
		||||
					LocalAgentHostPort: "127.0.0.1:6831",
 | 
			
		||||
					SamplingServerURL:      "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:           "const",
 | 
			
		||||
					SamplingParam:          1.0,
 | 
			
		||||
					LocalAgentHostPort:     "127.0.0.1:6831",
 | 
			
		||||
					TraceContextHeaderName: jaegercli.TraceContextHeaderName,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if gc.Tracing.Zipkin != nil {
 | 
			
		||||
@@ -368,6 +380,7 @@ func (gc *GlobalConfiguration) initTracing() {
 | 
			
		||||
					LocalAgentHostPort: "localhost:8126",
 | 
			
		||||
					GlobalTag:          "",
 | 
			
		||||
					Debug:              false,
 | 
			
		||||
					PrioritySampling:   false,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if gc.Tracing.Zipkin != nil {
 | 
			
		||||
@@ -405,11 +418,11 @@ func (gc *GlobalConfiguration) initACMEProvider() {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, domain := range gc.ACME.Domains {
 | 
			
		||||
			if domain.Main != lego.UnFqdn(domain.Main) {
 | 
			
		||||
			if domain.Main != dns01.UnFqdn(domain.Main) {
 | 
			
		||||
				log.Warnf("FQDN detected, please remove the trailing dot: %s", domain.Main)
 | 
			
		||||
			}
 | 
			
		||||
			for _, san := range domain.SANs {
 | 
			
		||||
				if san != lego.UnFqdn(san) {
 | 
			
		||||
				if san != dns01.UnFqdn(san) {
 | 
			
		||||
					log.Warnf("FQDN detected, please remove the trailing dot: %s", san)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/provider"
 | 
			
		||||
	acmeprovider "github.com/containous/traefik/provider/acme"
 | 
			
		||||
	"github.com/containous/traefik/provider/file"
 | 
			
		||||
	"github.com/containous/traefik/tls"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -142,10 +143,11 @@ func TestSetEffectiveConfigurationTracing(t *testing.T) {
 | 
			
		||||
			expected: &tracing.Tracing{
 | 
			
		||||
				Backend: "jaeger",
 | 
			
		||||
				Jaeger: &jaeger.Config{
 | 
			
		||||
					SamplingServerURL:  "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:       "const",
 | 
			
		||||
					SamplingParam:      1.0,
 | 
			
		||||
					LocalAgentHostPort: "127.0.0.1:6831",
 | 
			
		||||
					SamplingServerURL:      "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:           "const",
 | 
			
		||||
					SamplingParam:          1.0,
 | 
			
		||||
					LocalAgentHostPort:     "127.0.0.1:6831",
 | 
			
		||||
					TraceContextHeaderName: "uber-trace-id",
 | 
			
		||||
				},
 | 
			
		||||
				Zipkin: nil,
 | 
			
		||||
			},
 | 
			
		||||
@@ -155,10 +157,11 @@ func TestSetEffectiveConfigurationTracing(t *testing.T) {
 | 
			
		||||
			tracing: &tracing.Tracing{
 | 
			
		||||
				Backend: "zipkin",
 | 
			
		||||
				Jaeger: &jaeger.Config{
 | 
			
		||||
					SamplingServerURL:  "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:       "const",
 | 
			
		||||
					SamplingParam:      1.0,
 | 
			
		||||
					LocalAgentHostPort: "127.0.0.1:6831",
 | 
			
		||||
					SamplingServerURL:      "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:           "const",
 | 
			
		||||
					SamplingParam:          1.0,
 | 
			
		||||
					LocalAgentHostPort:     "127.0.0.1:6831",
 | 
			
		||||
					TraceContextHeaderName: "uber-trace-id",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expected: &tracing.Tracing{
 | 
			
		||||
@@ -177,10 +180,11 @@ func TestSetEffectiveConfigurationTracing(t *testing.T) {
 | 
			
		||||
			tracing: &tracing.Tracing{
 | 
			
		||||
				Backend: "zipkin",
 | 
			
		||||
				Jaeger: &jaeger.Config{
 | 
			
		||||
					SamplingServerURL:  "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:       "const",
 | 
			
		||||
					SamplingParam:      1.0,
 | 
			
		||||
					LocalAgentHostPort: "127.0.0.1:6831",
 | 
			
		||||
					SamplingServerURL:      "http://localhost:5778/sampling",
 | 
			
		||||
					SamplingType:           "const",
 | 
			
		||||
					SamplingParam:          1.0,
 | 
			
		||||
					LocalAgentHostPort:     "127.0.0.1:6831",
 | 
			
		||||
					TraceContextHeaderName: "uber-trace-id",
 | 
			
		||||
				},
 | 
			
		||||
				Zipkin: &zipkin.Config{
 | 
			
		||||
					HTTPEndpoint: "http://powpow:9411/api/v1/spans",
 | 
			
		||||
@@ -266,3 +270,69 @@ func TestInitACMEProvider(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSetEffectiveConfigurationTLSMinVersion(t *testing.T) {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		desc     string
 | 
			
		||||
		provided EntryPoint
 | 
			
		||||
		expected EntryPoint
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			desc: "Entrypoint with no TLS",
 | 
			
		||||
			provided: EntryPoint{
 | 
			
		||||
				Address: ":80",
 | 
			
		||||
			},
 | 
			
		||||
			expected: EntryPoint{
 | 
			
		||||
				Address:          ":80",
 | 
			
		||||
				ForwardedHeaders: &ForwardedHeaders{Insecure: true},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "Entrypoint with TLS Specifying MinVersion",
 | 
			
		||||
			provided: EntryPoint{
 | 
			
		||||
				Address: ":443",
 | 
			
		||||
				TLS: &tls.TLS{
 | 
			
		||||
					MinVersion: "VersionTLS12",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expected: EntryPoint{
 | 
			
		||||
				Address:          ":443",
 | 
			
		||||
				ForwardedHeaders: &ForwardedHeaders{Insecure: true},
 | 
			
		||||
				TLS: &tls.TLS{
 | 
			
		||||
					MinVersion: "VersionTLS12",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "Entrypoint with TLS without Specifying MinVersion",
 | 
			
		||||
			provided: EntryPoint{
 | 
			
		||||
				Address: ":443",
 | 
			
		||||
				TLS:     &tls.TLS{},
 | 
			
		||||
			},
 | 
			
		||||
			expected: EntryPoint{
 | 
			
		||||
				Address:          ":443",
 | 
			
		||||
				ForwardedHeaders: &ForwardedHeaders{Insecure: true},
 | 
			
		||||
				TLS: &tls.TLS{
 | 
			
		||||
					MinVersion: "VersionTLS10",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range testCases {
 | 
			
		||||
		test := test
 | 
			
		||||
		t.Run(test.desc, func(t *testing.T) {
 | 
			
		||||
			t.Parallel()
 | 
			
		||||
 | 
			
		||||
			gc := &GlobalConfiguration{
 | 
			
		||||
				EntryPoints: map[string]*EntryPoint{
 | 
			
		||||
					"foo": &test.provided,
 | 
			
		||||
				},
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gc.SetEffectiveConfiguration(defaultConfigFile)
 | 
			
		||||
 | 
			
		||||
			assert.Equal(t, &test.expected, gc.EntryPoints["foo"])
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -155,7 +155,8 @@ echo -e "-----BEGIN RSA PRIVATE KEY-----\n${priv}\n-----END RSA PRIVATE KEY-----
 | 
			
		||||
   | openssl rsa -inform pem -out "${pdir}/letsencrypt.key"
 | 
			
		||||
 | 
			
		||||
# Process the certificates for each of the domains in acme.json
 | 
			
		||||
for domain in $(jq -r '.Certificates[].Domain.Main' ${acmefile}); do
 | 
			
		||||
domains=$(jq -r '.Certificates[].Domain.Main' ${acmefile}) || bad_acme
 | 
			
		||||
for domain in $domains; do
 | 
			
		||||
	# Traefik stores a cert bundle for each domain.  Within this cert
 | 
			
		||||
	# bundle there is both proper the certificate and the Let's Encrypt CA
 | 
			
		||||
	echo "Extracting cert bundle for ${domain}"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,41 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Traefik
 | 
			
		||||
Documentation=https://docs.traefik.io/v1.7
 | 
			
		||||
#After=network-online.target
 | 
			
		||||
#AssertFileIsExecutable=/usr/bin/traefik
 | 
			
		||||
#AssertPathExists=/etc/traefik/traefik.toml
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
# Run traefik as its own user (create new user with: useradd -r -s /bin/false -U -M traefik)
 | 
			
		||||
#User=traefik
 | 
			
		||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
 | 
			
		||||
 | 
			
		||||
# configure service behavior
 | 
			
		||||
Type=notify
 | 
			
		||||
ExecStart=/usr/bin/traefik --configFile=/etc/traefik.toml
 | 
			
		||||
#ExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.toml
 | 
			
		||||
Restart=always
 | 
			
		||||
WatchdogSec=1s
 | 
			
		||||
 | 
			
		||||
# lock down system access
 | 
			
		||||
# prohibit any operating system and configuration modification
 | 
			
		||||
#ProtectSystem=strict
 | 
			
		||||
# create separate, new (and empty) /tmp and /var/tmp filesystems
 | 
			
		||||
#PrivateTmp=true
 | 
			
		||||
# make /home directories inaccessible
 | 
			
		||||
#ProtectHome=true
 | 
			
		||||
# turns off access to physical devices (/dev/...)
 | 
			
		||||
#PrivateDevices=true
 | 
			
		||||
# make kernel settings (procfs and sysfs) read-only
 | 
			
		||||
#ProtectKernelTunables=true
 | 
			
		||||
# make cgroups /sys/fs/cgroup read-only
 | 
			
		||||
#ProtectControlGroups=true
 | 
			
		||||
 | 
			
		||||
# allow writing of acme.json
 | 
			
		||||
#ReadWritePaths=/etc/traefik/acme.json
 | 
			
		||||
# depending on log and entrypoint configuration, you may need to allow writing to other paths, too
 | 
			
		||||
 | 
			
		||||
# limit number of processes in this unit
 | 
			
		||||
#LimitNPROC=1
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
 
 | 
			
		||||
@@ -94,10 +94,13 @@ Following is the list of existing modifier rules:
 | 
			
		||||
 | 
			
		||||
Matcher rules determine if a particular request should be forwarded to a backend.
 | 
			
		||||
 | 
			
		||||
Separate multiple rule values by `,` (comma) in order to enable ANY semantics (i.e., forward a request if any rule matches).
 | 
			
		||||
Does not work for `Headers` and `HeadersRegexp`.
 | 
			
		||||
The associativity rule is the following:
 | 
			
		||||
 | 
			
		||||
Separate multiple rule values by `;` (semicolon) in order to enable ALL semantics (i.e., forward a request if all rules match).
 | 
			
		||||
- `,` is the `OR` operator (works **only inside a matcher**, ex: `Host:foo.com,bar.com`).
 | 
			
		||||
    - i.e., forward a request if any rule matches.
 | 
			
		||||
    - Does not work for `Headers` and `HeadersRegexp`.
 | 
			
		||||
- `;` is the `AND` operator (works **only between matchers**, ex: `Host:foo.com;Path:/bar`) 
 | 
			
		||||
    - i.e., forward a request if all rules match
 | 
			
		||||
 | 
			
		||||
Following is the list of existing matcher rules along with examples:
 | 
			
		||||
 | 
			
		||||
@@ -234,7 +237,8 @@ The following rules are both `Matchers` and `Modifiers`, so the `Matcher` portio
 | 
			
		||||
#### Priorities
 | 
			
		||||
 | 
			
		||||
By default, routes will be sorted (in descending order) using rules length (to avoid path overlap):
 | 
			
		||||
`PathPrefix:/foo;Host:foo.com` (length == 28) will be matched before `PathPrefixStrip:/foobar` (length == 23) will be matched before `PathPrefix:/foo,/bar` (length == 20).
 | 
			
		||||
- `PathPrefix:/foo;Host:foo.com` (length == 28) will be matched before `PathPrefixStrip:/foobar` (length == 23) will be matched before `PathPrefix:/foo,/bar` (length == 20).  
 | 
			
		||||
- A priority value of 0 will be ignored, so the default value will be calculated (rules length).
 | 
			
		||||
 | 
			
		||||
You can customize priority by frontend. The priority value override the rule length during sorting:
 | 
			
		||||
 | 
			
		||||
@@ -742,12 +746,10 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col
 | 
			
		||||
 | 
			
		||||
### Show me the code !
 | 
			
		||||
 | 
			
		||||
If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/containous/traefik/blob/master/collector/collector.go)
 | 
			
		||||
If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/containous/traefik/blob/v1.7/collector/collector.go)
 | 
			
		||||
 | 
			
		||||
By default we anonymize all configuration fields, except fields tagged with `export=true`.
 | 
			
		||||
 | 
			
		||||
You can check all fields in the [godoc](https://godoc.org/github.com/containous/traefik/configuration#GlobalConfiguration).
 | 
			
		||||
 | 
			
		||||
### How to enable this ?
 | 
			
		||||
 | 
			
		||||
You can enable the collecting system by:
 | 
			
		||||
 
 | 
			
		||||
@@ -271,58 +271,90 @@ Useful if internal networks block external DNS queries.
 | 
			
		||||
 | 
			
		||||
##### `provider`
 | 
			
		||||
 | 
			
		||||
Here is a list of supported `provider`s, that can automate the DNS verification, along with the required environment variables and their [wildcard & root domain support](/configuration/acme/#wildcard-domains) for each. Do not hesitate to complete it.
 | 
			
		||||
Here is a list of supported `provider`s, that can automate the DNS verification, along with the required environment variables and their [wildcard & root domain support](/configuration/acme/#wildcard-domains) for each.
 | 
			
		||||
Do not hesitate to complete it.
 | 
			
		||||
Every lego environment variable can be overridden by their respective `_FILE` counterpart, which should have a filepath to a file that contains the secret as its value.
 | 
			
		||||
For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used to provide a Cloudflare API email address as a Docker secret named `traefik_cf-api-email`.
 | 
			
		||||
 | 
			
		||||
| Provider Name                                          | Provider Code  | Environment Variables                                                                                                                     | Wildcard & Root Domain Support |
 | 
			
		||||
|--------------------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
 | 
			
		||||
| [ACME DNS](https://github.com/joohoi/acme-dns)         | `acmedns`      | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH`                                                                                              | Not tested yet                 |
 | 
			
		||||
| [Alibaba Cloud](https://www.vultr.com)                 | `alidns`       | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID`                                                                        | Not tested yet                 |
 | 
			
		||||
| [Auroradns](https://www.pcextreme.com/aurora/dns)      | `auroradns`    | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT`                                                                                         | Not tested yet                 |
 | 
			
		||||
| [Azure](https://azure.microsoft.com/services/dns/)     | `azure`        | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet                 |
 | 
			
		||||
| [Blue Cat](https://www.bluecatnetworks.com/)           | `bluecat`      | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW`                                  | Not tested yet                 |
 | 
			
		||||
| [Cloudflare](https://www.cloudflare.com)               | `cloudflare`   | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key`                                             | YES                            |
 | 
			
		||||
| [CloudXNS](https://www.cloudxns.net)                   | `cloudxns`     | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY`                                                                                                 | Not tested yet                 |
 | 
			
		||||
| [DigitalOcean](https://www.digitalocean.com)           | `digitalocean` | `DO_AUTH_TOKEN`                                                                                                                           | YES                            |
 | 
			
		||||
| [DNSimple](https://dnsimple.com)                       | `dnsimple`     | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL`                                                                                               | Not tested yet                 |
 | 
			
		||||
| [DNS Made Easy](https://dnsmadeeasy.com)               | `dnsmadeeasy`  | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX`                                                                    | Not tested yet                 |
 | 
			
		||||
| [DNSPod](http://www.dnspod.net/)                       | `dnspod`       | `DNSPOD_API_KEY`                                                                                                                          | Not tested yet                 |
 | 
			
		||||
| [DreamHost](https://www.dreamhost.com/)                | `dreamhost`    | `DREAMHOST_API_KEY`                                                                                                                       | YES                            |
 | 
			
		||||
| [Duck DNS](https://www.duckdns.org/)                   | `duckdns`      | `DUCKDNS_TOKEN`                                                                                                                           | No                             |
 | 
			
		||||
| [Dyn](https://dyn.com)                                 | `dyn`          | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD`                                                                                      | Not tested yet                 |
 | 
			
		||||
| External Program                                       | `exec`         | `EXEC_PATH`                                                                                                                               | Not tested yet                 |
 | 
			
		||||
| [Exoscale](https://www.exoscale.com)                   | `exoscale`     | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT`                                                                            | YES                            |
 | 
			
		||||
| [Fast DNS](https://www.akamai.com/)                    | `fastdns`      | `AKAMAI_CLIENT_TOKEN`,  `AKAMAI_CLIENT_SECRET`,  `AKAMAI_ACCESS_TOKEN`                                                                    | Not tested yet                 |
 | 
			
		||||
| [Gandi](https://www.gandi.net)                         | `gandi`        | `GANDI_API_KEY`                                                                                                                           | Not tested yet                 |
 | 
			
		||||
| [Gandi v5](http://doc.livedns.gandi.net)               | `gandiv5`      | `GANDIV5_API_KEY`                                                                                                                         | YES                            |
 | 
			
		||||
| [Glesys](https://glesys.com/)                          | `glesys`       | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN`                                                                                      | Not tested yet                 |
 | 
			
		||||
| [GoDaddy](https://godaddy.com/domains)                 | `godaddy`      | `GODADDY_API_KEY`, `GODADDY_API_SECRET`                                                                                                   | Not tested yet                 |
 | 
			
		||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud`       | `GCE_PROJECT`, `GCE_SERVICE_ACCOUNT_FILE`                                                                                                 | YES                            |
 | 
			
		||||
| [hosting.de](https://www.hosting.de)                   | `hostingde`    | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME`                                                                                                | Not tested yet                 |
 | 
			
		||||
| [IIJ](https://www.iij.ad.jp/)                          | `iij`          | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE`                                                                         | Not tested yet                 |
 | 
			
		||||
| [Lightsail](https://aws.amazon.com/lightsail/)         | `lightsail`    | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE`                                                                                  | Not tested yet                 |
 | 
			
		||||
| [Linode](https://www.linode.com)                       | `linode`       | `LINODE_API_KEY`                                                                                                                          | Not tested yet                 |
 | 
			
		||||
| [Linode v4](https://www.linode.com)                    | `linodev4`     | `LINODE_TOKEN`                                                                                                                            | Not tested yet                 |
 | 
			
		||||
| manual                                                 | -              | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>.                    | YES                            |
 | 
			
		||||
| [Namecheap](https://www.namecheap.com)                 | `namecheap`    | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY`                                                                                                 | YES                            |
 | 
			
		||||
| [name.com](https://www.name.com/)                      | `namedotcom`   | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER`                                                                                 | Not tested yet                 |
 | 
			
		||||
| [Netcup](https://www.netcup.eu/)                       | `netcup`       | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD`                                                                         | Not tested yet                 |
 | 
			
		||||
| [NIFCloud](https://cloud.nifty.com/service/dns.htm)    | `nifcloud`     | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY`                                                                                    | Not tested yet                 |
 | 
			
		||||
| [Ns1](https://ns1.com/)                                | `ns1`          | `NS1_API_KEY`                                                                                                                             | Not tested yet                 |
 | 
			
		||||
| [Open Telekom Cloud](https://cloud.telekom.de)         | `otc`          | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT`                                           | Not tested yet                 |
 | 
			
		||||
| [OVH](https://www.ovh.com)                             | `ovh`          | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY`                                                       | YES                            |
 | 
			
		||||
| [PowerDNS](https://www.powerdns.com)                   | `pdns`         | `PDNS_API_KEY`, `PDNS_API_URL`                                                                                                            | Not tested yet                 |
 | 
			
		||||
| [Rackspace](https://www.rackspace.com/cloud/dns)       | `rackspace`    | `RACKSPACE_USER`, `RACKSPACE_API_KEY`                                                                                                     | Not tested yet                 |
 | 
			
		||||
| [RFC2136](https://tools.ietf.org/html/rfc2136)         | `rfc2136`      | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER`                                                 | Not tested yet                 |
 | 
			
		||||
| [Route 53](https://aws.amazon.com/route53/)            | `route53`      | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile.           | YES                            |
 | 
			
		||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/)            | `sakuracloud`  | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET`                                                                             | Not tested yet                 |
 | 
			
		||||
| [Stackpath](https://www.stackpath.com/)                | `stackpath`    | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID`                                                                    | Not tested yet                 |
 | 
			
		||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API)        | `vegadns`      | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL`                                                                              | Not tested yet                 |
 | 
			
		||||
| [VULTR](https://www.vultr.com)                         | `vultr`        | `VULTR_API_KEY`                                                                                                                           | Not tested yet                 |
 | 
			
		||||
| Provider Name                                               | Provider Code  | Environment Variables                                                                                                                       | Wildcard & Root Domain Support |
 | 
			
		||||
|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
 | 
			
		||||
| [ACME DNS](https://github.com/joohoi/acme-dns)              | `acme-dns`     | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH`                                                                                                | Not tested yet                 |
 | 
			
		||||
| [Alibaba Cloud](https://www.alibabacloud.com)               | `alidns`       | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID`                                                                          | Not tested yet                 |
 | 
			
		||||
| [Auroradns](https://www.pcextreme.com/aurora/dns)           | `auroradns`    | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT`                                                                                           | Not tested yet                 |
 | 
			
		||||
| [Azure](https://azure.microsoft.com/services/dns/)          | `azure`        | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]`   | Not tested yet                 |
 | 
			
		||||
| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook)  | `bindman`      | `BINDMAN_MANAGER_ADDRESS`                                                                                                                   | YES                            |
 | 
			
		||||
| [Blue Cat](https://www.bluecatnetworks.com/)                | `bluecat`      | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW`                                    | Not tested yet                 |
 | 
			
		||||
| [ClouDNS](https://www.cloudns.net/)                         | `cloudns`      | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD`                                                                                                  | YES                            |
 | 
			
		||||
| [Cloudflare](https://www.cloudflare.com)                    | `cloudflare`   | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key`                                               | YES                            |
 | 
			
		||||
| [CloudXNS](https://www.cloudxns.net)                        | `cloudxns`     | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY`                                                                                                   | Not tested yet                 |
 | 
			
		||||
| [ConoHa](https://www.conoha.jp)                             | `conoha`       | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD`                                                                            | YES                            |
 | 
			
		||||
| [DigitalOcean](https://www.digitalocean.com)                | `digitalocean` | `DO_AUTH_TOKEN`                                                                                                                             | YES                            |
 | 
			
		||||
| [DNSimple](https://dnsimple.com)                            | `dnsimple`     | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL`                                                                                                 | YES                            |
 | 
			
		||||
| [DNS Made Easy](https://dnsmadeeasy.com)                    | `dnsmadeeasy`  | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX`                                                                      | Not tested yet                 |
 | 
			
		||||
| [DNSPod](https://www.dnspod.com/)                           | `dnspod`       | `DNSPOD_API_KEY`                                                                                                                            | Not tested yet                 |
 | 
			
		||||
| [Domain Offensive (do.de)](https://www.do.de/)              | `dode`         | `DODE_TOKEN`                                                                                                                                | YES                            |
 | 
			
		||||
| [DreamHost](https://www.dreamhost.com/)                     | `dreamhost`    | `DREAMHOST_API_KEY`                                                                                                                         | YES                            |
 | 
			
		||||
| [Duck DNS](https://www.duckdns.org/)                        | `duckdns`      | `DUCKDNS_TOKEN`                                                                                                                             | YES                            |
 | 
			
		||||
| [Dyn](https://dyn.com)                                      | `dyn`          | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD`                                                                                        | Not tested yet                 |
 | 
			
		||||
| [EasyDNS](https://easydns.com/)                             | `easydns`      | `EASYDNS_TOKEN`, `EASYDNS_KEY`                                                                                                              | YES                            |
 | 
			
		||||
| External Program                                            | `exec`         | `EXEC_PATH`                                                                                                                                 | YES                            |
 | 
			
		||||
| [Exoscale](https://www.exoscale.com)                        | `exoscale`     | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT`                                                                              | YES                            |
 | 
			
		||||
| [Fast DNS](https://www.akamai.com/)                         | `fastdns`      | `AKAMAI_CLIENT_TOKEN`,  `AKAMAI_CLIENT_SECRET`,  `AKAMAI_ACCESS_TOKEN`                                                                      | YES                            |
 | 
			
		||||
| [Gandi](https://www.gandi.net)                              | `gandi`        | `GANDI_API_KEY`                                                                                                                             | Not tested yet                 |
 | 
			
		||||
| [Gandi v5](http://doc.livedns.gandi.net)                    | `gandiv5`      | `GANDIV5_API_KEY`                                                                                                                           | YES                            |
 | 
			
		||||
| [Glesys](https://glesys.com/)                               | `glesys`       | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN`                                                                                        | Not tested yet                 |
 | 
			
		||||
| [GoDaddy](https://godaddy.com/domains)                      | `godaddy`      | `GODADDY_API_KEY`, `GODADDY_API_SECRET`                                                                                                     | Not tested yet                 |
 | 
			
		||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/)      | `gcloud`       | `GCE_PROJECT`, Application Default Credentials (2) (3), [`GCE_SERVICE_ACCOUNT_FILE`]                                                        | YES                            |
 | 
			
		||||
| [hosting.de](https://www.hosting.de)                        | `hostingde`    | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME`                                                                                                  | YES                            |
 | 
			
		||||
| HTTP request                                                | `httpreq`      | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` (1)                                                              | YES                            |
 | 
			
		||||
| [IIJ](https://www.iij.ad.jp/)                               | `iij`          | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE`                                                                           | Not tested yet                 |
 | 
			
		||||
| [INWX](https://www.inwx.de/en)                              | `inwx`         | `INWX_USERNAME`, `INWX_PASSWORD`                                                                                                            | YES                            |
 | 
			
		||||
| [Joker.com](https://joker.com)                              | `joker`        | `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD`                                                                                       | YES                            |
 | 
			
		||||
| [Lightsail](https://aws.amazon.com/lightsail/)              | `lightsail`    | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE`                                                                                    | Not tested yet                 |
 | 
			
		||||
| [Linode](https://www.linode.com)                            | `linode`       | `LINODE_API_KEY`                                                                                                                            | Not tested yet                 |
 | 
			
		||||
| [Linode v4](https://www.linode.com)                         | `linodev4`     | `LINODE_TOKEN`                                                                                                                              | Not tested yet                 |
 | 
			
		||||
| manual                                                      | -              | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>.                      | YES                            |
 | 
			
		||||
| [MyDNS.jp](https://www.mydns.jp/)                           | `mydnsjp`      | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD`                                                                                                     | YES                            |
 | 
			
		||||
| [Namecheap](https://www.namecheap.com)                      | `namecheap`    | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY`                                                                                                   | YES                            |
 | 
			
		||||
| [Namesilo](https://www.namesilo.com/)                       | `namesilo`     | `NAMESILO_API_KEY`                                                                                                                          | YES                            |
 | 
			
		||||
| [name.com](https://www.name.com/)                           | `namedotcom`   | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER`                                                                                   | Not tested yet                 |
 | 
			
		||||
| [Netcup](https://www.netcup.eu/)                            | `netcup`       | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD`                                                                           | Not tested yet                 |
 | 
			
		||||
| [NIFCloud](https://cloud.nifty.com/service/dns.htm)         | `nifcloud`     | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY`                                                                                      | Not tested yet                 |
 | 
			
		||||
| [Ns1](https://ns1.com/)                                     | `ns1`          | `NS1_API_KEY`                                                                                                                               | Not tested yet                 |
 | 
			
		||||
| [Open Telekom Cloud](https://cloud.telekom.de)              | `otc`          | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT`                                             | Not tested yet                 |
 | 
			
		||||
| [OVH](https://www.ovh.com)                                  | `ovh`          | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY`                                                         | YES                            |
 | 
			
		||||
| [Openstack Designate](https://docs.openstack.org/designate) | `designate`    | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME`                                                             | YES                            |
 | 
			
		||||
| [Oracle Cloud](https://cloud.oracle.com/home)               | `oraclecloud`  | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | YES                            |
 | 
			
		||||
| [PowerDNS](https://www.powerdns.com)                        | `pdns`         | `PDNS_API_KEY`, `PDNS_API_URL`                                                                                                              | Not tested yet                 |
 | 
			
		||||
| [Rackspace](https://www.rackspace.com/cloud/dns)            | `rackspace`    | `RACKSPACE_USER`, `RACKSPACE_API_KEY`                                                                                                       | Not tested yet                 |
 | 
			
		||||
| [RFC2136](https://tools.ietf.org/html/rfc2136)              | `rfc2136`      | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER`                                                   | Not tested yet                 |
 | 
			
		||||
| [Route 53](https://aws.amazon.com/route53/)                 | `route53`      | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile.             | YES                            |
 | 
			
		||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/)                 | `sakuracloud`  | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET`                                                                               | Not tested yet                 |
 | 
			
		||||
| [Selectel](https://selectel.ru/en/)                         | `selectel`     | `SELECTEL_API_TOKEN`                                                                                                                        | YES                            |
 | 
			
		||||
| [Stackpath](https://www.stackpath.com/)                     | `stackpath`    | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID`                                                                      | Not tested yet                 |
 | 
			
		||||
| [TransIP](https://www.transip.nl/)                          | `transip`      | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH`                                                                                          | YES                            |
 | 
			
		||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API)             | `vegadns`      | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL`                                                                                | Not tested yet                 |
 | 
			
		||||
| [Versio](https://www.versio.nl/domeinnamen)                 | `versio`       | `VERSIO_USERNAME`, `VERSIO_PASSWORD`                                                                                                        | YES                            |
 | 
			
		||||
| [Vscale](https://vscale.io/)                                | `vscale`       | `VSCALE_API_TOKEN`                                                                                                                          | YES                            |
 | 
			
		||||
| [VULTR](https://www.vultr.com)                              | `vultr`        | `VULTR_API_KEY`                                                                                                                             | YES                            |
 | 
			
		||||
| [Zone.ee](https://www.zone.ee)                              | `zoneee`       | `ZONEEE_API_USER`, `ZONEEE_API_KEY`                                                                                                         | YES                            |
 | 
			
		||||
 | 
			
		||||
- (1): more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/)
 | 
			
		||||
- (2): https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
 | 
			
		||||
- (3): https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76
 | 
			
		||||
 | 
			
		||||
#### `resolvers`
 | 
			
		||||
 | 
			
		||||
Use custom DNS servers to resolve the FQDN authority.
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[acme]
 | 
			
		||||
# ...
 | 
			
		||||
[acme.dnsChallenge]
 | 
			
		||||
  # ...
 | 
			
		||||
  resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `domains`
 | 
			
		||||
 | 
			
		||||
You can provide SANs (alternative domains) to each main domain.
 | 
			
		||||
@@ -367,11 +399,10 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
It is not possible to request a double wildcard certificate for a domain (for example `*.*.local.com`).
 | 
			
		||||
Due to ACME limitation it is not possible to define wildcards in SANs (alternative domains). Thus, the wildcard domain has to be defined as a main domain.
 | 
			
		||||
Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed.
 | 
			
		||||
In this case the generated DNS TXT record for both domains is the same.
 | 
			
		||||
Even though this behaviour is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, it can lead to problems as all DNS providers keep DNS records cached for a certain time (TTL) and this TTL can be superior to the challenge timeout making the `DNS-01` challenge fail.
 | 
			
		||||
The Traefik ACME client library [LEGO](https://github.com/xenolf/lego) supports some but not all DNS providers to work around this issue.
 | 
			
		||||
The Traefik ACME client library [LEGO](https://github.com/go-acme/lego) supports some but not all DNS providers to work around this issue.
 | 
			
		||||
The [`provider` table](/configuration/acme/#provider) indicates if they allow generating certificates for a wildcard domain and its root domain.
 | 
			
		||||
 | 
			
		||||
### `onDemand` (Deprecated)
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
 | 
			
		||||
For more customization, see [entry points](/configuration/entrypoints/) documentation and the examples below.
 | 
			
		||||
 | 
			
		||||
## Web UI
 | 
			
		||||
## Dashboard (Web UI)
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@@ -106,10 +106,10 @@ entryPoint = "foo"
 | 
			
		||||
entryPoint = "bar"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In the above example, you would access a regular path, administration panel, and health-check as follows:
 | 
			
		||||
In the above example, you would access a regular path, dashboard, and health-check as follows:
 | 
			
		||||
 | 
			
		||||
* Regular path: `http://hostname:80/path`
 | 
			
		||||
* Admin Panel: `http://hostname:8083/`
 | 
			
		||||
* Dashboard: `http://hostname:8083/`
 | 
			
		||||
* Ping URL: `http://hostname:8082/ping`
 | 
			
		||||
 | 
			
		||||
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
 | 
			
		||||
@@ -301,7 +301,7 @@ curl -s "http://localhost:8080/health" | jq .
 | 
			
		||||
  // average response time in seconds
 | 
			
		||||
  "average_response_time_sec": 0.8648016000000001,
 | 
			
		||||
 | 
			
		||||
  // request statistics [requires --statistics to be set]
 | 
			
		||||
  // request statistics [requires --api.statistics to be set]
 | 
			
		||||
  // ten most recent requests with 4xx and 5xx status codes
 | 
			
		||||
  "recent_errors": [
 | 
			
		||||
    {
 | 
			
		||||
@@ -322,9 +322,12 @@ curl -s "http://localhost:8080/health" | jq .
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Metrics
 | 
			
		||||
## Dashboard Statistics
 | 
			
		||||
 | 
			
		||||
You can enable Traefik to export internal metrics to different monitoring systems.
 | 
			
		||||
You can control how the Traefik's internal metrics are shown in the Dashboard.
 | 
			
		||||
 | 
			
		||||
If you want to export internal metrics to different monitoring systems,
 | 
			
		||||
please check the page [Metrics](./metrics.md).
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[api]
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,15 @@ stale = false
 | 
			
		||||
#
 | 
			
		||||
domain = "consul.localhost"
 | 
			
		||||
 | 
			
		||||
# Keep a Consul node only if all checks status are passing
 | 
			
		||||
# If true, only the Consul nodes with checks status 'passing' will be kept.
 | 
			
		||||
# if false, only the Consul nodes with checks status 'passing' or 'warning' will be kept.
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
# Default: true
 | 
			
		||||
#
 | 
			
		||||
strictChecks = true
 | 
			
		||||
 | 
			
		||||
# Prefix for Consul catalog tags.
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
@@ -94,74 +103,82 @@ Additional settings can be defined using Consul Catalog tags.
 | 
			
		||||
!!! note
 | 
			
		||||
    The default prefix is `traefik`.
 | 
			
		||||
 | 
			
		||||
| Label                                                                | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|----------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `<prefix>.enable=false`                                              | Disables this container in Traefik.                                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.protocol=https`                                            | Overrides the default `http` protocol.                                                                                                                                                                                        |
 | 
			
		||||
| `<prefix>.weight=10`                                                 | Assigns this weight to the container.                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                     | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.backend.circuitbreaker.expression=EXPR`                    | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.`                                                                                                                 |
 | 
			
		||||
| `<prefix>.backend.responseForwarding.flushInterval=10ms`             | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `<prefix>.backend.healthcheck.path=/health`                          | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `<prefix>.backend.healthcheck.interval=1s`                           | Defines the health check interval.                                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.backend.healthcheck.port=8080`                             | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                            | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `<prefix>.backend.healthcheck.hostname=foobar.com`                   | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.backend.healthcheck.headers=EXPR`                          | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.method=drr`                           | Overrides the default `wrr` load balancer algorithm.                                                                                                                                                                          |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.stickiness=true`                      | Enables backend sticky sessions.                                                                                                                                                                                              |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME`           | Sets the cookie name manually for sticky sessions.                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.sticky=true`                          | Enables backend sticky sessions. (DEPRECATED)                                                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.backend.maxconn.amount=10`                                 | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `<prefix>.backend.maxconn.extractorfunc=client.ip`                   | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `<prefix>.frontend.auth.basic=EXPR`                                  | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.auth.basic.removeHeader=true`                     | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.basic.users=EXPR`                            | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `<prefix>.frontend.auth.basic.usersfile=/path/.htpasswd`             | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.digest.removeHeader=true`                    | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.digest.users=EXPR`                           | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.auth.digest.usersfile=/path/.htdigest`            | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.address=https://example.com`         | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.authResponseHeaders=EXPR`            | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.caOptional=true`                 | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.cert=/path/server.pem`           | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.insecureSkipVerify=true`         | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.key=/path/server.key`            | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.trustForwardHeader=true`             | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.auth.headerField=X-WebAuth-User`                  | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `<prefix>.frontend.entryPoints=http,https`                           | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.errors.<name>.backend=NAME`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.errors.<name>.query=PATH`                         | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.errors.<name>.status=RANGE`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.passHostHeader=true`                              | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.notAfter=true`            | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.notBefore=true`           | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.sans=true`                | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.commonName=true`  | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.country=true`     | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.locality=true`    | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.province=true`    | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.pem=true`                       | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `<prefix>.frontend.passTLSCert=true`                                 | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `<prefix>.frontend.priority=10`                                      | Overrides default frontend priority.                                                                                                                                                                                          |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.extractorFunc=EXP`                      | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.rateSet.<name>.period=6`                | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.rateSet.<name>.average=6`               | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.rateSet.<name>.burst=6`                 | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.redirect.entryPoint=https`                        | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS).                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.redirect.regex=^http://localhost/(.*)`            | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `<prefix>.frontend.redirect.replacement=http://mydomain/$1`          | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `<prefix>.frontend.redirect.permanent=true`                          | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.rule=EXPR`                                        | Overrides the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`.                                                                                                                                            |
 | 
			
		||||
| `<prefix>.frontend.whiteList.sourceRange=RANGE`                      | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `<prefix>.frontend.whiteList.useXForwardedFor=true`                  | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
| Label                                                                    | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|--------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `<prefix>.enable=false`                                                  | Disables this container in Traefik.                                                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.protocol=https`                                                | Overrides the default `http` protocol.                                                                                                                                                                                        |
 | 
			
		||||
| `<prefix>.weight=10`                                                     | Assigns this weight to the container.                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                         | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.backend.circuitbreaker.expression=EXPR`                        | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.`                                                                                                                 |
 | 
			
		||||
| `<prefix>.backend.responseForwarding.flushInterval=10ms`                 | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `<prefix>.backend.healthcheck.path=/health`                              | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `<prefix>.backend.healthcheck.interval=1s`                               | Defines the health check interval.                                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.backend.healthcheck.port=8080`                                 | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                                | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `<prefix>.backend.healthcheck.hostname=foobar.com`                       | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.backend.healthcheck.headers=EXPR`                              | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.method=drr`                               | Overrides the default `wrr` load balancer algorithm.                                                                                                                                                                          |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.stickiness=true`                          | Enables backend sticky sessions.                                                                                                                                                                                              |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME`               | Sets the cookie name manually for sticky sessions.                                                                                                                                                                            |
 | 
			
		||||
| `<prefix>.backend.loadbalancer.sticky=true`                              | Enables backend sticky sessions. (DEPRECATED)                                                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.backend.maxconn.amount=10`                                     | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `<prefix>.backend.maxconn.extractorfunc=client.ip`                       | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `<prefix>.frontend.auth.basic=EXPR`                                      | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.auth.basic.removeHeader=true`                         | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.basic.users=EXPR`                                | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `<prefix>.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.digest.removeHeader=true`                        | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.digest.users=EXPR`                               | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.auth.digest.usersFile=/path/.htdigest`                | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.address=https://example.com`             | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.authResponseHeaders=EXPR`                | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.caOptional=true`                     | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.cert=/path/server.pem`               | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.insecureSkipVerify=true`             | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.tls.key=/path/server.key`                | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.auth.forward.trustForwardHeader=true`                 | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.auth.headerField=X-WebAuth-User`                      | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `<prefix>.frontend.entryPoints=http,https`                               | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.errors.<name>.backend=NAME`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.errors.<name>.query=PATH`                             | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.errors.<name>.status=RANGE`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.passHostHeader=true`                                  | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.country=true`          | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                     |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                             |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.locality=true`         | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.organization=true`     | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.province=true`         | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.notAfter=true`                | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.notBefore=true`               | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.sans=true`                    | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.commonName=true`      | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.country=true`         | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                            |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.locality=true`        | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.organization=true`    | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.province=true`        | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `<prefix>.frontend.passTLSClientCert.pem=true`                           | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `<prefix>.frontend.passTLSCert=true`                                     | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `<prefix>.frontend.priority=10`                                          | Overrides default frontend priority.                                                                                                                                                                                          |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.extractorFunc=EXP`                          | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.rateSet.<name>.period=6`                    | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.rateSet.<name>.average=6`                   | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.rateLimit.rateSet.<name>.burst=6`                     | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `<prefix>.frontend.redirect.entryPoint=https`                            | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS).                                                                                                                                                         |
 | 
			
		||||
| `<prefix>.frontend.redirect.regex=^http://localhost/(.*)`                | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `<prefix>.frontend.redirect.replacement=http://mydomain/$1`              | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `<prefix>.frontend.redirect.permanent=true`                              | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `<prefix>.frontend.rule=EXPR`                                            | Overrides the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`.                                                                                                                                            |
 | 
			
		||||
| `<prefix>.frontend.whiteList.sourceRange=RANGE`                          | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `<prefix>.frontend.whiteList.useXForwardedFor=true`                      | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
 | 
			
		||||
### Multiple frontends for a single service
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ watch = true
 | 
			
		||||
exposedByDefault = true
 | 
			
		||||
 | 
			
		||||
# Use the IP address from the binded port instead of the inner network one.
 | 
			
		||||
# 
 | 
			
		||||
#
 | 
			
		||||
# In case no IP address is attached to the binded port (or in case 
 | 
			
		||||
# there is no bind), the inner network one will be used as a fallback.     
 | 
			
		||||
#
 | 
			
		||||
@@ -73,6 +73,13 @@ usebindportip = true
 | 
			
		||||
#
 | 
			
		||||
swarmMode = false
 | 
			
		||||
 | 
			
		||||
# Polling interval (in seconds) for Swarm Mode.
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
# Default: 15
 | 
			
		||||
#
 | 
			
		||||
swarmModeRefreshSeconds = 15
 | 
			
		||||
 | 
			
		||||
# Define a default docker network to use for connections to all containers.
 | 
			
		||||
# Can be overridden by the traefik.docker.network label.
 | 
			
		||||
#
 | 
			
		||||
@@ -93,7 +100,6 @@ network = "web"
 | 
			
		||||
 | 
			
		||||
To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Docker Swarm Mode
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
@@ -110,7 +116,10 @@ To enable constraints see [provider-specific constraints section](/configuration
 | 
			
		||||
# Required
 | 
			
		||||
# Default: "unix:///var/run/docker.sock"
 | 
			
		||||
#
 | 
			
		||||
endpoint = "tcp://127.0.0.1:2375"
 | 
			
		||||
# swarm classic (1.12-)
 | 
			
		||||
# endpoint = "tcp://127.0.0.1:2375"
 | 
			
		||||
# docker swarm mode (1.12+)
 | 
			
		||||
endpoint = "tcp://127.0.0.1:2377"
 | 
			
		||||
 | 
			
		||||
# Default base domain used for the frontend rules.
 | 
			
		||||
# Can be overridden by setting the "traefik.domain" label on a services.
 | 
			
		||||
@@ -177,6 +186,61 @@ exposedByDefault = false
 | 
			
		||||
 | 
			
		||||
To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific).
 | 
			
		||||
 | 
			
		||||
## Security Considerations
 | 
			
		||||
 | 
			
		||||
### Security Challenge with the Docker Socket
 | 
			
		||||
 | 
			
		||||
Traefik requires access to the docker socket to get its dynamic configuration,
 | 
			
		||||
by watching the Docker API through this socket.
 | 
			
		||||
 | 
			
		||||
!!! important
 | 
			
		||||
    Depending on your context and your usage, accessing the Docker API without any restriction might be a security concern.
 | 
			
		||||
 | 
			
		||||
As explained on the Docker documentation: ([Docker Daemon Attack Surface page](https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface)):
 | 
			
		||||
 | 
			
		||||
`[...] only **trusted** users should be allowed to control your Docker daemon [...]`
 | 
			
		||||
 | 
			
		||||
If the Traefik processes (handling requests from the outside world) is attacked,
 | 
			
		||||
then the attacker can access the Docker (or Swarm Mode) backend.
 | 
			
		||||
 | 
			
		||||
Also, when using Swarm Mode, it is mandatory to schedule Traefik's containers on the Swarm manager nodes,
 | 
			
		||||
to let Traefik accessing the Docker Socket of the Swarm manager node.
 | 
			
		||||
 | 
			
		||||
More information about Docker's security:
 | 
			
		||||
 | 
			
		||||
- [KubeCon EU 2018 Keynote, Running with Scissors, from Liz Rice](https://www.youtube.com/watch?v=ltrV-Qmh3oY)
 | 
			
		||||
- [Don't expose the Docker socket (not even to a container)](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html)
 | 
			
		||||
- [A thread on Stack Overflow about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623)
 | 
			
		||||
- [To Dind or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html)
 | 
			
		||||
 | 
			
		||||
### Workarounds
 | 
			
		||||
 | 
			
		||||
!!! note "Improved Security"
 | 
			
		||||
 | 
			
		||||
    [TraefikEE](https://containo.us/traefikee) solves this problem by separating the control plane (connected to Docker) and the data plane (handling the requests).
 | 
			
		||||
 | 
			
		||||
Another possible workaround is to expose the Docker socket over TCP, instead of the default Unix socket file.
 | 
			
		||||
It allows different implementation levels of the [AAA (Authentication, Authorization, Accounting) concepts](https://en.wikipedia.org/wiki/AAA_(computer_security)), depending on your security assessment:
 | 
			
		||||
 | 
			
		||||
- Authentication with Client Certificates as described in [the "Protect the Docker daemon socket" page of Docker's documentation](https://docs.docker.com/engine/security/https/)
 | 
			
		||||
 | 
			
		||||
- Authorization with the [Docker Authorization Plugin Mechanism](https://docs.docker.com/engine/extend/plugins_authorization/)
 | 
			
		||||
 | 
			
		||||
- Accounting at networking level, by exposing the socket only inside a Docker private network, only available for Traefik.
 | 
			
		||||
 | 
			
		||||
- Accounting at container level, by exposing the socket on a another container than Traefik's.
 | 
			
		||||
  With Swarm mode, it allows scheduling of Traefik on worker nodes, with only the "socket exposer" container on the manager nodes.
 | 
			
		||||
 | 
			
		||||
- Accounting at kernel level, by enforcing kernel calls with mechanisms like [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux),
 | 
			
		||||
  to only allows an identified set of actions for Traefik's process (or the "socket exposer" process).
 | 
			
		||||
 | 
			
		||||
Use the following ressources to get started:
 | 
			
		||||
 | 
			
		||||
- [Traefik issue GH-4174 about security with Docker socket](https://github.com/containous/traefik/issues/4174)
 | 
			
		||||
- [Inspecting Docker Activity with Socat](https://developers.redhat.com/blog/2015/02/25/inspecting-docker-activity-with-socat/)
 | 
			
		||||
- [Letting Traefik run on Worker Nodes](https://blog.mikesir87.io/2018/07/letting-traefik-run-on-worker-nodes/)
 | 
			
		||||
- [Docker Socket Proxy from Tecnativa](https://github.com/Tecnativa/docker-socket-proxy)
 | 
			
		||||
 | 
			
		||||
## Labels: overriding default behavior
 | 
			
		||||
 | 
			
		||||
### Using Docker with Swarm Mode
 | 
			
		||||
@@ -193,6 +257,20 @@ services:
 | 
			
		||||
        traefik.docker.network: traefik
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Required labels:
 | 
			
		||||
 | 
			
		||||
- `traefik.frontend.rule`
 | 
			
		||||
- `traefik.port` - Without this the debug logs will show this service is deliberately filtered out.
 | 
			
		||||
- `traefik.docker.network` - Without this a 504 may occur.
 | 
			
		||||
 | 
			
		||||
#### Troubleshooting
 | 
			
		||||
 | 
			
		||||
If service doesn't show up in the dashboard, check the debug logs to see if the port is missing:
 | 
			
		||||
`Filtering container without port, <SERVICE_NAME>: port label is missing, ...')`
 | 
			
		||||
 | 
			
		||||
If `504 Gateway Timeout` occurs and there are networks used, ensure that `traefik.docker.network` is defined. 
 | 
			
		||||
The complete name is required, meaning if the network is internal the name needs to be `<project_name>_<network_name>`.
 | 
			
		||||
 | 
			
		||||
### Using Docker Compose
 | 
			
		||||
 | 
			
		||||
If you are intending to use only Docker Compose commands (e.g. `docker-compose up --scale whoami=2 -d`), labels should be under your service, otherwise they will be ignored.
 | 
			
		||||
@@ -209,97 +287,109 @@ services:
 | 
			
		||||
 | 
			
		||||
Labels can be used on containers to override default behavior.
 | 
			
		||||
 | 
			
		||||
| Label                                                               | Description                                                                                                                                                                                                                      |
 | 
			
		||||
|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.docker.network`                                            | Overrides the default docker network to use for connections to the container. [1]                                                                                                                                                |
 | 
			
		||||
| `traefik.domain`                                                    | Sets the default base domain for the frontend rules. For more information, check the [Container Labels section's of the user guide "Let's Encrypt & Docker"](/user-guide/docker-and-lets-encrypt/#container-labels)              |
 | 
			
		||||
| `traefik.enable=false`                                              | Disables this container in Traefik.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.port=80`                                                   | Registers this port. Useful when the container exposes multiples ports.                                                                                                                                                          |
 | 
			
		||||
| `traefik.tags=foo,bar,myTag`                                        | Adds Traefik tags to the Docker container/service to be used in [constraints](/configuration/commons/#constraints).                                                                                                              |
 | 
			
		||||
| `traefik.protocol=https`                                            | Overrides the default `http` protocol                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.weight=10`                                                 | Assigns this weight to the container                                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend=foo`                                               | Gives the name `foo` to the generated backend for this container.                                                                                                                                                                |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                    | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                    |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`             | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                          | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                           | Defines the health check interval.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                             | Sets a different port for the health check.                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                           | Overrides the server URL scheme.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                   | Defines the health check hostname.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                          | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                        |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                           | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                      | Enables backend sticky sessions                                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`           | Sets the cookie name manually for sticky sessions                                                                                                                                                                                |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                          | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.swarm=true`                           | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode).                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                 | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                         |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                   | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                           |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                  | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2] (DEPRECATED).                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                     | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                            | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2].                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`             | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                    | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                           | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`            | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`         | Sets the URL of the authentication server.                                                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`            | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                 | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`           | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`         | If set to true invalid SSL certificates are accepted.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`            | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`             | Trusts X-Forwarded-* headers.                                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                  | Sets the header user to pass the authenticated user to the application.                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                           | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                         | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                              | Forwards client `Host` header to the backend.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`            | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`           | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`  | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`     | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`    | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`    | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                       | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                 | Forwards TLS Client certificates to the backend (DEPRECATED).                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.priority=10`                                      | Overrides default frontend priority                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                      | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`               | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                 | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                        | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`            | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`          | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                          | Returns 301 instead of 302.                                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                        | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`.                                                                     |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                      | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                  | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                          |
 | 
			
		||||
| Label                                                                   | Description                                                                                                                                                                                                                      |
 | 
			
		||||
|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.docker.network`                                                | Overrides the default docker network to use for connections to the container. [1]                                                                                                                                                |
 | 
			
		||||
| `traefik.domain`                                                        | Sets the default base domain for the frontend rules. For more information, check the [Container Labels section's of the user guide "Let's Encrypt & Docker"](/user-guide/docker-and-lets-encrypt/#container-labels)              |
 | 
			
		||||
| `traefik.enable=false`                                                  | Disables this container in Traefik.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.port=80`                                                       | Registers this port. Useful when the container exposes multiples ports.                                                                                                                                                          |
 | 
			
		||||
| `traefik.tags=foo,bar,myTag`                                            | Adds Traefik tags to the Docker container/service to be used in [constraints](/configuration/commons/#constraints).                                                                                                              |
 | 
			
		||||
| `traefik.protocol=https`                                                | Overrides the default `http` protocol                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.weight=10`                                                     | Assigns this weight to the container                                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend=foo`                                                   | Overrides the container name by `foo` in the generated name of the backend.                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                        | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                    |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`                 | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                              | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                               | Defines the health check interval.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                                 | Sets a different port for the health check.                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                               | Overrides the server URL scheme.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                       | Defines the health check hostname.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                              | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                        |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                               | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                          | Enables backend sticky sessions                                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`               | Sets the cookie name manually for sticky sessions                                                                                                                                                                                |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                              | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.swarm=true`                               | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode) [3].                                                                                                                                                         |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                     | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                         |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                       | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                           |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                      | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2] (DEPRECATED).                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                         | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                                | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2].                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                        | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                               | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`                | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`             | Sets the URL of the authentication server.                                                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`                | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                     | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`               | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`             | If set to true invalid SSL certificates are accepted.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`                | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`                 | Trusts X-Forwarded-* headers.                                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                      | Sets the header user to pass the authenticated user to the application.                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                               | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                             | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                                  | Forwards client `Host` header to the backend.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                     |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true`          | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                        |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true`         | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true`     | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true`         | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`                | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`               | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                    | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`      | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`         | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`        | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`    | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`        | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                           | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                     | Forwards TLS Client certificates to the backend (DEPRECATED).                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.priority=10`                                          | Overrides default frontend priority                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                          | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                    | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`                   | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                     | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                            | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`                | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`              | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                              | Returns 301 instead of 302.                                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                            | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`.                                                                     |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                          | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                      | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                          |
 | 
			
		||||
 | 
			
		||||
[1] `traefik.docker.network`:
 | 
			
		||||
If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them).
 | 
			
		||||
[1] `traefik.docker.network`:  
 | 
			
		||||
If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them).  
 | 
			
		||||
For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name.
 | 
			
		||||
Or if your service references external network use it's name instead.
 | 
			
		||||
 | 
			
		||||
[2] `traefik.frontend.auth.basic.users=EXPR `:  
 | 
			
		||||
[2] `traefik.frontend.auth.basic.users=EXPR`:  
 | 
			
		||||
To create `user:password` pair, it's possible to use this command:  
 | 
			
		||||
`echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g`.  
 | 
			
		||||
The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additional symbol `$` makes escaping.
 | 
			
		||||
 | 
			
		||||
[3] `traefik.backend.loadbalancer.swarm`:  
 | 
			
		||||
If you enable this option, Traefik will use the virtual IP provided by docker swarm instead of the containers IPs.
 | 
			
		||||
Which means that Traefik will not perform any kind of load balancing and will delegate this task to swarm.  
 | 
			
		||||
It also means that Traefik will manipulate only one backend, not one backend per container.
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
| Label                                                 | Description                                                                                                                                                                         |
 | 
			
		||||
|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.<br>Format: <code>HEADER:value||HEADER2:value2</code> |
 | 
			
		||||
| `traefik.frontend.headers.customRequestHeaders=EXPR`  | Provides the container with custom request headers that will be appended to each request forwarded to the container.<br>Format: <code>HEADER:value||HEADER2:value2</code> |
 | 
			
		||||
| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.<br>Format: <code>HEADER:value||HEADER2:value2</code>        |
 | 
			
		||||
 | 
			
		||||
#### Security Headers
 | 
			
		||||
@@ -314,7 +404,7 @@ The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additio
 | 
			
		||||
| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value.                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.headers.forceSTSHeader=false`          | Adds the STS  header to non-SSL requests.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.headers.frameDeny=false`               | Adds the `X-Frame-Options` header with the value of `DENY`.                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.headers.hostsProxyHeaders=EXPR `       | Provides a list of headers that the proxied hostname may be stored.<br>Format: `HEADER1,HEADER2`                                                                                                    |
 | 
			
		||||
| `traefik.frontend.headers.hostsProxyHeaders=EXPR`        | Provides a list of headers that the proxied hostname may be stored.<br>Format: `HEADER1,HEADER2`                                                                                                    |
 | 
			
		||||
| `traefik.frontend.headers.isDevelopment=false`           | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.<br>When deploying to production, be sure to set this to false. |
 | 
			
		||||
| `traefik.frontend.headers.publicKey=VALUE`               | Adds HPKP header.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.headers.referrerPolicy=VALUE`          | Adds referrer policy  header.                                                                                                                                                                       |
 | 
			
		||||
@@ -335,63 +425,71 @@ You can define as many segments as ports exposed in a container.
 | 
			
		||||
 | 
			
		||||
Segment labels override the default behavior.
 | 
			
		||||
 | 
			
		||||
| Label                                                                              | Description                                                            |
 | 
			
		||||
|------------------------------------------------------------------------------------|------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                           | Same as `traefik.backend`                                              |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                             | Same as `traefik.domain`                                               |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                 | Same as `traefik.port`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                             | Same as `traefik.protocol`                                             |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                 | Same as `traefik.weight`                                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                  | Same as `traefik.frontend.auth.basic`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                     | Same as `traefik.frontend.auth.basic.removeHeader`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                            | Same as `traefik.frontend.auth.basic.users`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`             | Same as `traefik.frontend.auth.basic.usersFile`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                    | Same as `traefik.frontend.auth.digest.removeHeader`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                           | Same as `traefik.frontend.auth.digest.users`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`            | Same as `traefik.frontend.auth.digest.usersFile`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`         | Same as `traefik.frontend.auth.forward.address`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`            | Same as `traefik.frontend.auth.forward.authResponseHeaders`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Same as `traefik.frontend.auth.forward.tls.ca`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                 | Same as `traefik.frontend.auth.forward.tls.caOptional`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`           | Same as `traefik.frontend.auth.forward.tls.cert`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`         | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`            | Same as `traefik.frontend.auth.forward.tls.key`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`             | Same as `traefik.frontend.auth.forward.trustForwardHeader`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                  | Same as `traefik.frontend.auth.headerField`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                | Same as `traefik.frontend.entryPoints`                                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                       | Same as `traefik.frontend.errors.<name>.backend`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                         | Same as `traefik.frontend.errors.<name>.query`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                       | Same as `traefik.frontend.errors.<name>.status`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                              | Same as `traefik.frontend.passHostHeader`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`            | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`           | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                | Same as `traefik.frontend.passTLSClientCert.infos.sans`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`  | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`     | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`|
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`|
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                       | Same as `traefik.frontend.passTLSClientCert.infos.pem`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                 | Same as `traefik.frontend.passTLSCert`                                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                      | Same as `traefik.frontend.priority`                                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                      | Same as `traefik.frontend.rateLimit.extractorFunc`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`               | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                 | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                        | Same as `traefik.frontend.redirect.entryPoint`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`            | Same as `traefik.frontend.redirect.regex`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`          | Same as `traefik.frontend.redirect.replacement`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                          | Same as `traefik.frontend.redirect.permanent`                          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                         | Same as `traefik.frontend.rule`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                      | Same as `traefik.frontend.whiteList.sourceRange`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                  | Same as `traefik.frontend.whiteList.useXForwardedFor`                  |
 | 
			
		||||
| Label                                                                                  | Description                                                                |
 | 
			
		||||
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                               | Same as `traefik.backend`                                                  |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                                 | Same as `traefik.domain`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                     | Same as `traefik.port`                                                     |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                                 | Same as `traefik.protocol`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                     | Same as `traefik.weight`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                      | Same as `traefik.frontend.auth.basic`                                      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                         | Same as `traefik.frontend.auth.basic.removeHeader`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                                | Same as `traefik.frontend.auth.basic.users`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Same as `traefik.frontend.auth.basic.usersFile`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                        | Same as `traefik.frontend.auth.digest.removeHeader`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                               | Same as `traefik.frontend.auth.digest.users`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`                | Same as `traefik.frontend.auth.digest.usersFile`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`             | Same as `traefik.frontend.auth.forward.address`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`                | Same as `traefik.frontend.auth.forward.authResponseHeaders`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Same as `traefik.frontend.auth.forward.tls.ca`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                     | Same as `traefik.frontend.auth.forward.tls.caOptional`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`               | Same as `traefik.frontend.auth.forward.tls.cert`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`             | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`                | Same as `traefik.frontend.auth.forward.tls.key`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`                 | Same as `traefik.frontend.auth.forward.trustForwardHeader`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                      | Same as `traefik.frontend.auth.headerField`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                    | Same as `traefik.frontend.entryPoints`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                           | Same as `traefik.frontend.errors.<name>.backend`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                             | Same as `traefik.frontend.errors.<name>.query`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                           | Same as `traefik.frontend.errors.<name>.status`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                                  | Same as `traefik.frontend.passHostHeader`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName`       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true`          | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country`          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`                | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`               | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                    | Same as `traefik.frontend.passTLSClientCert.infos.sans`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`      | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`         | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                           | Same as `traefik.frontend.passTLSClientCert.infos.pem`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                     | Same as `traefik.frontend.passTLSCert`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                          | Same as `traefik.frontend.priority`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                          | Same as `traefik.frontend.rateLimit.extractorFunc`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                    | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`                   | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                     | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                            | Same as `traefik.frontend.redirect.entryPoint`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`                | Same as `traefik.frontend.redirect.regex`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`              | Same as `traefik.frontend.redirect.replacement`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                              | Same as `traefik.frontend.redirect.permanent`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                             | Same as `traefik.frontend.rule`                                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                          | Same as `traefik.frontend.whiteList.sourceRange`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                      | Same as `traefik.frontend.whiteList.useXForwardedFor`                      |
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
| Label                                                                | Description                                              |
 | 
			
		||||
|----------------------------------------------------------------------|----------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.frontend.headers.customRequestHeaders=EXPR ` | Same as `traefik.frontend.headers.customRequestHeaders`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.headers.customRequestHeaders=EXPR`  | Same as `traefik.frontend.headers.customRequestHeaders`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.headers.customResponseHeaders=EXPR` | Same as `traefik.frontend.headers.customResponseHeaders` |
 | 
			
		||||
 | 
			
		||||
#### Security Headers
 | 
			
		||||
 
 | 
			
		||||
@@ -136,78 +136,86 @@ Traefik needs the following policy to read ECS information:
 | 
			
		||||
 | 
			
		||||
Labels can be used on task containers to override default behaviour:
 | 
			
		||||
 | 
			
		||||
| Label                                                               | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                    | Sets the default base domain for frontend rules.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.enable=false`                                              | Disables this container in Traefik.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.port=80`                                                   | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container                                                                                                                                         |
 | 
			
		||||
| `traefik.protocol=https`                                            | Overrides the default `http` protocol                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.weight=10`                                                 | Assigns this weight to the container                                                                                                                                                                                          |
 | 
			
		||||
| `traefik.backend=foo`                                               | Gives the name `foo` to the generated backend for this container.                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                    | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`            | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                          | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                           | Defines the health check interval. (Default: 30s)                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                           | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                             | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                   | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                          | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                           | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                      | Enables backend sticky sessions                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`           | Sets the cookie manually  name for sticky sessions                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                          | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                 | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                   | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                  | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                     | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                            | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`             | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                    | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                           | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`            | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`         | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`            | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                 | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`           | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`         | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`            | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`             | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                  | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.removeHeader=true`                           | If set to true, removes the Authorization header.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`            | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`           | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`  | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`     | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`    | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`    | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                       | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                           | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                         | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                              | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                 | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.priority=10`                                      | Overrides default frontend priority                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                      | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`               | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                 | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                        | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`            | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`          | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                          | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                        | Overrides the default frontend rule. Default: `Host:{instance_name}.{domain}`.                                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                      | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                  | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
| Label                                                                   | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                        | Sets the default base domain for frontend rules.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.enable=false`                                                  | Disables this container in Traefik.                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.port=80`                                                       | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container                                                                                                                                         |
 | 
			
		||||
| `traefik.protocol=https`                                                | Overrides the default `http` protocol                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.weight=10`                                                     | Assigns this weight to the container                                                                                                                                                                                          |
 | 
			
		||||
| `traefik.backend=foo`                                                   | Overrides the service name by `foo` in the generated name of the backend.                                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                        | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`                 | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                              | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                               | Defines the health check interval. (Default: 30s)                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                               | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                                 | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                       | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                              | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                               | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                          | Enables backend sticky sessions                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`               | Sets the cookie manually  name for sticky sessions                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                              | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                     | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                       | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                      | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                         | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                                | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                        | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                               | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`                | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`             | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`                | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                     | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`               | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`             | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`                | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`                 | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                      | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.removeHeader=true`                               | If set to true, removes the Authorization header.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true`          | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                     |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true`         | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true`     | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true`         | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`                | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`               | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                    | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`      | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`         | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`        | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`    | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`        | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                           | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                               | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                             | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                                  | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                     | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.priority=10`                                          | Overrides default frontend priority                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                          | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                    | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`                   | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                     | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                            | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`                | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`              | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                              | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                            | Overrides the default frontend rule. Default: `Host:{instance_name}.{domain}`.                                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                          | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                      | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
 | 
			
		||||
### Custom Headers
 | 
			
		||||
 | 
			
		||||
@@ -249,58 +257,66 @@ You can define as many segments as ports exposed in an application.
 | 
			
		||||
 | 
			
		||||
Segment labels override the default behavior.
 | 
			
		||||
 | 
			
		||||
| Label                                                                               | Description                                                             |
 | 
			
		||||
|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                            | Same as `traefik.backend`                                               |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                              | Same as `traefik.domain`                                                |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                  | Same as `traefik.port`                                                  |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                              | Same as `traefik.protocol`                                              |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                  | Same as `traefik.weight`                                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                   | Same as `traefik.frontend.auth.basic`                                   |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                      | Same as `traefik.frontend.auth.basic.removeHeader`                      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                             | Same as `traefik.frontend.auth.basic.users`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`              | Same as `traefik.frontend.auth.basic.usersFile`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                     | Same as `traefik.frontend.auth.digest.removeHeader`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                            | Same as `traefik.frontend.auth.digest.users`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`             | Same as `traefik.frontend.auth.digest.usersFile`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`          | Same as `traefik.frontend.auth.forward.address`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`             | Same as `traefik.frontend.auth.forward.authResponseHeaders`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                  | Same as `traefik.frontend.auth.forward.tls.ca`                          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                  | Same as `traefik.frontend.auth.forward.tls.caOptional`                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`            | Same as `traefik.frontend.auth.forward.tls.cert`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`          | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`             | Same as `traefik.frontend.auth.forward.tls.key`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`              | Same as `traefik.frontend.auth.forward.trustForwardHeader`              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                   | Same as `traefik.frontend.auth.headerField`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.removeHeader=true`                            | Same as `traefik.frontend.auth.removeHeader`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                 | Same as `traefik.frontend.entryPoints`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                        | Same as `traefik.frontend.errors.<name>.backend`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                          | Same as `traefik.frontend.errors.<name>.query`                          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                        | Same as `traefik.frontend.errors.<name>.status`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                               | Same as `traefik.frontend.passHostHeader`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`             | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`            | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                 | Same as `traefik.frontend.passTLSClientCert.infos.sans`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`   | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`   |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`      | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`     | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`     | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                        | Same as `traefik.frontend.passTLSClientCert.infos.pem`                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                  | Same as `traefik.frontend.passTLSCert`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                       | Same as `traefik.frontend.priority`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                       | Same as `traefik.frontend.rateLimit.extractorFunc`                      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                 | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`                | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                  | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                         | Same as `traefik.frontend.redirect.entryPoint`                          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`             | Same as `traefik.frontend.redirect.regex`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`           | Same as `traefik.frontend.redirect.replacement`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                           | Same as `traefik.frontend.redirect.permanent`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                          | Same as `traefik.frontend.rule`                                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                       | Same as `traefik.frontend.whiteList.sourceRange`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                   | Same as `traefik.frontend.whiteList.useXForwardedFor`                   |
 | 
			
		||||
| Label                                                                                  | Description                                                                |
 | 
			
		||||
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                               | Same as `traefik.backend`                                                  |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                                 | Same as `traefik.domain`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                     | Same as `traefik.port`                                                     |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                                 | Same as `traefik.protocol`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                     | Same as `traefik.weight`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                      | Same as `traefik.frontend.auth.basic`                                      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                         | Same as `traefik.frontend.auth.basic.removeHeader`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                                | Same as `traefik.frontend.auth.basic.users`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Same as `traefik.frontend.auth.basic.usersFile`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                        | Same as `traefik.frontend.auth.digest.removeHeader`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                               | Same as `traefik.frontend.auth.digest.users`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`                | Same as `traefik.frontend.auth.digest.usersFile`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`             | Same as `traefik.frontend.auth.forward.address`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`                | Same as `traefik.frontend.auth.forward.authResponseHeaders`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Same as `traefik.frontend.auth.forward.tls.ca`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                     | Same as `traefik.frontend.auth.forward.tls.caOptional`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`               | Same as `traefik.frontend.auth.forward.tls.cert`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`             | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`                | Same as `traefik.frontend.auth.forward.tls.key`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`                 | Same as `traefik.frontend.auth.forward.trustForwardHeader`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                      | Same as `traefik.frontend.auth.headerField`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.removeHeader=true`                               | Same as `traefik.frontend.auth.removeHeader`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                    | Same as `traefik.frontend.entryPoints`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                           | Same as `traefik.frontend.errors.<name>.backend`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                             | Same as `traefik.frontend.errors.<name>.query`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                           | Same as `traefik.frontend.errors.<name>.status`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                                  | Same as `traefik.frontend.passHostHeader`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName`       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true`          | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country`          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`                | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`               | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                    | Same as `traefik.frontend.passTLSClientCert.infos.sans`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`      | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`         | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                           | Same as `traefik.frontend.passTLSClientCert.infos.pem`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                     | Same as `traefik.frontend.passTLSCert`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                          | Same as `traefik.frontend.priority`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                          | Same as `traefik.frontend.rateLimit.extractorFunc`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                    | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`                   | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                     | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                            | Same as `traefik.frontend.redirect.entryPoint`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`                | Same as `traefik.frontend.redirect.regex`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`              | Same as `traefik.frontend.redirect.replacement`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                              | Same as `traefik.frontend.redirect.permanent`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                             | Same as `traefik.frontend.rule`                                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                          | Same as `traefik.frontend.whiteList.sourceRange`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                      | Same as `traefik.frontend.whiteList.useXForwardedFor`                      |
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -64,16 +64,21 @@ Traefik can be configured with a file.
 | 
			
		||||
      "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
 | 
			
		||||
    ]
 | 
			
		||||
    [frontends.frontend1.passTLSClientCert]
 | 
			
		||||
        # Pass the escaped pem in a `X-Forwarded-Ssl-Client-Cert` header
 | 
			
		||||
        pem = true
 | 
			
		||||
        # Pass the escaped client cert infos selected below in a `X-Forwarded-Ssl-Client-Cert-Infos` header
 | 
			
		||||
        # The unescaped header is like `Subject="C=%s,ST=%s,L=%s,O=%s,CN=%s",NB=%d,NA=%d,SAN=%s`
 | 
			
		||||
        # It there is more than one certificates, their are separated by a `;`
 | 
			
		||||
        [frontends.frontend-server.passTLSClientCert.infos]
 | 
			
		||||
        [frontends.frontend1.passTLSClientCert.infos]
 | 
			
		||||
            notBefore = true
 | 
			
		||||
            notAfter = true
 | 
			
		||||
            [frontends.frontend-server.passTLSClientCert.infos.subject]
 | 
			
		||||
            [frontends.frontend1.passTLSClientCert.infos.subject]
 | 
			
		||||
                country = true
 | 
			
		||||
                domainComponent = true
 | 
			
		||||
                province = true
 | 
			
		||||
                locality = true
 | 
			
		||||
                organization = true
 | 
			
		||||
                commonName = true
 | 
			
		||||
                serialNumber = true
 | 
			
		||||
            [frontends.frontend1.passTLSClientCert.infos.issuer]
 | 
			
		||||
                country = true
 | 
			
		||||
                domainComponent = true
 | 
			
		||||
                province = true
 | 
			
		||||
                locality = true
 | 
			
		||||
                organization = true
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,14 @@ See also [Kubernetes user guide](/user-guide/kubernetes).
 | 
			
		||||
#
 | 
			
		||||
# enablePassTLSCert = true
 | 
			
		||||
 | 
			
		||||
# Throttle how frequently we refresh our configuration from Ingresses when there
 | 
			
		||||
# are frequent changes.
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
# Default: 0 (no throttling)
 | 
			
		||||
#
 | 
			
		||||
# throttleDuration = 10s
 | 
			
		||||
 | 
			
		||||
# Override default configuration template.
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
@@ -128,10 +136,11 @@ This will give more flexibility in cloud/dynamic environments.
 | 
			
		||||
Traefik automatically requests endpoint information based on the service provided in the ingress spec.
 | 
			
		||||
Although traefik will connect directly to the endpoints (pods), it still checks the service port to see if TLS communication is required.
 | 
			
		||||
 | 
			
		||||
There are 2 ways to configure Traefik to use https to communicate with backend pods:
 | 
			
		||||
There are 3 ways to configure Traefik to use https to communicate with backend pods:
 | 
			
		||||
 | 
			
		||||
1. If the service port defined in the ingress spec is 443 (note that you can still use `targetPort` to use a different port on your pod).
 | 
			
		||||
2. If the service port defined in the ingress spec has a name that starts with `https` (such as `https-api`, `https-web` or just `https`).
 | 
			
		||||
3. If the ingress spec includes the annotation `ingress.kubernetes.io/protocol: https`.
 | 
			
		||||
 | 
			
		||||
If either of those configuration options exist, then the backend communication protocol is assumed to be TLS, and will connect via TLS automatically.
 | 
			
		||||
 | 
			
		||||
@@ -166,7 +175,7 @@ The following general annotations are applicable on the Ingress object:
 | 
			
		||||
| `traefik.ingress.kubernetes.io/service-weights: <YML>`                          | Set ingress backend weights specified as percentage or decimal numbers in YAML. (6)                                                                                                        |
 | 
			
		||||
| `traefik.ingress.kubernetes.io/whitelist-source-range: "1.2.3.0/24, fe80::/16"` | A comma-separated list of IP ranges permitted for access (7).                                                                                                                              |
 | 
			
		||||
| `ingress.kubernetes.io/whitelist-x-forwarded-for: "true"`                       | Use `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                     |
 | 
			
		||||
| `ingress.kubernetes.io/protocol: <NAME>`                                        | Set the protocol Traefik will use to communicate with pods.                                                                                                                                |
 | 
			
		||||
| `ingress.kubernetes.io/protocol:<NAME>`                                | Set the protocol Traefik will use to communicate with pods. Acceptable protocols: http,https,h2c                                                                                                                        |
 | 
			
		||||
 | 
			
		||||
<1> `traefik.ingress.kubernetes.io/app-root`:
 | 
			
		||||
Non-root paths will not be affected by this annotation and handled normally.
 | 
			
		||||
@@ -209,10 +218,14 @@ infos:
 | 
			
		||||
    serialnumber: true
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If `pem` is set, it will add a `X-Forwarded-Tls-Client-Cert` header that contains the escaped pem as value.  
 | 
			
		||||
If `pem` is set, it will add a `X-Forwarded-Tls-Client-Cert` header that contains the escaped pem as value.
 | 
			
		||||
If at least one flag of the `infos` part is set, it will add a `X-Forwarded-Tls-Client-Cert-Infos` header that contains an escaped string composed of the client certificate data selected by the infos flags.
 | 
			
		||||
This infos part is composed like the following example (not escaped):
 | 
			
		||||
```Subject="C=FR,ST=SomeState,L=Lyon,O=Cheese,CN=*.cheese.org",NB=1531900816,NA=1563436816,SAN=*.cheese.org,*.cheese.net,cheese.in,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2```
 | 
			
		||||
```
 | 
			
		||||
Subject="C=FR,ST=SomeState,L=Lyon,O=Cheese,CN=*.cheese.org",NB=1531900816,NA=1563436816,SAN=*.cheese.org,*.cheese.net,cheese.in,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note these options work only with certificates issued by CAs included in the applicable [EntryPoint ClientCA section](/configuration/entrypoints/#tls-mutual-authentication); certificates from other CAs are not parsed or passed through as-is.
 | 
			
		||||
 | 
			
		||||
<4> `traefik.ingress.kubernetes.io/rate-limit` example:
 | 
			
		||||
 | 
			
		||||
@@ -230,7 +243,7 @@ rateset:
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<5> `traefik.ingress.kubernetes.io/rule-type`
 | 
			
		||||
Note: `ReplacePath` is deprecated in this annotation, use the `traefik.ingress.kubernetes.io/request-modifier` annotation instead. Default: `PathPrefix`. 
 | 
			
		||||
Note: `ReplacePath` is deprecated in this annotation, use the `traefik.ingress.kubernetes.io/request-modifier` annotation instead. Default: `PathPrefix`.
 | 
			
		||||
 | 
			
		||||
<6> `traefik.ingress.kubernetes.io/service-weights`:
 | 
			
		||||
Service weights enable to split traffic across multiple backing services in a fine-grained manner.
 | 
			
		||||
@@ -316,7 +329,7 @@ The following security annotations are applicable on the Ingress object:
 | 
			
		||||
| `ingress.kubernetes.io/custom-browser-xss-value: VALUE`   | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option.                                                                                                           |
 | 
			
		||||
| `ingress.kubernetes.io/custom-frame-options-value: VALUE` | Overrides the `X-Frame-Options` header with the custom value.                                                                                                                                       |
 | 
			
		||||
| `ingress.kubernetes.io/force-hsts: "false"`               | Adds the STS  header to non-SSL requests.                                                                                                                                                           |
 | 
			
		||||
| `ingress.kubernetes.io/frame-deny: "false"`               | Adds the `X-Frame-Options` header with the value of `DENY`.                                                                                                                                         |
 | 
			
		||||
| `ingress.kubernetes.io/frame-deny: "true"`                | Adds the `X-Frame-Options` header with the value of `DENY`.                                                                                                                                         |
 | 
			
		||||
| `ingress.kubernetes.io/hsts-max-age: "315360000"`         | Sets the max-age of the HSTS header.                                                                                                                                                                |
 | 
			
		||||
| `ingress.kubernetes.io/hsts-include-subdomains: "true"`   | Adds the IncludeSubdomains section of the STS  header.                                                                                                                                              |
 | 
			
		||||
| `ingress.kubernetes.io/hsts-preload: "true"`              | Adds the preload flag to the HSTS  header.                                                                                                                                                          |
 | 
			
		||||
 
 | 
			
		||||
@@ -193,79 +193,87 @@ They may be specified on one of two levels: Application or service.
 | 
			
		||||
 | 
			
		||||
The following labels can be defined on Marathon applications. They adjust the behavior for the entire application.
 | 
			
		||||
 | 
			
		||||
| Label                                                               | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                    | Sets the default base domain used for the frontend rules.                                                                                                                                                                          |
 | 
			
		||||
| `traefik.enable=false`                                              | Disables this container in Traefik.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.port=80`                                                   | Registers this port. Useful when the container exposes multiples ports.                                                                                                                                                       |
 | 
			
		||||
| `traefik.portIndex=1`                                               | Registers port by index in the application's ports array. Useful when the application exposes multiple ports.                                                                                                                 |
 | 
			
		||||
| `traefik.protocol=https`                                            | Overrides the default `http` protocol.                                                                                                                                                                                        |
 | 
			
		||||
| `traefik.weight=10`                                                 | Assigns this weight to the container.                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.backend=foo`                                               | Gives the name `foo` to the generated backend for this container.                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                    | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`             | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                          | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                           | Defines the health check interval. (Default: 30s)                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                             | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                           | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                   | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                          | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                           | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                      | Enables backend sticky sessions                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`           | Sets the cookie name manually for sticky sessions                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                          | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                 | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                   | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                  | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                     | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                            | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`             | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                    | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                           | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`            | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`         | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`            | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                 | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`           | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`         | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`            | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`             | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                  | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.removeHeader=true`                           | If set to true, removes the Authorization header.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                           | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                         | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                              | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`            | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`           | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`  | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`     | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`    | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`    | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                       | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                 | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.priority=10`                                      | Overrides default frontend priority                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                      | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`               | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                 | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                        | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`            | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`          | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                          | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                        | Overrides the default frontend rule. Default: `Host:{sub_domain}.{domain}`.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                      | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                  | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
| Label                                                                   | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                        | Sets the default base domain used for the frontend rules.                                                                                                                                                                     |
 | 
			
		||||
| `traefik.enable=false`                                                  | Disables this container in Traefik.                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.port=80`                                                       | Registers this port. Useful when the container exposes multiples ports.                                                                                                                                                       |
 | 
			
		||||
| `traefik.portIndex=1`                                                   | Registers port by index in the application's ports array. Useful when the application exposes multiple ports.                                                                                                                 |
 | 
			
		||||
| `traefik.protocol=https`                                                | Overrides the default `http` protocol.                                                                                                                                                                                        |
 | 
			
		||||
| `traefik.weight=10`                                                     | Assigns this weight to the container.                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.backend=foo`                                                   | Overrides the application name by `foo` in the generated name of the backend.                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                        | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`                 | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                              | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                               | Defines the health check interval. (Default: 30s)                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                                 | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                               | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                       | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                              | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                               | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                          | Enables backend sticky sessions                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`               | Sets the cookie name manually for sticky sessions                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                              | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                     | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                       | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                      | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                         | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                                | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                        | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                               | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`                | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`             | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`                | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                     | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`               | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`             | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`                | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`                 | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                      | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.removeHeader=true`                               | If set to true, removes the Authorization header.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                               | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                             | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                                  | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true`          | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                     |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true`         | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true`     | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true`         | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`                | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`               | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                    | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`      | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`         | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`        | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`    | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`        | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                           | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                     | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.priority=10`                                          | Overrides default frontend priority                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                          | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                    | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`                   | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                     | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                            | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`                | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`              | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                              | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                            | Overrides the default frontend rule. Default: `Host:{sub_domain}.{domain}`.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                          | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                      | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
@@ -308,59 +316,67 @@ You can define as many segments as ports exposed in an application.
 | 
			
		||||
 | 
			
		||||
Segment labels override the default behavior.
 | 
			
		||||
 | 
			
		||||
| Label                                                                              | Description                                                            |
 | 
			
		||||
|------------------------------------------------------------------------------------|------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                           | Same as `traefik.backend`                                              |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                             | Same as `traefik.domain`                                               |
 | 
			
		||||
| `traefik.<segment_name>.portIndex=1`                                               | Same as `traefik.portIndex`                                            |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                 | Same as `traefik.port`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                             | Same as `traefik.protocol`                                             |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                 | Same as `traefik.weight`                                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                  | Same as `traefik.frontend.auth.basic`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                     | Same as `traefik.frontend.auth.basic.removeHeader`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                            | Same as `traefik.frontend.auth.basic.users`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`             | Same as `traefik.frontend.auth.basic.usersFile`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                    | Same as `traefik.frontend.auth.digest.removeHeader`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                           | Same as `traefik.frontend.auth.digest.users`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`            | Same as `traefik.frontend.auth.digest.usersFile`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`         | Same as `traefik.frontend.auth.forward.address`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`            | Same as `traefik.frontend.auth.forward.authResponseHeaders`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Same as `traefik.frontend.auth.forward.tls.ca`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                 | Same as `traefik.frontend.auth.forward.tls.caOptional`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`           | Same as `traefik.frontend.auth.forward.tls.cert`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`         | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`            | Same as `traefik.frontend.auth.forward.tls.key`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`             | Same as `traefik.frontend.auth.forward.trustForwardHeader`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                  | Same as `traefik.frontend.auth.headerField`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.removeHeader=true`                           | Same as `traefik.frontend.auth.removeHeader`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                | Same as `traefik.frontend.entryPoints`                                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                       | Same as `traefik.frontend.errors.<name>.backend`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                         | Same as `traefik.frontend.errors.<name>.query`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                       | Same as `traefik.frontend.errors.<name>.status`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                              | Same as `traefik.frontend.passHostHeader`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`            | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`           | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                | Same as `traefik.frontend.passTLSClientCert.infos.sans`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`  | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`     | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`|
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`|
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                       | Same as `traefik.frontend.passTLSClientCert.infos.pem`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                 | Same as `traefik.frontend.passTLSCert`                                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                      | Same as `traefik.frontend.priority`                                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                      | Same as `traefik.frontend.rateLimit.extractorFunc`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`               | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                 | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                        | Same as `traefik.frontend.redirect.entryPoint`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`            | Same as `traefik.frontend.redirect.regex`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`          | Same as `traefik.frontend.redirect.replacement`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                          | Same as `traefik.frontend.redirect.permanent`                          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                         | Same as `traefik.frontend.rule`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                      | Same as `traefik.frontend.whiteList.sourceRange`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                  | Same as `traefik.frontend.whiteList.useXForwardedFor`                  |
 | 
			
		||||
| Label                                                                                  | Description                                                                |
 | 
			
		||||
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                               | Same as `traefik.backend`                                                  |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                                 | Same as `traefik.domain`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.portIndex=1`                                                   | Same as `traefik.portIndex`                                                |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                     | Same as `traefik.port`                                                     |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                                 | Same as `traefik.protocol`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                     | Same as `traefik.weight`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                      | Same as `traefik.frontend.auth.basic`                                      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                         | Same as `traefik.frontend.auth.basic.removeHeader`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                                | Same as `traefik.frontend.auth.basic.users`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Same as `traefik.frontend.auth.basic.usersFile`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                        | Same as `traefik.frontend.auth.digest.removeHeader`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                               | Same as `traefik.frontend.auth.digest.users`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`                | Same as `traefik.frontend.auth.digest.usersFile`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`             | Same as `traefik.frontend.auth.forward.address`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`                | Same as `traefik.frontend.auth.forward.authResponseHeaders`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Same as `traefik.frontend.auth.forward.tls.ca`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                     | Same as `traefik.frontend.auth.forward.tls.caOptional`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`               | Same as `traefik.frontend.auth.forward.tls.cert`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`             | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`                | Same as `traefik.frontend.auth.forward.tls.key`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`                 | Same as `traefik.frontend.auth.forward.trustForwardHeader`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                      | Same as `traefik.frontend.auth.headerField`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.removeHeader=true`                               | Same as `traefik.frontend.auth.removeHeader`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                    | Same as `traefik.frontend.entryPoints`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                           | Same as `traefik.frontend.errors.<name>.backend`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                             | Same as `traefik.frontend.errors.<name>.query`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                           | Same as `traefik.frontend.errors.<name>.status`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                                  | Same as `traefik.frontend.passHostHeader`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName`       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true`          | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country`          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`                | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`               | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                    | Same as `traefik.frontend.passTLSClientCert.infos.sans`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`      | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`         | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                           | Same as `traefik.frontend.passTLSClientCert.infos.pem`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                     | Same as `traefik.frontend.passTLSCert`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                          | Same as `traefik.frontend.priority`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                          | Same as `traefik.frontend.rateLimit.extractorFunc`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                    | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`                   | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                     | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                            | Same as `traefik.frontend.redirect.entryPoint`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`                | Same as `traefik.frontend.redirect.regex`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`              | Same as `traefik.frontend.redirect.replacement`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                              | Same as `traefik.frontend.redirect.permanent`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                             | Same as `traefik.frontend.rule`                                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                          | Same as `traefik.frontend.whiteList.sourceRange`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                      | Same as `traefik.frontend.whiteList.useXForwardedFor`                      |
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -106,79 +106,87 @@ domain = "mesos.localhost"
 | 
			
		||||
 | 
			
		||||
The following labels can be defined on Mesos tasks. They adjust the behavior for the entire application.
 | 
			
		||||
 | 
			
		||||
| Label                                                               | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                    | Sets the default base domain for the frontend rules.                                                                                                                                                                               |
 | 
			
		||||
| `traefik.enable=false`                                              | Disables this container in Traefik.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.port=80`                                                   | Registers this port. Useful when the application exposes multiple ports.                                                                                                                                                      |
 | 
			
		||||
| `traefik.portName=web`                                              | Registers port by name in the application's ports array. Useful when the application exposes multiple ports.                                                                                                                  |
 | 
			
		||||
| `traefik.portIndex=1`                                               | Registers port by index in the application's ports array. Useful when the application exposes multiple ports.                                                                                                                 |
 | 
			
		||||
| `traefik.protocol=https`                                            | Overrides the default `http` protocol                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.weight=10`                                                 | Assigns this weight to the container                                                                                                                                                                                          |
 | 
			
		||||
| `traefik.backend=foo`                                               | Gives the name `foo` to the generated backend for this container.                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                    | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`             | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                          | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                           | Defines the health check interval. (Default: 30s)                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                           | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                             | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                   | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                          | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                           | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                      | Enables backend sticky sessions                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`           | Sets the cookie manually name for sticky sessions                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                 | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                   | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                  | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                            | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                     | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`             | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                    | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                           | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`            | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`         | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`            | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                 | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`           | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`         | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`            | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`             | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                  | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.removeHeader=true`                           | If set to true, removes the Authorization header.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                           | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                         | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                              | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`            | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`           | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`  | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`     | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`    | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`    | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                       | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                 | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.priority=10`                                      | Overrides default frontend priority                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                      | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`               | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                 | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                        | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`            | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`          | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                          | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                        | Overrides the default frontend rule. Default: `Host:{discovery_name}.{domain}`.                                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                      | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                  | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
| Label                                                                   | Description                                                                                                                                                                                                                   |
 | 
			
		||||
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                        | Sets the default base domain for the frontend rules.                                                                                                                                                                          |
 | 
			
		||||
| `traefik.enable=false`                                                  | Disables this container in Traefik.                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.port=80`                                                       | Registers this port. Useful when the application exposes multiple ports.                                                                                                                                                      |
 | 
			
		||||
| `traefik.portName=web`                                                  | Registers port by name in the application's ports array. Useful when the application exposes multiple ports.                                                                                                                  |
 | 
			
		||||
| `traefik.portIndex=1`                                                   | Registers port by index in the application's ports array. Useful when the application exposes multiple ports.                                                                                                                 |
 | 
			
		||||
| `traefik.protocol=https`                                                | Overrides the default `http` protocol                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.weight=10`                                                     | Assigns this weight to the container                                                                                                                                                                                          |
 | 
			
		||||
| `traefik.backend=foo`                                                   | Overrides the task name by `foo` in the generated name of the backend.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                        | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`                 | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                              | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                               | Defines the health check interval. (Default: 30s)                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                               | Overrides the server URL scheme.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                                 | Sets a different port for the health check.                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                       | Defines the health check hostname.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                              | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                     |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                               | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                          | Enables backend sticky sessions                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`               | Sets the cookie manually name for sticky sessions                                                                                                                                                                             |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                     | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                      |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                       | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                        |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                      | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                                | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`.                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                         | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                        | If set to `true`, removes the `Authorization` header.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                               | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`                | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`             | Sets the URL of the authentication server.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`                | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                     | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`               | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`             | If set to true invalid SSL certificates are accepted.                                                                                                                                                                         |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`                | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`                 | Trusts X-Forwarded-* headers.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                      | Sets the header used to pass the authenticated user to the application.                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.removeHeader=true`                               | If set to true, removes the Authorization header.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                               | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                             | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                                  | Forwards client `Host` header to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true`          | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                     |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true`         | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true`     | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true`         | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`                | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`               | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                    | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`      | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`         | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                            |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`        | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`    | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`        | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                           | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                     | Forwards TLS Client certificates to the backend.                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.priority=10`                                          | Overrides default frontend priority                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                          | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                    | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`                   | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                     | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                           |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                            | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`                | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`              | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                              | Returns 301 instead of 302.                                                                                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                            | Overrides the default frontend rule. Default: `Host:{discovery_name}.{domain}`.                                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                          | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                      | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                       |
 | 
			
		||||
 | 
			
		||||
### Custom Headers
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,11 @@
 | 
			
		||||
 | 
			
		||||
Traefik can be configured to use Rancher as a provider.
 | 
			
		||||
 | 
			
		||||
!!! important
 | 
			
		||||
    This provider is specific to Rancher 1.x.
 | 
			
		||||
    Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query.
 | 
			
		||||
    As such, Rancher 2.x users should utilize the [Kubernetes provider](./kubernetes.md) directly.
 | 
			
		||||
 | 
			
		||||
## Global Configuration
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
@@ -138,77 +143,85 @@ secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 | 
			
		||||
 | 
			
		||||
Labels can be used on task containers to override default behavior:
 | 
			
		||||
 | 
			
		||||
| Label                                                               | Description                                                                                                                                                                                                                      |
 | 
			
		||||
|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                    | Sets the default base domain for the frontend rules.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.enable=false`                                              | Disables this container in Traefik.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.port=80`                                                   | Registers this port. Useful when the container exposes multiple ports.                                                                                                                                                           |
 | 
			
		||||
| `traefik.protocol=https`                                            | Overrides the default `http` protocol.                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.weight=10`                                                 | Assigns this weight to the container.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend=foo`                                               | Gives the name `foo` to the generated backend for this container.                                                                                                                                                                |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                   | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                  | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                    | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                    | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                    |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`             | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                          | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                           | Defines the health check interval.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                             | Sets a different port for the health check.                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                           | Overrides the server URL scheme.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                   | Defines the health check hostname.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                          | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                        |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                           | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                      | Enables backend sticky sessions                                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`           | Sets the cookie name manually for sticky sessions                                                                                                                                                                                |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                          | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                 | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                         |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                   | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                           |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                  | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                     | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                            | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` .                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`             | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                    | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                           | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`            | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`         | Sets the URL of the authentication server.                                                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`            | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                 | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`           | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`         | If set to true invalid SSL certificates are accepted.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`            | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`             | Trusts X-Forwarded-* headers.                                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                  | Sets the header used to pass the authenticated user to the application.                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                           | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                         | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                       | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                              | Forwards client `Host` header to the backend.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`            | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`           | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`  | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`     | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`    | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`    | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                       | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                 | Forwards TLS Client certificates to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.priority=10`                                      | Overrides default frontend priority                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                      | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`               | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                 | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                        | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`            | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`          | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                          | Returns 301 instead of 302.                                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                        | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`.                                                                     |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                      | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                  | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                          |
 | 
			
		||||
| Label                                                                   | Description                                                                                                                                                                                                                      |
 | 
			
		||||
|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.domain`                                                        | Sets the default base domain for the frontend rules.                                                                                                                                                                             |
 | 
			
		||||
| `traefik.enable=false`                                                  | Disables this container in Traefik.                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.port=80`                                                       | Registers this port. Useful when the container exposes multiple ports.                                                                                                                                                           |
 | 
			
		||||
| `traefik.protocol=https`                                                | Overrides the default `http` protocol.                                                                                                                                                                                           |
 | 
			
		||||
| `traefik.weight=10`                                                     | Assigns this weight to the container.                                                                                                                                                                                            |
 | 
			
		||||
| `traefik.backend=foo`                                                   | Overrides the service name by `foo` in the generated name of the backend.                                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.buffering.maxRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.maxResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memRequestBodyBytes=0`                       | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.memResponseBodyBytes=0`                      | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.buffering.retryExpression=EXPR`                        | See [buffering](/configuration/commons/#buffering) section.                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`                        | Creates a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                                    |
 | 
			
		||||
| `traefik.backend.responseForwarding.flushInterval=10ms`                 | Defines the interval between two flushes when forwarding response from backend to client.                                                                                                                                        |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                              | Enables health check for the backend, hitting the container at `path`.                                                                                                                                                           |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                               | Defines the health check interval.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                                 | Sets a different port for the health check.                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.backend.healthcheck.scheme=http`                               | Overrides the server URL scheme.                                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.backend.healthcheck.hostname=foobar.com`                       | Defines the health check hostname.                                                                                                                                                                                               |
 | 
			
		||||
| `traefik.backend.healthcheck.headers=EXPR`                              | Defines the health check request headers <br>Format:  <code>HEADER:value||HEADER2:value2</code>                                                                                                                        |
 | 
			
		||||
| `traefik.backend.loadbalancer.method=drr`                               | Overrides the default `wrr` load balancer algorithm                                                                                                                                                                              |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness=true`                          | Enables backend sticky sessions                                                                                                                                                                                                  |
 | 
			
		||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME`               | Sets the cookie name manually for sticky sessions                                                                                                                                                                                |
 | 
			
		||||
| `traefik.backend.loadbalancer.sticky=true`                              | Enables backend sticky sessions (DEPRECATED)                                                                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.maxconn.amount=10`                                     | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect.                                                                                                         |
 | 
			
		||||
| `traefik.backend.maxconn.extractorfunc=client.ip`                       | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect.                                           |
 | 
			
		||||
| `traefik.frontend.auth.basic=EXPR`                                      | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED).                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.basic.removeHeader=true`                         | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.users=EXPR`                                | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` .                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                        |
 | 
			
		||||
| `traefik.frontend.auth.digest.removeHeader=true`                        | If set to `true`, removes the `Authorization` header.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.digest.users=EXPR`                               | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest`                | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence.                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.address=https://example.com`             | Sets the URL of the authentication server.                                                                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR`                | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header`                                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Sets the Certificate Authority (CA) for the TLS connection with the authentication server.                                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.caOptional=true`                     | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA).                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem`               | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`             | If set to true invalid SSL certificates are accepted.                                                                                                                                                                            |
 | 
			
		||||
| `traefik.frontend.auth.forward.tls.key=/path/server.key`                | Sets the Certificate for the TLS connection with the authentication server.                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.auth.forward.trustForwardHeader=true`                 | Trusts X-Forwarded-* headers.                                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.auth.headerField=X-WebAuth-User`                      | Sets the header used to pass the authenticated user to the application.                                                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.entryPoints=http,https`                               | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints`                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.errors.<name>.backend=NAME`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.query=PATH`                             | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.errors.<name>.status=RANGE`                           | See [custom error pages](/configuration/commons/#custom-error-pages) section.                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passHostHeader=true`                                  | Forwards client `Host` header to the backend.                                                                                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                     |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true`          | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                        |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true`         | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true`     | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true`         | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                   |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notAfter=true`                | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.notBefore=true`               | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.sans=true`                    | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true`      | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                    |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.country=true`         | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                       |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                               |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true`        | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`    | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.province=true`        | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header.                                                                                                                  |
 | 
			
		||||
| `traefik.frontend.passTLSClientCert.pem=true`                           | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header.                                                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.passTLSCert=true`                                     | Forwards TLS Client certificates to the backend.                                                                                                                                                                                 |
 | 
			
		||||
| `traefik.frontend.priority=10`                                          | Overrides default frontend priority                                                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.extractorFunc=EXP`                          | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.period=6`                    | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.average=6`                   | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6`                     | See [rate limiting](/configuration/commons/#rate-limiting) section.                                                                                                                                                              |
 | 
			
		||||
| `traefik.frontend.redirect.entryPoint=https`                            | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS)                                                                                                                                                             |
 | 
			
		||||
| `traefik.frontend.redirect.regex=^http://localhost/(.*)`                | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`.                                                                                                                          |
 | 
			
		||||
| `traefik.frontend.redirect.replacement=http://mydomain/$1`              | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`.                                                                                                                                |
 | 
			
		||||
| `traefik.frontend.redirect.permanent=true`                              | Returns 301 instead of 302.                                                                                                                                                                                                      |
 | 
			
		||||
| `traefik.frontend.rule=EXPR`                                            | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`.                                                                     |
 | 
			
		||||
| `traefik.frontend.whiteList.sourceRange=RANGE`                          | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
 | 
			
		||||
| `traefik.frontend.whiteList.useXForwardedFor=true`                      | Uses `X-Forwarded-For` header as valid source of IP for the white list.                                                                                                                                                          |
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
@@ -250,57 +263,65 @@ You can define as many segments as ports exposed in a container.
 | 
			
		||||
 | 
			
		||||
Segment labels override the default behavior.
 | 
			
		||||
 | 
			
		||||
| Label                                                                              | Description                                                            |
 | 
			
		||||
|------------------------------------------------------------------------------------|------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                           | Same as `traefik.backend`                                              |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                             | Same as `traefik.domain`                                               |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                 | Same as `traefik.port`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                             | Same as `traefik.protocol`                                             |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                 | Same as `traefik.weight`                                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                  | Same as `traefik.frontend.auth.basic`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                     | Same as `traefik.frontend.auth.basic.removeHeader`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                            | Same as `traefik.frontend.auth.basic.users`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`             | Same as `traefik.frontend.auth.basic.usersFile`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                    | Same as `traefik.frontend.auth.digest.removeHeader`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                           | Same as `traefik.frontend.auth.digest.users`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`            | Same as `traefik.frontend.auth.digest.usersFile`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`         | Same as `traefik.frontend.auth.forward.address`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`            | Same as `traefik.frontend.auth.forward.authResponseHeaders`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                 | Same as `traefik.frontend.auth.forward.tls.ca`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                 | Same as `traefik.frontend.auth.forward.tls.caOptional`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`           | Same as `traefik.frontend.auth.forward.tls.cert`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`         | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`            | Same as `traefik.frontend.auth.forward.tls.key`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`             | Same as `traefik.frontend.auth.forward.trustForwardHeader`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                  | Same as `traefik.frontend.auth.headerField`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                | Same as `traefik.frontend.entryPoints`                                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                       | Same as `traefik.frontend.errors.<name>.backend`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                         | Same as `traefik.frontend.errors.<name>.query`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                       | Same as `traefik.frontend.errors.<name>.status`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                              | Same as `traefik.frontend.passHostHeader`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`            | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`           | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                | Same as `traefik.frontend.passTLSClientCert.infos.sans`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`  | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`     | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`|
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`|
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                       | Same as `traefik.frontend.passTLSClientCert.infos.pem`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                 | Same as `traefik.frontend.passTLSCert`                                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                      | Same as `traefik.frontend.priority`                                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                      | Same as `traefik.frontend.rateLimit.extractorFunc`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`               | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                 | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                        | Same as `traefik.frontend.redirect.entryPoint`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`            | Same as `traefik.frontend.redirect.regex`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`          | Same as `traefik.frontend.redirect.replacement`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                          | Same as `traefik.frontend.redirect.permanent`                          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                         | Same as `traefik.frontend.rule`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                      | Same as `traefik.frontend.whiteList.sourceRange`                       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                  | Same as `traefik.frontend.whiteList.useXForwardedFor`                  |
 | 
			
		||||
| Label                                                                                  | Description                                                                |
 | 
			
		||||
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.<segment_name>.backend=BACKEND`                                               | Same as `traefik.backend`                                                  |
 | 
			
		||||
| `traefik.<segment_name>.domain=DOMAIN`                                                 | Same as `traefik.domain`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.port=PORT`                                                     | Same as `traefik.port`                                                     |
 | 
			
		||||
| `traefik.<segment_name>.protocol=http`                                                 | Same as `traefik.protocol`                                                 |
 | 
			
		||||
| `traefik.<segment_name>.weight=10`                                                     | Same as `traefik.weight`                                                   |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic=EXPR`                                      | Same as `traefik.frontend.auth.basic`                                      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true`                         | Same as `traefik.frontend.auth.basic.removeHeader`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR`                                | Same as `traefik.frontend.auth.basic.users`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd`                 | Same as `traefik.frontend.auth.basic.usersFile`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true`                        | Same as `traefik.frontend.auth.digest.removeHeader`                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR`                               | Same as `traefik.frontend.auth.digest.users`                               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest`                | Same as `traefik.frontend.auth.digest.usersFile`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`             | Same as `traefik.frontend.auth.forward.address`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR`                | Same as `traefik.frontend.auth.forward.authResponseHeaders`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem`                     | Same as `traefik.frontend.auth.forward.tls.ca`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true`                     | Same as `traefik.frontend.auth.forward.tls.caOptional`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem`               | Same as `traefik.frontend.auth.forward.tls.cert`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`             | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key`                | Same as `traefik.frontend.auth.forward.tls.key`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true`                 | Same as `traefik.frontend.auth.forward.trustForwardHeader`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User`                      | Same as `traefik.frontend.auth.headerField`                                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.entryPoints=https`                                    | Same as `traefik.frontend.entryPoints`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME`                           | Same as `traefik.frontend.errors.<name>.backend`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH`                             | Same as `traefik.frontend.errors.<name>.query`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE`                           | Same as `traefik.frontend.errors.<name>.status`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passHostHeader=true`                                  | Same as `traefik.frontend.passHostHeader`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true`       | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName`       |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true`          | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country`          |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true`  | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent`  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true`         | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true`     | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber`     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true`                | Same as `traefik.frontend.passTLSClientCert.infos.notAfter`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true`               | Same as `traefik.frontend.passTLSClientCert.infos.notBefore`               |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true`                    | Same as `traefik.frontend.passTLSClientCert.infos.sans`                    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true`      | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName`      |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true`         | Same as `traefik.frontend.passTLSClientCert.infos.subject.country`         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true`        | Same as `traefik.frontend.passTLSClientCert.infos.subject.province`        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`    | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`    |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true`                           | Same as `traefik.frontend.passTLSClientCert.infos.pem`                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.passTLSCert=true`                                     | Same as `traefik.frontend.passTLSCert`                                     |
 | 
			
		||||
| `traefik.<segment_name>.frontend.priority=10`                                          | Same as `traefik.frontend.priority`                                        |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP`                          | Same as `traefik.frontend.rateLimit.extractorFunc`                         |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6`                    | Same as `traefik.frontend.rateLimit.rateSet.<name>.period`                 |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6`                   | Same as `traefik.frontend.rateLimit.rateSet.<name>.average`                |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6`                     | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst`                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.entryPoint=https`                            | Same as `traefik.frontend.redirect.entryPoint`                             |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)`                | Same as `traefik.frontend.redirect.regex`                                  |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1`              | Same as `traefik.frontend.redirect.replacement`                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.redirect.permanent=true`                              | Same as `traefik.frontend.redirect.permanent`                              |
 | 
			
		||||
| `traefik.<segment_name>.frontend.rule=EXP`                                             | Same as `traefik.frontend.rule`                                            |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE`                          | Same as `traefik.frontend.whiteList.sourceRange`                           |
 | 
			
		||||
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true`                      | Same as `traefik.frontend.whiteList.useXForwardedFor`                      |
 | 
			
		||||
 | 
			
		||||
#### Custom Headers
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ Traefik can be configured:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
curl -XPUT @file "http://localhost:8080/api/providers/rest"
 | 
			
		||||
curl -XPUT -d @file "http://localhost:8080/api/providers/rest"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
with `@file`:
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,8 @@ Here is an example of an extension setting Traefik labels:
 | 
			
		||||
</StatelessServiceType>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> **Note**: The `Label` tag and its `Key` attribute are case sensitive. That is, if you use `label` instead of `Label` or `key` instead of `Key`, they will be silently ignored.
 | 
			
		||||
 | 
			
		||||
#### Property Manager
 | 
			
		||||
 | 
			
		||||
Set Labels with the property manager API to overwrite and add labels, while your service is running.
 | 
			
		||||
@@ -96,11 +98,12 @@ Labels, set through extensions or the property manager, can be used on services
 | 
			
		||||
 | 
			
		||||
| Label                                                      | Description                                                                                                                                                                                                               |
 | 
			
		||||
|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `traefik.enable=false`                                     | Disable this container in Traefik                                                                                                                                                                                          |
 | 
			
		||||
| `traefik.enable=false`                                     | Disable this container in Traefik                                                                                                                                                                                         |
 | 
			
		||||
| `traefik.backend.circuitbreaker.expression=EXPR`           | Create a [circuit breaker](/basics/#backends) to be used against the backend                                                                                                                                              |
 | 
			
		||||
| `traefik.servicefabric.groupname`                               | Group all services with the same name into a single backend in Traefik                                                                                                                                                     |
 | 
			
		||||
| `traefik.servicefabric.groupweight`                             | Set the weighting of the current services nodes in the backend group                                                                                                                                                      |
 | 
			
		||||
| `traefik.servicefabric.enablelabeloverrides`                             | Toggle whether labels can be overridden using the Service Fabric Property Manager API                                                                                                                                                      |
 | 
			
		||||
| `traefik.servicefabric.groupname`                          | Group all services with the same name into a single backend in Traefik                                                                                                                                                    |
 | 
			
		||||
| `traefik.servicefabric.groupweight`                        | Set the weighting of the current services nodes in the backend group                                                                                                                                                      |
 | 
			
		||||
| `traefik.servicefabric.enablelabeloverrides`               | Toggle whether labels can be overridden using the Service Fabric Property Manager API                                                                                                                                     |
 | 
			
		||||
| `traefik.servicefabric.endpointname`                       | Specify the name of the endpoint                                                                                                                                                                                          |
 | 
			
		||||
| `traefik.backend.healthcheck.path=/health`                 | Enable health check for the backend, hitting the container at `path`.                                                                                                                                                     |
 | 
			
		||||
| `traefik.backend.healthcheck.port=8080`                    | Allow to use a different port for the health check.                                                                                                                                                                       |
 | 
			
		||||
| `traefik.backend.healthcheck.interval=1s`                  | Define the health check interval.                                                                                                                                                                                         |
 | 
			
		||||
 
 | 
			
		||||
@@ -249,8 +249,13 @@ Multiple sets of rates can be added to each frontend, but the time periods must
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In the above example, frontend1 is configured to limit requests by the client's ip address.  
 | 
			
		||||
An average of 5 requests every 3 seconds is allowed and an average of 100 requests every 10 seconds.  
 | 
			
		||||
These can "burst" up to 10 and 200 in each period respectively.
 | 
			
		||||
An average of 100 requests every 10 seconds is allowed and an average of 5 requests every 3 seconds.  
 | 
			
		||||
These can "burst" up to 200 and 10 in each period respectively. 
 | 
			
		||||
 | 
			
		||||
Valid values for `extractorfunc` are:
 | 
			
		||||
  * `client.ip`
 | 
			
		||||
  * `request.host`
 | 
			
		||||
  * `request.header.<header name>`
 | 
			
		||||
 | 
			
		||||
## Buffering
 | 
			
		||||
 | 
			
		||||
@@ -528,3 +533,40 @@ Example:
 | 
			
		||||
  backend = "{{$backend}}"
 | 
			
		||||
{{end}}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Pass TLS Client Cert
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
# Pass the escaped client cert infos selected below in a `X-Forwarded-Ssl-Client-Cert-Infos` header.
 | 
			
		||||
[frontends.frontend1.passTLSClientCert]
 | 
			
		||||
        pem = true
 | 
			
		||||
        [frontends.frontend1.passTLSClientCert.infos]
 | 
			
		||||
            notBefore = true
 | 
			
		||||
            notAfter = true
 | 
			
		||||
            [frontends.frontend1.passTLSClientCert.infos.subject]
 | 
			
		||||
                country = true
 | 
			
		||||
                domainComponent = true
 | 
			
		||||
                province = true
 | 
			
		||||
                locality = true
 | 
			
		||||
                organization = true
 | 
			
		||||
                commonName = true
 | 
			
		||||
                serialNumber = true
 | 
			
		||||
            [frontends.frontend1.passTLSClientCert.infos.issuer]
 | 
			
		||||
                country = true
 | 
			
		||||
                domainComponent = true
 | 
			
		||||
                province = true
 | 
			
		||||
                locality = true
 | 
			
		||||
                organization = true
 | 
			
		||||
                commonName = true
 | 
			
		||||
                serialNumber = true
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Pass TLS Client Cert `pem` defines if the escaped pem is added to a `X-Forwarded-Ssl-Client-Cert` header.  
 | 
			
		||||
Pass TLS Client Cert `infos` defines how the certificate data are added to a `X-Forwarded-Ssl-Client-Cert-Infos` header.  
 | 
			
		||||
 | 
			
		||||
The following example shows an unescaped result that uses all the available fields:
 | 
			
		||||
If there are more than one certificate, they are separated by a `;`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=*.cheese.com",Issuer="DC=org,DC=cheese,C=FR,C=US,ST=Signing State,ST=Signing State 2,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=Simple Signing CA 2",NB=1544094616,NA=1607166616,SAN=*.cheese.org,*.cheese.net,*.cheese.com,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -93,11 +93,11 @@ For more information about the CLI, see the documentation about [Traefik command
 | 
			
		||||
    Whitespace is used as option separator and `,` is used as value separator for the list.  
 | 
			
		||||
    The names of the options are case-insensitive.
 | 
			
		||||
 | 
			
		||||
In compose file the entrypoint syntax is different:
 | 
			
		||||
In compose file the entrypoint syntax is different. Notice how quotes are used:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
traefik:
 | 
			
		||||
    image: traefik
 | 
			
		||||
    image: traefik:v1.7
 | 
			
		||||
    command:
 | 
			
		||||
        - --defaultentrypoints=powpow
 | 
			
		||||
        - "--entryPoints=Name:powpow Address::42 Compress:true"
 | 
			
		||||
@@ -105,7 +105,7 @@ traefik:
 | 
			
		||||
or
 | 
			
		||||
```yaml
 | 
			
		||||
traefik:
 | 
			
		||||
    image: traefik
 | 
			
		||||
    image: traefik:v1.7
 | 
			
		||||
    command: --defaultentrypoints=powpow --entryPoints='Name:powpow Address::42 Compress:true'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -235,8 +235,10 @@ If you need to add or remove TLS certificates while Traefik is started, Dynamic
 | 
			
		||||
## TLS Mutual Authentication
 | 
			
		||||
 | 
			
		||||
TLS Mutual Authentication can be `optional` or not.
 | 
			
		||||
If it's `optional`, Traefik will authorize connection with certificates not signed by a specified Certificate Authority (CA).
 | 
			
		||||
Otherwise, Traefik will only accept clients that present a certificate signed by a specified Certificate Authority (CA).
 | 
			
		||||
 | 
			
		||||
* If `optional = true`, if a certificate is provided, verifies if it is signed by a specified Certificate Authority (CA). Otherwise proceeds without any certificate.
 | 
			
		||||
* If `optional = false`, Traefik will only accept clients that present a certificate signed by a specified Certificate Authority (CA).
 | 
			
		||||
 | 
			
		||||
`ClientCAFiles` can be configured with multiple `CA:s` in the same file or use multiple files containing one or several `CA:s`.
 | 
			
		||||
The `CA:s` has to be in PEM format.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ logLevel = "INFO"
 | 
			
		||||
 | 
			
		||||
For more information about the CLI, see the documentation about [Traefik command](/basics/#traefik).
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
```bash
 | 
			
		||||
--logLevel="DEBUG"
 | 
			
		||||
--traefikLog.filePath="/path/to/traefik.log"
 | 
			
		||||
--traefikLog.format="json"
 | 
			
		||||
@@ -54,7 +54,6 @@ For more information about the CLI, see the documentation about [Traefik command
 | 
			
		||||
--accessLog.fields.headers.names="User-Agent=redact Authorization=drop Content-Type=keep"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Traefik Logs
 | 
			
		||||
 | 
			
		||||
By default the Traefik log is written to stdout in text format.
 | 
			
		||||
@@ -66,7 +65,7 @@ To write the logs into a log file specify the `filePath`:
 | 
			
		||||
  filePath = "/path/to/traefik.log"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To write JSON format logs, specify `json` as the format:
 | 
			
		||||
To switch to JSON format instead of standard format (`common`), specify `json` as the format:
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[traefikLog]
 | 
			
		||||
@@ -74,7 +73,6 @@ To write JSON format logs, specify `json` as the format:
 | 
			
		||||
  format   = "json"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Deprecated way (before 1.4):
 | 
			
		||||
 | 
			
		||||
!!! danger "DEPRECATED"
 | 
			
		||||
@@ -105,13 +103,12 @@ To customize the log level:
 | 
			
		||||
logLevel = "ERROR"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Access Logs
 | 
			
		||||
 | 
			
		||||
Access logs are written when `[accessLog]` is defined.
 | 
			
		||||
By default it will write to stdout and produce logs in the textual Common Log Format (CLF), extended with additional fields.
 | 
			
		||||
Access logs are written when the entry `[accessLog]` is defined (or the command line flag `--accesslog`).
 | 
			
		||||
By default it writes to stdout and produces logs in the textual [Common Log Format (CLF)](#clf-common-log-format), extended with additional fields.
 | 
			
		||||
 | 
			
		||||
To enable access logs using the default settings just add the `[accessLog]` entry:
 | 
			
		||||
To enable access logs using the default settings, add the `[accessLog]` entry in your `traefik.toml` configuration file:
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[accessLog]
 | 
			
		||||
@@ -124,12 +121,12 @@ To write the logs into a log file specify the `filePath`:
 | 
			
		||||
filePath = "/path/to/access.log"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To write JSON format logs, specify `json` as the format:
 | 
			
		||||
To switch to JSON format instead of [Common Log Format (CLF)](#clf-common-log-format), specify `json` as the format:
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[accessLog]
 | 
			
		||||
filePath = "/path/to/access.log"
 | 
			
		||||
format = "json"
 | 
			
		||||
format = "json"  # Default: "common"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To write the logs in async, specify `bufferingSize` as the format (must be >0):
 | 
			
		||||
@@ -152,7 +149,7 @@ To filter logs you can specify a set of filters which are logically "OR-connecte
 | 
			
		||||
```toml
 | 
			
		||||
[accessLog]
 | 
			
		||||
filePath = "/path/to/access.log"
 | 
			
		||||
format = "json"
 | 
			
		||||
format = "json"  # Default: "common"
 | 
			
		||||
 | 
			
		||||
  [accessLog.filters]
 | 
			
		||||
 | 
			
		||||
@@ -178,22 +175,42 @@ format = "json"
 | 
			
		||||
  minDuration = "10ms"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To customize logs format:
 | 
			
		||||
### CLF - Common Log Format
 | 
			
		||||
 | 
			
		||||
By default, Traefik use the CLF (`common`) as access log format.
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <origin_server_HTTP_status> <origin_server_content_size> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_frontend_name>" "<Traefik_backend_URL>" <request_duration_in_ms>ms
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Customize Fields
 | 
			
		||||
 | 
			
		||||
You can customize the fields written in the access logs.
 | 
			
		||||
The list of available fields is found below: [List of All Available Fields](#list-of-all-available-fields).
 | 
			
		||||
 | 
			
		||||
Each field has a "mode" which defines if it is written or not in the access log lines.
 | 
			
		||||
The possible values for the mode are:
 | 
			
		||||
 | 
			
		||||
* `keep`: the field and its value are written on the access log line. This is the default behavior.
 | 
			
		||||
* `drop`: the field is not written at all on the access log.
 | 
			
		||||
 | 
			
		||||
To customize the fields, you must:
 | 
			
		||||
 | 
			
		||||
* Switch to the JSON format (mandatory)
 | 
			
		||||
* Define the "default mode" for all fields (default is `keep`)
 | 
			
		||||
* OR Define the fields which does not follow the default mode
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[accessLog]
 | 
			
		||||
filePath = "/path/to/access.log"
 | 
			
		||||
# Access Log Format
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
# Default: "common"
 | 
			
		||||
#
 | 
			
		||||
# Accepted values "common", "json"
 | 
			
		||||
#
 | 
			
		||||
format = "json"
 | 
			
		||||
 | 
			
		||||
  [accessLog.filters]
 | 
			
		||||
 | 
			
		||||
  # statusCodes keep only access logs with status codes in the specified range
 | 
			
		||||
  #
 | 
			
		||||
  # Optional
 | 
			
		||||
  # Default: []
 | 
			
		||||
  #
 | 
			
		||||
  statusCodes = ["200", "300-302"]
 | 
			
		||||
 | 
			
		||||
  [accessLog.fields]
 | 
			
		||||
 | 
			
		||||
  # defaultMode
 | 
			
		||||
@@ -209,6 +226,43 @@ format = "json"
 | 
			
		||||
  [accessLog.fields.names]
 | 
			
		||||
    "ClientUsername" = "drop"
 | 
			
		||||
    # ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Customize Headers
 | 
			
		||||
 | 
			
		||||
Access logs prints the headers of each request, as fields of the access log line.
 | 
			
		||||
You can customize which and how the headers are printed, likewise the other fields (see ["Customize Fields" section](#customize-fields)).
 | 
			
		||||
 | 
			
		||||
Each header has a "mode" which defines how it is written in the access log lines.
 | 
			
		||||
The possible values for the mode are:
 | 
			
		||||
 | 
			
		||||
* `keep`: the header and its value are written on the access log line. This is the default behavior.
 | 
			
		||||
* `drop`: the header is not written at all on the access log.
 | 
			
		||||
* `redacted`: the header is written, but its value is redacted to avoid leaking sensitive information.
 | 
			
		||||
 | 
			
		||||
To customize the headers, you must:
 | 
			
		||||
 | 
			
		||||
* Switch to the JSON format (mandatory)
 | 
			
		||||
* Define the "default mode" for all headers (default is `keep`)
 | 
			
		||||
* OR Define the headers which does not follow the default mode
 | 
			
		||||
 | 
			
		||||
!!! important
 | 
			
		||||
    The headers are written with the prefix `request_` in the access log.
 | 
			
		||||
    This prefix must not be included when specifying a header in the TOML configuration.
 | 
			
		||||
 | 
			
		||||
    * Do: `"User-Agent" = "drop"`
 | 
			
		||||
    * Don't: `"redacted_User-Agent" = "drop"`
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[accessLog]
 | 
			
		||||
# Access Log Format
 | 
			
		||||
#
 | 
			
		||||
# Optional
 | 
			
		||||
# Default: "common"
 | 
			
		||||
#
 | 
			
		||||
# Accepted values "common", "json"
 | 
			
		||||
#
 | 
			
		||||
format = "json"
 | 
			
		||||
 | 
			
		||||
  [accessLog.fields.headers]
 | 
			
		||||
    # defaultMode
 | 
			
		||||
@@ -227,41 +281,42 @@ format = "json"
 | 
			
		||||
      # ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### List of All Available Fields
 | 
			
		||||
 | 
			
		||||
### List of all available fields
 | 
			
		||||
| Field                   | Description                                                                                                                                                         |
 | 
			
		||||
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `StartUTC`              | The time at which request processing started.                                                                                                                       |
 | 
			
		||||
| `StartLocal`            | The local time at which request processing started.                                                                                                                 |
 | 
			
		||||
| `Duration`              | The total time taken by processing the response, including the origin server's time but not the log writing time.                                                   |
 | 
			
		||||
| `FrontendName`          | The name of the Traefik frontend.                                                                                                                                   |
 | 
			
		||||
| `BackendName`           | The name of the Traefik backend.                                                                                                                                    |
 | 
			
		||||
| `BackendURL`            | The URL of the Traefik backend.                                                                                                                                     |
 | 
			
		||||
| `BackendAddr`           | The IP:port of the Traefik backend (extracted from `BackendURL`)                                                                                                    |
 | 
			
		||||
| `ClientAddr`            | The remote address in its original form (usually IP:port).                                                                                                          |
 | 
			
		||||
| `ClientHost`            | The remote IP address from which the client request was received.                                                                                                   |
 | 
			
		||||
| `ClientPort`            | The remote TCP port from which the client request was received.                                                                                                     |
 | 
			
		||||
| `ClientUsername`        | The username provided in the URL, if present.                                                                                                                       |
 | 
			
		||||
| `RequestAddr`           | The HTTP Host header (usually IP:port). This is treated as not a header by the Go API.                                                                              |
 | 
			
		||||
| `RequestHost`           | The HTTP Host server name (not including port).                                                                                                                     |
 | 
			
		||||
| `RequestPort`           | The TCP port from the HTTP Host.                                                                                                                                    |
 | 
			
		||||
| `RequestMethod`         | The HTTP method.                                                                                                                                                    |
 | 
			
		||||
| `RequestPath`           | The HTTP request URI, not including the scheme, host or port.                                                                                                       |
 | 
			
		||||
| `RequestProtocol`       | The version of HTTP requested.                                                                                                                                      |
 | 
			
		||||
| `RequestLine`           | `RequestMethod` + `RequestPath` + `RequestProtocol`                                                                                                                 |
 | 
			
		||||
| `RequestContentSize`    | The number of bytes in the request entity (a.k.a. body) sent by the client.                                                                                         |
 | 
			
		||||
| `OriginDuration`        | The time taken by the origin server ('upstream') to return its response.                                                                                            |
 | 
			
		||||
| `OriginContentSize`     | The content length specified by the origin server, or 0 if unspecified.                                                                                             |
 | 
			
		||||
| `OriginStatus`          | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent.     |
 | 
			
		||||
| `OriginStatusLine`      | `OriginStatus` + Status code explanation                                                                                                                            |
 | 
			
		||||
| `DownstreamStatus`      | The HTTP status code returned to the client.                                                                                                                        |
 | 
			
		||||
| `DownstreamStatusLine`  | `DownstreamStatus` + Status code explanation                                                                                                                        |
 | 
			
		||||
| `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. |
 | 
			
		||||
| `RequestCount`          | The number of requests received since the Traefik instance started.                                                                                                 |
 | 
			
		||||
| `GzipRatio`             | The response body compression ratio achieved.                                                                                                                       |
 | 
			
		||||
| `Overhead`              | The processing time overhead caused by Traefik.                                                                                                                     |
 | 
			
		||||
| `RetryAttempts`         | The amount of attempts the request was retried.                                                                                                                     |
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
StartUTC
 | 
			
		||||
StartLocal
 | 
			
		||||
Duration
 | 
			
		||||
FrontendName
 | 
			
		||||
BackendName
 | 
			
		||||
BackendURL
 | 
			
		||||
BackendAddr
 | 
			
		||||
ClientAddr
 | 
			
		||||
ClientHost
 | 
			
		||||
ClientPort
 | 
			
		||||
ClientUsername
 | 
			
		||||
RequestAddr
 | 
			
		||||
RequestHost
 | 
			
		||||
RequestPort
 | 
			
		||||
RequestMethod
 | 
			
		||||
RequestPath
 | 
			
		||||
RequestProtocol
 | 
			
		||||
RequestLine
 | 
			
		||||
RequestContentSize
 | 
			
		||||
OriginDuration
 | 
			
		||||
OriginContentSize
 | 
			
		||||
OriginStatus
 | 
			
		||||
OriginStatusLine
 | 
			
		||||
DownstreamStatus
 | 
			
		||||
DownstreamStatusLine
 | 
			
		||||
DownstreamContentSize
 | 
			
		||||
RequestCount
 | 
			
		||||
GzipRatio
 | 
			
		||||
Overhead
 | 
			
		||||
RetryAttempts
 | 
			
		||||
```
 | 
			
		||||
### Depreciation Notice
 | 
			
		||||
 | 
			
		||||
Deprecated way (before 1.4):
 | 
			
		||||
 | 
			
		||||
@@ -276,15 +331,6 @@ Deprecated way (before 1.4):
 | 
			
		||||
accessLogsFile = "log/access.log"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### CLF - Common Log Format
 | 
			
		||||
 | 
			
		||||
By default, Traefik use the CLF (`common`) as access log format.
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <origin_server_HTTP_status> <origin_server_content_size> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_frontend_name>" "<Traefik_backend_URL>" <request_duration_in_ms>ms 
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Log Rotation
 | 
			
		||||
 | 
			
		||||
Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal.
 | 
			
		||||
@@ -292,3 +338,34 @@ This allows the logs to be rotated and processed by an external program, such as
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
    This does not work on Windows due to the lack of USR signals.
 | 
			
		||||
 | 
			
		||||
## Time Zones
 | 
			
		||||
 | 
			
		||||
The timestamp of each log line is in UTC time by default.
 | 
			
		||||
 | 
			
		||||
If you want to use local timezone, you need to ensure the 3 following elements:
 | 
			
		||||
 | 
			
		||||
1. Provide the timezone data into /usr/share/zoneinfo
 | 
			
		||||
2. Set the environement variable TZ to the timezone to be used
 | 
			
		||||
3. Specify the field StartLocal instead of StartUTC (works on default Common Log Format (CLF) as well as JSON)
 | 
			
		||||
 | 
			
		||||
Example using docker-compose:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
version: '3'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  traefik:
 | 
			
		||||
    image: containous/traefik:[latest stable version]
 | 
			
		||||
    ports:
 | 
			
		||||
      - "80:80"
 | 
			
		||||
    environment:
 | 
			
		||||
      - "TZ=US/Alaska"
 | 
			
		||||
    command:
 | 
			
		||||
      - --docker
 | 
			
		||||
      - --accesslog
 | 
			
		||||
      - --accesslog.fields.names="StartUTC=drop"
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "/var/run/docker.sock:/var/run/docker.sock"
 | 
			
		||||
      - "/usr/share/zoneinfo:/usr/share/zoneinfo:ro"
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
    # Buckets for latency metrics
 | 
			
		||||
    #
 | 
			
		||||
    # Optional
 | 
			
		||||
    # Default: [0.1, 0.3, 1.2, 5]
 | 
			
		||||
    # Default: [0.1, 0.3, 1.2, 5.0]
 | 
			
		||||
    #
 | 
			
		||||
    buckets = [0.1,0.3,1.2,5.0]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ Thus, if you have a regular path for `/foo` and an entrypoint on `:80`, you woul
 | 
			
		||||
* Admin panel: `http://hostname:8080/`
 | 
			
		||||
* Ping URL: `http://hostname:8080/ping`
 | 
			
		||||
 | 
			
		||||
However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your administration panel's port.
 | 
			
		||||
However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your dashboard's port.
 | 
			
		||||
In many environments, the security staff may not _allow_ you to expose it.
 | 
			
		||||
 | 
			
		||||
You have two options:
 | 
			
		||||
@@ -40,7 +40,7 @@ You have two options:
 | 
			
		||||
 | 
			
		||||
### Ping health check on a regular entry point
 | 
			
		||||
 | 
			
		||||
To proxy `/ping` from a regular entry point to the administration one without exposing the panel, do the following:
 | 
			
		||||
To proxy `/ping` from a regular entry point to the administration one without exposing the dashboard, do the following:
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
defaultEntryPoints = ["http"]
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,13 @@ Traefik supports three tracing backends: Jaeger, Zipkin and DataDog.
 | 
			
		||||
    # Default: "127.0.0.1:6831"
 | 
			
		||||
    #
 | 
			
		||||
    localAgentHostPort = "127.0.0.1:6831"
 | 
			
		||||
    
 | 
			
		||||
    # Trace Context Header Name is the http header name used to propagate tracing context.
 | 
			
		||||
    # This must be in lower-case to avoid mismatches when decoding incoming headers.
 | 
			
		||||
    #
 | 
			
		||||
    # Default: "uber-trace-id"
 | 
			
		||||
    #
 | 
			
		||||
    traceContextHeaderName = "uber-trace-id"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
!!! warning
 | 
			
		||||
@@ -156,4 +163,10 @@ Traefik supports three tracing backends: Jaeger, Zipkin and DataDog.
 | 
			
		||||
    #
 | 
			
		||||
    globalTag = ""
 | 
			
		||||
 | 
			
		||||
    # Enable priority sampling. When using distributed tracing, this option must be enabled in order
 | 
			
		||||
    # to get all the parts of a distributed trace sampled.
 | 
			
		||||
    #
 | 
			
		||||
    # Default: false
 | 
			
		||||
    #
 | 
			
		||||
    prioritySampling = false
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
[](/)
 | 
			
		||||
[](https://goreportcard.com/report/github.com/containous/traefik)
 | 
			
		||||
[](https://github.com/containous/traefik/blob/master/LICENSE.md)
 | 
			
		||||
[](https://slack.traefik.io)
 | 
			
		||||
[](https://community.containo.us/)
 | 
			
		||||
[](https://twitter.com/intent/follow?screen_name=traefik)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -66,7 +66,7 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t
 | 
			
		||||
 | 
			
		||||
In this quickstart, we'll use [Docker compose](https://docs.docker.com/compose) to create our demo infrastructure.
 | 
			
		||||
 | 
			
		||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/master/examples/quickstart/) directory.
 | 
			
		||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/v1.7/examples/quickstart/) directory.
 | 
			
		||||
 | 
			
		||||
### 1 — Launch Traefik — Tell It to Listen to Docker
 | 
			
		||||
 | 
			
		||||
@@ -77,7 +77,7 @@ version: '3'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  reverse-proxy:
 | 
			
		||||
    image: traefik # The official Traefik docker image
 | 
			
		||||
    image: traefik:v1.7 # The official Traefik docker image
 | 
			
		||||
    command: --api --docker # Enables the web UI and tells Traefik to listen to docker
 | 
			
		||||
    ports:
 | 
			
		||||
      - "80:80"     # The HTTP port
 | 
			
		||||
@@ -176,7 +176,7 @@ Our recommendation would be to see for yourself how simple it is to enable HTTPS
 | 
			
		||||
 | 
			
		||||
## Resources
 | 
			
		||||
 | 
			
		||||
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at [GopherCon 2017](https://gophercon.com).
 | 
			
		||||
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at GopherCon 2017.
 | 
			
		||||
You will learn Traefik basics in less than 10 minutes.
 | 
			
		||||
 | 
			
		||||
[](https://www.youtube.com/watch?v=RgudiksfL-k)
 | 
			
		||||
@@ -190,7 +190,7 @@ You will learn fundamental Traefik features and see some demos with Kubernetes.
 | 
			
		||||
 | 
			
		||||
### The Official Binary File
 | 
			
		||||
 | 
			
		||||
You can grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and just run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
 | 
			
		||||
You can grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and just run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v1.7/traefik.sample.toml):
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
./traefik -c traefik.toml
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								docs/theme/partials/footer.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								docs/theme/partials/footer.html
									
									
									
									
										vendored
									
									
								
							@@ -88,9 +88,9 @@
 | 
			
		||||
                </div>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                powered by
 | 
			
		||||
                <a href="http://www.mkdocs.org" title="MkDocs">MkDocs</a>
 | 
			
		||||
                <a href="https://www.mkdocs.org" title="MkDocs">MkDocs</a>
 | 
			
		||||
                and
 | 
			
		||||
                <a href="http://squidfunk.github.io/mkdocs-material/"
 | 
			
		||||
                <a href="https://squidfunk.github.io/mkdocs-material/"
 | 
			
		||||
                   title="Material for MkDocs">
 | 
			
		||||
                    Material for MkDocs</a>
 | 
			
		||||
            </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@ To watch docker events, add `--docker.watch`.
 | 
			
		||||
version: "3"
 | 
			
		||||
services:
 | 
			
		||||
  traefik:
 | 
			
		||||
    image: traefik:1.5
 | 
			
		||||
    image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
    command:
 | 
			
		||||
      - "--api"
 | 
			
		||||
      - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
 | 
			
		||||
@@ -156,7 +156,7 @@ The initializer in a docker-compose file will be:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
  traefik_init:
 | 
			
		||||
    image: traefik:1.5
 | 
			
		||||
    image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
    command:
 | 
			
		||||
      - "storeconfig"
 | 
			
		||||
      - "--api"
 | 
			
		||||
@@ -177,7 +177,7 @@ And now, the Traefik part will only have the Consul configuration.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
  traefik:
 | 
			
		||||
    image: traefik:1.5
 | 
			
		||||
    image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - traefik_init
 | 
			
		||||
      - consul
 | 
			
		||||
@@ -200,7 +200,7 @@ The new configuration will be stored in Consul, and you need to restart the Trae
 | 
			
		||||
version: "3.4"
 | 
			
		||||
services:
 | 
			
		||||
  traefik_init:
 | 
			
		||||
    image: traefik:1.5
 | 
			
		||||
    image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
    command:
 | 
			
		||||
      - "storeconfig"
 | 
			
		||||
      - "--api"
 | 
			
		||||
@@ -229,7 +229,7 @@ services:
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - consul
 | 
			
		||||
  traefik:
 | 
			
		||||
    image: traefik:1.5
 | 
			
		||||
    image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - traefik_init
 | 
			
		||||
      - consul
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ version: '2'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  traefik:
 | 
			
		||||
    image: traefik:1.5.4
 | 
			
		||||
    image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
    restart: always
 | 
			
		||||
    ports:
 | 
			
		||||
      - 80:80
 | 
			
		||||
@@ -108,6 +108,28 @@ onHostRule = true
 | 
			
		||||
entryPoint = "http"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Alternatively, the `TOML` file above can also be translated into command line switches. 
 | 
			
		||||
This is the `command` value of the `traefik` service in the `docker-compose.yml` manifest:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
command:
 | 
			
		||||
  - --debug=false
 | 
			
		||||
  - --logLevel=ERROR
 | 
			
		||||
  - --defaultentrypoints=https,http
 | 
			
		||||
  - --entryPoints=Name:http Address::80 Redirect.EntryPoint:https
 | 
			
		||||
  - --entryPoints=Name:https Address::443 TLS
 | 
			
		||||
  - --retry
 | 
			
		||||
  - --docker.endpoint=unix:///var/run/docker.sock
 | 
			
		||||
  - --docker.domain=my-awesome-app.org
 | 
			
		||||
  - --docker.watch=true
 | 
			
		||||
  - --docker.exposedbydefault=false
 | 
			
		||||
  - --acme.email=your-email-here@my-awesome-app.org
 | 
			
		||||
  - --acme.storage=acme.json
 | 
			
		||||
  - --acme.entryPoint=https
 | 
			
		||||
  - --acme.onHostRule=true
 | 
			
		||||
  - --acme.httpchallenge.entrypoint=http
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This is the minimum configuration required to do the following:
 | 
			
		||||
 | 
			
		||||
- Log `ERROR`-level messages (or more severe) to the console, but silence `DEBUG`-level messages
 | 
			
		||||
 
 | 
			
		||||
@@ -336,37 +336,37 @@ Pay attention to the **labels** section:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
home:
 | 
			
		||||
image: abiosoft/caddy:0.10.14
 | 
			
		||||
networks:
 | 
			
		||||
  - ntw_front
 | 
			
		||||
volumes:
 | 
			
		||||
  - ./www/home/srv/:/srv/
 | 
			
		||||
deploy:
 | 
			
		||||
  mode: replicated
 | 
			
		||||
  replicas: 2
 | 
			
		||||
  #placement:
 | 
			
		||||
  #  constraints: [node.role==manager]
 | 
			
		||||
  restart_policy:
 | 
			
		||||
    condition: on-failure
 | 
			
		||||
    max_attempts: 5
 | 
			
		||||
  resources:
 | 
			
		||||
    limits:
 | 
			
		||||
      cpus: '0.20'
 | 
			
		||||
      memory: 9M
 | 
			
		||||
    reservations:
 | 
			
		||||
      cpus: '0.05'
 | 
			
		||||
      memory: 9M
 | 
			
		||||
  labels:
 | 
			
		||||
  - "traefik.frontend.rule=PathPrefixStrip:/"
 | 
			
		||||
  - "traefik.backend=home"
 | 
			
		||||
  - "traefik.port=2015"
 | 
			
		||||
  - "traefik.weight=10"
 | 
			
		||||
  - "traefik.enable=true"
 | 
			
		||||
  - "traefik.passHostHeader=true"
 | 
			
		||||
  - "traefik.docker.network=ntw_front"
 | 
			
		||||
  - "traefik.frontend.entryPoints=http"
 | 
			
		||||
  - "traefik.backend.loadbalancer.swarm=true"
 | 
			
		||||
  - "traefik.backend.loadbalancer.method=drr"
 | 
			
		||||
  image: abiosoft/caddy:0.10.14
 | 
			
		||||
  networks:
 | 
			
		||||
    - ntw_front
 | 
			
		||||
  volumes:
 | 
			
		||||
    - ./www/home/srv/:/srv/
 | 
			
		||||
  deploy:
 | 
			
		||||
    mode: replicated
 | 
			
		||||
    replicas: 2
 | 
			
		||||
    #placement:
 | 
			
		||||
    #  constraints: [node.role==manager]
 | 
			
		||||
    restart_policy:
 | 
			
		||||
      condition: on-failure
 | 
			
		||||
      max_attempts: 5
 | 
			
		||||
    resources:
 | 
			
		||||
      limits:
 | 
			
		||||
        cpus: '0.20'
 | 
			
		||||
        memory: 9M
 | 
			
		||||
      reservations:
 | 
			
		||||
        cpus: '0.05'
 | 
			
		||||
        memory: 9M
 | 
			
		||||
    labels:
 | 
			
		||||
      - "traefik.frontend.rule=PathPrefixStrip:/"
 | 
			
		||||
      - "traefik.backend=home"
 | 
			
		||||
      - "traefik.port=2015"
 | 
			
		||||
      - "traefik.weight=10"
 | 
			
		||||
      - "traefik.enable=true"
 | 
			
		||||
      - "traefik.passHostHeader=true"
 | 
			
		||||
      - "traefik.docker.network=ntw_front"
 | 
			
		||||
      - "traefik.frontend.entryPoints=http"
 | 
			
		||||
      - "traefik.backend.loadbalancer.swarm=true"
 | 
			
		||||
      - "traefik.backend.loadbalancer.method=drr"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Something more tricky using `regex`.
 | 
			
		||||
@@ -377,39 +377,39 @@ The double sign `$$` are variables managed by the docker compose file ([document
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
portainer:
 | 
			
		||||
image: portainer/portainer:1.16.5
 | 
			
		||||
networks:
 | 
			
		||||
  - ntw_front
 | 
			
		||||
volumes:
 | 
			
		||||
  - /var/run/docker.sock:/var/run/docker.sock
 | 
			
		||||
deploy:
 | 
			
		||||
  mode: replicated
 | 
			
		||||
  replicas: 1
 | 
			
		||||
  placement:
 | 
			
		||||
    constraints: [node.role==manager]
 | 
			
		||||
  restart_policy:
 | 
			
		||||
    condition: on-failure
 | 
			
		||||
    max_attempts: 5
 | 
			
		||||
  resources:
 | 
			
		||||
    limits:
 | 
			
		||||
      cpus: '0.33'
 | 
			
		||||
      memory: 20M
 | 
			
		||||
    reservations:
 | 
			
		||||
      cpus: '0.05'
 | 
			
		||||
      memory: 10M
 | 
			
		||||
  labels:
 | 
			
		||||
    - "traefik.frontend.rule=PathPrefixStrip:/portainer"
 | 
			
		||||
    - "traefik.backend=portainer"
 | 
			
		||||
    - "traefik.port=9000"
 | 
			
		||||
    - "traefik.weight=10"
 | 
			
		||||
    - "traefik.enable=true"
 | 
			
		||||
    - "traefik.passHostHeader=true"
 | 
			
		||||
    - "traefik.docker.network=ntw_front"
 | 
			
		||||
    - "traefik.frontend.entryPoints=http"
 | 
			
		||||
    - "traefik.backend.loadbalancer.swarm=true"
 | 
			
		||||
    - "traefik.backend.loadbalancer.method=drr"
 | 
			
		||||
    # https://github.com/containous/traefik/issues/563#issuecomment-421360934
 | 
			
		||||
    - "traefik.frontend.redirect.regex=^(.*)/portainer$$"
 | 
			
		||||
    - "traefik.frontend.redirect.replacement=$$1/portainer/"
 | 
			
		||||
    - "traefik.frontend.rule=PathPrefix:/portainer;ReplacePathRegex: ^/portainer/(.*) /$$1"
 | 
			
		||||
  image: portainer/portainer:1.16.5
 | 
			
		||||
  networks:
 | 
			
		||||
    - ntw_front
 | 
			
		||||
  volumes:
 | 
			
		||||
    - /var/run/docker.sock:/var/run/docker.sock
 | 
			
		||||
  deploy:
 | 
			
		||||
    mode: replicated
 | 
			
		||||
    replicas: 1
 | 
			
		||||
    placement:
 | 
			
		||||
      constraints: [node.role==manager]
 | 
			
		||||
    restart_policy:
 | 
			
		||||
      condition: on-failure
 | 
			
		||||
      max_attempts: 5
 | 
			
		||||
    resources:
 | 
			
		||||
      limits:
 | 
			
		||||
        cpus: '0.33'
 | 
			
		||||
        memory: 20M
 | 
			
		||||
      reservations:
 | 
			
		||||
        cpus: '0.05'
 | 
			
		||||
        memory: 10M
 | 
			
		||||
    labels:
 | 
			
		||||
      - "traefik.frontend.rule=PathPrefixStrip:/portainer"
 | 
			
		||||
      - "traefik.backend=portainer"
 | 
			
		||||
      - "traefik.port=9000"
 | 
			
		||||
      - "traefik.weight=10"
 | 
			
		||||
      - "traefik.enable=true"
 | 
			
		||||
      - "traefik.passHostHeader=true"
 | 
			
		||||
      - "traefik.docker.network=ntw_front"
 | 
			
		||||
      - "traefik.frontend.entryPoints=http"
 | 
			
		||||
      - "traefik.backend.loadbalancer.swarm=true"
 | 
			
		||||
      - "traefik.backend.loadbalancer.method=drr"
 | 
			
		||||
      # https://github.com/containous/traefik/issues/563#issuecomment-421360934
 | 
			
		||||
      - "traefik.frontend.redirect.regex=^(.*)/portainer$$"
 | 
			
		||||
      - "traefik.frontend.redirect.replacement=$$1/portainer/"
 | 
			
		||||
      - "traefik.frontend.rule=PathPrefix:/portainer;ReplacePathRegex: ^/portainer/(.*) /$$1"
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ defaultEntryPoints = ["https"]
 | 
			
		||||
[entryPoints]
 | 
			
		||||
  [entryPoints.http]
 | 
			
		||||
  address = ":80"
 | 
			
		||||
    [entryPoints.http]
 | 
			
		||||
 | 
			
		||||
[api]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ This guide explains how to use Traefik as an Ingress controller for a Kubernetes
 | 
			
		||||
 | 
			
		||||
If you are not familiar with Ingresses in Kubernetes you might want to read the [Kubernetes user guide](https://kubernetes.io/docs/concepts/services-networking/ingress/)
 | 
			
		||||
 | 
			
		||||
The config files used in this guide can be found in the [examples directory](https://github.com/containous/traefik/tree/master/examples/k8s)
 | 
			
		||||
The config files used in this guide can be found in the [examples directory](https://github.com/containous/traefik/tree/v1.7/examples/k8s)
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
@@ -68,10 +68,10 @@ subjects:
 | 
			
		||||
  namespace: kube-system
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/traefik-rbac.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-rbac.yaml)
 | 
			
		||||
[examples/k8s/traefik-rbac.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/traefik-rbac.yaml)
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For namespaced restrictions, one RoleBinding is required per watched namespace along with a corresponding configuration of Traefik's `kubernetes.namespaces` parameter.
 | 
			
		||||
@@ -118,7 +118,7 @@ spec:
 | 
			
		||||
      serviceAccountName: traefik-ingress-controller
 | 
			
		||||
      terminationGracePeriodSeconds: 60
 | 
			
		||||
      containers:
 | 
			
		||||
      - image: traefik
 | 
			
		||||
      - image: traefik:v1.7
 | 
			
		||||
        name: traefik-ingress-lb
 | 
			
		||||
        ports:
 | 
			
		||||
        - name: http
 | 
			
		||||
@@ -148,7 +148,7 @@ spec:
 | 
			
		||||
  type: NodePort
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-deployment.yaml)
 | 
			
		||||
[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/traefik-deployment.yaml)
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
    The Service will expose two NodePorts which allow access to the ingress and the web interface.
 | 
			
		||||
@@ -180,7 +180,7 @@ spec:
 | 
			
		||||
      serviceAccountName: traefik-ingress-controller
 | 
			
		||||
      terminationGracePeriodSeconds: 60
 | 
			
		||||
      containers:
 | 
			
		||||
      - image: traefik
 | 
			
		||||
      - image: traefik:v1.7
 | 
			
		||||
        name: traefik-ingress-lb
 | 
			
		||||
        ports:
 | 
			
		||||
        - name: http
 | 
			
		||||
@@ -216,7 +216,7 @@ spec:
 | 
			
		||||
      name: admin
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/traefik-ds.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-ds.yaml)
 | 
			
		||||
[examples/k8s/traefik-ds.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/traefik-ds.yaml)
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
    This will create a Daemonset that uses privileged ports 80/8080 on the host. This may not work on all providers, but illustrates the static (non-NodePort) hostPort binding. The `traefik-ingress-service` can still be used inside the cluster to access the DaemonSet pods.
 | 
			
		||||
@@ -224,11 +224,11 @@ spec:
 | 
			
		||||
To deploy Traefik to your cluster start by submitting one of the YAML files to the cluster with `kubectl`:
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-deployment.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-deployment.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
There are some significant differences between using Deployments and DaemonSets:
 | 
			
		||||
@@ -352,10 +352,10 @@ spec:
 | 
			
		||||
          servicePort: web
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/ui.yaml)
 | 
			
		||||
[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/ui.yaml)
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/ui.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now lets setup an entry in our `/etc/hosts` file to route `traefik-ui.minikube` to our cluster.
 | 
			
		||||
@@ -375,6 +375,14 @@ We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube)
 | 
			
		||||
    For this example to work you need a TLS entrypoint. You don't have to provide a TLS certificate at this point.
 | 
			
		||||
    For more details see [here](/configuration/entrypoints/).
 | 
			
		||||
 | 
			
		||||
You can add a TLS entrypoint by adding the following `args` to the container spec:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
 --defaultentrypoints=http,https
 | 
			
		||||
 --entrypoints=Name:https Address::443 TLS
 | 
			
		||||
 --entrypoints=Name:http Address::80
 | 
			
		||||
```
 | 
			
		||||
    
 | 
			
		||||
To setup an HTTPS-protected ingress, you can leverage the TLS feature of the ingress resource.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
@@ -573,10 +581,10 @@ spec:
 | 
			
		||||
        - containerPort: 80
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-deployments.yaml)
 | 
			
		||||
[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheese-deployments.yaml)
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-deployments.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheese-deployments.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Next we need to setup a Service for each of the cheese pods.
 | 
			
		||||
@@ -628,10 +636,10 @@ spec:
 | 
			
		||||
!!! note
 | 
			
		||||
    We also set a [circuit breaker expression](/basics/#backends) for one of the backends by setting the `traefik.backend.circuitbreaker` annotation on the service.
 | 
			
		||||
 | 
			
		||||
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml)
 | 
			
		||||
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheese-services.yaml)
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-services.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheese-services.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now we can submit an ingress for the cheese websites.
 | 
			
		||||
@@ -668,13 +676,13 @@ spec:
 | 
			
		||||
          servicePort: http
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-ingress.yaml)
 | 
			
		||||
[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheese-ingress.yaml)
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
    we list each hostname, and add a backend service.
 | 
			
		||||
    We list each hostname, and add a backend service.
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheese-ingress.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now visit the [Traefik dashboard](http://traefik-ui.minikube/) and you should see a frontend for each host.
 | 
			
		||||
@@ -723,13 +731,13 @@ spec:
 | 
			
		||||
          servicePort: http
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheeses-ingress.yaml)
 | 
			
		||||
[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheeses-ingress.yaml)
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
    We are configuring Traefik to strip the prefix from the url path with the `traefik.frontend.rule.type` annotation so that we can use the containers from the previous example without modification.
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheeses-ingress.yaml
 | 
			
		||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheeses-ingress.yaml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
@@ -775,11 +783,11 @@ Traefik will now look for cheddar service endpoints (ports on healthy pods) in b
 | 
			
		||||
Deploying cheddar into the cheese namespace and afterwards shutting down cheddar in the default namespace is enough to migrate the traffic.
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
   The kubernetes documentation does not specify this merging behavior.
 | 
			
		||||
    The kubernetes documentation does not specify this merging behavior.
 | 
			
		||||
 | 
			
		||||
!!! note
 | 
			
		||||
   Merging ingress definitions can cause problems if the annotations differ or if the services handle requests differently.
 | 
			
		||||
   Be careful and extra cautious when running multiple overlapping ingress definitions.
 | 
			
		||||
    Merging ingress definitions can cause problems if the annotations differ or if the services handle requests differently.
 | 
			
		||||
    Be careful and extra cautious when running multiple overlapping ingress definitions.
 | 
			
		||||
 | 
			
		||||
## Specifying Routing Priorities
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -139,7 +139,7 @@ Here is the [docker-compose file](https://docs.docker.com/compose/compose-file/)
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
traefik:
 | 
			
		||||
  image: traefik
 | 
			
		||||
  image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
 | 
			
		||||
  command: --consul --consul.endpoint=127.0.0.1:8500
 | 
			
		||||
  ports:
 | 
			
		||||
    - "80:80"
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ The cluster consists of:
 | 
			
		||||
- 3 servers
 | 
			
		||||
- 1 manager
 | 
			
		||||
- 2 workers
 | 
			
		||||
- 1 [overlay](https://docs.docker.com/engine/userguide/networking/dockernetworks/#an-overlay-network) network (multi-host networking)
 | 
			
		||||
- 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
@@ -76,7 +76,7 @@ docker-machine ssh manager "docker network create --driver=overlay traefik-net"
 | 
			
		||||
## Deploy Traefik
 | 
			
		||||
 | 
			
		||||
Let's deploy Traefik as a docker service in our cluster.
 | 
			
		||||
The only requirement for Traefik to work with swarm mode is that it needs to run on a manager node - we are going to use a [constraint](https://docs.docker.com/engine/reference/commandline/service_create/#/specify-service-constraints-constraint) for that.
 | 
			
		||||
The only requirement for Traefik to work with swarm mode is that it needs to run on a manager node - we are going to use a [constraint](https://docs.docker.com/engine/reference/commandline/service_create/#specify-service-constraints---constraint) for that.
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
docker-machine ssh manager "docker service create \
 | 
			
		||||
@@ -85,7 +85,7 @@ docker-machine ssh manager "docker service create \
 | 
			
		||||
	--publish 80:80 --publish 8080:8080 \
 | 
			
		||||
	--mount	type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
 | 
			
		||||
	--network traefik-net \
 | 
			
		||||
	traefik \
 | 
			
		||||
	traefik:<stable version from https://hub.docker.com/_/traefik> \
 | 
			
		||||
	--docker \
 | 
			
		||||
	--docker.swarmMode \
 | 
			
		||||
	--docker.domain=traefik \
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ The cluster consists of:
 | 
			
		||||
- 2 servers
 | 
			
		||||
- 1 swarm master
 | 
			
		||||
- 2 swarm nodes
 | 
			
		||||
- 1 [overlay](https://docs.docker.com/engine/userguide/networking/dockernetworks/#an-overlay-network) network (multi-host networking)
 | 
			
		||||
- 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking)
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
@@ -81,7 +81,7 @@ docker $(docker-machine config mhs-demo0) run \
 | 
			
		||||
    -p 80:80 -p 8080:8080 \
 | 
			
		||||
    --net=my-net \
 | 
			
		||||
    -v /var/lib/boot2docker/:/ssl \
 | 
			
		||||
    traefik \
 | 
			
		||||
    traefik:<stable version from https://hub.docker.com/_/traefik> \
 | 
			
		||||
    -l DEBUG \
 | 
			
		||||
    -c /dev/null \
 | 
			
		||||
    --docker \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
traefik:
 | 
			
		||||
  image: traefik
 | 
			
		||||
  image: traefik:v1.7
 | 
			
		||||
  command: --api --rancher --rancher.domain=rancher.localhost --rancher.endpoint=http://example.com --rancher.accesskey=XXXXXXX --rancher.secretkey=YYYYYY --logLevel=DEBUG
 | 
			
		||||
  ports:
 | 
			
		||||
    - "80:80"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
traefik:
 | 
			
		||||
  image: traefik
 | 
			
		||||
  image: traefik:v1.7
 | 
			
		||||
  command: -c /dev/null --api --docker --docker.domain=docker.localhost --logLevel=DEBUG
 | 
			
		||||
  ports:
 | 
			
		||||
    - "80:80"
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ spec:
 | 
			
		||||
      serviceAccountName: traefik-ingress-controller
 | 
			
		||||
      terminationGracePeriodSeconds: 60
 | 
			
		||||
      containers:
 | 
			
		||||
      - image: traefik
 | 
			
		||||
      - image: traefik:v1.7
 | 
			
		||||
        name: traefik-ingress-lb
 | 
			
		||||
        ports:
 | 
			
		||||
        - name: http
 | 
			
		||||
 
 | 
			
		||||
@@ -6,13 +6,17 @@ metadata:
 | 
			
		||||
  namespace: kube-system
 | 
			
		||||
---
 | 
			
		||||
kind: DaemonSet
 | 
			
		||||
apiVersion: extensions/v1beta1
 | 
			
		||||
apiVersion: apps/v1
 | 
			
		||||
metadata:
 | 
			
		||||
  name: traefik-ingress-controller
 | 
			
		||||
  namespace: kube-system
 | 
			
		||||
  labels:
 | 
			
		||||
    k8s-app: traefik-ingress-lb
 | 
			
		||||
spec:
 | 
			
		||||
  selector:
 | 
			
		||||
    matchLabels:
 | 
			
		||||
      k8s-app: traefik-ingress-lb
 | 
			
		||||
      name: traefik-ingress-lb
 | 
			
		||||
  template:
 | 
			
		||||
    metadata:
 | 
			
		||||
      labels:
 | 
			
		||||
@@ -22,7 +26,7 @@ spec:
 | 
			
		||||
      serviceAccountName: traefik-ingress-controller
 | 
			
		||||
      terminationGracePeriodSeconds: 60
 | 
			
		||||
      containers:
 | 
			
		||||
      - image: traefik
 | 
			
		||||
      - image: traefik:v1.7
 | 
			
		||||
        name: traefik-ingress-lb
 | 
			
		||||
        ports:
 | 
			
		||||
        - name: http
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,12 @@ rules:
 | 
			
		||||
      - get
 | 
			
		||||
      - list
 | 
			
		||||
      - watch
 | 
			
		||||
  - apiGroups:
 | 
			
		||||
    - extensions
 | 
			
		||||
    resources:
 | 
			
		||||
    - ingresses/status
 | 
			
		||||
    verbs:
 | 
			
		||||
    - update
 | 
			
		||||
---
 | 
			
		||||
kind: ClusterRoleBinding
 | 
			
		||||
apiVersion: rbac.authorization.k8s.io/v1beta1
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
In this quickstart, we'll use [Docker compose](https://docs.docker.com/compose) to create our demo infrastructure.
 | 
			
		||||
 | 
			
		||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/master/examples/quickstart/) directory.
 | 
			
		||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/v1.7/examples/quickstart/) directory.
 | 
			
		||||
 | 
			
		||||
### 1 — Launch Traefik — Tell It to Listen to Docker
 | 
			
		||||
 | 
			
		||||
@@ -13,7 +13,7 @@ version: '3'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  reverse-proxy:
 | 
			
		||||
    image: traefik # The official Traefik docker image
 | 
			
		||||
    image: traefik:v1.7 # The official Traefik docker image
 | 
			
		||||
    command: --api --docker # Enables the web UI and tells Traefik to listen to docker
 | 
			
		||||
    ports:
 | 
			
		||||
      - "80:80"     # The HTTP port
 | 
			
		||||
@@ -101,7 +101,7 @@ IP: 172.27.0.4
 | 
			
		||||
 | 
			
		||||
### 4 — Enjoy Traefik's Magic
 | 
			
		||||
 | 
			
		||||
Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it might be time to dive into [the documentation](https://docs.traefik.io/) and let Traefik work for you!
 | 
			
		||||
Whatever your infrastructure is, there is probably [an available Traefik backend](https://docs.traefik.io/#supported-backends) that will do the job.
 | 
			
		||||
Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it might be time to dive into [the documentation](https://docs.traefik.io/v1.7/) and let Traefik work for you!
 | 
			
		||||
Whatever your infrastructure is, there is probably [an available Traefik backend](https://docs.traefik.io/v1.7/#supported-backends) that will do the job.
 | 
			
		||||
 | 
			
		||||
Our recommendation would be to see for yourself how simple it is to enable HTTPS with [Traefik's let's encrypt integration](https://docs.traefik.io/user-guide/examples/#lets-encrypt-support) using the dedicated [user guide](https://docs.traefik.io/user-guide/docker-and-lets-encrypt/).
 | 
			
		||||
Our recommendation would be to see for yourself how simple it is to enable HTTPS with [Traefik's let's encrypt integration](https://docs.traefik.io/v1.7/user-guide/examples/#lets-encrypt-support) using the dedicated [user guide](https://docs.traefik.io/v1.7/user-guide/docker-and-lets-encrypt/).
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ version: '3'
 | 
			
		||||
services:
 | 
			
		||||
  # The reverse proxy service (Traefik)
 | 
			
		||||
  reverse-proxy:
 | 
			
		||||
    image: traefik  # The official Traefik docker image
 | 
			
		||||
    image: traefik:v1.7  # The official Traefik docker image
 | 
			
		||||
    command: --api --docker  # Enables the web UI and tells Traefik to listen to docker
 | 
			
		||||
    ports:
 | 
			
		||||
      - "80:80"      # The HTTP port
 | 
			
		||||
@@ -13,6 +13,6 @@ services:
 | 
			
		||||
 | 
			
		||||
  # A container that exposes a simple API
 | 
			
		||||
  whoami:
 | 
			
		||||
    image: emilevauge/whoami  # A container that exposes an API to show it's IP address
 | 
			
		||||
    image: emilevauge/whoami  # A container that exposes an API to show its IP address
 | 
			
		||||
    labels:
 | 
			
		||||
      - "traefik.frontend.rule=Host:whoami.docker.localhost"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								exp.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								exp.Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
# WEBUI
 | 
			
		||||
FROM node:8.15.0 as webui
 | 
			
		||||
 | 
			
		||||
ENV WEBUI_DIR /src/webui
 | 
			
		||||
RUN mkdir -p $WEBUI_DIR
 | 
			
		||||
 | 
			
		||||
COPY ./webui/ $WEBUI_DIR/
 | 
			
		||||
 | 
			
		||||
WORKDIR $WEBUI_DIR
 | 
			
		||||
RUN yarn install
 | 
			
		||||
 | 
			
		||||
RUN npm run build
 | 
			
		||||
 | 
			
		||||
# BUILD
 | 
			
		||||
FROM golang:1.12-alpine as gobuild
 | 
			
		||||
 | 
			
		||||
RUN apk --update upgrade \
 | 
			
		||||
    && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
 | 
			
		||||
    && update-ca-certificates \
 | 
			
		||||
    && rm -rf /var/cache/apk/*
 | 
			
		||||
 | 
			
		||||
RUN mkdir -p /usr/local/bin \
 | 
			
		||||
    && curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \
 | 
			
		||||
    && chmod +x /usr/local/bin/go-bindata
 | 
			
		||||
 | 
			
		||||
WORKDIR /go/src/github.com/containous/traefik
 | 
			
		||||
COPY . /go/src/github.com/containous/traefik
 | 
			
		||||
 | 
			
		||||
RUN rm -rf /go/src/github.com/containous/traefik/static/
 | 
			
		||||
COPY --from=webui /src/static/ /go/src/github.com/containous/traefik/static/
 | 
			
		||||
 | 
			
		||||
RUN ./script/make.sh generate binary
 | 
			
		||||
 | 
			
		||||
## IMAGE
 | 
			
		||||
FROM scratch
 | 
			
		||||
 | 
			
		||||
COPY --from=gobuild /usr/share/zoneinfo /usr/share/zoneinfo
 | 
			
		||||
COPY --from=gobuild /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
 | 
			
		||||
COPY --from=gobuild /go/src/github.com/containous/traefik/dist/traefik /
 | 
			
		||||
 | 
			
		||||
EXPOSE 80
 | 
			
		||||
VOLUME ["/tmp"]
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["/traefik"]
 | 
			
		||||
@@ -49,17 +49,24 @@ func (opt Options) String() string {
 | 
			
		||||
	return fmt.Sprintf("[Hostname: %s Headers: %v Path: %s Port: %d Interval: %s]", opt.Hostname, opt.Headers, opt.Path, opt.Port, opt.Interval)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type backendURL struct {
 | 
			
		||||
	url    *url.URL
 | 
			
		||||
	weight int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BackendConfig HealthCheck configuration for a backend
 | 
			
		||||
type BackendConfig struct {
 | 
			
		||||
	Options
 | 
			
		||||
	name           string
 | 
			
		||||
	disabledURLs   []*url.URL
 | 
			
		||||
	disabledURLs   []backendURL
 | 
			
		||||
	requestTimeout time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *BackendConfig) newRequest(serverURL *url.URL) (*http.Request, error) {
 | 
			
		||||
	u := &url.URL{}
 | 
			
		||||
	*u = *serverURL
 | 
			
		||||
	u, err := serverURL.Parse(b.Path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(b.Scheme) > 0 {
 | 
			
		||||
		u.Scheme = b.Scheme
 | 
			
		||||
@@ -69,8 +76,6 @@ func (b *BackendConfig) newRequest(serverURL *url.URL) (*http.Request, error) {
 | 
			
		||||
		u.Host = net.JoinHostPort(u.Hostname(), strconv.Itoa(b.Port))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	u.Path += b.Path
 | 
			
		||||
 | 
			
		||||
	return http.NewRequest(http.MethodGet, u.String(), http.NoBody)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -129,18 +134,18 @@ func (hc *HealthCheck) execute(ctx context.Context, backend *BackendConfig) {
 | 
			
		||||
 | 
			
		||||
func (hc *HealthCheck) checkBackend(backend *BackendConfig) {
 | 
			
		||||
	enabledURLs := backend.LB.Servers()
 | 
			
		||||
	var newDisabledURLs []*url.URL
 | 
			
		||||
	for _, url := range backend.disabledURLs {
 | 
			
		||||
	var newDisabledURLs []backendURL
 | 
			
		||||
	for _, backendurl := range backend.disabledURLs {
 | 
			
		||||
		serverUpMetricValue := float64(0)
 | 
			
		||||
		if err := checkHealth(url, backend); err == nil {
 | 
			
		||||
			log.Warnf("Health check up: Returning to server list. Backend: %q URL: %q", backend.name, url.String())
 | 
			
		||||
			backend.LB.UpsertServer(url, roundrobin.Weight(1))
 | 
			
		||||
		if err := checkHealth(backendurl.url, backend); err == nil {
 | 
			
		||||
			log.Warnf("Health check up: Returning to server list. Backend: %q URL: %q Weight: %d", backend.name, backendurl.url.String(), backendurl.weight)
 | 
			
		||||
			backend.LB.UpsertServer(backendurl.url, roundrobin.Weight(backendurl.weight))
 | 
			
		||||
			serverUpMetricValue = 1
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, url.String(), err)
 | 
			
		||||
			newDisabledURLs = append(newDisabledURLs, url)
 | 
			
		||||
			log.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, backendurl.url.String(), err)
 | 
			
		||||
			newDisabledURLs = append(newDisabledURLs, backendurl)
 | 
			
		||||
		}
 | 
			
		||||
		labelValues := []string{"backend", backend.name, "url", url.String()}
 | 
			
		||||
		labelValues := []string{"backend", backend.name, "url", backendurl.url.String()}
 | 
			
		||||
		hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue)
 | 
			
		||||
	}
 | 
			
		||||
	backend.disabledURLs = newDisabledURLs
 | 
			
		||||
@@ -148,9 +153,18 @@ func (hc *HealthCheck) checkBackend(backend *BackendConfig) {
 | 
			
		||||
	for _, url := range enabledURLs {
 | 
			
		||||
		serverUpMetricValue := float64(1)
 | 
			
		||||
		if err := checkHealth(url, backend); err != nil {
 | 
			
		||||
			log.Warnf("Health check failed: Remove from server list. Backend: %q URL: %q Reason: %s", backend.name, url.String(), err)
 | 
			
		||||
			weight := 1
 | 
			
		||||
			rr, ok := backend.LB.(*roundrobin.RoundRobin)
 | 
			
		||||
			if ok {
 | 
			
		||||
				var gotWeight bool
 | 
			
		||||
				weight, gotWeight = rr.ServerWeight(url)
 | 
			
		||||
				if !gotWeight {
 | 
			
		||||
					weight = 1
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			log.Warnf("Health check failed: Remove from server list. Backend: %q URL: %q Weight: %d Reason: %s", backend.name, url.String(), weight, err)
 | 
			
		||||
			backend.LB.RemoveServer(url)
 | 
			
		||||
			backend.disabledURLs = append(backend.disabledURLs, url)
 | 
			
		||||
			backend.disabledURLs = append(backend.disabledURLs, backendURL{url, weight})
 | 
			
		||||
			serverUpMetricValue = 0
 | 
			
		||||
		}
 | 
			
		||||
		labelValues := []string{"backend", backend.name, "url", url.String()}
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,7 @@ func TestSetBackendsConfiguration(t *testing.T) {
 | 
			
		||||
			if test.startHealthy {
 | 
			
		||||
				lb.servers = append(lb.servers, serverURL)
 | 
			
		||||
			} else {
 | 
			
		||||
				backend.disabledURLs = append(backend.disabledURLs, serverURL)
 | 
			
		||||
				backend.disabledURLs = append(backend.disabledURLs, backendURL{serverURL, 1})
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			collectingMetrics := testhelpers.NewCollectingHealthCheckMetrics()
 | 
			
		||||
@@ -150,11 +150,16 @@ func TestSetBackendsConfiguration(t *testing.T) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewRequest(t *testing.T) {
 | 
			
		||||
	type expected struct {
 | 
			
		||||
		err   bool
 | 
			
		||||
		value string
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		desc      string
 | 
			
		||||
		serverURL string
 | 
			
		||||
		options   Options
 | 
			
		||||
		expected  string
 | 
			
		||||
		expected  expected
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "no port override",
 | 
			
		||||
@@ -163,7 +168,10 @@ func TestNewRequest(t *testing.T) {
 | 
			
		||||
				Path: "/test",
 | 
			
		||||
				Port: 0,
 | 
			
		||||
			},
 | 
			
		||||
			expected: "http://backend1:80/test",
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend1:80/test",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "port override",
 | 
			
		||||
@@ -172,7 +180,10 @@ func TestNewRequest(t *testing.T) {
 | 
			
		||||
				Path: "/test",
 | 
			
		||||
				Port: 8080,
 | 
			
		||||
			},
 | 
			
		||||
			expected: "http://backend2:8080/test",
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend2:8080/test",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "no port override with no port in server URL",
 | 
			
		||||
@@ -181,7 +192,10 @@ func TestNewRequest(t *testing.T) {
 | 
			
		||||
				Path: "/health",
 | 
			
		||||
				Port: 0,
 | 
			
		||||
			},
 | 
			
		||||
			expected: "http://backend1/health",
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend1/health",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "port override with no port in server URL",
 | 
			
		||||
@@ -190,7 +204,10 @@ func TestNewRequest(t *testing.T) {
 | 
			
		||||
				Path: "/health",
 | 
			
		||||
				Port: 8080,
 | 
			
		||||
			},
 | 
			
		||||
			expected: "http://backend2:8080/health",
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend2:8080/health",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "scheme override",
 | 
			
		||||
@@ -200,7 +217,46 @@ func TestNewRequest(t *testing.T) {
 | 
			
		||||
				Path:   "/test",
 | 
			
		||||
				Port:   0,
 | 
			
		||||
			},
 | 
			
		||||
			expected: "http://backend1:80/test",
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend1:80/test",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "path with param",
 | 
			
		||||
			serverURL: "http://backend1:80",
 | 
			
		||||
			options: Options{
 | 
			
		||||
				Path: "/health?powpow=do",
 | 
			
		||||
				Port: 0,
 | 
			
		||||
			},
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend1:80/health?powpow=do",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "path with params",
 | 
			
		||||
			serverURL: "http://backend1:80",
 | 
			
		||||
			options: Options{
 | 
			
		||||
				Path: "/health?powpow=do&do=powpow",
 | 
			
		||||
				Port: 0,
 | 
			
		||||
			},
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   false,
 | 
			
		||||
				value: "http://backend1:80/health?powpow=do&do=powpow",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:      "path with invalid path",
 | 
			
		||||
			serverURL: "http://backend1:80",
 | 
			
		||||
			options: Options{
 | 
			
		||||
				Path: ":",
 | 
			
		||||
				Port: 0,
 | 
			
		||||
			},
 | 
			
		||||
			expected: expected{
 | 
			
		||||
				err:   true,
 | 
			
		||||
				value: "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -211,13 +267,18 @@ func TestNewRequest(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
			backend := NewBackendConfig(test.options, "backendName")
 | 
			
		||||
 | 
			
		||||
			u, err := url.Parse(test.serverURL)
 | 
			
		||||
			require.NoError(t, err)
 | 
			
		||||
			u := testhelpers.MustParseURL(test.serverURL)
 | 
			
		||||
 | 
			
		||||
			req, err := backend.newRequest(u)
 | 
			
		||||
			require.NoError(t, err, "failed to create new backend request")
 | 
			
		||||
 | 
			
		||||
			assert.Equal(t, test.expected, req.URL.String())
 | 
			
		||||
			if test.expected.err {
 | 
			
		||||
				require.Error(t, err)
 | 
			
		||||
				assert.Nil(t, nil)
 | 
			
		||||
			} else {
 | 
			
		||||
				require.NoError(t, err, "failed to create new backend request")
 | 
			
		||||
				require.NotNil(t, req)
 | 
			
		||||
				assert.Equal(t, test.expected.value, req.URL.String())
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/abronan/valkeyrie"
 | 
			
		||||
	"github.com/abronan/valkeyrie/store"
 | 
			
		||||
	"github.com/abronan/valkeyrie/store/etcd/v3"
 | 
			
		||||
	etcdv3 "github.com/abronan/valkeyrie/store/etcd/v3"
 | 
			
		||||
	"github.com/containous/traefik/integration/try"
 | 
			
		||||
	"github.com/go-check/check"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								integration/fixtures/grpc/config_retry.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								integration/fixtures/grpc/config_retry.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
defaultEntryPoints = ["https"]
 | 
			
		||||
 | 
			
		||||
rootCAs = [ """{{ .CertContent }}""" ]
 | 
			
		||||
 | 
			
		||||
[retry]
 | 
			
		||||
 | 
			
		||||
[entryPoints]
 | 
			
		||||
  [entryPoints.https]
 | 
			
		||||
  address = ":4443"
 | 
			
		||||
    [entryPoints.https.tls]
 | 
			
		||||
     [[entryPoints.https.tls.certificates]]
 | 
			
		||||
     certFile = """{{ .CertContent }}"""
 | 
			
		||||
     keyFile  = """{{ .KeyContent }}"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[api]
 | 
			
		||||
 | 
			
		||||
[file]
 | 
			
		||||
 | 
			
		||||
[backends]
 | 
			
		||||
  [backends.backend1]
 | 
			
		||||
    [backends.backend1.servers.server1]
 | 
			
		||||
    url = "https://127.0.0.1:{{ .GRPCServerPort }}"
 | 
			
		||||
    weight = 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[frontends]
 | 
			
		||||
  [frontends.frontend1]
 | 
			
		||||
  backend = "backend1"
 | 
			
		||||
    [frontends.frontend1.routes.test_1]
 | 
			
		||||
    rule = "Host:127.0.0.1"
 | 
			
		||||
@@ -0,0 +1,37 @@
 | 
			
		||||
logLevel = "DEBUG"
 | 
			
		||||
 | 
			
		||||
defaultEntryPoints = ["https"]
 | 
			
		||||
 | 
			
		||||
[entryPoints]
 | 
			
		||||
  [entryPoints.https]
 | 
			
		||||
  address = ":4443"
 | 
			
		||||
    [entryPoints.https.tls]
 | 
			
		||||
     [entryPoints.https.tls.defaultCertificate]
 | 
			
		||||
     certFile = "fixtures/https/wildcard.snitest.com.cert"
 | 
			
		||||
     keyFile = "fixtures/https/wildcard.snitest.com.key"
 | 
			
		||||
 | 
			
		||||
[api]
 | 
			
		||||
 | 
			
		||||
[file]
 | 
			
		||||
 | 
			
		||||
[backends]
 | 
			
		||||
  [backends.backend1]
 | 
			
		||||
    [backends.backend1.servers.server1]
 | 
			
		||||
    url = "http://127.0.0.1:9010"
 | 
			
		||||
    weight = 1
 | 
			
		||||
 | 
			
		||||
[frontends]
 | 
			
		||||
  [frontends.frontend1]
 | 
			
		||||
  backend = "backend1"
 | 
			
		||||
    [frontends.frontend1.routes.test_1]
 | 
			
		||||
    rule = "HostRegexp: {subdomain:[a-z1-9-]+}.snitest.com"
 | 
			
		||||
  [frontends.frontend2]
 | 
			
		||||
  backend = "backend1"
 | 
			
		||||
    [frontends.frontend2.routes.test_1]
 | 
			
		||||
    rule = "HostRegexp: {subdomain:[a-z1-9-]+}.www.snitest.com"
 | 
			
		||||
 | 
			
		||||
[[tls]]
 | 
			
		||||
  entryPoints = ["https"]
 | 
			
		||||
  [tls.certificate]
 | 
			
		||||
    certFile = "fixtures/https/uppercase_wildcard.www.snitest.com.cert"
 | 
			
		||||
    keyFile = "fixtures/https/uppercase_wildcard.www.snitest.com.key"
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
logLevel = "DEBUG"
 | 
			
		||||
 | 
			
		||||
defaultEntryPoints = ["https"]
 | 
			
		||||
 | 
			
		||||
[entryPoints]
 | 
			
		||||
  [entryPoints.https]
 | 
			
		||||
  address = ":4443"
 | 
			
		||||
    [entryPoints.https.tls]
 | 
			
		||||
     [[entryPoints.https.tls.certificates]]
 | 
			
		||||
     certFile = "fixtures/https/uppercase_wildcard.www.snitest.com.cert"
 | 
			
		||||
     keyFile = "fixtures/https/uppercase_wildcard.www.snitest.com.key"
 | 
			
		||||
     [entryPoints.https.tls.defaultCertificate]
 | 
			
		||||
     certFile = "fixtures/https/wildcard.snitest.com.cert"
 | 
			
		||||
     keyFile = "fixtures/https/wildcard.snitest.com.key"
 | 
			
		||||
 | 
			
		||||
[api]
 | 
			
		||||
 | 
			
		||||
[file]
 | 
			
		||||
 | 
			
		||||
[backends]
 | 
			
		||||
  [backends.backend1]
 | 
			
		||||
    [backends.backend1.servers.server1]
 | 
			
		||||
    url = "http://127.0.0.1:9010"
 | 
			
		||||
    weight = 1
 | 
			
		||||
 | 
			
		||||
[frontends]
 | 
			
		||||
  [frontends.frontend1]
 | 
			
		||||
  backend = "backend1"
 | 
			
		||||
    [frontends.frontend1.routes.test_1]
 | 
			
		||||
    rule = "HostRegexp: {subdomain:[a-z1-9-]+}.snitest.com"
 | 
			
		||||
  [frontends.frontend2]
 | 
			
		||||
  backend = "backend1"
 | 
			
		||||
    [frontends.frontend2.routes.test_2]
 | 
			
		||||
    rule = "HostRegexp: {subdomain:[a-z1-9-]+}.www.snitest.com"
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
-----BEGIN CERTIFICATE-----
 | 
			
		||||
MIIDDDCCAfSgAwIBAgIJAI1YpPACcsQnMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV
 | 
			
		||||
BAMME0ZPTy5XV1cuU05JVEVTVC5DT00wHhcNMTgxMDI5MTU1NDI4WhcNMjgxMDI2
 | 
			
		||||
MTU1NDI4WjAeMRwwGgYDVQQDDBNGT08uV1dXLlNOSVRFU1QuQ09NMIIBIjANBgkq
 | 
			
		||||
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxyWr+1O/tf4yjwhfp3/SDGT5fD0chhGs
 | 
			
		||||
Qc+QM7Ewb5SOmIL5UskxT5pCKc6Kuie5qqEp9xH8Rrfo18iEJQPdhFC1YkaBEI0L
 | 
			
		||||
l1qvN4jmXzAK/E/u4+X+FFprHyruXCmuXqsWQt/qEOqU1ciN47GE9+ZW4R+q70uB
 | 
			
		||||
zrEQ+dzN7IBsyf1lzzS3/TwDgj085QmiZYxKxX40d5hZW6AHxPEKJa2p+Gweqg74
 | 
			
		||||
SpzBWL1DYQLcqHUuMKlbigHg+gleqcO8NiHT5UdeSPVokD5VJPO1La1PMqkLmJYr
 | 
			
		||||
3vVkQ9YzNQ615bX98VMIi17cmE7LE+vz+v287cdFT2f1pNXr3pCGzQIDAQABo00w
 | 
			
		||||
SzALBgNVHQ8EBAMCBDAwCQYDVR0TBAIwADATBgNVHSUEDDAKBggrBgEFBQcDATAc
 | 
			
		||||
BgNVHREEFTATghEqLldXVy5TTklURVNULkNPTTANBgkqhkiG9w0BAQsFAAOCAQEA
 | 
			
		||||
HJyMCj9oHwECmSGWHnYHkO42zeyj24RKlhNG5skUCqZmpmeDc2BRMYH4fjP75MD2
 | 
			
		||||
kuasZBMAxyQnur/DEn8TzQ1mlKxYCqoza1ql5PkfcwNUp/tvQ7Jhf45Z5mQVeUM7
 | 
			
		||||
RSiBhpeetjHY5/xQb7gXHa97+OjDoRJ6NL/dzGxqypf37kiQPw2jWI5RTFBkP+h/
 | 
			
		||||
sPbeAZJjmiEzvw31SAw9IGj3VvIwcuTxbsdJQITU7hCXDSd1EIocmzAoobY7WRcT
 | 
			
		||||
B1pLmHlP/BaIsM7m0NF/HgUsgo/kgSsxnGA2MHMYQiTImR2DUgrJYzKlJ5acscLK
 | 
			
		||||
sMq9xUnjr6KF1C15R2FpDw==
 | 
			
		||||
-----END CERTIFICATE-----
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
-----BEGIN PRIVATE KEY-----
 | 
			
		||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHJav7U7+1/jKP
 | 
			
		||||
CF+nf9IMZPl8PRyGEaxBz5AzsTBvlI6YgvlSyTFPmkIpzoq6J7mqoSn3EfxGt+jX
 | 
			
		||||
yIQlA92EULViRoEQjQuXWq83iOZfMAr8T+7j5f4UWmsfKu5cKa5eqxZC3+oQ6pTV
 | 
			
		||||
yI3jsYT35lbhH6rvS4HOsRD53M3sgGzJ/WXPNLf9PAOCPTzlCaJljErFfjR3mFlb
 | 
			
		||||
oAfE8Qolran4bB6qDvhKnMFYvUNhAtyodS4wqVuKAeD6CV6pw7w2IdPlR15I9WiQ
 | 
			
		||||
PlUk87UtrU8yqQuYlive9WRD1jM1DrXltf3xUwiLXtyYTssT6/P6/bztx0VPZ/Wk
 | 
			
		||||
1evekIbNAgMBAAECggEAVOFEnTmD47D1oasjAgRj5a5/+6kcaDROJDqwrqeeCmDa
 | 
			
		||||
KjzgwZ1JLDGGc8U5scBOzWAlv83lpcqrLpWjZRdxqfywYrPEPOaxAxC+z7/E2Ntk
 | 
			
		||||
Q0hafL5BfjFPqRgmQhft3yGyukwvuogRadEyUNMP5o1BiHBz7cxUBmHH54dqKZuO
 | 
			
		||||
ueUMgqraJX/GK+Om2rIUst0oOT9yUED+f6ciIjVAmCx1EVxZmX7sxKig10e70eOJ
 | 
			
		||||
rfHlRguJWtxy0+Wl8R8TVrpI5r7qsE8y2fet9RqFOof/4ds8uA2nlZ3NpGkAq3Oo
 | 
			
		||||
+65h/2fjD5uQ7jmT+XZcbC7SGhboV42zIrmn0DyNIQKBgQDneeqzMlooNzLD6x+v
 | 
			
		||||
bXo6BJAHXuml440zS5i5RawKc3+/GxGQjBvnfhFH6AQ7cL4ohYyfuAo4srgifRle
 | 
			
		||||
x3Gl8yvFf0uLaQHj811HPWV0fU8bwekI77jmH7WZi2ED/qX7X06R2vvUPGshvJi5
 | 
			
		||||
yPCmJpDQQA6wmxBG1U4SqNw0xQKBgQDcPu2DMAJpbMWWeb5xWv5/6h6TUF4tV7fV
 | 
			
		||||
eIBWuVfe9Jry3gAnb6YUOKYmA5xYJJ+fTz4Nhe4+LQbFS1esT/7ZIATvILogZc3S
 | 
			
		||||
X9+ZCYG/tmDDZvhZqIWWSzzdrjb7dseP1RI4Wp6OnRqHWErrkfzDJKuN15qgW5vR
 | 
			
		||||
FUR2ykV6aQKBgQCv5ZQ00dly3+ciu+QbAb00o0zzXOt91Lnytcp7V3dRhc0YYrBp
 | 
			
		||||
QB7gPYtSMfwtUxIdZsaihE64IQ8NnjSOMk6pRW0Iqh+083mtR7ylKwGSkLpxpFu6
 | 
			
		||||
H7hInuX3pNN3HqXwq87fxSFCeRsLyu3fl9NO3tWCenrvNxYaTXMDeO/E5QKBgE7D
 | 
			
		||||
XlMU/zfOg1bN0PJe1TbPdgG+sv9KKF76CgN5otgD58nE5I812VHP9HMRxX6sEj15
 | 
			
		||||
rDpP1CR+G7bAu+jObtgdIEaYEJf3cES0rpTfFnyF71LR5yzBHIzj+S9Z1yXUk4d3
 | 
			
		||||
bl2i4qMjwdH3HEvkWF09JvDB0vVX7YA3N9W3fmNJAoGBALRi9EbkEBW1vMPwMzps
 | 
			
		||||
YoJ1lp/YyDGTFcg6KFgTfNaOYccb6EXL2Cd21qvDsJw6wthXS+cSqX3qlTLAVLY8
 | 
			
		||||
az/NfyFmW1fUtGjs2s0ZtplStGBhv8VR+2fpt9fgDOOrGYiN2dtmPm7jCAmyQQq7
 | 
			
		||||
JCg7Vq6f0q95DUwiUAo24CBn
 | 
			
		||||
-----END PRIVATE KEY-----
 | 
			
		||||
@@ -417,3 +417,45 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) {
 | 
			
		||||
	})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *GRPCSuite) TestGRPCWithRetry(c *check.C) {
 | 
			
		||||
	lis, err := net.Listen("tcp", ":0")
 | 
			
		||||
	_, port, err := net.SplitHostPort(lis.Addr().String())
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		err := startGRPCServer(lis, &myserver{})
 | 
			
		||||
		c.Log(err)
 | 
			
		||||
		c.Assert(err, check.IsNil)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	file := s.adaptFile(c, "fixtures/grpc/config_retry.toml", struct {
 | 
			
		||||
		CertContent    string
 | 
			
		||||
		KeyContent     string
 | 
			
		||||
		GRPCServerPort string
 | 
			
		||||
	}{
 | 
			
		||||
		CertContent:    string(LocalhostCert),
 | 
			
		||||
		KeyContent:     string(LocalhostKey),
 | 
			
		||||
		GRPCServerPort: port,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	defer os.Remove(file)
 | 
			
		||||
	cmd, display := s.traefikCmd(withConfigFile(file))
 | 
			
		||||
	defer display(c)
 | 
			
		||||
 | 
			
		||||
	err = cmd.Start()
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	defer cmd.Process.Kill()
 | 
			
		||||
 | 
			
		||||
	// wait for Traefik
 | 
			
		||||
	err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("Host:127.0.0.1"))
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	var response string
 | 
			
		||||
	err = try.Do(1*time.Second, func() error {
 | 
			
		||||
		response, err = callHelloClientGRPC("World", true)
 | 
			
		||||
		return err
 | 
			
		||||
	})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(response, check.Equals, "Hello World")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -341,24 +341,32 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAs(c *check.
 | 
			
		||||
	err = try.GetRequest("http://127.0.0.1:8080/api/providers", 500*time.Millisecond, try.BodyContains("Host:snitest.org"))
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443", nil)
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
	req.Host = "snitest.com"
 | 
			
		||||
 | 
			
		||||
	tlsConfig := &tls.Config{
 | 
			
		||||
		InsecureSkipVerify: true,
 | 
			
		||||
		ServerName:         "snitest.com",
 | 
			
		||||
		Certificates:       []tls.Certificate{},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client := http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
 | 
			
		||||
		Timeout:   1 * time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Connection without client certificate should fail
 | 
			
		||||
	_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	// Connect with client signed by ca1
 | 
			
		||||
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
 | 
			
		||||
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
 | 
			
		||||
 | 
			
		||||
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
 | 
			
		||||
 | 
			
		||||
	conn.Close()
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	// Connect with client signed by ca2
 | 
			
		||||
	tlsConfig = &tls.Config{
 | 
			
		||||
@@ -370,10 +378,13 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAs(c *check.
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
 | 
			
		||||
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
 | 
			
		||||
 | 
			
		||||
	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
 | 
			
		||||
	client = http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
 | 
			
		||||
		Timeout:   1 * time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conn.Close()
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	// Connect with client signed by ca3 should fail
 | 
			
		||||
	tlsConfig = &tls.Config{
 | 
			
		||||
@@ -385,8 +396,13 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAs(c *check.
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
 | 
			
		||||
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
 | 
			
		||||
 | 
			
		||||
	_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
 | 
			
		||||
	client = http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
 | 
			
		||||
		Timeout:   1 * time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestWithClientCertificateAuthentication
 | 
			
		||||
@@ -402,24 +418,32 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAsMultipleFi
 | 
			
		||||
	err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1000*time.Millisecond, try.BodyContains("Host:snitest.org"))
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443", nil)
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
	req.Host = "snitest.com"
 | 
			
		||||
 | 
			
		||||
	tlsConfig := &tls.Config{
 | 
			
		||||
		InsecureSkipVerify: true,
 | 
			
		||||
		ServerName:         "snitest.com",
 | 
			
		||||
		Certificates:       []tls.Certificate{},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client := http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
 | 
			
		||||
		Timeout:   1 * time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Connection without client certificate should fail
 | 
			
		||||
	_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	// Connect with client signed by ca1
 | 
			
		||||
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
 | 
			
		||||
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
 | 
			
		||||
 | 
			
		||||
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
 | 
			
		||||
 | 
			
		||||
	conn.Close()
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	// Connect with client signed by ca2
 | 
			
		||||
	tlsConfig = &tls.Config{
 | 
			
		||||
@@ -431,9 +455,13 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAsMultipleFi
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
 | 
			
		||||
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
 | 
			
		||||
 | 
			
		||||
	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
 | 
			
		||||
	conn.Close()
 | 
			
		||||
	client = http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
 | 
			
		||||
		Timeout:   1 * time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	// Connect with client signed by ca3 should fail
 | 
			
		||||
	tlsConfig = &tls.Config{
 | 
			
		||||
@@ -445,8 +473,13 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAsMultipleFi
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
 | 
			
		||||
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
 | 
			
		||||
 | 
			
		||||
	_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
 | 
			
		||||
	client = http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
 | 
			
		||||
		Timeout:   1 * time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = client.Do(req)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *HTTPSSuite) TestWithRootCAsContentForHTTPSOnBackend(c *check.C) {
 | 
			
		||||
@@ -830,3 +863,71 @@ func (s *HTTPSSuite) TestEntrypointHttpsRedirectAndPathModification(c *check.C)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestWithSNIStaticCaseInsensitive involves a client sending a SNI hostname of
 | 
			
		||||
// "bar.www.snitest.com", which matches the DNS SAN of '*.WWW.SNITEST.COM'. The test
 | 
			
		||||
// verifies that traefik presents the correct certificate.
 | 
			
		||||
func (s *HTTPSSuite) TestWithSNIStaticCaseInsensitive(c *check.C) {
 | 
			
		||||
	cmd, display := s.traefikCmd(withConfigFile("fixtures/https/https_sni_case_insensitive_static.toml"))
 | 
			
		||||
	defer display(c)
 | 
			
		||||
	err := cmd.Start()
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
	defer cmd.Process.Kill()
 | 
			
		||||
 | 
			
		||||
	// wait for Traefik
 | 
			
		||||
	err = try.GetRequest("http://127.0.0.1:8080/api/providers", 500*time.Millisecond, try.BodyContains("HostRegexp: {subdomain:[a-z1-9-]+}.www.snitest.com"))
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	tlsConfig := &tls.Config{
 | 
			
		||||
		InsecureSkipVerify: true,
 | 
			
		||||
		ServerName:         "bar.www.snitest.com",
 | 
			
		||||
		NextProtos:         []string{"h2", "http/1.1"},
 | 
			
		||||
	}
 | 
			
		||||
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
 | 
			
		||||
 | 
			
		||||
	defer conn.Close()
 | 
			
		||||
	err = conn.Handshake()
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("TLS handshake error"))
 | 
			
		||||
 | 
			
		||||
	cs := conn.ConnectionState()
 | 
			
		||||
	err = cs.PeerCertificates[0].VerifyHostname("*.WWW.SNITEST.COM")
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername"))
 | 
			
		||||
 | 
			
		||||
	proto := conn.ConnectionState().NegotiatedProtocol
 | 
			
		||||
	c.Assert(proto, checker.Equals, "h2")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestWithSNIDynamicCaseInsensitive involves a client sending a SNI hostname of
 | 
			
		||||
// "bar.www.snitest.com", which matches the DNS SAN of '*.WWW.SNITEST.COM'. The test
 | 
			
		||||
// verifies that traefik presents the correct certificate.
 | 
			
		||||
func (s *HTTPSSuite) TestWithSNIDynamicCaseInsensitive(c *check.C) {
 | 
			
		||||
	cmd, display := s.traefikCmd(withConfigFile("fixtures/https/https_sni_case_insensitive_dynamic.toml"))
 | 
			
		||||
	defer display(c)
 | 
			
		||||
	err := cmd.Start()
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
	defer cmd.Process.Kill()
 | 
			
		||||
 | 
			
		||||
	// wait for Traefik
 | 
			
		||||
	err = try.GetRequest("http://127.0.0.1:8080/api/providers", 500*time.Millisecond, try.BodyContains("HostRegexp: {subdomain:[a-z1-9-]+}.www.snitest.com"))
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	tlsConfig := &tls.Config{
 | 
			
		||||
		InsecureSkipVerify: true,
 | 
			
		||||
		ServerName:         "bar.www.snitest.com",
 | 
			
		||||
		NextProtos:         []string{"h2", "http/1.1"},
 | 
			
		||||
	}
 | 
			
		||||
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
 | 
			
		||||
 | 
			
		||||
	defer conn.Close()
 | 
			
		||||
	err = conn.Handshake()
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("TLS handshake error"))
 | 
			
		||||
 | 
			
		||||
	cs := conn.ConnectionState()
 | 
			
		||||
	err = cs.PeerCertificates[0].VerifyHostname("*.WWW.SNITEST.COM")
 | 
			
		||||
	c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername"))
 | 
			
		||||
 | 
			
		||||
	proto := conn.ConnectionState().NegotiatedProtocol
 | 
			
		||||
	c.Assert(proto, checker.Equals, "h2")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,11 +25,6 @@ var host = flag.Bool("host", false, "run host integration tests")
 | 
			
		||||
var showLog = flag.Bool("tlog", false, "always show Traefik logs")
 | 
			
		||||
 | 
			
		||||
func Test(t *testing.T) {
 | 
			
		||||
	check.TestingT(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
	if !*integration {
 | 
			
		||||
		log.Info("Integration tests disabled.")
 | 
			
		||||
		return
 | 
			
		||||
@@ -70,6 +65,8 @@ func init() {
 | 
			
		||||
		check.Suite(&ProxyProtocolSuite{})
 | 
			
		||||
		check.Suite(&Etcd3Suite{})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	check.TestingT(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var traefikBinary = "../dist/traefik"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,8 @@
 | 
			
		||||
consul:
 | 
			
		||||
  image: consul
 | 
			
		||||
  # use v1.4.0 because https://github.com/hashicorp/consul/issues/5270
 | 
			
		||||
  # v1.4.1 cannot be used.
 | 
			
		||||
  # waiting for v1.4.2
 | 
			
		||||
  image: consul:1.4.0
 | 
			
		||||
  command: agent -server -bootstrap-expect 1 -client 0.0.0.0 -log-level debug -ui
 | 
			
		||||
  ports:
 | 
			
		||||
    - "8400:8400"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
pebble:
 | 
			
		||||
  image: letsencrypt/pebble:2018-07-27
 | 
			
		||||
  image: letsencrypt/pebble:v2.0.1
 | 
			
		||||
  command: pebble --dnsserver ${DOCKER_HOST_IP}:5053
 | 
			
		||||
  ports:
 | 
			
		||||
    - 14000:14000
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
zipkin:
 | 
			
		||||
  # Fix zipkin version 2.4.2
 | 
			
		||||
  # due to a bug in latest version https://github.com/openzipkin/zipkin/releases/tag/2.4.4
 | 
			
		||||
  image: openzipkin/zipkin:2.4.2
 | 
			
		||||
  image: openzipkin/zipkin:2.12.6
 | 
			
		||||
  environment:
 | 
			
		||||
    STORAGE_TYPE: mem
 | 
			
		||||
    JAVA_OPTS: -Dlogging.level.zipkin=DEBUG
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package integration
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"time"
 | 
			
		||||
@@ -38,6 +39,10 @@ func (s *TimeoutSuite) TestForwardingTimeouts(c *check.C) {
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
	c.Assert(response.StatusCode, checker.Equals, http.StatusGatewayTimeout)
 | 
			
		||||
 | 
			
		||||
	// Check that timeout service is available
 | 
			
		||||
	statusURL := fmt.Sprintf("http://%s:9000/statusTest?status=200", httpTimeoutEndpoint)
 | 
			
		||||
	c.Assert(try.GetRequest(statusURL, 60*time.Second, try.StatusCodeIs(http.StatusOK)), checker.IsNil)
 | 
			
		||||
 | 
			
		||||
	// This simulates a ResponseHeaderTimeout.
 | 
			
		||||
	response, err = http.Get("http://127.0.0.1:8000/responseHeaderTimeout?sleep=1000")
 | 
			
		||||
	c.Assert(err, checker.IsNil)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package accesslog
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
@@ -32,6 +33,19 @@ const (
 | 
			
		||||
	JSONFormat = "json"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type noopCloser struct {
 | 
			
		||||
	*os.File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n noopCloser) Write(p []byte) (int, error) {
 | 
			
		||||
	return n.File.Write(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n noopCloser) Close() error {
 | 
			
		||||
	// noop
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type logHandlerParams struct {
 | 
			
		||||
	logDataTable *LogData
 | 
			
		||||
	crr          *captureRequestReader
 | 
			
		||||
@@ -42,7 +56,7 @@ type logHandlerParams struct {
 | 
			
		||||
type LogHandler struct {
 | 
			
		||||
	config         *types.AccessLog
 | 
			
		||||
	logger         *logrus.Logger
 | 
			
		||||
	file           *os.File
 | 
			
		||||
	file           io.WriteCloser
 | 
			
		||||
	mu             sync.Mutex
 | 
			
		||||
	httpCodeRanges types.HTTPCodeRanges
 | 
			
		||||
	logHandlerChan chan logHandlerParams
 | 
			
		||||
@@ -51,7 +65,7 @@ type LogHandler struct {
 | 
			
		||||
 | 
			
		||||
// NewLogHandler creates a new LogHandler
 | 
			
		||||
func NewLogHandler(config *types.AccessLog) (*LogHandler, error) {
 | 
			
		||||
	file := os.Stdout
 | 
			
		||||
	var file io.WriteCloser = noopCloser{os.Stdout}
 | 
			
		||||
	if len(config.FilePath) > 0 {
 | 
			
		||||
		f, err := openAccessLogFile(config.FilePath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -205,14 +219,15 @@ func (l *LogHandler) Close() error {
 | 
			
		||||
// Rotate closes and reopens the log file to allow for rotation
 | 
			
		||||
// by an external source.
 | 
			
		||||
func (l *LogHandler) Rotate() error {
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	if l.file != nil {
 | 
			
		||||
		defer func(f *os.File) {
 | 
			
		||||
			f.Close()
 | 
			
		||||
		}(l.file)
 | 
			
		||||
	if l.config.FilePath == "" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if l.file != nil {
 | 
			
		||||
		defer func(f io.Closer) { _ = f.Close() }(l.file)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	l.file, err = os.OpenFile(l.config.FilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,8 @@ func (f *CommonLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
 | 
			
		||||
	var timestamp = defaultValue
 | 
			
		||||
	if v, ok := entry.Data[StartUTC]; ok {
 | 
			
		||||
		timestamp = v.(time.Time).Format(commonLogTimeFormat)
 | 
			
		||||
	} else if v, ok := entry.Data[StartLocal]; ok {
 | 
			
		||||
		timestamp = v.(time.Time).Local().Format(commonLogTimeFormat)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var elapsedMillis int64
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package accesslog
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@@ -57,10 +58,34 @@ func TestCommonLogFormatter_Format(t *testing.T) {
 | 
			
		||||
				BackendURL:             "http://10.0.0.2/toto",
 | 
			
		||||
			},
 | 
			
		||||
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:23:00:00 +0000] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
 | 
			
		||||
`,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "all data with local time",
 | 
			
		||||
			data: map[string]interface{}{
 | 
			
		||||
				StartLocal:             time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
 | 
			
		||||
				Duration:               123 * time.Second,
 | 
			
		||||
				ClientHost:             "10.0.0.1",
 | 
			
		||||
				ClientUsername:         "Client",
 | 
			
		||||
				RequestMethod:          http.MethodGet,
 | 
			
		||||
				RequestPath:            "/foo",
 | 
			
		||||
				RequestProtocol:        "http",
 | 
			
		||||
				OriginStatus:           123,
 | 
			
		||||
				OriginContentSize:      132,
 | 
			
		||||
				RequestRefererHeader:   "referer",
 | 
			
		||||
				RequestUserAgentHeader: "agent",
 | 
			
		||||
				RequestCount:           nil,
 | 
			
		||||
				FrontendName:           "foo",
 | 
			
		||||
				BackendURL:             "http://10.0.0.2/toto",
 | 
			
		||||
			},
 | 
			
		||||
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:14:00:00 -0900] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
 | 
			
		||||
`,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set timezone to Alaska to have a constant behavior
 | 
			
		||||
	os.Setenv("TZ", "US/Alaska")
 | 
			
		||||
 | 
			
		||||
	for _, test := range testCases {
 | 
			
		||||
		test := test
 | 
			
		||||
		t.Run(test.name, func(t *testing.T) {
 | 
			
		||||
 
 | 
			
		||||
@@ -44,8 +44,9 @@ func TestLogRotation(t *testing.T) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("Error setting up temporary directory: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer os.RemoveAll(tempDir)
 | 
			
		||||
 | 
			
		||||
	fileName := tempDir + "traefik.log"
 | 
			
		||||
	fileName := filepath.Join(tempDir, "traefik.log")
 | 
			
		||||
	rotatedFileName := fileName + ".rotated"
 | 
			
		||||
 | 
			
		||||
	config := &types.AccessLog{FilePath: fileName, Format: CommonFormat}
 | 
			
		||||
@@ -587,6 +588,7 @@ func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) {
 | 
			
		||||
 | 
			
		||||
	restoreStdout = func() {
 | 
			
		||||
		os.Stdout = original
 | 
			
		||||
		os.RemoveAll(file.Name())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return file, restoreStdout
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,7 @@ func getLinesFromFile(filename string) ([]string, error) {
 | 
			
		||||
	var filteredLines []string
 | 
			
		||||
	for _, rawLine := range rawLines {
 | 
			
		||||
		line := strings.TrimSpace(rawLine)
 | 
			
		||||
		if line != "" {
 | 
			
		||||
		if line != "" && !strings.HasPrefix(line, "#") {
 | 
			
		||||
			filteredLines = append(filteredLines, line)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,17 @@ func TestAuthUsersFromFile(t *testing.T) {
 | 
			
		||||
				return parserDigestUsers(digest)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			authType: "basic",
 | 
			
		||||
			usersStr: "#Comment\ntest:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/\ntest2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0\n",
 | 
			
		||||
			userKeys: []string{"test", "test2"},
 | 
			
		||||
			parserFunc: func(fileName string) (map[string]string, error) {
 | 
			
		||||
				basic := &types.Basic{
 | 
			
		||||
					UsersFile: fileName,
 | 
			
		||||
				}
 | 
			
		||||
				return parserBasicUsers(basic)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range tests {
 | 
			
		||||
 
 | 
			
		||||
@@ -96,7 +96,11 @@ func Forward(config *types.Forward, w http.ResponseWriter, r *http.Request, next
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, headerName := range config.AuthResponseHeaders {
 | 
			
		||||
		r.Header.Set(headerName, forwardResponse.Header.Get(headerName))
 | 
			
		||||
		headerKey := http.CanonicalHeaderKey(headerName)
 | 
			
		||||
		r.Header.Del(headerKey)
 | 
			
		||||
		if len(forwardResponse.Header[headerKey]) > 0 {
 | 
			
		||||
			r.Header[headerKey] = append([]string(nil), forwardResponse.Header[headerKey]...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.RequestURI = r.URL.RequestURI()
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,8 @@ func TestForwardAuthFail(t *testing.T) {
 | 
			
		||||
func TestForwardAuthSuccess(t *testing.T) {
 | 
			
		||||
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		w.Header().Set("X-Auth-User", "user@example.com")
 | 
			
		||||
		w.Header().Add("X-Auth-Group", "group1")
 | 
			
		||||
		w.Header().Add("X-Auth-Group", "group2")
 | 
			
		||||
		w.Header().Set("X-Auth-Secret", "secret")
 | 
			
		||||
		fmt.Fprintln(w, "Success")
 | 
			
		||||
	}))
 | 
			
		||||
@@ -58,13 +60,14 @@ func TestForwardAuthSuccess(t *testing.T) {
 | 
			
		||||
	middleware, err := NewAuthenticator(&types.Auth{
 | 
			
		||||
		Forward: &types.Forward{
 | 
			
		||||
			Address:             server.URL,
 | 
			
		||||
			AuthResponseHeaders: []string{"X-Auth-User"},
 | 
			
		||||
			AuthResponseHeaders: []string{"X-Auth-User", "X-Auth-Group"},
 | 
			
		||||
		},
 | 
			
		||||
	}, &tracing.Tracing{})
 | 
			
		||||
	assert.NoError(t, err, "there should be no error")
 | 
			
		||||
 | 
			
		||||
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		assert.Equal(t, "user@example.com", r.Header.Get("X-Auth-User"))
 | 
			
		||||
		assert.Equal(t, []string{"group1", "group2"}, r.Header["X-Auth-Group"])
 | 
			
		||||
		assert.Empty(t, r.Header.Get("X-Auth-Secret"))
 | 
			
		||||
		fmt.Fprintln(w, "traefik")
 | 
			
		||||
	})
 | 
			
		||||
@@ -74,6 +77,7 @@ func TestForwardAuthSuccess(t *testing.T) {
 | 
			
		||||
	defer ts.Close()
 | 
			
		||||
 | 
			
		||||
	req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
 | 
			
		||||
	req.Header.Set("X-Auth-Group", "admin_group")
 | 
			
		||||
	res, err := http.DefaultClient.Do(req)
 | 
			
		||||
	assert.NoError(t, err, "there should be no error")
 | 
			
		||||
	assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal")
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,10 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Compile time validation that the response recorder implements http interfaces correctly.
 | 
			
		||||
var _ middlewares.Stateful = &responseRecorderWithCloseNotify{}
 | 
			
		||||
var (
 | 
			
		||||
	_ middlewares.Stateful = &responseRecorderWithCloseNotify{}
 | 
			
		||||
	_ middlewares.Stateful = &codeCatcherWithCloseNotify{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Handler is a middleware that provides the custom error pages
 | 
			
		||||
type Handler struct {
 | 
			
		||||
@@ -74,25 +77,29 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	recorder := newResponseRecorder(w)
 | 
			
		||||
	next.ServeHTTP(recorder, req)
 | 
			
		||||
	catcher := newCodeCatcher(w, h.httpCodeRanges)
 | 
			
		||||
	next.ServeHTTP(catcher, req)
 | 
			
		||||
	if !catcher.isFilteredCode() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check the recorder code against the configured http status code ranges
 | 
			
		||||
	code := catcher.getCode()
 | 
			
		||||
	for _, block := range h.httpCodeRanges {
 | 
			
		||||
		if recorder.GetCode() >= block[0] && recorder.GetCode() <= block[1] {
 | 
			
		||||
			log.Errorf("Caught HTTP Status Code %d, returning error page", recorder.GetCode())
 | 
			
		||||
		if code >= block[0] && code <= block[1] {
 | 
			
		||||
			log.Errorf("Caught HTTP Status Code %d, returning error page", code)
 | 
			
		||||
 | 
			
		||||
			var query string
 | 
			
		||||
			if len(h.backendQuery) > 0 {
 | 
			
		||||
				query = "/" + strings.TrimPrefix(h.backendQuery, "/")
 | 
			
		||||
				query = strings.Replace(query, "{status}", strconv.Itoa(recorder.GetCode()), -1)
 | 
			
		||||
				query = strings.Replace(query, "{status}", strconv.Itoa(code), -1)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			pageReq, err := newRequest(h.backendURL + query)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Error(err)
 | 
			
		||||
				w.WriteHeader(recorder.GetCode())
 | 
			
		||||
				fmt.Fprint(w, http.StatusText(recorder.GetCode()))
 | 
			
		||||
				w.WriteHeader(code)
 | 
			
		||||
				fmt.Fprint(w, http.StatusText(code))
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -102,16 +109,11 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.
 | 
			
		||||
			h.backendHandler.ServeHTTP(recorderErrorPage, pageReq.WithContext(req.Context()))
 | 
			
		||||
 | 
			
		||||
			utils.CopyHeaders(w.Header(), recorderErrorPage.Header())
 | 
			
		||||
			w.WriteHeader(recorder.GetCode())
 | 
			
		||||
			w.WriteHeader(code)
 | 
			
		||||
			w.Write(recorderErrorPage.GetBody().Bytes())
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// did not catch a configured status code so proceed with the request
 | 
			
		||||
	utils.CopyHeaders(w.Header(), recorder.Header())
 | 
			
		||||
	w.WriteHeader(recorder.GetCode())
 | 
			
		||||
	w.Write(recorder.GetBody().Bytes())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newRequest(baseURL string) (*http.Request, error) {
 | 
			
		||||
@@ -129,6 +131,133 @@ func newRequest(baseURL string) (*http.Request, error) {
 | 
			
		||||
	return req, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type responseInterceptor interface {
 | 
			
		||||
	http.ResponseWriter
 | 
			
		||||
	http.Flusher
 | 
			
		||||
	getCode() int
 | 
			
		||||
	isFilteredCode() bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// codeCatcher is a response writer that detects as soon as possible whether the
 | 
			
		||||
// response is a code within the ranges of codes it watches for. If it is, it
 | 
			
		||||
// simply drops the data from the response. Otherwise, it forwards it directly to
 | 
			
		||||
// the original client (its responseWriter) without any buffering.
 | 
			
		||||
type codeCatcher struct {
 | 
			
		||||
	headerMap          http.Header
 | 
			
		||||
	code               int
 | 
			
		||||
	httpCodeRanges     types.HTTPCodeRanges
 | 
			
		||||
	firstWrite         bool
 | 
			
		||||
	caughtFilteredCode bool
 | 
			
		||||
	responseWriter     http.ResponseWriter
 | 
			
		||||
	headersSent        bool
 | 
			
		||||
	err                error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type codeCatcherWithCloseNotify struct {
 | 
			
		||||
	*codeCatcher
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CloseNotify returns a channel that receives at most a
 | 
			
		||||
// single value (true) when the client connection has gone away.
 | 
			
		||||
func (cc *codeCatcherWithCloseNotify) CloseNotify() <-chan bool {
 | 
			
		||||
	return cc.responseWriter.(http.CloseNotifier).CloseNotify()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newCodeCatcher(rw http.ResponseWriter, httpCodeRanges types.HTTPCodeRanges) responseInterceptor {
 | 
			
		||||
	catcher := &codeCatcher{
 | 
			
		||||
		headerMap:      make(http.Header),
 | 
			
		||||
		code:           http.StatusOK, // If backend does not call WriteHeader on us, we consider it's a 200.
 | 
			
		||||
		responseWriter: rw,
 | 
			
		||||
		httpCodeRanges: httpCodeRanges,
 | 
			
		||||
		firstWrite:     true,
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := rw.(http.CloseNotifier); ok {
 | 
			
		||||
		return &codeCatcherWithCloseNotify{catcher}
 | 
			
		||||
	}
 | 
			
		||||
	return catcher
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cc *codeCatcher) Header() http.Header {
 | 
			
		||||
	if cc.headerMap == nil {
 | 
			
		||||
		cc.headerMap = make(http.Header)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cc.headerMap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cc *codeCatcher) getCode() int {
 | 
			
		||||
	return cc.code
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isFilteredCode returns whether the codeCatcher received a response code among the ones it is watching,
 | 
			
		||||
// and for which the response should be deferred to the error handler.
 | 
			
		||||
func (cc *codeCatcher) isFilteredCode() bool {
 | 
			
		||||
	return cc.caughtFilteredCode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cc *codeCatcher) Write(buf []byte) (int, error) {
 | 
			
		||||
	if !cc.firstWrite {
 | 
			
		||||
		if cc.caughtFilteredCode {
 | 
			
		||||
			// We don't care about the contents of the response,
 | 
			
		||||
			// since we want to serve the ones from the error page,
 | 
			
		||||
			// so we just drop them.
 | 
			
		||||
			return len(buf), nil
 | 
			
		||||
		}
 | 
			
		||||
		return cc.responseWriter.Write(buf)
 | 
			
		||||
	}
 | 
			
		||||
	cc.firstWrite = false
 | 
			
		||||
 | 
			
		||||
	// If WriteHeader was already called from the caller, this is a NOOP.
 | 
			
		||||
	// Otherwise, cc.code is actually a 200 here.
 | 
			
		||||
	cc.WriteHeader(cc.code)
 | 
			
		||||
 | 
			
		||||
	if cc.caughtFilteredCode {
 | 
			
		||||
		return len(buf), nil
 | 
			
		||||
	}
 | 
			
		||||
	return cc.responseWriter.Write(buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cc *codeCatcher) WriteHeader(code int) {
 | 
			
		||||
	if cc.headersSent || cc.caughtFilteredCode {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cc.code = code
 | 
			
		||||
	for _, block := range cc.httpCodeRanges {
 | 
			
		||||
		if cc.code >= block[0] && cc.code <= block[1] {
 | 
			
		||||
			cc.caughtFilteredCode = true
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// it will be up to the other response recorder to send the headers,
 | 
			
		||||
	// so it is out of our hands now.
 | 
			
		||||
	if cc.caughtFilteredCode {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	utils.CopyHeaders(cc.responseWriter.Header(), cc.Header())
 | 
			
		||||
	cc.responseWriter.WriteHeader(cc.code)
 | 
			
		||||
	cc.headersSent = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hijack hijacks the connection
 | 
			
		||||
func (cc *codeCatcher) Hijack() (net.Conn, *bufio.ReadWriter, error) {
 | 
			
		||||
	if hj, ok := cc.responseWriter.(http.Hijacker); ok {
 | 
			
		||||
		return hj.Hijack()
 | 
			
		||||
	}
 | 
			
		||||
	return nil, nil, fmt.Errorf("%T is not a http.Hijacker", cc.responseWriter)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Flush sends any buffered data to the client.
 | 
			
		||||
func (cc *codeCatcher) Flush() {
 | 
			
		||||
	// If WriteHeader was already called from the caller, this is a NOOP.
 | 
			
		||||
	// Otherwise, cc.code is actually a 200 here.
 | 
			
		||||
	cc.WriteHeader(cc.code)
 | 
			
		||||
 | 
			
		||||
	if flusher, ok := cc.responseWriter.(http.Flusher); ok {
 | 
			
		||||
		flusher.Flush()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type responseRecorder interface {
 | 
			
		||||
	http.ResponseWriter
 | 
			
		||||
	http.Flusher
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,30 @@ func TestHandler(t *testing.T) {
 | 
			
		||||
				assert.Contains(t, recorder.Body.String(), http.StatusText(http.StatusOK))
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:        "no error, but not a 200",
 | 
			
		||||
			errorPage:   &types.ErrorPage{Backend: "error", Query: "/test", Status: []string{"500-501", "503-599"}},
 | 
			
		||||
			backendCode: http.StatusPartialContent,
 | 
			
		||||
			backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
				fmt.Fprintln(w, "My error page.")
 | 
			
		||||
			}),
 | 
			
		||||
			validate: func(t *testing.T, recorder *httptest.ResponseRecorder) {
 | 
			
		||||
				assert.Equal(t, http.StatusPartialContent, recorder.Code, "HTTP status")
 | 
			
		||||
				assert.Contains(t, recorder.Body.String(), http.StatusText(http.StatusPartialContent))
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:        "a 304, so no Write called",
 | 
			
		||||
			errorPage:   &types.ErrorPage{Backend: "error", Query: "/test", Status: []string{"500-501", "503-599"}},
 | 
			
		||||
			backendCode: http.StatusNotModified,
 | 
			
		||||
			backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
				fmt.Fprintln(w, "whatever, should not be called")
 | 
			
		||||
			}),
 | 
			
		||||
			validate: func(t *testing.T, recorder *httptest.ResponseRecorder) {
 | 
			
		||||
				assert.Equal(t, http.StatusNotModified, recorder.Code, "HTTP status")
 | 
			
		||||
				assert.Contains(t, recorder.Body.String(), "")
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:        "in the range",
 | 
			
		||||
			errorPage:   &types.ErrorPage{Backend: "error", Query: "/test", Status: []string{"500-501", "503-599"}},
 | 
			
		||||
@@ -108,6 +132,9 @@ func TestHandler(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
			handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
				w.WriteHeader(test.backendCode)
 | 
			
		||||
				if test.backendCode == http.StatusNotModified {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				fmt.Fprintln(w, http.StatusText(test.backendCode))
 | 
			
		||||
			})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -125,8 +125,15 @@ type moveHandler struct {
 | 
			
		||||
func (m *moveHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 | 
			
		||||
	rw.Header().Set("Location", m.location.String())
 | 
			
		||||
	status := http.StatusFound
 | 
			
		||||
	if req.Method != http.MethodGet {
 | 
			
		||||
		status = http.StatusTemporaryRedirect
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if m.permanent {
 | 
			
		||||
		status = http.StatusMovedPermanently
 | 
			
		||||
		if req.Method != http.MethodGet {
 | 
			
		||||
			status = http.StatusPermanentRedirect
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	rw.WriteHeader(status)
 | 
			
		||||
	rw.Write([]byte(http.StatusText(status)))
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ func TestNewEntryPointHandler(t *testing.T) {
 | 
			
		||||
		desc           string
 | 
			
		||||
		entryPoint     *configuration.EntryPoint
 | 
			
		||||
		permanent      bool
 | 
			
		||||
		method         string
 | 
			
		||||
		url            string
 | 
			
		||||
		expectedURL    string
 | 
			
		||||
		expectedStatus int
 | 
			
		||||
@@ -59,6 +60,24 @@ func TestNewEntryPointHandler(t *testing.T) {
 | 
			
		||||
			expectedURL:    "http://foo:80",
 | 
			
		||||
			expectedStatus: http.StatusMovedPermanently,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:           "HTTP to HTTP POST",
 | 
			
		||||
			entryPoint:     &configuration.EntryPoint{Address: ":80"},
 | 
			
		||||
			permanent:      false,
 | 
			
		||||
			url:            "http://foo:90",
 | 
			
		||||
			method:         http.MethodPost,
 | 
			
		||||
			expectedURL:    "http://foo:80",
 | 
			
		||||
			expectedStatus: http.StatusTemporaryRedirect,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:           "HTTP to HTTP POST permanent",
 | 
			
		||||
			entryPoint:     &configuration.EntryPoint{Address: ":80"},
 | 
			
		||||
			permanent:      true,
 | 
			
		||||
			url:            "http://foo:90",
 | 
			
		||||
			method:         http.MethodPost,
 | 
			
		||||
			expectedURL:    "http://foo:80",
 | 
			
		||||
			expectedStatus: http.StatusPermanentRedirect,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:          "invalid address",
 | 
			
		||||
			entryPoint:    &configuration.EntryPoint{Address: ":foo", TLS: &tls.TLS{}},
 | 
			
		||||
@@ -80,7 +99,11 @@ func TestNewEntryPointHandler(t *testing.T) {
 | 
			
		||||
				require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
				recorder := httptest.NewRecorder()
 | 
			
		||||
				r := testhelpers.MustNewRequest(http.MethodGet, test.url, nil)
 | 
			
		||||
				method := http.MethodGet
 | 
			
		||||
				if test.method != "" {
 | 
			
		||||
					method = test.method
 | 
			
		||||
				}
 | 
			
		||||
				r := testhelpers.MustNewRequest(method, test.url, nil)
 | 
			
		||||
				handler.ServeHTTP(recorder, r, nil)
 | 
			
		||||
 | 
			
		||||
				location, err := recorder.Result().Location()
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,7 @@ func (retry *Retry) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
	attempts := 1
 | 
			
		||||
	for {
 | 
			
		||||
		attemptsExhausted := attempts >= retry.attempts
 | 
			
		||||
 | 
			
		||||
		shouldRetry := !attemptsExhausted
 | 
			
		||||
		shouldRetry := attempts < retry.attempts
 | 
			
		||||
		retryResponseWriter := newRetryResponseWriter(rw, shouldRetry)
 | 
			
		||||
 | 
			
		||||
		// Disable retries when the backend already received request data
 | 
			
		||||
@@ -99,6 +97,7 @@ type retryResponseWriter interface {
 | 
			
		||||
func newRetryResponseWriter(rw http.ResponseWriter, shouldRetry bool) retryResponseWriter {
 | 
			
		||||
	responseWriter := &retryResponseWriterWithoutCloseNotify{
 | 
			
		||||
		responseWriter: rw,
 | 
			
		||||
		headers:        make(http.Header),
 | 
			
		||||
		shouldRetry:    shouldRetry,
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := rw.(http.CloseNotifier); ok {
 | 
			
		||||
@@ -109,7 +108,9 @@ func newRetryResponseWriter(rw http.ResponseWriter, shouldRetry bool) retryRespo
 | 
			
		||||
 | 
			
		||||
type retryResponseWriterWithoutCloseNotify struct {
 | 
			
		||||
	responseWriter http.ResponseWriter
 | 
			
		||||
	headers        http.Header
 | 
			
		||||
	shouldRetry    bool
 | 
			
		||||
	written        bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rr *retryResponseWriterWithoutCloseNotify) ShouldRetry() bool {
 | 
			
		||||
@@ -121,10 +122,10 @@ func (rr *retryResponseWriterWithoutCloseNotify) DisableRetries() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rr *retryResponseWriterWithoutCloseNotify) Header() http.Header {
 | 
			
		||||
	if rr.ShouldRetry() {
 | 
			
		||||
		return make(http.Header)
 | 
			
		||||
	if rr.written {
 | 
			
		||||
		return rr.responseWriter.Header()
 | 
			
		||||
	}
 | 
			
		||||
	return rr.responseWriter.Header()
 | 
			
		||||
	return rr.headers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rr *retryResponseWriterWithoutCloseNotify) Write(buf []byte) (int, error) {
 | 
			
		||||
@@ -147,7 +148,18 @@ func (rr *retryResponseWriterWithoutCloseNotify) WriteHeader(code int) {
 | 
			
		||||
	if rr.ShouldRetry() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// In that case retry case is set to false which means we at least managed
 | 
			
		||||
	// to write headers to the backend : we are not going to perform any further retry.
 | 
			
		||||
	// So it is now safe to alter current response headers with headers collected during
 | 
			
		||||
	// the latest try before writing headers to client.
 | 
			
		||||
	headers := rr.responseWriter.Header()
 | 
			
		||||
	for header, value := range rr.headers {
 | 
			
		||||
		headers[header] = value
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rr.responseWriter.WriteHeader(code)
 | 
			
		||||
	rr.written = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rr *retryResponseWriterWithoutCloseNotify) Hijack() (net.Conn, *bufio.ReadWriter, error) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,11 @@
 | 
			
		||||
package middlewares
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/httptest"
 | 
			
		||||
	"net/http/httptrace"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +36,7 @@ func TestRetry(t *testing.T) {
 | 
			
		||||
			desc:                  "no retry when max request attempts is one",
 | 
			
		||||
			maxRequestAttempts:    1,
 | 
			
		||||
			wantRetryAttempts:     0,
 | 
			
		||||
			wantResponseStatus:    http.StatusInternalServerError,
 | 
			
		||||
			wantResponseStatus:    http.StatusBadGateway,
 | 
			
		||||
			amountFaultyEndpoints: 1,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -54,7 +57,7 @@ func TestRetry(t *testing.T) {
 | 
			
		||||
			desc:                  "max attempts exhausted delivers the 5xx response",
 | 
			
		||||
			maxRequestAttempts:    3,
 | 
			
		||||
			wantRetryAttempts:     2,
 | 
			
		||||
			wantResponseStatus:    http.StatusInternalServerError,
 | 
			
		||||
			wantResponseStatus:    http.StatusBadGateway,
 | 
			
		||||
			amountFaultyEndpoints: 3,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
@@ -80,17 +83,18 @@ func TestRetry(t *testing.T) {
 | 
			
		||||
				t.Fatalf("Error creating load balancer: %s", err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			basePort := 33444
 | 
			
		||||
			// out of range port
 | 
			
		||||
			basePort := 1133444
 | 
			
		||||
			for i := 0; i < test.amountFaultyEndpoints; i++ {
 | 
			
		||||
				// 192.0.2.0 is a non-routable IP for testing purposes.
 | 
			
		||||
				// See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928
 | 
			
		||||
				// We only use the port specification here because the URL is used as identifier
 | 
			
		||||
				// in the load balancer and using the exact same URL would not add a new server.
 | 
			
		||||
				loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + string(basePort+i)))
 | 
			
		||||
				_ = loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + strconv.Itoa(basePort+i)))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// add the functioning server to the end of the load balancer list
 | 
			
		||||
			loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
 | 
			
		||||
			_ = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
 | 
			
		||||
 | 
			
		||||
			retryListener := &countingRetryListener{}
 | 
			
		||||
			retry := NewRetry(test.maxRequestAttempts, loadBalancer, retryListener)
 | 
			
		||||
@@ -152,17 +156,18 @@ func TestRetryWebsocket(t *testing.T) {
 | 
			
		||||
				t.Fatalf("Error creating load balancer: %s", err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			basePort := 33444
 | 
			
		||||
			// out of range port
 | 
			
		||||
			basePort := 1133444
 | 
			
		||||
			for i := 0; i < test.amountFaultyEndpoints; i++ {
 | 
			
		||||
				// 192.0.2.0 is a non-routable IP for testing purposes.
 | 
			
		||||
				// See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928
 | 
			
		||||
				// We only use the port specification here because the URL is used as identifier
 | 
			
		||||
				// in the load balancer and using the exact same URL would not add a new server.
 | 
			
		||||
				loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + string(basePort+i)))
 | 
			
		||||
				_ = loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + strconv.Itoa(basePort+i)))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// add the functioning server to the end of the load balancer list
 | 
			
		||||
			loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
 | 
			
		||||
			_ = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
 | 
			
		||||
 | 
			
		||||
			retryListener := &countingRetryListener{}
 | 
			
		||||
			retry := NewRetry(test.maxRequestAttempts, loadBalancer, retryListener)
 | 
			
		||||
@@ -256,3 +261,45 @@ func TestRetryWithFlush(t *testing.T) {
 | 
			
		||||
		t.Errorf("Wrong body %q want %q", responseRecorder.Body.String(), "FULL DATA")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMultipleRetriesShouldNotLooseHeaders(t *testing.T) {
 | 
			
		||||
	attempt := 0
 | 
			
		||||
	expectedHeaderName := "X-Foo-Test-2"
 | 
			
		||||
	expectedHeaderValue := "bar"
 | 
			
		||||
 | 
			
		||||
	next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		headerName := fmt.Sprintf("X-Foo-Test-%d", attempt)
 | 
			
		||||
		rw.Header().Add(headerName, expectedHeaderValue)
 | 
			
		||||
		if attempt < 2 {
 | 
			
		||||
			attempt++
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Request has been successfully written to backend
 | 
			
		||||
		trace := httptrace.ContextClientTrace(req.Context())
 | 
			
		||||
		trace.WroteHeaders()
 | 
			
		||||
 | 
			
		||||
		// And we decide to answer to client
 | 
			
		||||
		rw.WriteHeader(http.StatusNoContent)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	retry := NewRetry(3, next, &countingRetryListener{})
 | 
			
		||||
	responseRecorder := httptest.NewRecorder()
 | 
			
		||||
	retry.ServeHTTP(responseRecorder, &http.Request{})
 | 
			
		||||
 | 
			
		||||
	headerValue := responseRecorder.Header().Get(expectedHeaderName)
 | 
			
		||||
 | 
			
		||||
	// Validate if we have the correct header
 | 
			
		||||
	if headerValue != expectedHeaderValue {
 | 
			
		||||
		t.Errorf("Expected to have %s for header %s, got %s", expectedHeaderValue, expectedHeaderName, headerValue)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Validate that we don't have headers from previous attempts
 | 
			
		||||
	for i := 0; i < attempt; i++ {
 | 
			
		||||
		headerName := fmt.Sprintf("X-Foo-Test-%d", i)
 | 
			
		||||
		headerValue = responseRecorder.Header().Get("headerName")
 | 
			
		||||
		if headerValue != "" {
 | 
			
		||||
			t.Errorf("Expected no value for header %s, got %s", headerName, headerValue)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ func NewSecure(headers *types.Headers) *secure.Secure {
 | 
			
		||||
		SSLRedirect:             headers.SSLRedirect,
 | 
			
		||||
		SSLTemporaryRedirect:    headers.SSLTemporaryRedirect,
 | 
			
		||||
		SSLHost:                 headers.SSLHost,
 | 
			
		||||
		SSLForceHost:            headers.SSLForceHost,
 | 
			
		||||
		SSLProxyHeaders:         headers.SSLProxyHeaders,
 | 
			
		||||
		STSSeconds:              headers.STSSeconds,
 | 
			
		||||
		STSIncludeSubdomains:    headers.STSIncludeSubdomains,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								middlewares/secure_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								middlewares/secure_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
package middlewares
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/httptest"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/containous/traefik/testhelpers"
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
	"github.com/unrolled/secure"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestSSLForceHost(t *testing.T) {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		desc             string
 | 
			
		||||
		host             string
 | 
			
		||||
		secureMiddleware *secure.Secure
 | 
			
		||||
		expected         int
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			desc: "http should return a 301",
 | 
			
		||||
			host: "http://powpow.example.com",
 | 
			
		||||
			secureMiddleware: NewSecure(&types.Headers{
 | 
			
		||||
				SSLRedirect:  true,
 | 
			
		||||
				SSLForceHost: true,
 | 
			
		||||
				SSLHost:      "powpow.example.com",
 | 
			
		||||
			}),
 | 
			
		||||
			expected: http.StatusMovedPermanently,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "http sub domain should return a 301",
 | 
			
		||||
			host: "http://www.powpow.example.com",
 | 
			
		||||
			secureMiddleware: NewSecure(&types.Headers{
 | 
			
		||||
				SSLRedirect:  true,
 | 
			
		||||
				SSLForceHost: true,
 | 
			
		||||
				SSLHost:      "powpow.example.com",
 | 
			
		||||
			}),
 | 
			
		||||
			expected: http.StatusMovedPermanently,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "https should return a 200",
 | 
			
		||||
			host: "https://powpow.example.com",
 | 
			
		||||
			secureMiddleware: NewSecure(&types.Headers{
 | 
			
		||||
				SSLRedirect:  true,
 | 
			
		||||
				SSLForceHost: true,
 | 
			
		||||
				SSLHost:      "powpow.example.com",
 | 
			
		||||
			}),
 | 
			
		||||
			expected: http.StatusOK,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "https sub domain should return a 301",
 | 
			
		||||
			host: "https://www.powpow.example.com",
 | 
			
		||||
			secureMiddleware: NewSecure(&types.Headers{
 | 
			
		||||
				SSLRedirect:  true,
 | 
			
		||||
				SSLForceHost: true,
 | 
			
		||||
				SSLHost:      "powpow.example.com",
 | 
			
		||||
			}),
 | 
			
		||||
			expected: http.StatusMovedPermanently,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "http without force host and sub domain should return a 301",
 | 
			
		||||
			host: "http://www.powpow.example.com",
 | 
			
		||||
			secureMiddleware: NewSecure(&types.Headers{
 | 
			
		||||
				SSLRedirect:  true,
 | 
			
		||||
				SSLForceHost: false,
 | 
			
		||||
				SSLHost:      "powpow.example.com",
 | 
			
		||||
			}),
 | 
			
		||||
			expected: http.StatusMovedPermanently,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc: "https without force host and sub domain should return a 301",
 | 
			
		||||
			host: "https://www.powpow.example.com",
 | 
			
		||||
			secureMiddleware: NewSecure(&types.Headers{
 | 
			
		||||
				SSLRedirect:  true,
 | 
			
		||||
				SSLForceHost: false,
 | 
			
		||||
				SSLHost:      "powpow.example.com",
 | 
			
		||||
			}),
 | 
			
		||||
			expected: http.StatusOK,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range testCases {
 | 
			
		||||
		t.Run(test.desc, func(t *testing.T) {
 | 
			
		||||
			req := testhelpers.MustNewRequest(http.MethodGet, test.host, nil)
 | 
			
		||||
			next := func(rw http.ResponseWriter, r *http.Request) {
 | 
			
		||||
				rw.Write([]byte("OK"))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			rw := httptest.NewRecorder()
 | 
			
		||||
			test.secureMiddleware.HandlerFuncWithNextForRequestOnly(rw, req, next)
 | 
			
		||||
 | 
			
		||||
			assert.Equal(t, test.expected, rw.Result().StatusCode)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -13,45 +13,54 @@ import (
 | 
			
		||||
	"github.com/containous/traefik/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const xForwardedTLSClientCert = "X-Forwarded-Tls-Client-Cert"
 | 
			
		||||
const xForwardedTLSClientCertInfos = "X-Forwarded-Tls-Client-Cert-Infos"
 | 
			
		||||
const (
 | 
			
		||||
	xForwardedTLSClientCert      = "X-Forwarded-Tls-Client-Cert"
 | 
			
		||||
	xForwardedTLSClientCertInfos = "X-Forwarded-Tls-Client-Cert-Infos"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var attributeTypeNames = map[string]string{
 | 
			
		||||
	"0.9.2342.19200300.100.1.25": "DC", // Domain component OID - RFC 2247
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TLSClientCertificateInfos is a struct for specifying the configuration for the tlsClientHeaders middleware.
 | 
			
		||||
type TLSClientCertificateInfos struct {
 | 
			
		||||
	Issuer    *DistinguishedNameOptions
 | 
			
		||||
	NotAfter  bool
 | 
			
		||||
	NotBefore bool
 | 
			
		||||
	Subject   *TLSCLientCertificateSubjectInfos
 | 
			
		||||
	Sans      bool
 | 
			
		||||
	Subject   *DistinguishedNameOptions
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TLSCLientCertificateSubjectInfos contains the configuration for the certificate subject infos.
 | 
			
		||||
type TLSCLientCertificateSubjectInfos struct {
 | 
			
		||||
	Country      bool
 | 
			
		||||
	Province     bool
 | 
			
		||||
	Locality     bool
 | 
			
		||||
	Organization bool
 | 
			
		||||
	CommonName   bool
 | 
			
		||||
	SerialNumber bool
 | 
			
		||||
// DistinguishedNameOptions is a struct for specifying the configuration for the distinguished name info.
 | 
			
		||||
type DistinguishedNameOptions struct {
 | 
			
		||||
	CommonName          bool
 | 
			
		||||
	CountryName         bool
 | 
			
		||||
	DomainComponent     bool
 | 
			
		||||
	LocalityName        bool
 | 
			
		||||
	OrganizationName    bool
 | 
			
		||||
	SerialNumber        bool
 | 
			
		||||
	StateOrProvinceName bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TLSClientHeaders is a middleware that helps setup a few tls infos features.
 | 
			
		||||
// TLSClientHeaders is a middleware that helps setup a few tls info features.
 | 
			
		||||
type TLSClientHeaders struct {
 | 
			
		||||
	Infos *TLSClientCertificateInfos // pass selected information from the client certificate
 | 
			
		||||
	PEM   bool                       // pass the sanitized pem to the backend in a specific header
 | 
			
		||||
	Infos *TLSClientCertificateInfos // pass selected informations from the client certificate
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newTLSCLientCertificateSubjectInfos(infos *types.TLSCLientCertificateSubjectInfos) *TLSCLientCertificateSubjectInfos {
 | 
			
		||||
func newDistinguishedNameOptions(infos *types.TLSCLientCertificateDNInfos) *DistinguishedNameOptions {
 | 
			
		||||
	if infos == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &TLSCLientCertificateSubjectInfos{
 | 
			
		||||
		SerialNumber: infos.SerialNumber,
 | 
			
		||||
		CommonName:   infos.CommonName,
 | 
			
		||||
		Country:      infos.Country,
 | 
			
		||||
		Locality:     infos.Locality,
 | 
			
		||||
		Organization: infos.Organization,
 | 
			
		||||
		Province:     infos.Province,
 | 
			
		||||
	return &DistinguishedNameOptions{
 | 
			
		||||
		CommonName:          infos.CommonName,
 | 
			
		||||
		CountryName:         infos.Country,
 | 
			
		||||
		DomainComponent:     infos.DomainComponent,
 | 
			
		||||
		LocalityName:        infos.Locality,
 | 
			
		||||
		OrganizationName:    infos.Organization,
 | 
			
		||||
		SerialNumber:        infos.SerialNumber,
 | 
			
		||||
		StateOrProvinceName: infos.Province,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -61,31 +70,23 @@ func newTLSClientInfos(infos *types.TLSClientCertificateInfos) *TLSClientCertifi
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &TLSClientCertificateInfos{
 | 
			
		||||
		NotBefore: infos.NotBefore,
 | 
			
		||||
		Issuer:    newDistinguishedNameOptions(infos.Issuer),
 | 
			
		||||
		NotAfter:  infos.NotAfter,
 | 
			
		||||
		NotBefore: infos.NotBefore,
 | 
			
		||||
		Sans:      infos.Sans,
 | 
			
		||||
		Subject:   newTLSCLientCertificateSubjectInfos(infos.Subject),
 | 
			
		||||
		Subject:   newDistinguishedNameOptions(infos.Subject),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewTLSClientHeaders constructs a new TLSClientHeaders instance from supplied frontend header struct.
 | 
			
		||||
func NewTLSClientHeaders(frontend *types.Frontend) *TLSClientHeaders {
 | 
			
		||||
	if frontend == nil {
 | 
			
		||||
func NewTLSClientHeaders(passTLSClientCert *types.TLSClientHeaders) *TLSClientHeaders {
 | 
			
		||||
	if passTLSClientCert == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var pem bool
 | 
			
		||||
	var infos *TLSClientCertificateInfos
 | 
			
		||||
 | 
			
		||||
	if frontend.PassTLSClientCert != nil {
 | 
			
		||||
		conf := frontend.PassTLSClientCert
 | 
			
		||||
		pem = conf.PEM
 | 
			
		||||
		infos = newTLSClientInfos(conf.Infos)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &TLSClientHeaders{
 | 
			
		||||
		PEM:   pem,
 | 
			
		||||
		Infos: infos,
 | 
			
		||||
		Infos: newTLSClientInfos(passTLSClientCert.Infos),
 | 
			
		||||
		PEM:   passTLSClientCert.PEM,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -153,46 +154,67 @@ func getSANs(cert *x509.Certificate) []string {
 | 
			
		||||
	return append(sans, uris...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getSubjectInfos extract the requested informations from the certificate subject
 | 
			
		||||
func (s *TLSClientHeaders) getSubjectInfos(cs *pkix.Name) string {
 | 
			
		||||
	var subject string
 | 
			
		||||
func getDNInfos(prefix string, options *DistinguishedNameOptions, cs *pkix.Name) string {
 | 
			
		||||
	if options == nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.Infos != nil && s.Infos.Subject != nil {
 | 
			
		||||
		options := s.Infos.Subject
 | 
			
		||||
	content := &strings.Builder{}
 | 
			
		||||
 | 
			
		||||
		var content []string
 | 
			
		||||
 | 
			
		||||
		if options.Country && len(cs.Country) > 0 {
 | 
			
		||||
			content = append(content, fmt.Sprintf("C=%s", cs.Country[0]))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if options.Province && len(cs.Province) > 0 {
 | 
			
		||||
			content = append(content, fmt.Sprintf("ST=%s", cs.Province[0]))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if options.Locality && len(cs.Locality) > 0 {
 | 
			
		||||
			content = append(content, fmt.Sprintf("L=%s", cs.Locality[0]))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if options.Organization && len(cs.Organization) > 0 {
 | 
			
		||||
			content = append(content, fmt.Sprintf("O=%s", cs.Organization[0]))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if options.CommonName && len(cs.CommonName) > 0 {
 | 
			
		||||
			content = append(content, fmt.Sprintf("CN=%s", cs.CommonName))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(content) > 0 {
 | 
			
		||||
			subject = `Subject="` + strings.Join(content, ",") + `"`
 | 
			
		||||
	// Manage non standard attributes
 | 
			
		||||
	for _, name := range cs.Names {
 | 
			
		||||
		// Domain Component - RFC 2247
 | 
			
		||||
		if options.DomainComponent && attributeTypeNames[name.Type.String()] == "DC" {
 | 
			
		||||
			content.WriteString(fmt.Sprintf("DC=%s,", name.Value))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return subject
 | 
			
		||||
	if options.CountryName {
 | 
			
		||||
		writeParts(content, cs.Country, "C")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if options.StateOrProvinceName {
 | 
			
		||||
		writeParts(content, cs.Province, "ST")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if options.LocalityName {
 | 
			
		||||
		writeParts(content, cs.Locality, "L")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if options.OrganizationName {
 | 
			
		||||
		writeParts(content, cs.Organization, "O")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if options.SerialNumber {
 | 
			
		||||
		writePart(content, cs.SerialNumber, "SN")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if options.CommonName {
 | 
			
		||||
		writePart(content, cs.CommonName, "CN")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if content.Len() > 0 {
 | 
			
		||||
		return prefix + `="` + strings.TrimSuffix(content.String(), ",") + `"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getXForwardedTLSClientCertInfos Build a string with the wanted client certificates informations
 | 
			
		||||
// like Subject="C=%s,ST=%s,L=%s,O=%s,CN=%s",NB=%d,NA=%d,SAN=%s;
 | 
			
		||||
func (s *TLSClientHeaders) getXForwardedTLSClientCertInfos(certs []*x509.Certificate) string {
 | 
			
		||||
func writeParts(content *strings.Builder, entries []string, prefix string) {
 | 
			
		||||
	for _, entry := range entries {
 | 
			
		||||
		writePart(content, entry, prefix)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writePart(content *strings.Builder, entry string, prefix string) {
 | 
			
		||||
	if len(entry) > 0 {
 | 
			
		||||
		content.WriteString(fmt.Sprintf("%s=%s,", prefix, entry))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getXForwardedTLSClientCertInfo Build a string with the wanted client certificates information
 | 
			
		||||
// like Subject="DC=%s,C=%s,ST=%s,L=%s,O=%s,CN=%s",NB=%d,NA=%d,SAN=%s;
 | 
			
		||||
func (s *TLSClientHeaders) getXForwardedTLSClientCertInfo(certs []*x509.Certificate) string {
 | 
			
		||||
	var headerValues []string
 | 
			
		||||
 | 
			
		||||
	for _, peerCert := range certs {
 | 
			
		||||
@@ -201,9 +223,16 @@ func (s *TLSClientHeaders) getXForwardedTLSClientCertInfos(certs []*x509.Certifi
 | 
			
		||||
		var nb string
 | 
			
		||||
		var na string
 | 
			
		||||
 | 
			
		||||
		subject := s.getSubjectInfos(&peerCert.Subject)
 | 
			
		||||
		if len(subject) > 0 {
 | 
			
		||||
			values = append(values, subject)
 | 
			
		||||
		if s.Infos != nil {
 | 
			
		||||
			subject := getDNInfos("Subject", s.Infos.Subject, &peerCert.Subject)
 | 
			
		||||
			if len(subject) > 0 {
 | 
			
		||||
				values = append(values, subject)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			issuer := getDNInfos("Issuer", s.Infos.Issuer, &peerCert.Issuer)
 | 
			
		||||
			if len(issuer) > 0 {
 | 
			
		||||
				values = append(values, issuer)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ci := s.Infos
 | 
			
		||||
@@ -230,8 +259,9 @@ func (s *TLSClientHeaders) getXForwardedTLSClientCertInfos(certs []*x509.Certifi
 | 
			
		||||
	return strings.Join(headerValues, ";")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ModifyRequestHeaders set the wanted headers with the certificates informations
 | 
			
		||||
// ModifyRequestHeaders set the wanted headers with the certificates information
 | 
			
		||||
func (s *TLSClientHeaders) ModifyRequestHeaders(r *http.Request) {
 | 
			
		||||
	r.Header.Del(xForwardedTLSClientCert)
 | 
			
		||||
	if s.PEM {
 | 
			
		||||
		if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
 | 
			
		||||
			r.Header.Set(xForwardedTLSClientCert, getXForwardedTLSClientCert(r.TLS.PeerCertificates))
 | 
			
		||||
@@ -240,9 +270,10 @@ func (s *TLSClientHeaders) ModifyRequestHeaders(r *http.Request) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.Header.Del(xForwardedTLSClientCertInfos)
 | 
			
		||||
	if s.Infos != nil {
 | 
			
		||||
		if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
 | 
			
		||||
			headerContent := s.getXForwardedTLSClientCertInfos(r.TLS.PeerCertificates)
 | 
			
		||||
			headerContent := s.getXForwardedTLSClientCertInfo(r.TLS.PeerCertificates)
 | 
			
		||||
			r.Header.Set(xForwardedTLSClientCertInfos, url.QueryEscape(headerContent))
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Warn("Try to extract certificate on a request without TLS")
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -15,9 +15,14 @@ const Name = "datadog"
 | 
			
		||||
 | 
			
		||||
// Config provides configuration settings for a datadog tracer
 | 
			
		||||
type Config struct {
 | 
			
		||||
	LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used. Defaults to localhost:8126" export:"false"`
 | 
			
		||||
	GlobalTag          string `description:"Key:Value tag to be set on all the spans." export:"true"`
 | 
			
		||||
	Debug              bool   `description:"Enable DataDog debug." export:"true"`
 | 
			
		||||
	LocalAgentHostPort         string `description:"Set datadog-agent's host:port that the reporter will used. Defaults to localhost:8126" export:"false"`
 | 
			
		||||
	GlobalTag                  string `description:"Key:Value tag to be set on all the spans." export:"true"`
 | 
			
		||||
	Debug                      bool   `description:"Enable DataDog debug." export:"true"`
 | 
			
		||||
	PrioritySampling           bool   `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled."`
 | 
			
		||||
	TraceIDHeaderName          string `description:"Specifies the header name that will be used to store the trace ID." export:"true"`
 | 
			
		||||
	ParentIDHeaderName         string `description:"Specifies the header name that will be used to store the parent ID." export:"true"`
 | 
			
		||||
	SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." export:"true"`
 | 
			
		||||
	BagagePrefixHeaderName     string `description:"specifies the header name prefix that will be used to store baggage items in a map." export:"true"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Setup sets up the tracer
 | 
			
		||||
@@ -29,12 +34,22 @@ func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error
 | 
			
		||||
		value = tag[1]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tracer := ddtracer.New(
 | 
			
		||||
	opts := []datadog.StartOption{
 | 
			
		||||
		datadog.WithAgentAddr(c.LocalAgentHostPort),
 | 
			
		||||
		datadog.WithServiceName(serviceName),
 | 
			
		||||
		datadog.WithGlobalTag(tag[0], value),
 | 
			
		||||
		datadog.WithDebugMode(c.Debug),
 | 
			
		||||
	)
 | 
			
		||||
		datadog.WithPropagator(datadog.NewPropagator(&datadog.PropagatorConfig{
 | 
			
		||||
			TraceHeader:    c.TraceIDHeaderName,
 | 
			
		||||
			ParentHeader:   c.ParentIDHeaderName,
 | 
			
		||||
			PriorityHeader: c.SamplingPriorityHeaderName,
 | 
			
		||||
			BaggagePrefix:  c.BagagePrefixHeaderName,
 | 
			
		||||
		})),
 | 
			
		||||
	}
 | 
			
		||||
	if c.PrioritySampling {
 | 
			
		||||
		opts = append(opts, datadog.WithPrioritySampling())
 | 
			
		||||
	}
 | 
			
		||||
	tracer := ddtracer.New(opts...)
 | 
			
		||||
 | 
			
		||||
	// Without this, child spans are getting the NOOP tracer
 | 
			
		||||
	opentracing.SetGlobalTracer(tracer)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/containous/traefik/log"
 | 
			
		||||
	"github.com/opentracing/opentracing-go"
 | 
			
		||||
	"github.com/uber/jaeger-client-go"
 | 
			
		||||
	jaegercfg "github.com/uber/jaeger-client-go/config"
 | 
			
		||||
	jaegermet "github.com/uber/jaeger-lib/metrics"
 | 
			
		||||
)
 | 
			
		||||
@@ -14,10 +15,11 @@ const Name = "jaeger"
 | 
			
		||||
 | 
			
		||||
// Config provides configuration settings for a jaeger tracer
 | 
			
		||||
type Config struct {
 | 
			
		||||
	SamplingServerURL  string  `description:"set the sampling server url." export:"false"`
 | 
			
		||||
	SamplingType       string  `description:"set the sampling type." export:"true"`
 | 
			
		||||
	SamplingParam      float64 `description:"set the sampling parameter." export:"true"`
 | 
			
		||||
	LocalAgentHostPort string  `description:"set jaeger-agent's host:port that the reporter will used." export:"false"`
 | 
			
		||||
	SamplingServerURL      string  `description:"set the sampling server url." export:"false"`
 | 
			
		||||
	SamplingType           string  `description:"set the sampling type." export:"true"`
 | 
			
		||||
	SamplingParam          float64 `description:"set the sampling parameter." export:"true"`
 | 
			
		||||
	LocalAgentHostPort     string  `description:"set jaeger-agent's host:port that the reporter will used." export:"false"`
 | 
			
		||||
	TraceContextHeaderName string  `description:"set the header to use for the trace-id." export:"true"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Setup sets up the tracer
 | 
			
		||||
@@ -32,6 +34,9 @@ func (c *Config) Setup(componentName string) (opentracing.Tracer, io.Closer, err
 | 
			
		||||
			LogSpans:           true,
 | 
			
		||||
			LocalAgentHostPort: c.LocalAgentHostPort,
 | 
			
		||||
		},
 | 
			
		||||
		Headers: &jaeger.HeadersConfig{
 | 
			
		||||
			TraceContextHeaderName: c.TraceContextHeaderName,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	jMetricsFactory := jaegermet.NullFactory
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user