Auth support in frontends

This commit is contained in:
Jean-Baptiste Doumenjou 2018-07-06 16:52:04 +02:00 committed by Traefiker Bot
parent 0c0ecc1cdc
commit 79bf19c897
38 changed files with 3550 additions and 631 deletions

View file

@ -209,9 +209,47 @@ var _templatesConsul_catalogTmpl = []byte(`[backends]
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $service.TraefikLabels }} {{ $auth := getAuth $service.TraefikLabels }}
"{{.}}",
{{end}}] {{if $auth }}
[frontends."frontend-{{ $service.ServiceName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $service.ServiceName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $service.ServiceName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $service.ServiceName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $service.ServiceName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $service.TraefikLabels }} {{ $whitelist := getWhiteList $service.TraefikLabels }}
{{if $whitelist }} {{if $whitelist }}
@ -619,9 +657,46 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $container.SegmentLabels }} {{ $auth := getAuth $container.SegmentLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $container.SegmentLabels }} {{ $whitelist := getWhiteList $container.SegmentLabels }}
{{if $whitelist }} {{if $whitelist }}
@ -880,9 +955,46 @@ var _templatesEcsTmpl = []byte(`[backends]
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $instance.TraefikLabels }} {{ $auth := getAuth $instance.TraefikLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $serviceName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $serviceName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $serviceName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $serviceName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $serviceName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $instance.TraefikLabels }} {{ $whitelist := getWhiteList $instance.TraefikLabels }}
{{if $whitelist }} {{if $whitelist }}
@ -1099,10 +1211,6 @@ var _templatesKubernetesTmpl = []byte(`[backends]
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range $frontend.BasicAuth }}
"{{.}}",
{{end}}]
{{if $frontend.Auth }} {{if $frontend.Auth }}
[frontends."{{ $frontendName }}".auth] [frontends."{{ $frontendName }}".auth]
headerField = "X-WebAuth-User" headerField = "X-WebAuth-User"
@ -1336,9 +1444,46 @@ var _templatesKvTmpl = []byte(`[backends]
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $frontend }} {{ $auth := getAuth $frontend }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $frontend }} {{ $whitelist := getWhiteList $frontend }}
{{if $whitelist }} {{if $whitelist }}
@ -1639,9 +1784,46 @@ var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }}
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $app.SegmentLabels }} {{ $auth := getAuth $app.SegmentLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $app.SegmentLabels }} {{ $whitelist := getWhiteList $app.SegmentLabels }}
{{if $whitelist }} {{if $whitelist }}
@ -1886,10 +2068,47 @@ var _templatesMesosTmpl = []byte(`[backends]
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $app.TraefikLabels }} {{ $auth := getAuth $app.TraefikLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $app.TraefikLabels }} {{ $whitelist := getWhiteList $app.TraefikLabels }}
{{if $whitelist }} {{if $whitelist }}
[frontends."frontend-{{ $frontendName }}".whiteList] [frontends."frontend-{{ $frontendName }}".whiteList]
@ -2186,9 +2405,46 @@ var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }}
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $service.SegmentLabels }} {{ $auth := getAuth $service.SegmentLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $service.SegmentLabels }} {{ $whitelist := getWhiteList $service.SegmentLabels }}
{{if $whitelist }} {{if $whitelist }}

View file

@ -94,48 +94,60 @@ Additional settings can be defined using Consul Catalog tags.
!!! note !!! note
The default prefix is `traefik`. The default prefix is `traefik`.
| Label | Description | | Label | Description |
|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `<prefix>.enable=false` | Disable this container in Træfik. | | `<prefix>.enable=false` | Disables this container in Træfik. |
| `<prefix>.protocol=https` | Override the default `http` protocol. | | `<prefix>.protocol=https` | Overrides the default `http` protocol. |
| `<prefix>.weight=10` | Assign this weight to the container. | | `<prefix>.weight=10` | Assigns this weight to the container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | | `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.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=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.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | | `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `<prefix>.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` | | `<prefix>.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` |
| `<prefix>.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | | `<prefix>.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `<prefix>.backend.healthcheck.interval=1s` | Define the health check interval. | | `<prefix>.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `<prefix>.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | | `<prefix>.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | | `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `<prefix>.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | | `<prefix>.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `<prefix>.backend.healthcheck.headers=EXPR` | Define the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> | | `<prefix>.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `<prefix>.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm. | | `<prefix>.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm. |
| `<prefix>.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions. | | `<prefix>.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions. |
| `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions. | | `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions. |
| `<prefix>.backend.loadbalancer.sticky=true` | Enable backend sticky sessions. (DEPRECATED) | | `<prefix>.backend.loadbalancer.sticky=true` | Enables backend sticky sessions. (DEPRECATED) |
| `<prefix>.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. | | `<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` | Set 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>.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 for that frontend in CSV format: `User:Hash,User:Hash` | | `<prefix>.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `<prefix>.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` | | `<prefix>.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `<prefix>.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `<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.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `<prefix>.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `<prefix>.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `<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.passHostHeader=true` | Forward client `Host` header to the backend. | | `<prefix>.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. |
| `<prefix>.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | | `<prefix>.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `<prefix>.frontend.priority=10` | Override default frontend priority. | | `<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.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `<prefix>.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `<prefix>.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `<prefix>.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `<prefix>.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `<prefix>.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS). | | `<prefix>.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `<prefix>.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. | | `<prefix>.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `<prefix>.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. | | `<prefix>.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.redirect.permanent=true` | Return 301 instead of 302. | | `<prefix>.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`. | | `<prefix>.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.whiteList.sourceRange=RANGE` | 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.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `<prefix>.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | | `<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. |
### Custom Headers ### Custom Headers

View file

@ -207,63 +207,77 @@ services:
Labels can be used on containers to override default behavior. Labels can be used on containers to override default behavior.
| Label | Description | | Label | Description |
|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.docker.network` | Override the default docker network to use for connections to this container. [1] | | `traefik.docker.network` | Overrides the default docker network to use for connections to the container. [1] |
| `traefik.domain` | Default domain used for frontend rules. | | `traefik.domain` | Sets the default domain for the frontend rules. |
| `traefik.enable=false` | Disable this container in Træfik | | `traefik.enable=false` | Disables this container in Træfik. |
| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | | `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. |
| `traefik.protocol=https` | Override the default `http` protocol | | `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container | | `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this 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.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=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.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=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.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | | `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | | `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Define the health check interval. | | `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | | `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | | `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | | `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> | | `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | | `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | | `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | | `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | | `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.loadbalancer.swarm=true` | Use Swarm's inbuilt load balancer (only relevant under Swarm Mode). | | `traefik.backend.loadbalancer.swarm=true` | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode). |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. | | `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` | Set 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.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 for that frontend in CSV format: `User:Hash,User:Hash` [2] | | `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2] (DEPRECATED). |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` | | `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2]. |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.passHostHeader=true` | Forward client `Host` header to the backend. | | `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. |
| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | | `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.priority=10` | Override default frontend priority | | `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.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | | `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header user to pass the authenticated user to the application. |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. | | `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. | | `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | | `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. | | `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | 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.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | | `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. |
[1] `traefik.docker.network`: [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). 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. 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. Or if your service references external network use it's name instead.
[2] `traefik.frontend.auth.basic=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`. 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. The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additional symbol `$` makes escaping.
#### Custom Headers #### Custom Headers
| Label | Description | | Label | Description |
@ -304,32 +318,44 @@ You can define as many segments as ports exposed in a container.
Segment labels override the default behavior. Segment labels override the default behavior.
| Label | Description | | Label | Description |
|---------------------------------------------------------------------------|-------------------------------------------------------------| |---------------------------------------------------------------------------|---------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` | | `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` | | `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` | | `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` | | `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` | | `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=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | | `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` | | `traefik.<segment_name>.frontend.auth.basic.usersfile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersfile` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` | | `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` | | `traefik.<segment_name>.frontend.auth.digest.usersfile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersfile` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | | `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`| Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | | `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` | | `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | | `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` | | `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`| Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`|
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` | | `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` | | `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | | `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | | `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | | `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | | `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` | | `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | | `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | | `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 #### Custom Headers

View file

@ -136,51 +136,63 @@ Træfik needs the following policy to read ECS information:
Labels can be used on task containers to override default behaviour: Labels can be used on task containers to override default behaviour:
| Label | Description | | Label | Description |
|------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Default domain used for frontend rules. | | `traefik.domain` | Sets the default domain for frontend rules. |
| `traefik.enable=false` | Disable this container in Træfik | | `traefik.enable=false` | Disables this container in Træfik. |
| `traefik.port=80` | Override the default `port` value. Overrides `NetworkBindings` from Docker Container | | `traefik.port=80` | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container |
| `traefik.protocol=https` | Override the default `http` protocol | | `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container | | `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this 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.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=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.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=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.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | | `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | | `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Define the health check interval. (Default: 30s) | | `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | | `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | | `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | | `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> | | `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | | `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | | `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | | `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | | `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. | | `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` | Set 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.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 for that frontend in CSV format: `User:Hash,User:Hash` | | `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` | | `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.passHostHeader=true` | Forward client `Host` header to the backend. | | `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. |
| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | | `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.priority=10` | Override default frontend priority | | `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.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | | `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. | | `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. | | `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | | `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{instance_name}.{domain}`. | | `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | 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.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | | `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 ### Custom Headers

View file

@ -304,7 +304,7 @@ The source of the authentication is a Secret object that contains the credential
| `ingress.kubernetes.io/auth-type: basic` | x | x | x | Contains the authentication type: `basic`, `digest`, `forward`. | | `ingress.kubernetes.io/auth-type: basic` | x | x | x | Contains the authentication type: `basic`, `digest`, `forward`. |
| `ingress.kubernetes.io/auth-secret: mysecret` | x | x | | Name of Secret containing the username and password with access to the paths defined in the Ingress object. | | `ingress.kubernetes.io/auth-secret: mysecret` | x | x | | Name of Secret containing the username and password with access to the paths defined in the Ingress object. |
| `ingress.kubernetes.io/auth-header-field: X-WebAuth-User` | x | x | | Pass Authenticated user to application via headers. | | `ingress.kubernetes.io/auth-header-field: X-WebAuth-User` | x | x | | Pass Authenticated user to application via headers. |
| `ingress.kubernetes.io/auth-url: https://example.com` | | | x | [The URL of the authentication server](configuration/entrypoints/#forward-authentication). | | `ingress.kubernetes.io/auth-url: https://example.com` | | | x | [The URL of the authentication server](/configuration/entrypoints/#forward-authentication). |
| `ingress.kubernetes.io/auth-trust-headers: false` | | | x | Trust `X-Forwarded-*` headers. | | `ingress.kubernetes.io/auth-trust-headers: false` | | | x | Trust `X-Forwarded-*` headers. |
| `ingress.kubernetes.io/auth-response-headers: X-Auth-User, X-Secret` | | | x | Copy headers from the authentication server to the request. | | `ingress.kubernetes.io/auth-response-headers: X-Auth-User, X-Secret` | | | x | Copy headers from the authentication server to the request. |
| `ingress.kubernetes.io/auth-tls-secret: secret` | | | x | Name of Secret containing the certificate and key for the forward auth. | | `ingress.kubernetes.io/auth-tls-secret: secret` | | | x | Name of Secret containing the certificate and key for the forward auth. |

View file

@ -193,52 +193,64 @@ 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. The following labels can be defined on Marathon applications. They adjust the behavior for the entire application.
| Label | Description | | Label | Description |
|------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Default domain used for frontend rules. | | `traefik.domain` | Sets the default domain used for the frontend rules. |
| `traefik.enable=false` | Disable this container in Træfik | | `traefik.enable=false` | Disables this container in Træfik. |
| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | | `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. |
| `traefik.portIndex=1` | Register port by index 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` | Override the default `http` protocol | | `traefik.protocol=https` | Overrides the default `http` protocol. |
| `traefik.weight=10` | Assign this weight to the container | | `traefik.weight=10` | Assigns this weight to the container. |
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this 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.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=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.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=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.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | | `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | | `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Define the health check interval. (Default: 30s) | | `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | | `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | | `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | | `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> | | `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | | `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | | `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | | `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | | `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. | | `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` | Set 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.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 for that frontend in CSV format: `User:Hash,User:Hash` | | `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` | | `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.passHostHeader=true` | Forward client `Host` header to the backend. | | `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. |
| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | | `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.priority=10` | Override default frontend priority | | `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.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | | `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. | | `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. | | `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | | `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{sub_domain}.{domain}`. | | `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | 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.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | | `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 #### Custom Headers

View file

@ -106,52 +106,64 @@ domain = "mesos.localhost"
The following labels can be defined on Mesos tasks. They adjust the behavior for the entire application. The following labels can be defined on Mesos tasks. They adjust the behavior for the entire application.
| Label | Description | | Label | Description |
|------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Default domain used for frontend rules. | | `traefik.domain` | Sets the default domain for the frontend rules. |
| `traefik.enable=false` | Disable this container in Træfik | | `traefik.enable=false` | Disables this container in Træfik. |
| `traefik.port=80` | Register this port. Useful when the application exposes multiple ports. | | `traefik.port=80` | Registers this port. Useful when the application exposes multiple ports. |
| `traefik.portName=web` | Register port by name in the application's ports array. 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` | Register port by index 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` | Override the default `http` protocol | | `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container | | `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this 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.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=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.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=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.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | | `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | | `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Define the health check interval. (Default: 30s) | | `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | | `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | | `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | | `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> | | `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | | `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | | `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | | `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. | | `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` | Set 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.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 for that frontend in CSV format: `User:Hash,User:Hash` | | `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` | | `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.passHostHeader=true` | Forward client `Host` header to the backend. | | `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. |
| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | | `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.priority=10` | Override default frontend priority | | `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.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | | `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. | | `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. | | `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | | `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{discovery_name}.{domain}`. | | `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | 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.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | | `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 ### Custom Headers

View file

@ -138,51 +138,63 @@ secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Labels can be used on task containers to override default behavior: Labels can be used on task containers to override default behavior:
| Label | Description | | Label | Description |
|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Default domain used for frontend rules. | | `traefik.domain` | Sets the default domain for the frontend rules. |
| `traefik.enable=false` | Disable this container in Træfik | | `traefik.enable=false` | Disables this container in Træfik. |
| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | | `traefik.port=80` | Registers this port. Useful when the container exposes multiple ports. |
| `traefik.protocol=https` | Override the default `http` protocol | | `traefik.protocol=https` | Overrides the default `http` protocol. |
| `traefik.weight=10` | Assign this weight to the container | | `traefik.weight=10` | Assigns this weight to the container. |
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this 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.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=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.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=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.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | | `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | | `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Define the health check interval. | | `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | | `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | | `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | | `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> | | `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | | `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | | `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | | `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | | `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. | | `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` | Set 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.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 for that frontend in CSV format: `User:Hash,User:Hash` | | `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` | | `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` . |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | | `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.passHostHeader=true` | Forward client `Host` header to the backend. | | `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. |
| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | | `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.priority=10` | Override default frontend priority | | `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.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | | `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | | `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. | | `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. | | `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | | `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{service_name}.{stack_name}.{domain}`. | | `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | 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.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | | `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 #### Custom Headers
@ -224,32 +236,44 @@ You can define as many segments as ports exposed in a container.
Segment labels override the default behavior. Segment labels override the default behavior.
| Label | Description | | Label | Description |
|---------------------------------------------------------------------------|-------------------------------------------------------------| |---------------------------------------------------------------------------|---------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` | | `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` | | `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` | | `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` | | `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` | | `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=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | | `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` | | `traefik.<segment_name>.frontend.auth.basic.usersfile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersfile` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` | | `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` | | `traefik.<segment_name>.frontend.auth.digest.usersfile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersfile` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | | `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`| Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | | `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` | | `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | | `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` | | `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`| Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`|
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` | | `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` | | `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | | `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | | `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | | `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | | `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` | | `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | | `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | | `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 #### Custom Headers

View file

@ -266,10 +266,11 @@ Here is the toml configuration we would like to store in the store :
backend = "backend1" backend = "backend1"
passHostHeader = true passHostHeader = true
priority = 10 priority = 10
basicAuth = [ [frontends.frontend2.auth.basic]
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", users = [
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
] "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
entrypoints = ["https"] # overrides defaultEntryPoints entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1] [frontends.frontend2.routes.test_1]
rule = "Host:{subdomain:[a-z]+}.localhost" rule = "Host:{subdomain:[a-z]+}.localhost"
@ -334,8 +335,8 @@ And there, the same dynamic configuration in a KV Store (using `prefix = "traefi
| `/traefik/frontends/frontend2/backend` | `backend1` | | `/traefik/frontends/frontend2/backend` | `backend1` |
| `/traefik/frontends/frontend2/passhostheader` | `true` | | `/traefik/frontends/frontend2/passhostheader` | `true` |
| `/traefik/frontends/frontend2/priority` | `10` | | `/traefik/frontends/frontend2/priority` | `10` |
| `/traefik/frontends/frontend2/basicauth/0` | `test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/` | | `/traefik/frontends/frontend2/auth/basic/users/0` | `test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/` |
| `/traefik/frontends/frontend2/basicauth/1` | `test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | | `/traefik/frontends/frontend2/auth/basic/users/1` | `test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` |
| `/traefik/frontends/frontend2/entrypoints` | `http,https` | | `/traefik/frontends/frontend2/entrypoints` | `http,https` |
| `/traefik/frontends/frontend2/routes/test_2/rule` | `PathPrefix:/test` | | `/traefik/frontends/frontend2/routes/test_2/rule` | `PathPrefix:/test` |

View file

@ -102,7 +102,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
formatOnly: false, formatOnly: false,
code: "401", code: "401",
user: "-", user: "-",
frontendName: "Basic Auth for frontend-Host-frontend-auth-docker-local", frontendName: "Auth for frontend-Host-frontend-auth-docker-local",
backendURL: "/", backendURL: "/",
}, },
} }

View file

@ -38,7 +38,8 @@ func (p *Provider) buildConfigurationV2(catalog []catalogUpdate) *types.Configur
// Frontend functions // Frontend functions
"getFrontendRule": p.getFrontendRule, "getFrontendRule": p.getFrontendRule,
"getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated
"getAuth": label.GetAuth,
"getFrontEndEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getFrontEndEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints),
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority), "getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),

View file

@ -57,7 +57,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
label.TraefikBackendCircuitBreakerExpression + "=NetworkErrorRatio() > 0.5", label.TraefikBackendCircuitBreakerExpression + "=NetworkErrorRatio() > 0.5",
label.TraefikBackendMaxConnAmount + "=1000", label.TraefikBackendMaxConnAmount + "=1000",
label.TraefikBackendMaxConnExtractorFunc + "=client.ip", label.TraefikBackendMaxConnExtractorFunc + "=client.ip",
label.TraefikFrontendAuthBasic + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasicUsers + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
}, },
}, },
Nodes: []*api.ServiceEntry{ Nodes: []*api.ServiceEntry{
@ -90,8 +90,13 @@ func TestProviderBuildConfiguration(t *testing.T) {
Rule: "Host:test.localhost", Rule: "Host:test.localhost",
}, },
}, },
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
}, },
}, },
expectedBackends: map[string]*types.Backend{ expectedBackends: map[string]*types.Backend{
@ -115,6 +120,205 @@ func TestProviderBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "Should build config with a basic auth with a backward compatibility",
nodes: []catalogUpdate{
{
Service: &serviceUpdate{
ServiceName: "test",
Attributes: []string{
"random.foo=bar",
label.TraefikFrontendAuthBasicUsers + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
},
},
Nodes: []*api.ServiceEntry{
{
Service: &api.AgentService{
Service: "test",
Address: "127.0.0.1",
Port: 80,
Tags: []string{
"random.foo=bar",
label.Prefix + "backend.weight=42", // Deprecated label
label.TraefikFrontendPassHostHeader + "=true",
label.TraefikProtocol + "=https",
},
},
Node: &api.Node{
Node: "localhost",
Address: "127.0.0.1",
},
},
},
},
},
expectedFrontends: map[string]*types.Frontend{
"frontend-test": {
Backend: "backend-test",
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-test": {
Rule: "Host:test.localhost",
},
},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
URL: "https://127.0.0.1:80",
Weight: 42,
},
},
},
},
}, {
desc: "Should build config with a digest auth",
nodes: []catalogUpdate{
{
Service: &serviceUpdate{
ServiceName: "test",
Attributes: []string{
"random.foo=bar",
label.TraefikFrontendAuthDigestUsers + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile + "=.htpasswd",
},
},
Nodes: []*api.ServiceEntry{
{
Service: &api.AgentService{
Service: "test",
Address: "127.0.0.1",
Port: 80,
Tags: []string{
"random.foo=bar",
label.Prefix + "backend.weight=42", // Deprecated label
label.TraefikFrontendPassHostHeader + "=true",
label.TraefikProtocol + "=https",
},
},
Node: &api.Node{
Node: "localhost",
Address: "127.0.0.1",
},
},
},
},
},
expectedFrontends: map[string]*types.Frontend{
"frontend-test": {
Backend: "backend-test",
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-test": {
Rule: "Host:test.localhost",
},
},
Auth: &types.Auth{
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
URL: "https://127.0.0.1:80",
Weight: 42,
},
},
},
},
},
{
desc: "Should build config with a forward auth",
nodes: []catalogUpdate{
{
Service: &serviceUpdate{
ServiceName: "test",
Attributes: []string{
"random.foo=bar",
label.TraefikFrontendAuthForwardAddress + "=auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader + "=true",
label.TraefikFrontendAuthForwardTLSCa + "=ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional + "=true",
label.TraefikFrontendAuthForwardTLSCert + "=server.crt",
label.TraefikFrontendAuthForwardTLSKey + "=server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify + "=true",
label.TraefikFrontendAuthHeaderField + "=X-WebAuth-User",
},
},
Nodes: []*api.ServiceEntry{
{
Service: &api.AgentService{
Service: "test",
Address: "127.0.0.1",
Port: 80,
Tags: []string{
"random.foo=bar",
label.Prefix + "backend.weight=42", // Deprecated label
label.TraefikFrontendPassHostHeader + "=true",
label.TraefikProtocol + "=https",
},
},
Node: &api.Node{
Node: "localhost",
Address: "127.0.0.1",
},
},
},
},
},
expectedFrontends: map[string]*types.Frontend{
"frontend-test": {
Backend: "backend-test",
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-test": {
Rule: "Host:test.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
URL: "https://127.0.0.1:80",
Weight: 42,
},
},
},
},
},
{ {
desc: "when all labels are set", desc: "when all labels are set",
nodes: []catalogUpdate{ nodes: []catalogUpdate{
@ -144,6 +348,19 @@ func TestProviderBuildConfiguration(t *testing.T) {
label.TraefikBackendBufferingRetryExpression + "=IsNetworkError() && Attempts() <= 2", label.TraefikBackendBufferingRetryExpression + "=IsNetworkError() && Attempts() <= 2",
label.TraefikFrontendAuthBasic + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasic + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsers + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile + "=.htpasswd",
label.TraefikFrontendAuthDigestUsers + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile + "=.htpasswd",
label.TraefikFrontendAuthForwardAddress + "=auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader + "=true",
label.TraefikFrontendAuthForwardTLSCa + "=ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional + "=true",
label.TraefikFrontendAuthForwardTLSCert + "=server.crt",
label.TraefikFrontendAuthForwardTLSKey + "=server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify + "=true",
label.TraefikFrontendAuthHeaderField + "=X-WebAuth-User",
label.TraefikFrontendEntryPoints + "=http,https", label.TraefikFrontendEntryPoints + "=http,https",
label.TraefikFrontendPassHostHeader + "=true", label.TraefikFrontendPassHostHeader + "=true",
label.TraefikFrontendPassTLSCert + "=true", label.TraefikFrontendPassTLSCert + "=true",
@ -244,9 +461,13 @@ func TestProviderBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{ SourceRange: []string{
@ -389,7 +610,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
label.TraefikBackendCircuitBreakerExpression + "=NetworkErrorRatio() > 0.5", label.TraefikBackendCircuitBreakerExpression + "=NetworkErrorRatio() > 0.5",
label.TraefikBackendMaxConnAmount + "=1000", label.TraefikBackendMaxConnAmount + "=1000",
label.TraefikBackendMaxConnExtractorFunc + "=client.ip", label.TraefikBackendMaxConnExtractorFunc + "=client.ip",
label.TraefikFrontendAuthBasic + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasicUsers + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
}, },
}, },
Nodes: []*api.ServiceEntry{ Nodes: []*api.ServiceEntry{
@ -439,8 +660,13 @@ func TestProviderBuildConfiguration(t *testing.T) {
Rule: "Host:test.localhost", Rule: "Host:test.localhost",
}, },
}, },
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
}, },
}, },
expectedBackends: map[string]*types.Backend{ expectedBackends: map[string]*types.Backend{

View file

@ -47,7 +47,8 @@ func (p *Provider) buildConfigurationV2(containersInspected []dockerData) *types
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
"getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints),
"getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated
"getAuth": label.GetAuth,
"getFrontendRule": p.getFrontendRule, "getFrontendRule": p.getFrontendRule,
"getRedirect": label.GetRedirect, "getRedirect": label.GetRedirect,
"getErrorPages": label.GetErrorPages, "getErrorPages": label.GetErrorPages,

View file

@ -44,7 +44,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
Backend: "backend-test", Backend: "backend-test",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": { "route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost", Rule: "Host:test.docker.localhost",
@ -63,7 +62,201 @@ func TestDockerBuildConfiguration(t *testing.T) {
CircuitBreaker: nil, CircuitBreaker: nil,
}, },
}, },
}, { },
{
desc: "when frontend basic auth",
containers: []docker.ContainerJSON{
containerJSON(
name("test"),
labels(map[string]string{
label.TraefikFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile: ".htpasswd",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "when frontend basic auth backward compatibility",
containers: []docker.ContainerJSON{
containerJSON(
name("test"),
labels(map[string]string{
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "when frontend digest auth",
containers: []docker.ContainerJSON{
containerJSON(
name("test"),
labels(map[string]string{
label.TraefikFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile: ".htpasswd",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "when frontend forward auth",
containers: []docker.ContainerJSON{
containerJSON(
name("test"),
labels(map[string]string{
label.TraefikFrontendAuthForwardTrustForwardHeader: "true",
label.TraefikFrontendAuthForwardAddress: "auth.server",
label.TraefikFrontendAuthForwardTLSCa: "ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional: "true",
label.TraefikFrontendAuthForwardTLSCert: "server.crt",
label.TraefikFrontendAuthForwardTLSKey: "server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "when basic container configuration with multiple network", desc: "when basic container configuration with multiple network",
containers: []docker.ContainerJSON{ containers: []docker.ContainerJSON{
containerJSON( containerJSON(
@ -80,7 +273,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
Backend: "backend-test", Backend: "backend-test",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": { "route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost", Rule: "Host:test.docker.localhost",
@ -121,7 +313,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
Backend: "backend-test", Backend: "backend-test",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": { "route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost", Rule: "Host:test.docker.localhost",
@ -193,7 +384,20 @@ func TestDockerBuildConfiguration(t *testing.T) {
label.TraefikBackendBufferingMemRequestBodyBytes: "2097152", label.TraefikBackendBufferingMemRequestBodyBytes: "2097152",
label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2", label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2",
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile: ".htpasswd",
label.TraefikFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile: ".htpasswd",
label.TraefikFrontendAuthForwardAddress: "auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader: "true",
label.TraefikFrontendAuthForwardTLSCa: "ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional: "true",
label.TraefikFrontendAuthForwardTLSCert: "server.crt",
label.TraefikFrontendAuthForwardTLSKey: "server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.TraefikFrontendAuthHeaderField: "X-WebAuth-User",
label.TraefikFrontendEntryPoints: "http,https", label.TraefikFrontendEntryPoints: "http,https",
label.TraefikFrontendPassHostHeader: "true", label.TraefikFrontendPassHostHeader: "true",
label.TraefikFrontendPassTLSCert: "true", label.TraefikFrontendPassTLSCert: "true",
@ -265,9 +469,13 @@ func TestDockerBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},
@ -438,7 +646,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
Backend: "backend-myService-myProject", Backend: "backend-myService-myProject",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-myService-myProject-docker-localhost-0": { "route-frontend-Host-myService-myProject-docker-localhost-0": {
Rule: "Host:myService.myProject.docker.localhost", Rule: "Host:myService.myProject.docker.localhost",
@ -449,7 +656,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
Backend: "backend-myService2-myProject", Backend: "backend-myService2-myProject",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-myService2-myProject-docker-localhost-2": { "route-frontend-Host-myService2-myProject-docker-localhost-2": {
Rule: "Host:myService2.myProject.docker.localhost", Rule: "Host:myService2.myProject.docker.localhost",

View file

@ -46,7 +46,6 @@ func TestSwarmBuildConfiguration(t *testing.T) {
Backend: "backend-test", Backend: "backend-test",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": { "route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost", Rule: "Host:test.docker.localhost",
@ -94,6 +93,211 @@ func TestSwarmBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "when frontend basic auth configuration",
services: []swarm.Service{
swarmService(
serviceName("test"),
serviceLabels(map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile: ".htpasswd",
}),
withEndpointSpec(modeVIP),
withEndpoint(virtualIP("1", "127.0.0.1/24")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
},
},
networks: map[string]*docker.NetworkResource{
"1": {
Name: "foo",
},
},
},
{
desc: "when frontend basic auth configuration backward compatibility",
services: []swarm.Service{
swarmService(
serviceName("test"),
serviceLabels(map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
}),
withEndpointSpec(modeVIP),
withEndpoint(virtualIP("1", "127.0.0.1/24")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
},
},
networks: map[string]*docker.NetworkResource{
"1": {
Name: "foo",
},
},
},
{
desc: "when frontend digest auth configuration",
services: []swarm.Service{
swarmService(
serviceName("test"),
serviceLabels(map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile: ".htpasswd",
}),
withEndpointSpec(modeVIP),
withEndpoint(virtualIP("1", "127.0.0.1/24")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
},
},
networks: map[string]*docker.NetworkResource{
"1": {
Name: "foo",
},
},
},
{
desc: "when frontend forward auth configuration",
services: []swarm.Service{
swarmService(
serviceName("test"),
serviceLabels(map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthForwardAddress: "auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader: "true",
label.TraefikFrontendAuthForwardTLSCa: "ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional: "true",
label.TraefikFrontendAuthForwardTLSCert: "server.crt",
label.TraefikFrontendAuthForwardTLSKey: "server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
}),
withEndpointSpec(modeVIP),
withEndpoint(virtualIP("1", "127.0.0.1/24")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost-0": {
Backend: "backend-test",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
Cert: "server.crt",
Key: "server.key",
InsecureSkipVerify: true,
},
},
},
Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test": {
Servers: map[string]types.Server{
"server-test-842895ca2aca17f6ee36ddb2f621194d": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
},
},
networks: map[string]*docker.NetworkResource{
"1": {
Name: "foo",
},
},
},
{ {
desc: "when all labels are set", desc: "when all labels are set",
services: []swarm.Service{ services: []swarm.Service{
@ -125,6 +329,19 @@ func TestSwarmBuildConfiguration(t *testing.T) {
label.TraefikBackendBufferingMemRequestBodyBytes: "2097152", label.TraefikBackendBufferingMemRequestBodyBytes: "2097152",
label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2", label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2",
label.TraefikFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile: ".htpasswd",
label.TraefikFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile: ".htpasswd",
label.TraefikFrontendAuthForwardAddress: "auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader: "true",
label.TraefikFrontendAuthForwardTLSCa: "ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional: "true",
label.TraefikFrontendAuthForwardTLSCert: "server.crt",
label.TraefikFrontendAuthForwardTLSKey: "server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.TraefikFrontendAuthHeaderField: "X-WebAuth-User",
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendEntryPoints: "http,https", label.TraefikFrontendEntryPoints: "http,https",
label.TraefikFrontendPassHostHeader: "true", label.TraefikFrontendPassHostHeader: "true",
@ -194,9 +411,13 @@ func TestSwarmBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},

View file

@ -46,7 +46,6 @@ func TestSegmentBuildConfiguration(t *testing.T) {
Backend: "backend-foo-sauternes", Backend: "backend-foo-sauternes",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": { "route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.docker.localhost", Rule: "Host:foo.docker.localhost",
@ -66,6 +65,213 @@ func TestSegmentBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "auth basic",
containers: []docker.ContainerJSON{
containerJSON(
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsersFile: ".htpasswd",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.docker.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth basic backward compatibility",
containers: []docker.ContainerJSON{
containerJSON(
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.docker.localhost",
},
},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth digest",
containers: []docker.ContainerJSON{
containerJSON(
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsersFile: ".htpasswd",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.docker.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth forward",
containers: []docker.ContainerJSON{
containerJSON(
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardAddress: "auth.server",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTrustForwardHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCa: "ca.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCaOptional: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCert: "server.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSKey: "server.key",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSInsecureSkipVerify: "true",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.docker.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
Cert: "server.crt",
Key: "server.key",
InsecureSkipVerify: true,
},
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{ {
desc: "when all labels are set", desc: "when all labels are set",
containers: []docker.ContainerJSON{ containers: []docker.ContainerJSON{
@ -76,6 +282,19 @@ func TestSegmentBuildConfiguration(t *testing.T) {
label.Prefix + "sauternes." + label.SuffixProtocol: "https", label.Prefix + "sauternes." + label.SuffixProtocol: "https",
label.Prefix + "sauternes." + label.SuffixWeight: "12", label.Prefix + "sauternes." + label.SuffixWeight: "12",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardAddress: "auth.server",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTrustForwardHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCa: "ca.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCaOptional: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCert: "server.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSKey: "server.key",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https", label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true", label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true",
@ -142,9 +361,13 @@ func TestSegmentBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},
@ -285,7 +508,12 @@ func TestSegmentBuildConfiguration(t *testing.T) {
PassHostHeader: false, PassHostHeader: false,
Priority: 5000, Priority: 5000,
EntryPoints: []string{"http", "https", "ws"}, EntryPoints: []string{"http", "https", "ws"},
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
}, },
@ -299,7 +527,6 @@ func TestSegmentBuildConfiguration(t *testing.T) {
Backend: "backend-test2-anothersauternes", Backend: "backend-test2-anothersauternes",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-anothersauternes-test2-anothersauternes": { "route-frontend-anothersauternes-test2-anothersauternes": {
Rule: "Path:/anotherpath", Rule: "Path:/anotherpath",
@ -360,7 +587,6 @@ func TestSegmentBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
Priority: 5000, Priority: 5000,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{},
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
}, },
@ -375,7 +601,6 @@ func TestSegmentBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
Priority: 3000, Priority: 3000,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{},
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
}, },
@ -432,7 +657,6 @@ func TestSegmentBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
Priority: 5000, Priority: 5000,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{},
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
}, },
@ -447,7 +671,6 @@ func TestSegmentBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
Priority: 3000, Priority: 3000,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{},
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
}, },

View file

@ -46,7 +46,8 @@ func (p *Provider) buildConfigurationV2(instances []ecsInstance) (*types.Configu
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority), "getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
"getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated
"getAuth": label.GetAuth,
"getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints),
"getRedirect": label.GetRedirect, "getRedirect": label.GetRedirect,
"getErrorPages": label.GetErrorPages, "getErrorPages": label.GetErrorPages,

View file

@ -56,7 +56,6 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
}, },
}, },
}, },
@ -103,7 +102,216 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{}, },
},
},
},
{
desc: "config parsed successfully with basic auth labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend-instance": {
Servers: map[string]types.Server{
"server-instance-1": {
URL: "http://10.0.0.1:1337",
Weight: label.DefaultWeight,
}},
},
},
Frontends: map[string]*types.Frontend{
"frontend-instance": {
EntryPoints: []string{},
Backend: "backend-instance",
Routes: map[string]types.Route{
"route-frontend-instance": {
Rule: "Host:instance.",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
PassHostHeader: true,
},
},
},
},
{
desc: "config parsed successfully with basic auth (backward compatibility) labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend-instance": {
Servers: map[string]types.Server{
"server-instance-1": {
URL: "http://10.0.0.1:1337",
Weight: label.DefaultWeight,
}},
},
},
Frontends: map[string]*types.Frontend{
"frontend-instance": {
EntryPoints: []string{},
Backend: "backend-instance",
Routes: map[string]types.Route{
"route-frontend-instance": {
Rule: "Host:instance.",
},
},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
PassHostHeader: true,
},
},
},
},
{
desc: "config parsed successfully with digest auth labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend-instance": {
Servers: map[string]types.Server{
"server-instance-1": {
URL: "http://10.0.0.1:1337",
Weight: label.DefaultWeight,
}},
},
},
Frontends: map[string]*types.Frontend{
"frontend-instance": {
EntryPoints: []string{},
Backend: "backend-instance",
Routes: map[string]types.Route{
"route-frontend-instance": {
Rule: "Host:instance.",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
PassHostHeader: true,
},
},
},
},
{
desc: "config parsed successfully with forward auth labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"), label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend-instance": {
Servers: map[string]types.Server{
"server-instance-1": {
URL: "http://10.0.0.1:1337",
Weight: label.DefaultWeight,
}},
},
},
Frontends: map[string]*types.Frontend{
"frontend-instance": {
EntryPoints: []string{},
Backend: "backend-instance",
Routes: map[string]types.Route{
"route-frontend-instance": {
Rule: "Host:instance.",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
PassHostHeader: true,
}, },
}, },
}, },
@ -141,7 +349,20 @@ func TestBuildConfiguration(t *testing.T) {
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"), label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"), label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
label.TraefikFrontendEntryPoints: aws.String("http,https"), label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"), label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"), label.TraefikFrontendPassTLSCert: aws.String("true"),
@ -257,9 +478,13 @@ func TestBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},
@ -381,7 +606,7 @@ func TestBuildConfiguration(t *testing.T) {
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"), label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"), label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendEntryPoints: aws.String("http,https"), label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"), label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"), label.TraefikFrontendPassTLSCert: aws.String("true"),
@ -588,9 +813,11 @@ func TestBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", Basic: &types.Basic{
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},

View file

@ -33,22 +33,41 @@ const (
pathFrontendPassTLSCert = "/passtlscert" pathFrontendPassTLSCert = "/passtlscert"
pathFrontendWhiteListSourceRange = "/whitelist/sourcerange" pathFrontendWhiteListSourceRange = "/whitelist/sourcerange"
pathFrontendWhiteListUseXForwardedFor = "/whitelist/usexforwardedfor" pathFrontendWhiteListUseXForwardedFor = "/whitelist/usexforwardedfor"
pathFrontendBasicAuth = "/basicauth"
pathFrontendEntryPoints = "/entrypoints" pathFrontendBasicAuth = "/basicauth" // Deprecated
pathFrontendRedirectEntryPoint = "/redirect/entrypoint" pathFrontendAuth = "/auth/"
pathFrontendRedirectRegex = "/redirect/regex" pathFrontendAuthBasic = pathFrontendAuth + "basic/"
pathFrontendRedirectReplacement = "/redirect/replacement" pathFrontendAuthBasicUsers = pathFrontendAuthBasic + "users"
pathFrontendRedirectPermanent = "/redirect/permanent" pathFrontendAuthBasicUsersFile = pathFrontendAuthBasic + "usersfile"
pathFrontendErrorPages = "/errors/" pathFrontendAuthDigest = pathFrontendAuth + "digest/"
pathFrontendErrorPagesBackend = "/backend" pathFrontendAuthDigestUsers = pathFrontendAuthDigest + "users"
pathFrontendErrorPagesQuery = "/query" pathFrontendAuthDigestUsersFile = pathFrontendAuthDigest + "usersfile"
pathFrontendErrorPagesStatus = "/status" pathFrontendAuthForward = pathFrontendAuth + "forward/"
pathFrontendRateLimit = "/ratelimit/" pathFrontendAuthForwardAddress = pathFrontendAuthForward + "address"
pathFrontendRateLimitRateSet = pathFrontendRateLimit + "rateset/" pathFrontendAuthForwardTLS = pathFrontendAuthForward + "tls/"
pathFrontendRateLimitExtractorFunc = pathFrontendRateLimit + "extractorfunc" pathFrontendAuthForwardTLSCa = pathFrontendAuthForwardTLS + "ca"
pathFrontendRateLimitPeriod = "/period" pathFrontendAuthForwardTLSCaOptional = pathFrontendAuthForwardTLS + "caoptional"
pathFrontendRateLimitAverage = "/average" pathFrontendAuthForwardTLSCert = pathFrontendAuthForwardTLS + "cert"
pathFrontendRateLimitBurst = "/burst" pathFrontendAuthForwardTLSInsecureSkipVerify = pathFrontendAuthForwardTLS + "insecureskipverify"
pathFrontendAuthForwardTLSKey = pathFrontendAuthForwardTLS + "key"
pathFrontendAuthForwardTrustForwardHeader = pathFrontendAuthForward + "trustforwardheader"
pathFrontendAuthHeaderField = pathFrontendAuth + "headerfield"
pathFrontendEntryPoints = "/entrypoints"
pathFrontendRedirectEntryPoint = "/redirect/entrypoint"
pathFrontendRedirectRegex = "/redirect/regex"
pathFrontendRedirectReplacement = "/redirect/replacement"
pathFrontendRedirectPermanent = "/redirect/permanent"
pathFrontendErrorPages = "/errors/"
pathFrontendErrorPagesBackend = "/backend"
pathFrontendErrorPagesQuery = "/query"
pathFrontendErrorPagesStatus = "/status"
pathFrontendRateLimit = "/ratelimit/"
pathFrontendRateLimitRateSet = pathFrontendRateLimit + "rateset/"
pathFrontendRateLimitExtractorFunc = pathFrontendRateLimit + "extractorfunc"
pathFrontendRateLimitPeriod = "/period"
pathFrontendRateLimitAverage = "/average"
pathFrontendRateLimitBurst = "/burst"
pathFrontendCustomRequestHeaders = "/headers/customrequestheaders/" pathFrontendCustomRequestHeaders = "/headers/customrequestheaders/"
pathFrontendCustomResponseHeaders = "/headers/customresponseheaders/" pathFrontendCustomResponseHeaders = "/headers/customresponseheaders/"

View file

@ -46,7 +46,8 @@ func (p *Provider) buildConfiguration() *types.Configuration {
"getPassHostHeader": p.getPassHostHeader(), "getPassHostHeader": p.getPassHostHeader(),
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert), "getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
"getEntryPoints": p.getFuncList(pathFrontendEntryPoints), "getEntryPoints": p.getFuncList(pathFrontendEntryPoints),
"getBasicAuth": p.getFuncList(pathFrontendBasicAuth), "getBasicAuth": p.getFuncList(pathFrontendBasicAuth), // Deprecated
"getAuth": p.getAuth,
"getRoutes": p.getRoutes, "getRoutes": p.getRoutes,
"getRedirect": p.getRedirect, "getRedirect": p.getRedirect,
"getErrorPages": p.getErrorPages, "getErrorPages": p.getErrorPages,
@ -368,6 +369,78 @@ func (p *Provider) getTLSSection(prefix string) []*tls.Configuration {
return tlsSection return tlsSection
} }
// hasDeprecatedBasicAuth check if the frontend basic auth use the deprecated configuration
func (p *Provider) hasDeprecatedBasicAuth(rootPath string) bool {
return len(p.getList(rootPath, pathFrontendBasicAuth)) > 0
}
// GetAuth Create auth from path
func (p *Provider) getAuth(rootPath string) *types.Auth {
hasDeprecatedBasicAuth := p.hasDeprecatedBasicAuth(rootPath)
if len(p.getList(rootPath, pathFrontendAuth)) > 0 || hasDeprecatedBasicAuth {
auth := &types.Auth{
HeaderField: p.get("", rootPath, pathFrontendAuthHeaderField),
}
if len(p.getList(rootPath, pathFrontendAuthBasic)) > 0 || hasDeprecatedBasicAuth {
auth.Basic = p.getAuthBasic(rootPath)
} else if len(p.getList(rootPath, pathFrontendAuthDigest)) > 0 {
auth.Digest = p.getAuthDigest(rootPath)
} else if len(p.getList(rootPath, pathFrontendAuthForward)) > 0 {
auth.Forward = p.getAuthForward(rootPath)
}
return auth
}
return nil
}
// getAuthBasic Create Basic Auth from path
func (p *Provider) getAuthBasic(rootPath string) *types.Basic {
basicAuth := &types.Basic{
UsersFile: p.get("", rootPath, pathFrontendAuthBasicUsersFile),
}
// backward compatibility
if p.hasDeprecatedBasicAuth(rootPath) {
basicAuth.Users = p.getList(rootPath, pathFrontendBasicAuth)
log.Warnf("Deprecated configuration found: %s. Please use %s.", pathFrontendBasicAuth, pathFrontendAuthBasic)
} else {
basicAuth.Users = p.getList(rootPath, pathFrontendAuthBasicUsers)
}
return basicAuth
}
// getAuthDigest Create Digest Auth from path
func (p *Provider) getAuthDigest(rootPath string) *types.Digest {
return &types.Digest{
Users: p.getList(rootPath, pathFrontendAuthDigestUsers),
UsersFile: p.get("", rootPath, pathFrontendAuthDigestUsersFile),
}
}
// getAuthForward Create Forward Auth from path
func (p *Provider) getAuthForward(rootPath string) *types.Forward {
forwardAuth := &types.Forward{
Address: p.get("", rootPath, pathFrontendAuthForwardAddress),
TrustForwardHeader: p.getBool(false, rootPath, pathFrontendAuthForwardTrustForwardHeader),
}
// TLS configuration
if len(p.getList(rootPath, pathFrontendAuthForwardTLS)) > 0 {
forwardAuth.TLS = &types.ClientTLS{
CA: p.get("", rootPath, pathFrontendAuthForwardTLSCa),
CAOptional: p.getBool(false, rootPath, pathFrontendAuthForwardTLSCaOptional),
Cert: p.get("", rootPath, pathFrontendAuthForwardTLSCert),
InsecureSkipVerify: p.getBool(false, rootPath, pathFrontendAuthForwardTLSInsecureSkipVerify),
Key: p.get("", rootPath, pathFrontendAuthForwardTLSKey),
}
}
return forwardAuth
}
func (p *Provider) getRoutes(rootPath string) map[string]types.Route { func (p *Provider) getRoutes(rootPath string) map[string]types.Route {
var routes map[string]types.Route var routes map[string]types.Route

View file

@ -52,7 +52,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
Backend: "backend.with.dot.too", Backend: "backend.with.dot.too",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route.with.dot": { "route.with.dot": {
Rule: "Host:test.localhost", Rule: "Host:test.localhost",
@ -62,6 +61,157 @@ func TestProviderBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "basic auth",
kvPairs: filler("traefik",
frontend("frontend",
withPair(pathFrontendBackend, "backend"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"),
withList(pathFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withPair(pathFrontendAuthBasicUsersFile, ".htpasswd"),
),
backend("backend"),
),
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend": {
LoadBalancer: &types.LoadBalancer{
Method: "wrr",
},
},
},
Frontends: map[string]*types.Frontend{
"frontend": {
Backend: "backend",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
},
},
{
desc: "basic auth (backward compatibility)",
kvPairs: filler("traefik",
frontend("frontend",
withPair(pathFrontendBackend, "backend"),
withList(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
),
backend("backend"),
),
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend": {
LoadBalancer: &types.LoadBalancer{
Method: "wrr",
},
},
},
Frontends: map[string]*types.Frontend{
"frontend": {
Backend: "backend",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
},
},
},
},
{
desc: "digest auth",
kvPairs: filler("traefik",
frontend("frontend",
withPair(pathFrontendBackend, "backend"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"),
withList(pathFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withPair(pathFrontendAuthDigestUsersFile, ".htpasswd"),
),
backend("backend"),
),
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend": {
LoadBalancer: &types.LoadBalancer{
Method: "wrr",
},
},
},
Frontends: map[string]*types.Frontend{
"frontend": {
Backend: "backend",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
},
},
{
desc: "forward auth",
kvPairs: filler("traefik",
frontend("frontend",
withPair(pathFrontendBackend, "backend"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"),
withPair(pathFrontendAuthForwardAddress, "auth.server"),
withPair(pathFrontendAuthForwardTrustForwardHeader, "true"),
withPair(pathFrontendAuthForwardTLSCa, "ca.crt"),
withPair(pathFrontendAuthForwardTLSCaOptional, "true"),
withPair(pathFrontendAuthForwardTLSCert, "server.crt"),
withPair(pathFrontendAuthForwardTLSKey, "server.key"),
withPair(pathFrontendAuthForwardTLSInsecureSkipVerify, "true"),
),
backend("backend"),
),
expected: &types.Configuration{
Backends: map[string]*types.Backend{
"backend": {
LoadBalancer: &types.LoadBalancer{
Method: "wrr",
},
},
},
Frontends: map[string]*types.Frontend{
"frontend": {
Backend: "backend",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
},
},
},
},
{ {
desc: "all parameters", desc: "all parameters",
kvPairs: filler("traefik", kvPairs: filler("traefik",
@ -96,7 +246,21 @@ func TestProviderBuildConfiguration(t *testing.T) {
withList(pathFrontendEntryPoints, "http", "https"), withList(pathFrontendEntryPoints, "http", "https"),
withList(pathFrontendWhiteListSourceRange, "1.1.1.1/24", "1234:abcd::42/32"), withList(pathFrontendWhiteListSourceRange, "1.1.1.1/24", "1234:abcd::42/32"),
withPair(pathFrontendWhiteListUseXForwardedFor, "true"), withPair(pathFrontendWhiteListUseXForwardedFor, "true"),
withList(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), withList(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withList(pathFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withPair(pathFrontendAuthBasicUsersFile, ".htpasswd"),
withList(pathFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withPair(pathFrontendAuthDigestUsersFile, ".htpasswd"),
withPair(pathFrontendAuthForwardAddress, "auth.server"),
withPair(pathFrontendAuthForwardTrustForwardHeader, "true"),
withPair(pathFrontendAuthForwardTLSCa, "ca.crt"),
withPair(pathFrontendAuthForwardTLSCaOptional, "true"),
withPair(pathFrontendAuthForwardTLSCert, "server.crt"),
withPair(pathFrontendAuthForwardTLSKey, "server.key"),
withPair(pathFrontendAuthForwardTLSInsecureSkipVerify, "true"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"),
withPair(pathFrontendRedirectEntryPoint, "https"), withPair(pathFrontendRedirectEntryPoint, "https"),
withPair(pathFrontendRedirectRegex, "nope"), withPair(pathFrontendRedirectRegex, "nope"),
withPair(pathFrontendRedirectReplacement, "nope"), withPair(pathFrontendRedirectReplacement, "nope"),
@ -200,7 +364,14 @@ func TestProviderBuildConfiguration(t *testing.T) {
SourceRange: []string{"1.1.1.1/24", "1234:abcd::42/32"}, SourceRange: []string{"1.1.1.1/24", "1234:abcd::42/32"},
UseXForwardedFor: true, UseXForwardedFor: true,
}, },
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
Permanent: true, Permanent: true,
@ -1939,6 +2110,166 @@ func TestProviderGetTLSes(t *testing.T) {
} }
} }
func TestProviderGetAuth(t *testing.T) {
testCases := []struct {
desc string
rootPath string
kvPairs []*store.KVPair
expected *types.Auth
}{
{
desc: "should return nil when no data",
expected: nil,
},
{
desc: "should return a valid basic auth",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withList(pathFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withPair(pathFrontendAuthBasicUsersFile, ".htpasswd"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"))),
expected: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
{
desc: "should return a valid basic auth (backward compatibility)",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withPair(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
)),
expected: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
},
{
desc: "should return a valid digest auth",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withList(pathFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withPair(pathFrontendAuthDigestUsersFile, ".htpasswd"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"),
)),
expected: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
{
desc: "should return a valid forward auth",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withPair(pathFrontendAuthForwardAddress, "auth.server"),
withPair(pathFrontendAuthForwardTrustForwardHeader, "true"),
withPair(pathFrontendAuthForwardTLSCa, "ca.crt"),
withPair(pathFrontendAuthForwardTLSCaOptional, "true"),
withPair(pathFrontendAuthForwardTLSCert, "server.crt"),
withPair(pathFrontendAuthForwardTLSKey, "server.key"),
withPair(pathFrontendAuthForwardTLSInsecureSkipVerify, "true"),
withPair(pathFrontendAuthHeaderField, "X-WebAuth-User"),
)),
expected: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
p := newProviderMock(test.kvPairs)
result := p.getAuth(test.rootPath)
assert.Equal(t, test.expected, result)
})
}
}
func TestProviderHasDeprecatedBasicAuth(t *testing.T) {
testCases := []struct {
desc string
rootPath string
kvPairs []*store.KVPair
expected bool
}{
{
desc: "should return nil when no data",
expected: false,
},
{
desc: "should return a valid basic auth",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withList(pathFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
)),
expected: false,
},
{
desc: "should return a valid basic auth",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withList(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
)),
expected: true,
},
{
desc: "should return a valid basic auth",
rootPath: "traefik/frontends/foo",
kvPairs: filler("traefik",
frontend("foo",
withList(pathFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withList(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
)),
expected: true,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
p := newProviderMock(test.kvPairs)
result := p.hasDeprecatedBasicAuth(test.rootPath)
assert.Equal(t, test.expected, result)
})
}
}
func TestProviderGetRoutes(t *testing.T) { func TestProviderGetRoutes(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string

View file

@ -2,151 +2,183 @@ package label
// Traefik labels // Traefik labels
const ( const (
Prefix = "traefik." Prefix = "traefik."
SuffixBackend = "backend" SuffixBackend = "backend"
SuffixDomain = "domain" SuffixDomain = "domain"
SuffixEnable = "enable" SuffixEnable = "enable"
SuffixPort = "port" SuffixPort = "port"
SuffixPortName = "portName" SuffixPortName = "portName"
SuffixPortIndex = "portIndex" SuffixPortIndex = "portIndex"
SuffixProtocol = "protocol" SuffixProtocol = "protocol"
SuffixTags = "tags" SuffixTags = "tags"
SuffixWeight = "weight" SuffixWeight = "weight"
SuffixBackendID = "backend.id" SuffixBackendID = "backend.id"
SuffixBackendCircuitBreaker = "backend.circuitbreaker" SuffixBackendCircuitBreaker = "backend.circuitbreaker"
SuffixBackendCircuitBreakerExpression = "backend.circuitbreaker.expression" SuffixBackendCircuitBreakerExpression = "backend.circuitbreaker.expression"
SuffixBackendHealthCheckScheme = "backend.healthcheck.scheme" SuffixBackendHealthCheckScheme = "backend.healthcheck.scheme"
SuffixBackendHealthCheckPath = "backend.healthcheck.path" SuffixBackendHealthCheckPath = "backend.healthcheck.path"
SuffixBackendHealthCheckPort = "backend.healthcheck.port" SuffixBackendHealthCheckPort = "backend.healthcheck.port"
SuffixBackendHealthCheckInterval = "backend.healthcheck.interval" SuffixBackendHealthCheckInterval = "backend.healthcheck.interval"
SuffixBackendHealthCheckHostname = "backend.healthcheck.hostname" SuffixBackendHealthCheckHostname = "backend.healthcheck.hostname"
SuffixBackendHealthCheckHeaders = "backend.healthcheck.headers" SuffixBackendHealthCheckHeaders = "backend.healthcheck.headers"
SuffixBackendLoadBalancer = "backend.loadbalancer" SuffixBackendLoadBalancer = "backend.loadbalancer"
SuffixBackendLoadBalancerMethod = SuffixBackendLoadBalancer + ".method" SuffixBackendLoadBalancerMethod = SuffixBackendLoadBalancer + ".method"
SuffixBackendLoadBalancerSticky = SuffixBackendLoadBalancer + ".sticky" SuffixBackendLoadBalancerSticky = SuffixBackendLoadBalancer + ".sticky"
SuffixBackendLoadBalancerStickiness = SuffixBackendLoadBalancer + ".stickiness" SuffixBackendLoadBalancerStickiness = SuffixBackendLoadBalancer + ".stickiness"
SuffixBackendLoadBalancerStickinessCookieName = SuffixBackendLoadBalancer + ".stickiness.cookieName" SuffixBackendLoadBalancerStickinessCookieName = SuffixBackendLoadBalancer + ".stickiness.cookieName"
SuffixBackendMaxConnAmount = "backend.maxconn.amount" SuffixBackendMaxConnAmount = "backend.maxconn.amount"
SuffixBackendMaxConnExtractorFunc = "backend.maxconn.extractorfunc" SuffixBackendMaxConnExtractorFunc = "backend.maxconn.extractorfunc"
SuffixBackendBuffering = "backend.buffering" SuffixBackendBuffering = "backend.buffering"
SuffixBackendBufferingMaxRequestBodyBytes = SuffixBackendBuffering + ".maxRequestBodyBytes" SuffixBackendBufferingMaxRequestBodyBytes = SuffixBackendBuffering + ".maxRequestBodyBytes"
SuffixBackendBufferingMemRequestBodyBytes = SuffixBackendBuffering + ".memRequestBodyBytes" SuffixBackendBufferingMemRequestBodyBytes = SuffixBackendBuffering + ".memRequestBodyBytes"
SuffixBackendBufferingMaxResponseBodyBytes = SuffixBackendBuffering + ".maxResponseBodyBytes" SuffixBackendBufferingMaxResponseBodyBytes = SuffixBackendBuffering + ".maxResponseBodyBytes"
SuffixBackendBufferingMemResponseBodyBytes = SuffixBackendBuffering + ".memResponseBodyBytes" SuffixBackendBufferingMemResponseBodyBytes = SuffixBackendBuffering + ".memResponseBodyBytes"
SuffixBackendBufferingRetryExpression = SuffixBackendBuffering + ".retryExpression" SuffixBackendBufferingRetryExpression = SuffixBackendBuffering + ".retryExpression"
SuffixFrontend = "frontend" SuffixFrontend = "frontend"
SuffixFrontendAuthBasic = "frontend.auth.basic" SuffixFrontendAuth = SuffixFrontend + ".auth"
SuffixFrontendEntryPoints = "frontend.entryPoints" SuffixFrontendAuthBasic = SuffixFrontendAuth + ".basic"
SuffixFrontendHeaders = "frontend.headers." SuffixFrontendAuthBasicUsers = SuffixFrontendAuthBasic + ".users"
SuffixFrontendRequestHeaders = SuffixFrontendHeaders + "customRequestHeaders" SuffixFrontendAuthBasicUsersFile = SuffixFrontendAuthBasic + ".usersFile"
SuffixFrontendResponseHeaders = SuffixFrontendHeaders + "customResponseHeaders" SuffixFrontendAuthDigest = SuffixFrontendAuth + ".digest"
SuffixFrontendHeadersAllowedHosts = SuffixFrontendHeaders + "allowedHosts" SuffixFrontendAuthDigestUsers = SuffixFrontendAuthDigest + ".users"
SuffixFrontendHeadersHostsProxyHeaders = SuffixFrontendHeaders + "hostsProxyHeaders" SuffixFrontendAuthDigestUsersFile = SuffixFrontendAuthDigest + ".usersFile"
SuffixFrontendHeadersSSLForceHost = SuffixFrontendHeaders + "SSLForceHost" SuffixFrontendAuthForward = SuffixFrontendAuth + ".forward"
SuffixFrontendHeadersSSLRedirect = SuffixFrontendHeaders + "SSLRedirect" SuffixFrontendAuthForwardAddress = SuffixFrontendAuthForward + ".address"
SuffixFrontendHeadersSSLTemporaryRedirect = SuffixFrontendHeaders + "SSLTemporaryRedirect" SuffixFrontendAuthForwardTLS = SuffixFrontendAuthForward + ".tls"
SuffixFrontendHeadersSSLHost = SuffixFrontendHeaders + "SSLHost" SuffixFrontendAuthForwardTLSCa = SuffixFrontendAuthForwardTLS + ".ca"
SuffixFrontendHeadersSSLProxyHeaders = SuffixFrontendHeaders + "SSLProxyHeaders" SuffixFrontendAuthForwardTLSCaOptional = SuffixFrontendAuthForwardTLS + ".caOptional"
SuffixFrontendHeadersSTSSeconds = SuffixFrontendHeaders + "STSSeconds" SuffixFrontendAuthForwardTLSCert = SuffixFrontendAuthForwardTLS + ".cert"
SuffixFrontendHeadersSTSIncludeSubdomains = SuffixFrontendHeaders + "STSIncludeSubdomains" SuffixFrontendAuthForwardTLSInsecureSkipVerify = SuffixFrontendAuthForwardTLS + ".insecureSkipVerify"
SuffixFrontendHeadersSTSPreload = SuffixFrontendHeaders + "STSPreload" SuffixFrontendAuthForwardTLSKey = SuffixFrontendAuthForwardTLS + ".key"
SuffixFrontendHeadersForceSTSHeader = SuffixFrontendHeaders + "forceSTSHeader" SuffixFrontendAuthForwardTrustForwardHeader = SuffixFrontendAuthForward + ".trustForwardHeader"
SuffixFrontendHeadersFrameDeny = SuffixFrontendHeaders + "frameDeny" SuffixFrontendAuthHeaderField = SuffixFrontendAuth + ".headerField"
SuffixFrontendHeadersCustomFrameOptionsValue = SuffixFrontendHeaders + "customFrameOptionsValue" SuffixFrontendEntryPoints = "frontend.entryPoints"
SuffixFrontendHeadersContentTypeNosniff = SuffixFrontendHeaders + "contentTypeNosniff" SuffixFrontendHeaders = "frontend.headers."
SuffixFrontendHeadersBrowserXSSFilter = SuffixFrontendHeaders + "browserXSSFilter" SuffixFrontendRequestHeaders = SuffixFrontendHeaders + "customRequestHeaders"
SuffixFrontendHeadersCustomBrowserXSSValue = SuffixFrontendHeaders + "customBrowserXSSValue" SuffixFrontendResponseHeaders = SuffixFrontendHeaders + "customResponseHeaders"
SuffixFrontendHeadersContentSecurityPolicy = SuffixFrontendHeaders + "contentSecurityPolicy" SuffixFrontendHeadersAllowedHosts = SuffixFrontendHeaders + "allowedHosts"
SuffixFrontendHeadersPublicKey = SuffixFrontendHeaders + "publicKey" SuffixFrontendHeadersHostsProxyHeaders = SuffixFrontendHeaders + "hostsProxyHeaders"
SuffixFrontendHeadersReferrerPolicy = SuffixFrontendHeaders + "referrerPolicy" SuffixFrontendHeadersSSLForceHost = SuffixFrontendHeaders + "SSLForceHost"
SuffixFrontendHeadersIsDevelopment = SuffixFrontendHeaders + "isDevelopment" SuffixFrontendHeadersSSLRedirect = SuffixFrontendHeaders + "SSLRedirect"
SuffixFrontendPassHostHeader = "frontend.passHostHeader" SuffixFrontendHeadersSSLTemporaryRedirect = SuffixFrontendHeaders + "SSLTemporaryRedirect"
SuffixFrontendPassTLSCert = "frontend.passTLSCert" SuffixFrontendHeadersSSLHost = SuffixFrontendHeaders + "SSLHost"
SuffixFrontendPriority = "frontend.priority" SuffixFrontendHeadersSSLProxyHeaders = SuffixFrontendHeaders + "SSLProxyHeaders"
SuffixFrontendRateLimitExtractorFunc = "frontend.rateLimit.extractorFunc" SuffixFrontendHeadersSTSSeconds = SuffixFrontendHeaders + "STSSeconds"
SuffixFrontendRedirectEntryPoint = "frontend.redirect.entryPoint" SuffixFrontendHeadersSTSIncludeSubdomains = SuffixFrontendHeaders + "STSIncludeSubdomains"
SuffixFrontendRedirectRegex = "frontend.redirect.regex" SuffixFrontendHeadersSTSPreload = SuffixFrontendHeaders + "STSPreload"
SuffixFrontendRedirectReplacement = "frontend.redirect.replacement" SuffixFrontendHeadersForceSTSHeader = SuffixFrontendHeaders + "forceSTSHeader"
SuffixFrontendRedirectPermanent = "frontend.redirect.permanent" SuffixFrontendHeadersFrameDeny = SuffixFrontendHeaders + "frameDeny"
SuffixFrontendRule = "frontend.rule" SuffixFrontendHeadersCustomFrameOptionsValue = SuffixFrontendHeaders + "customFrameOptionsValue"
SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange" // Deprecated SuffixFrontendHeadersContentTypeNosniff = SuffixFrontendHeaders + "contentTypeNosniff"
SuffixFrontendWhiteList = "frontend.whiteList." SuffixFrontendHeadersBrowserXSSFilter = SuffixFrontendHeaders + "browserXSSFilter"
SuffixFrontendWhiteListSourceRange = SuffixFrontendWhiteList + "sourceRange" SuffixFrontendHeadersCustomBrowserXSSValue = SuffixFrontendHeaders + "customBrowserXSSValue"
SuffixFrontendWhiteListUseXForwardedFor = SuffixFrontendWhiteList + "useXForwardedFor" SuffixFrontendHeadersContentSecurityPolicy = SuffixFrontendHeaders + "contentSecurityPolicy"
TraefikDomain = Prefix + SuffixDomain SuffixFrontendHeadersPublicKey = SuffixFrontendHeaders + "publicKey"
TraefikEnable = Prefix + SuffixEnable SuffixFrontendHeadersReferrerPolicy = SuffixFrontendHeaders + "referrerPolicy"
TraefikPort = Prefix + SuffixPort SuffixFrontendHeadersIsDevelopment = SuffixFrontendHeaders + "isDevelopment"
TraefikPortName = Prefix + SuffixPortName SuffixFrontendPassHostHeader = "frontend.passHostHeader"
TraefikPortIndex = Prefix + SuffixPortIndex SuffixFrontendPassTLSCert = "frontend.passTLSCert"
TraefikProtocol = Prefix + SuffixProtocol SuffixFrontendPriority = "frontend.priority"
TraefikTags = Prefix + SuffixTags SuffixFrontendRateLimitExtractorFunc = "frontend.rateLimit.extractorFunc"
TraefikWeight = Prefix + SuffixWeight SuffixFrontendRedirectEntryPoint = "frontend.redirect.entryPoint"
TraefikBackend = Prefix + SuffixBackend SuffixFrontendRedirectRegex = "frontend.redirect.regex"
TraefikBackendID = Prefix + SuffixBackendID SuffixFrontendRedirectReplacement = "frontend.redirect.replacement"
TraefikBackendCircuitBreaker = Prefix + SuffixBackendCircuitBreaker SuffixFrontendRedirectPermanent = "frontend.redirect.permanent"
TraefikBackendCircuitBreakerExpression = Prefix + SuffixBackendCircuitBreakerExpression SuffixFrontendRule = "frontend.rule"
TraefikBackendHealthCheckScheme = Prefix + SuffixBackendHealthCheckScheme SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange" // Deprecated
TraefikBackendHealthCheckPath = Prefix + SuffixBackendHealthCheckPath SuffixFrontendWhiteList = "frontend.whiteList."
TraefikBackendHealthCheckPort = Prefix + SuffixBackendHealthCheckPort SuffixFrontendWhiteListSourceRange = SuffixFrontendWhiteList + "sourceRange"
TraefikBackendHealthCheckInterval = Prefix + SuffixBackendHealthCheckInterval SuffixFrontendWhiteListUseXForwardedFor = SuffixFrontendWhiteList + "useXForwardedFor"
TraefikBackendHealthCheckHostname = Prefix + SuffixBackendHealthCheckHostname TraefikDomain = Prefix + SuffixDomain
TraefikBackendHealthCheckHeaders = Prefix + SuffixBackendHealthCheckHeaders TraefikEnable = Prefix + SuffixEnable
TraefikBackendLoadBalancer = Prefix + SuffixBackendLoadBalancer TraefikPort = Prefix + SuffixPort
TraefikBackendLoadBalancerMethod = Prefix + SuffixBackendLoadBalancerMethod TraefikPortName = Prefix + SuffixPortName
TraefikBackendLoadBalancerSticky = Prefix + SuffixBackendLoadBalancerSticky TraefikPortIndex = Prefix + SuffixPortIndex
TraefikBackendLoadBalancerStickiness = Prefix + SuffixBackendLoadBalancerStickiness TraefikProtocol = Prefix + SuffixProtocol
TraefikBackendLoadBalancerStickinessCookieName = Prefix + SuffixBackendLoadBalancerStickinessCookieName TraefikTags = Prefix + SuffixTags
TraefikBackendMaxConnAmount = Prefix + SuffixBackendMaxConnAmount TraefikWeight = Prefix + SuffixWeight
TraefikBackendMaxConnExtractorFunc = Prefix + SuffixBackendMaxConnExtractorFunc TraefikBackend = Prefix + SuffixBackend
TraefikBackendBuffering = Prefix + SuffixBackendBuffering TraefikBackendID = Prefix + SuffixBackendID
TraefikBackendBufferingMaxRequestBodyBytes = Prefix + SuffixBackendBufferingMaxRequestBodyBytes TraefikBackendCircuitBreaker = Prefix + SuffixBackendCircuitBreaker
TraefikBackendBufferingMemRequestBodyBytes = Prefix + SuffixBackendBufferingMemRequestBodyBytes TraefikBackendCircuitBreakerExpression = Prefix + SuffixBackendCircuitBreakerExpression
TraefikBackendBufferingMaxResponseBodyBytes = Prefix + SuffixBackendBufferingMaxResponseBodyBytes TraefikBackendHealthCheckScheme = Prefix + SuffixBackendHealthCheckScheme
TraefikBackendBufferingMemResponseBodyBytes = Prefix + SuffixBackendBufferingMemResponseBodyBytes TraefikBackendHealthCheckPath = Prefix + SuffixBackendHealthCheckPath
TraefikBackendBufferingRetryExpression = Prefix + SuffixBackendBufferingRetryExpression TraefikBackendHealthCheckPort = Prefix + SuffixBackendHealthCheckPort
TraefikFrontend = Prefix + SuffixFrontend TraefikBackendHealthCheckInterval = Prefix + SuffixBackendHealthCheckInterval
TraefikFrontendAuthBasic = Prefix + SuffixFrontendAuthBasic TraefikBackendHealthCheckHostname = Prefix + SuffixBackendHealthCheckHostname
TraefikFrontendEntryPoints = Prefix + SuffixFrontendEntryPoints TraefikBackendHealthCheckHeaders = Prefix + SuffixBackendHealthCheckHeaders
TraefikFrontendPassHostHeader = Prefix + SuffixFrontendPassHostHeader TraefikBackendLoadBalancer = Prefix + SuffixBackendLoadBalancer
TraefikFrontendPassTLSCert = Prefix + SuffixFrontendPassTLSCert TraefikBackendLoadBalancerMethod = Prefix + SuffixBackendLoadBalancerMethod
TraefikFrontendPriority = Prefix + SuffixFrontendPriority TraefikBackendLoadBalancerSticky = Prefix + SuffixBackendLoadBalancerSticky
TraefikFrontendRateLimitExtractorFunc = Prefix + SuffixFrontendRateLimitExtractorFunc TraefikBackendLoadBalancerStickiness = Prefix + SuffixBackendLoadBalancerStickiness
TraefikFrontendRedirectEntryPoint = Prefix + SuffixFrontendRedirectEntryPoint TraefikBackendLoadBalancerStickinessCookieName = Prefix + SuffixBackendLoadBalancerStickinessCookieName
TraefikFrontendRedirectRegex = Prefix + SuffixFrontendRedirectRegex TraefikBackendMaxConnAmount = Prefix + SuffixBackendMaxConnAmount
TraefikFrontendRedirectReplacement = Prefix + SuffixFrontendRedirectReplacement TraefikBackendMaxConnExtractorFunc = Prefix + SuffixBackendMaxConnExtractorFunc
TraefikFrontendRedirectPermanent = Prefix + SuffixFrontendRedirectPermanent TraefikBackendBuffering = Prefix + SuffixBackendBuffering
TraefikFrontendRule = Prefix + SuffixFrontendRule TraefikBackendBufferingMaxRequestBodyBytes = Prefix + SuffixBackendBufferingMaxRequestBodyBytes
TraefikFrontendWhitelistSourceRange = Prefix + SuffixFrontendWhitelistSourceRange // Deprecated TraefikBackendBufferingMemRequestBodyBytes = Prefix + SuffixBackendBufferingMemRequestBodyBytes
TraefikFrontendWhiteListSourceRange = Prefix + SuffixFrontendWhiteListSourceRange TraefikBackendBufferingMaxResponseBodyBytes = Prefix + SuffixBackendBufferingMaxResponseBodyBytes
TraefikFrontendWhiteListUseXForwardedFor = Prefix + SuffixFrontendWhiteListUseXForwardedFor TraefikBackendBufferingMemResponseBodyBytes = Prefix + SuffixBackendBufferingMemResponseBodyBytes
TraefikFrontendRequestHeaders = Prefix + SuffixFrontendRequestHeaders TraefikBackendBufferingRetryExpression = Prefix + SuffixBackendBufferingRetryExpression
TraefikFrontendResponseHeaders = Prefix + SuffixFrontendResponseHeaders TraefikFrontend = Prefix + SuffixFrontend
TraefikFrontendAllowedHosts = Prefix + SuffixFrontendHeadersAllowedHosts TraefikFrontendAuth = Prefix + SuffixFrontendAuth
TraefikFrontendHostsProxyHeaders = Prefix + SuffixFrontendHeadersHostsProxyHeaders TraefikFrontendAuthBasic = Prefix + SuffixFrontendAuthBasic
TraefikFrontendSSLForceHost = Prefix + SuffixFrontendHeadersSSLForceHost TraefikFrontendAuthBasicUsers = Prefix + SuffixFrontendAuthBasicUsers
TraefikFrontendSSLRedirect = Prefix + SuffixFrontendHeadersSSLRedirect TraefikFrontendAuthBasicUsersFile = Prefix + SuffixFrontendAuthBasicUsersFile
TraefikFrontendSSLTemporaryRedirect = Prefix + SuffixFrontendHeadersSSLTemporaryRedirect TraefikFrontendAuthDigest = Prefix + SuffixFrontendAuthDigest
TraefikFrontendSSLHost = Prefix + SuffixFrontendHeadersSSLHost TraefikFrontendAuthDigestUsers = Prefix + SuffixFrontendAuthDigestUsers
TraefikFrontendSSLProxyHeaders = Prefix + SuffixFrontendHeadersSSLProxyHeaders TraefikFrontendAuthDigestUsersFile = Prefix + SuffixFrontendAuthDigestUsersFile
TraefikFrontendSTSSeconds = Prefix + SuffixFrontendHeadersSTSSeconds TraefikFrontendAuthForward = Prefix + SuffixFrontendAuthForward
TraefikFrontendSTSIncludeSubdomains = Prefix + SuffixFrontendHeadersSTSIncludeSubdomains TraefikFrontendAuthForwardAddress = Prefix + SuffixFrontendAuthForwardAddress
TraefikFrontendSTSPreload = Prefix + SuffixFrontendHeadersSTSPreload TraefikFrontendAuthForwardTLS = Prefix + SuffixFrontendAuthForwardTLS
TraefikFrontendForceSTSHeader = Prefix + SuffixFrontendHeadersForceSTSHeader TraefikFrontendAuthForwardTLSCa = Prefix + SuffixFrontendAuthForwardTLSCa
TraefikFrontendFrameDeny = Prefix + SuffixFrontendHeadersFrameDeny TraefikFrontendAuthForwardTLSCaOptional = Prefix + SuffixFrontendAuthForwardTLSCaOptional
TraefikFrontendCustomFrameOptionsValue = Prefix + SuffixFrontendHeadersCustomFrameOptionsValue TraefikFrontendAuthForwardTLSCert = Prefix + SuffixFrontendAuthForwardTLSCert
TraefikFrontendContentTypeNosniff = Prefix + SuffixFrontendHeadersContentTypeNosniff TraefikFrontendAuthForwardTLSInsecureSkipVerify = Prefix + SuffixFrontendAuthForwardTLSInsecureSkipVerify
TraefikFrontendBrowserXSSFilter = Prefix + SuffixFrontendHeadersBrowserXSSFilter TraefikFrontendAuthForwardTLSKey = Prefix + SuffixFrontendAuthForwardTLSKey
TraefikFrontendCustomBrowserXSSValue = Prefix + SuffixFrontendHeadersCustomBrowserXSSValue TraefikFrontendAuthForwardTrustForwardHeader = Prefix + SuffixFrontendAuthForwardTrustForwardHeader
TraefikFrontendContentSecurityPolicy = Prefix + SuffixFrontendHeadersContentSecurityPolicy TraefikFrontendAuthHeaderField = Prefix + SuffixFrontendAuthHeaderField
TraefikFrontendPublicKey = Prefix + SuffixFrontendHeadersPublicKey TraefikFrontendEntryPoints = Prefix + SuffixFrontendEntryPoints
TraefikFrontendReferrerPolicy = Prefix + SuffixFrontendHeadersReferrerPolicy TraefikFrontendPassHostHeader = Prefix + SuffixFrontendPassHostHeader
TraefikFrontendIsDevelopment = Prefix + SuffixFrontendHeadersIsDevelopment TraefikFrontendPassTLSCert = Prefix + SuffixFrontendPassTLSCert
BaseFrontendErrorPage = "frontend.errors." TraefikFrontendPriority = Prefix + SuffixFrontendPriority
SuffixErrorPageBackend = "backend" TraefikFrontendRateLimitExtractorFunc = Prefix + SuffixFrontendRateLimitExtractorFunc
SuffixErrorPageQuery = "query" TraefikFrontendRedirectEntryPoint = Prefix + SuffixFrontendRedirectEntryPoint
SuffixErrorPageStatus = "status" TraefikFrontendRedirectRegex = Prefix + SuffixFrontendRedirectRegex
BaseFrontendRateLimit = "frontend.rateLimit.rateSet." TraefikFrontendRedirectReplacement = Prefix + SuffixFrontendRedirectReplacement
SuffixRateLimitPeriod = "period" TraefikFrontendRedirectPermanent = Prefix + SuffixFrontendRedirectPermanent
SuffixRateLimitAverage = "average" TraefikFrontendRule = Prefix + SuffixFrontendRule
SuffixRateLimitBurst = "burst" TraefikFrontendWhitelistSourceRange = Prefix + SuffixFrontendWhitelistSourceRange // Deprecated
TraefikFrontendWhiteListSourceRange = Prefix + SuffixFrontendWhiteListSourceRange
TraefikFrontendWhiteListUseXForwardedFor = Prefix + SuffixFrontendWhiteListUseXForwardedFor
TraefikFrontendRequestHeaders = Prefix + SuffixFrontendRequestHeaders
TraefikFrontendResponseHeaders = Prefix + SuffixFrontendResponseHeaders
TraefikFrontendAllowedHosts = Prefix + SuffixFrontendHeadersAllowedHosts
TraefikFrontendHostsProxyHeaders = Prefix + SuffixFrontendHeadersHostsProxyHeaders
TraefikFrontendSSLForceHost = Prefix + SuffixFrontendHeadersSSLForceHost
TraefikFrontendSSLRedirect = Prefix + SuffixFrontendHeadersSSLRedirect
TraefikFrontendSSLTemporaryRedirect = Prefix + SuffixFrontendHeadersSSLTemporaryRedirect
TraefikFrontendSSLHost = Prefix + SuffixFrontendHeadersSSLHost
TraefikFrontendSSLProxyHeaders = Prefix + SuffixFrontendHeadersSSLProxyHeaders
TraefikFrontendSTSSeconds = Prefix + SuffixFrontendHeadersSTSSeconds
TraefikFrontendSTSIncludeSubdomains = Prefix + SuffixFrontendHeadersSTSIncludeSubdomains
TraefikFrontendSTSPreload = Prefix + SuffixFrontendHeadersSTSPreload
TraefikFrontendForceSTSHeader = Prefix + SuffixFrontendHeadersForceSTSHeader
TraefikFrontendFrameDeny = Prefix + SuffixFrontendHeadersFrameDeny
TraefikFrontendCustomFrameOptionsValue = Prefix + SuffixFrontendHeadersCustomFrameOptionsValue
TraefikFrontendContentTypeNosniff = Prefix + SuffixFrontendHeadersContentTypeNosniff
TraefikFrontendBrowserXSSFilter = Prefix + SuffixFrontendHeadersBrowserXSSFilter
TraefikFrontendCustomBrowserXSSValue = Prefix + SuffixFrontendHeadersCustomBrowserXSSValue
TraefikFrontendContentSecurityPolicy = Prefix + SuffixFrontendHeadersContentSecurityPolicy
TraefikFrontendPublicKey = Prefix + SuffixFrontendHeadersPublicKey
TraefikFrontendReferrerPolicy = Prefix + SuffixFrontendHeadersReferrerPolicy
TraefikFrontendIsDevelopment = Prefix + SuffixFrontendHeadersIsDevelopment
BaseFrontendErrorPage = "frontend.errors."
SuffixErrorPageBackend = "backend"
SuffixErrorPageQuery = "query"
SuffixErrorPageStatus = "status"
BaseFrontendRateLimit = "frontend.rateLimit.rateSet."
SuffixRateLimitPeriod = "period"
SuffixRateLimitAverage = "average"
SuffixRateLimitBurst = "burst"
) )

View file

@ -60,6 +60,73 @@ func GetRedirect(labels map[string]string) *types.Redirect {
return nil return nil
} }
// GetAuth Create auth from labels
func GetAuth(labels map[string]string) *types.Auth {
if !HasPrefix(labels, TraefikFrontendAuth) {
return nil
}
auth := &types.Auth{
HeaderField: GetStringValue(labels, TraefikFrontendAuthHeaderField, ""),
}
if HasPrefix(labels, TraefikFrontendAuthBasic) {
auth.Basic = getAuthBasic(labels)
} else if HasPrefix(labels, TraefikFrontendAuthDigest) {
auth.Digest = getAuthDigest(labels)
} else if HasPrefix(labels, TraefikFrontendAuthForward) {
auth.Forward = getAuthForward(labels)
}
return auth
}
// getAuthBasic Create Basic Auth from labels
func getAuthBasic(labels map[string]string) *types.Basic {
basicAuth := &types.Basic{
UsersFile: GetStringValue(labels, TraefikFrontendAuthBasicUsersFile, ""),
}
// backward compatibility
if Has(labels, TraefikFrontendAuthBasic) {
basicAuth.Users = GetSliceStringValue(labels, TraefikFrontendAuthBasic)
log.Warnf("Deprecated configuration found: %s. Please use %s.", TraefikFrontendAuthBasic, TraefikFrontendAuthBasicUsers)
} else {
basicAuth.Users = GetSliceStringValue(labels, TraefikFrontendAuthBasicUsers)
}
return basicAuth
}
// getAuthDigest Create Digest Auth from labels
func getAuthDigest(labels map[string]string) *types.Digest {
return &types.Digest{
Users: GetSliceStringValue(labels, TraefikFrontendAuthDigestUsers),
UsersFile: GetStringValue(labels, TraefikFrontendAuthDigestUsersFile, ""),
}
}
// getAuthForward Create Forward Auth from labels
func getAuthForward(labels map[string]string) *types.Forward {
forwardAuth := &types.Forward{
Address: GetStringValue(labels, TraefikFrontendAuthForwardAddress, ""),
TrustForwardHeader: GetBoolValue(labels, TraefikFrontendAuthForwardTrustForwardHeader, false),
}
// TLS configuration
if HasPrefix(labels, TraefikFrontendAuthForwardTLS) {
forwardAuth.TLS = &types.ClientTLS{
CA: GetStringValue(labels, TraefikFrontendAuthForwardTLSCa, ""),
CAOptional: GetBoolValue(labels, TraefikFrontendAuthForwardTLSCaOptional, false),
Cert: GetStringValue(labels, TraefikFrontendAuthForwardTLSCert, ""),
InsecureSkipVerify: GetBoolValue(labels, TraefikFrontendAuthForwardTLSInsecureSkipVerify, false),
Key: GetStringValue(labels, TraefikFrontendAuthForwardTLSKey, ""),
}
}
return forwardAuth
}
// GetErrorPages Create error pages from labels // GetErrorPages Create error pages from labels
func GetErrorPages(labels map[string]string) map[string]*types.ErrorPage { func GetErrorPages(labels map[string]string) map[string]*types.ErrorPage {
prefix := Prefix + BaseFrontendErrorPage prefix := Prefix + BaseFrontendErrorPage

View file

@ -720,3 +720,79 @@ func TestProviderGetErrorPages(t *testing.T) {
}) })
} }
} }
func TestGetAuth(t *testing.T) {
testCases := []struct {
desc string
labels map[string]string
expected *types.Auth
}{
{
desc: "should return nil when no tags",
labels: map[string]string{},
expected: nil,
},
{
desc: "should return a basic auth",
labels: map[string]string{
TraefikFrontendAuthHeaderField: "myHeaderField",
TraefikFrontendAuthBasicUsers: "user:pwd,user2:pwd2",
TraefikFrontendAuthBasicUsersFile: "myUsersFile",
},
expected: &types.Auth{
HeaderField: "myHeaderField",
Basic: &types.Basic{UsersFile: "myUsersFile", Users: []string{"user:pwd", "user2:pwd2"}},
},
},
{
desc: "should return a digest auth",
labels: map[string]string{
TraefikFrontendAuthHeaderField: "myHeaderField",
TraefikFrontendAuthDigestUsers: "user:pwd,user2:pwd2",
TraefikFrontendAuthDigestUsersFile: "myUsersFile",
},
expected: &types.Auth{
HeaderField: "myHeaderField",
Digest: &types.Digest{UsersFile: "myUsersFile", Users: []string{"user:pwd", "user2:pwd2"}},
},
},
{
desc: "should return a forward auth",
labels: map[string]string{
TraefikFrontendAuthHeaderField: "myHeaderField",
TraefikFrontendAuthForwardAddress: "myAddress",
TraefikFrontendAuthForwardTrustForwardHeader: "true",
TraefikFrontendAuthForwardTLSCa: "ca.crt",
TraefikFrontendAuthForwardTLSCaOptional: "true",
TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
TraefikFrontendAuthForwardTLSKey: "myKey",
TraefikFrontendAuthForwardTLSCert: "myCert",
},
expected: &types.Auth{
HeaderField: "myHeaderField",
Forward: &types.Forward{
TrustForwardHeader: true,
Address: "myAddress",
TLS: &types.ClientTLS{
InsecureSkipVerify: true,
CA: "ca.crt",
CAOptional: true,
Key: "myKey",
Cert: "myCert",
},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
result := GetAuth(test.labels)
assert.Equal(t, test.expected, result)
})
}
}

View file

@ -48,7 +48,8 @@ func (p *Provider) buildConfigurationV2(applications *marathon.Applications) *ty
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority), "getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
"getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints),
"getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated
"getAuth": label.GetAuth,
"getRedirect": label.GetRedirect, "getRedirect": label.GetRedirect,
"getErrorPages": label.GetErrorPages, "getErrorPages": label.GetErrorPages,
"getRateLimit": label.GetRateLimit, "getRateLimit": label.GetRateLimit,

View file

@ -51,7 +51,6 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
}, },
@ -84,7 +83,6 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
}, },
@ -110,7 +108,6 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
}, },
@ -143,7 +140,6 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
}, },
@ -158,6 +154,188 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "with basic auth",
applications: withApplications(
application(
appID("/app"),
appPorts(80),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
withLabel(label.TraefikFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthBasicUsersFile, ".htpasswd"),
withTasks(localhostTask(taskPorts(80))),
)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
Routes: map[string]types.Route{
"route-host-app": {
Rule: "Host:app.marathon.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
PassHostHeader: true,
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-app": {
Servers: map[string]types.Server{
"server-app-taskID": {
URL: "http://localhost:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "with basic auth with backward compatibility",
applications: withApplications(
application(
appID("/app"),
appPorts(80),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withTasks(localhostTask(taskPorts(80))),
)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
Routes: map[string]types.Route{
"route-host-app": {
Rule: "Host:app.marathon.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
PassHostHeader: true,
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-app": {
Servers: map[string]types.Server{
"server-app-taskID": {
URL: "http://localhost:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "with digest auth",
applications: withApplications(
application(
appID("/app"),
appPorts(80),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
withLabel(label.TraefikFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthDigestUsersFile, ".htpasswd"),
withTasks(localhostTask(taskPorts(80))),
)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
Routes: map[string]types.Route{
"route-host-app": {
Rule: "Host:app.marathon.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
PassHostHeader: true,
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-app": {
Servers: map[string]types.Server{
"server-app-taskID": {
URL: "http://localhost:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "with forward auth",
applications: withApplications(
application(
appID("/app"),
appPorts(80),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
withLabel(label.TraefikFrontendAuthForwardAddress, "auth.server"),
withLabel(label.TraefikFrontendAuthForwardTrustForwardHeader, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCa, "ca.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSCaOptional, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCert, "server.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSKey, "server.key"),
withLabel(label.TraefikFrontendAuthForwardTLSInsecureSkipVerify, "true"),
withTasks(localhostTask(taskPorts(80))),
)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
Routes: map[string]types.Route{
"route-host-app": {
Rule: "Host:app.marathon.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
PassHostHeader: true,
EntryPoints: []string{},
},
},
expectedBackends: map[string]*types.Backend{
"backend-app": {
Servers: map[string]types.Server{
"server-app-taskID": {
URL: "http://localhost:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{ {
desc: "with all labels", desc: "with all labels",
applications: withApplications( applications: withApplications(
@ -193,6 +371,19 @@ func TestBuildConfiguration(t *testing.T) {
withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"), withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"),
withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthBasicUsersFile, ".htpasswd"),
withLabel(label.TraefikFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthDigestUsersFile, ".htpasswd"),
withLabel(label.TraefikFrontendAuthForwardAddress, "auth.server"),
withLabel(label.TraefikFrontendAuthForwardTrustForwardHeader, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCa, "ca.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSCaOptional, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCert, "server.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSKey, "server.key"),
withLabel(label.TraefikFrontendAuthForwardTLSInsecureSkipVerify, "true"),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
withLabel(label.TraefikFrontendEntryPoints, "http,https"), withLabel(label.TraefikFrontendEntryPoints, "http,https"),
withLabel(label.TraefikFrontendPassHostHeader, "true"), withLabel(label.TraefikFrontendPassHostHeader, "true"),
withLabel(label.TraefikFrontendPassTLSCert, "true"), withLabel(label.TraefikFrontendPassTLSCert, "true"),
@ -258,9 +449,13 @@ func TestBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},
@ -424,7 +619,6 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
}, },
}, },
expectedBackends: map[string]*types.Backend{ expectedBackends: map[string]*types.Backend{
@ -495,7 +689,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
"frontend-app-service-admin": { "frontend-app-service-admin": {
@ -506,7 +699,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
}, },
@ -633,9 +825,11 @@ func TestBuildConfigurationSegments(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", Basic: &types.Basic{
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},

View file

@ -43,7 +43,8 @@ func (p *Provider) buildConfigurationV2(tasks []state.Task) *types.Configuration
"getSegmentNameSuffix": getSegmentNameSuffix, "getSegmentNameSuffix": getSegmentNameSuffix,
"getFrontEndName": getFrontendName, "getFrontEndName": getFrontendName,
"getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints),
"getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated
"getAuth": label.GetAuth,
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority), "getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),

View file

@ -65,7 +65,6 @@ func TestBuildConfiguration(t *testing.T) {
"frontend-ID1": { "frontend-ID1": {
Backend: "backend-name1", Backend: "backend-name1",
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
PassHostHeader: true, PassHostHeader: true,
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-host-ID1": { "route-host-ID1": {
@ -76,7 +75,6 @@ func TestBuildConfiguration(t *testing.T) {
"frontend-ID3": { "frontend-ID3": {
Backend: "backend-name2", Backend: "backend-name2",
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{},
PassHostHeader: true, PassHostHeader: true,
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-host-ID3": { "route-host-ID3": {
@ -112,6 +110,193 @@ func TestBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "With basic auth",
tasks: []state.Task{
// App 1
aTask("ID1",
withIP("10.10.10.10"),
withInfo("name1",
withPorts(withPort("TCP", 80, "WEB"))),
withStatus(withHealthy(true), withState("TASK_RUNNING")),
withLabel(label.TraefikFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthBasicUsersFile, ".htpasswd"),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-ID1": {
Backend: "backend-name1",
EntryPoints: []string{},
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-ID1": {
Rule: "Host:name1.mesos.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-name1": {
Servers: map[string]types.Server{
"server-ID1": {
URL: "http://10.10.10.10:80",
Weight: label.DefaultWeight,
},
},
},
},
},
{
desc: "With basic auth (backward compatibility)",
tasks: []state.Task{
// App 1
aTask("ID1",
withIP("10.10.10.10"),
withInfo("name1",
withPorts(withPort("TCP", 80, "WEB"))),
withStatus(withHealthy(true), withState("TASK_RUNNING")),
withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-ID1": {
Backend: "backend-name1",
EntryPoints: []string{},
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-ID1": {
Rule: "Host:name1.mesos.localhost",
},
},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-name1": {
Servers: map[string]types.Server{
"server-ID1": {
URL: "http://10.10.10.10:80",
Weight: label.DefaultWeight,
},
},
},
},
},
{
desc: "With digest auth",
tasks: []state.Task{
// App 1
aTask("ID1",
withIP("10.10.10.10"),
withInfo("name1",
withPorts(withPort("TCP", 80, "WEB"))),
withStatus(withHealthy(true), withState("TASK_RUNNING")),
withLabel(label.TraefikFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthDigestUsersFile, ".htpasswd"),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-ID1": {
Backend: "backend-name1",
EntryPoints: []string{},
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-ID1": {
Rule: "Host:name1.mesos.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-name1": {
Servers: map[string]types.Server{
"server-ID1": {
URL: "http://10.10.10.10:80",
Weight: label.DefaultWeight,
},
},
},
},
},
{
desc: "With Forward auth",
tasks: []state.Task{
// App 1
aTask("ID1",
withIP("10.10.10.10"),
withInfo("name1",
withPorts(withPort("TCP", 80, "WEB"))),
withStatus(withHealthy(true), withState("TASK_RUNNING")),
withLabel(label.TraefikFrontendAuthForwardAddress, "auth.server"),
withLabel(label.TraefikFrontendAuthForwardTrustForwardHeader, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCa, "ca.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSCaOptional, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCert, "server.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSKey, "server.key"),
withLabel(label.TraefikFrontendAuthForwardTLSInsecureSkipVerify, "true"),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-ID1": {
Backend: "backend-name1",
EntryPoints: []string{},
PassHostHeader: true,
Routes: map[string]types.Route{
"route-host-ID1": {
Rule: "Host:name1.mesos.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-name1": {
Servers: map[string]types.Server{
"server-ID1": {
URL: "http://10.10.10.10:80",
Weight: label.DefaultWeight,
},
},
},
},
},
{ {
desc: "with all labels", desc: "with all labels",
tasks: []state.Task{ tasks: []state.Task{
@ -142,6 +327,19 @@ func TestBuildConfiguration(t *testing.T) {
withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"), withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"),
withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthBasicUsersFile, ".htpasswd"),
withLabel(label.TraefikFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel(label.TraefikFrontendAuthDigestUsersFile, ".htpasswd"),
withLabel(label.TraefikFrontendAuthForwardAddress, "auth.server"),
withLabel(label.TraefikFrontendAuthForwardTrustForwardHeader, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCa, "ca.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSCaOptional, "true"),
withLabel(label.TraefikFrontendAuthForwardTLSCert, "server.crt"),
withLabel(label.TraefikFrontendAuthForwardTLSKey, "server.key"),
withLabel(label.TraefikFrontendAuthForwardTLSInsecureSkipVerify, "true"),
withLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User"),
withLabel(label.TraefikFrontendEntryPoints, "http,https"), withLabel(label.TraefikFrontendEntryPoints, "http,https"),
withLabel(label.TraefikFrontendPassHostHeader, "true"), withLabel(label.TraefikFrontendPassHostHeader, "true"),
withLabel(label.TraefikFrontendPassTLSCert, "true"), withLabel(label.TraefikFrontendPassTLSCert, "true"),
@ -213,9 +411,13 @@ func TestBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},
@ -398,7 +600,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
"frontend-app-taskID-service-admin": { "frontend-app-taskID-service-admin": {
@ -409,7 +610,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
}, },
}, },
PassHostHeader: true, PassHostHeader: true,
BasicAuth: []string{},
EntryPoints: []string{}, EntryPoints: []string{},
}, },
}, },
@ -478,6 +678,19 @@ func TestBuildConfigurationSegments(t *testing.T) {
withSegmentLabel(label.TraefikWeight, "12", "containous"), withSegmentLabel(label.TraefikWeight, "12", "containous"),
withSegmentLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", "containous"), withSegmentLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", "containous"),
withSegmentLabel(label.TraefikFrontendAuthBasicUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", "containous"),
withSegmentLabel(label.TraefikFrontendAuthBasicUsersFile, ".htpasswd", "containous"),
withSegmentLabel(label.TraefikFrontendAuthDigestUsers, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", "containous"),
withSegmentLabel(label.TraefikFrontendAuthDigestUsersFile, ".htpasswd", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardAddress, "auth.server", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardTrustForwardHeader, "true", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardTLSCa, "ca.crt", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardTLSCaOptional, "true", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardTLSCert, "server.crt", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardTLSKey, "server.key", "containous"),
withSegmentLabel(label.TraefikFrontendAuthForwardTLSInsecureSkipVerify, "true", "containous"),
withSegmentLabel(label.TraefikFrontendAuthHeaderField, "X-WebAuth-User", "containous"),
withSegmentLabel(label.TraefikFrontendEntryPoints, "http,https", "containous"), withSegmentLabel(label.TraefikFrontendEntryPoints, "http,https", "containous"),
withSegmentLabel(label.TraefikFrontendPassHostHeader, "true", "containous"), withSegmentLabel(label.TraefikFrontendPassHostHeader, "true", "containous"),
withSegmentLabel(label.TraefikFrontendPassTLSCert, "true", "containous"), withSegmentLabel(label.TraefikFrontendPassTLSCert, "true", "containous"),
@ -544,10 +757,15 @@ func TestBuildConfigurationSegments(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"}, SourceRange: []string{"10.10.10.10"},
UseXForwardedFor: true, UseXForwardedFor: true,

View file

@ -34,7 +34,8 @@ func (p *Provider) buildConfigurationV2(services []rancherData) *types.Configura
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
"getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints),
"getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated
"getAuth": label.GetAuth,
"getErrorPages": label.GetErrorPages, "getErrorPages": label.GetErrorPages,
"getRateLimit": label.GetRateLimit, "getRateLimit": label.GetRateLimit,
"getRedirect": label.GetRedirect, "getRedirect": label.GetRedirect,

View file

@ -59,7 +59,20 @@ func TestProviderBuildConfiguration(t *testing.T) {
label.TraefikBackendBufferingMemRequestBodyBytes: "2097152", label.TraefikBackendBufferingMemRequestBodyBytes: "2097152",
label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2", label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2",
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile: ".htpasswd",
label.TraefikFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile: ".htpasswd",
label.TraefikFrontendAuthForwardAddress: "auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader: "true",
label.TraefikFrontendAuthForwardTLSCa: "ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional: "true",
label.TraefikFrontendAuthForwardTLSCert: "server.crt",
label.TraefikFrontendAuthForwardTLSKey: "server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.TraefikFrontendAuthHeaderField: "X-WebAuth-User",
label.TraefikFrontendEntryPoints: "http,https", label.TraefikFrontendEntryPoints: "http,https",
label.TraefikFrontendPassHostHeader: "true", label.TraefikFrontendPassHostHeader: "true",
label.TraefikFrontendPassTLSCert: "true", label.TraefikFrontendPassTLSCert: "true",
@ -129,9 +142,13 @@ func TestProviderBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{ SourceRange: []string{
@ -271,8 +288,20 @@ func TestProviderBuildConfiguration(t *testing.T) {
label.Prefix + "sauternes." + label.SuffixProtocol: "https", label.Prefix + "sauternes." + label.SuffixProtocol: "https",
label.Prefix + "sauternes." + label.SuffixWeight: "12", label.Prefix + "sauternes." + label.SuffixWeight: "12",
label.Prefix + "sauternes." + label.SuffixFrontendRule: "Host:traefik.wtf", label.Prefix + "sauternes." + label.SuffixFrontendRule: "Host:traefik.wtf",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardAddress: "auth.server",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTrustForwardHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCa: "ca.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCaOptional: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCert: "server.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSKey: "server.key",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https", label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true", label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendPassTLSCert: "true", label.Prefix + "sauternes." + label.SuffixFrontendPassTLSCert: "true",
@ -338,9 +367,13 @@ func TestProviderBuildConfiguration(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
PassTLSCert: true, PassTLSCert: true,
Priority: 666, Priority: 666,
BasicAuth: []string{ Auth: &types.Auth{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", HeaderField: "X-WebAuth-User",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
}, },
WhiteList: &types.WhiteList{ WhiteList: &types.WhiteList{
SourceRange: []string{ SourceRange: []string{
@ -438,7 +471,8 @@ func TestProviderBuildConfiguration(t *testing.T) {
Name: "test/service", Name: "test/service",
Labels: map[string]string{ Labels: map[string]string{
label.TraefikPort: "80", label.TraefikPort: "80",
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", label.TraefikFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthBasicUsersFile: ".htpasswd",
label.TraefikFrontendRedirectEntryPoint: "https", label.TraefikFrontendRedirectEntryPoint: "https",
}, },
Health: "healthy", Health: "healthy",
@ -450,8 +484,14 @@ func TestProviderBuildConfiguration(t *testing.T) {
Backend: "backend-test-service", Backend: "backend-test-service",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, Auth: &types.Auth{
Priority: 0, Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Priority: 0,
Redirect: &types.Redirect{ Redirect: &types.Redirect{
EntryPoint: "https", EntryPoint: "https",
}, },
@ -474,6 +514,155 @@ func TestProviderBuildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "with basic auth backward compatibility",
services: []rancherData{
{
Name: "test/service",
Labels: map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
},
Health: "healthy",
Containers: []string{"127.0.0.1"},
},
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-service-rancher-localhost": {
Backend: "backend-test-service",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
Priority: 0,
Routes: map[string]types.Route{
"route-frontend-Host-test-service-rancher-localhost": {
Rule: "Host:test.service.rancher.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test-service": {
Servers: map[string]types.Server{
"server-0": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "with digest auth",
services: []rancherData{
{
Name: "test/service",
Labels: map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.TraefikFrontendAuthDigestUsersFile: ".htpasswd",
},
Health: "healthy",
Containers: []string{"127.0.0.1"},
},
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-service-rancher-localhost": {
Backend: "backend-test-service",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
Digest: &types.Digest{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
Priority: 0,
Routes: map[string]types.Route{
"route-frontend-Host-test-service-rancher-localhost": {
Rule: "Host:test.service.rancher.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test-service": {
Servers: map[string]types.Server{
"server-0": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "with forward auth",
services: []rancherData{
{
Name: "test/service",
Labels: map[string]string{
label.TraefikPort: "80",
label.TraefikFrontendAuthForwardAddress: "auth.server",
label.TraefikFrontendAuthForwardTrustForwardHeader: "true",
label.TraefikFrontendAuthForwardTLSCa: "ca.crt",
label.TraefikFrontendAuthForwardTLSCaOptional: "true",
label.TraefikFrontendAuthForwardTLSCert: "server.crt",
label.TraefikFrontendAuthForwardTLSKey: "server.key",
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.TraefikFrontendAuthHeaderField: "X-WebAuth-User",
},
Health: "healthy",
Containers: []string{"127.0.0.1"},
},
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-service-rancher-localhost": {
Backend: "backend-test-service",
PassHostHeader: true,
EntryPoints: []string{},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
InsecureSkipVerify: true,
Cert: "server.crt",
Key: "server.key",
},
},
},
Priority: 0,
Routes: map[string]types.Route{
"route-frontend-Host-test-service-rancher-localhost": {
Rule: "Host:test.service.rancher.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test-service": {
Servers: map[string]types.Server{
"server-0": {
URL: "http://127.0.0.1:80",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
} }
for _, test := range testCases { for _, test := range testCases {

View file

@ -74,9 +74,47 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $service.TraefikLabels }} {{ $auth := getAuth $service.TraefikLabels }}
"{{.}}",
{{end}}] {{if $auth }}
[frontends."frontend-{{ $service.ServiceName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $service.ServiceName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $service.ServiceName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $service.ServiceName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $service.ServiceName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $service.TraefikLabels }} {{ $whitelist := getWhiteList $service.TraefikLabels }}
{{if $whitelist }} {{if $whitelist }}

View file

@ -75,9 +75,46 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $container.SegmentLabels }} {{ $auth := getAuth $container.SegmentLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $container.SegmentLabels }} {{ $whitelist := getWhiteList $container.SegmentLabels }}
{{if $whitelist }} {{if $whitelist }}

View file

@ -74,9 +74,46 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $instance.TraefikLabels }} {{ $auth := getAuth $instance.TraefikLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $serviceName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $serviceName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $serviceName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $serviceName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $serviceName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $instance.TraefikLabels }} {{ $whitelist := getWhiteList $instance.TraefikLabels }}
{{if $whitelist }} {{if $whitelist }}

View file

@ -52,10 +52,6 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range $frontend.BasicAuth }}
"{{.}}",
{{end}}]
{{if $frontend.Auth }} {{if $frontend.Auth }}
[frontends."{{ $frontendName }}".auth] [frontends."{{ $frontendName }}".auth]
headerField = "X-WebAuth-User" headerField = "X-WebAuth-User"

View file

@ -74,9 +74,46 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $frontend }} {{ $auth := getAuth $frontend }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $frontend }} {{ $whitelist := getWhiteList $frontend }}
{{if $whitelist }} {{if $whitelist }}

View file

@ -77,9 +77,46 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $app.SegmentLabels }} {{ $auth := getAuth $app.SegmentLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $app.SegmentLabels }} {{ $whitelist := getWhiteList $app.SegmentLabels }}
{{if $whitelist }} {{if $whitelist }}

View file

@ -77,10 +77,47 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $app.TraefikLabels }} {{ $auth := getAuth $app.TraefikLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $app.TraefikLabels }} {{ $whitelist := getWhiteList $app.TraefikLabels }}
{{if $whitelist }} {{if $whitelist }}
[frontends."frontend-{{ $frontendName }}".whiteList] [frontends."frontend-{{ $frontendName }}".whiteList]

View file

@ -75,9 +75,46 @@
"{{.}}", "{{.}}",
{{end}}] {{end}}]
basicAuth = [{{range getBasicAuth $service.SegmentLabels }} {{ $auth := getAuth $service.SegmentLabels }}
"{{.}}", {{if $auth }}
{{end}}] [frontends."frontend-{{ $frontendName }}".auth]
headerField = "{{ $auth.HeaderField }}"
{{if $auth.Forward }}
[frontends."frontend-{{ $frontendName }}".auth.forward]
address = "{{ $auth.Forward.Address }}"
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
{{if $auth.Forward.TLS }}
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
ca = "{{ $auth.Forward.TLS.CA }}"
caOptional = {{ $auth.Forward.TLS.CAOptional }}
cert = "{{ $auth.Forward.TLS.Cert }}"
key = "{{ $auth.Forward.TLS.Key }}"
insecureSkipVerify = {{ $auth.Forward.TLS.InsecureSkipVerify }}
{{end}}
{{end}}
{{if $auth.Basic }}
[frontends."frontend-{{ $frontendName }}".auth.basic]
{{if $auth.Basic.Users }}
users = [{{range $auth.Basic.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Basic.UsersFile }}"
{{end}}
{{if $auth.Digest }}
[frontends."frontend-{{ $frontendName }}".auth.digest]
{{if $auth.Digest.Users }}
users = [{{range $auth.Digest.Users }}
"{{.}}",
{{end}}]
{{end}}
usersFile = "{{ $auth.Digest.UsersFile }}"
{{end}}
{{end}}
{{ $whitelist := getWhiteList $service.SegmentLabels }} {{ $whitelist := getWhiteList $service.SegmentLabels }}
{{if $whitelist }} {{if $whitelist }}