diff --git a/autogen/gentemplates/gen.go b/autogen/gentemplates/gen.go index 43c63f861..87647b094 100644 --- a/autogen/gentemplates/gen.go +++ b/autogen/gentemplates/gen.go @@ -209,9 +209,47 @@ var _templatesConsul_catalogTmpl = []byte(`[backends] "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $service.TraefikLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $service.TraefikLabels }} + + {{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 }} {{if $whitelist }} @@ -619,9 +657,46 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}} "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $container.SegmentLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $container.SegmentLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} @@ -880,9 +955,46 @@ var _templatesEcsTmpl = []byte(`[backends] "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $instance.TraefikLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $instance.TraefikLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} @@ -1099,10 +1211,6 @@ var _templatesKubernetesTmpl = []byte(`[backends] "{{.}}", {{end}}] - basicAuth = [{{range $frontend.BasicAuth }} - "{{.}}", - {{end}}] - {{if $frontend.Auth }} [frontends."{{ $frontendName }}".auth] headerField = "X-WebAuth-User" @@ -1336,9 +1444,46 @@ var _templatesKvTmpl = []byte(`[backends] "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $frontend }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $frontend }} + {{if $auth }} + [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 }} {{if $whitelist }} @@ -1639,9 +1784,46 @@ var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }} "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $app.SegmentLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $app.SegmentLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} @@ -1886,10 +2068,47 @@ var _templatesMesosTmpl = []byte(`[backends] "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $app.TraefikLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $app.TraefikLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} [frontends."frontend-{{ $frontendName }}".whiteList] @@ -2186,9 +2405,46 @@ var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }} "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $service.SegmentLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $service.SegmentLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} diff --git a/docs/configuration/backends/consulcatalog.md b/docs/configuration/backends/consulcatalog.md index eb83b0164..7b34e9835 100644 --- a/docs/configuration/backends/consulcatalog.md +++ b/docs/configuration/backends/consulcatalog.md @@ -94,48 +94,60 @@ Additional settings can be defined using Consul Catalog tags. !!! note The default prefix is `traefik`. -| Label | Description | -|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `.enable=false` | Disable this container in Træfik. | -| `.protocol=https` | Override the default `http` protocol. | -| `.weight=10` | Assign this weight to the container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` | -| `.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | -| `.backend.healthcheck.interval=1s` | Define the health check interval. | -| `.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | -| `.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm. | -| `.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions. | -| `.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions. | -| `.backend.loadbalancer.sticky=true` | Enable backend sticky sessions. (DEPRECATED) | -| `.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `.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.
Must be used in conjunction with the above label to take effect. | -| `.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` | -| `.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `.frontend.priority=10` | Override default frontend priority. | -| `.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS). | -| `.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`. | -| `.frontend.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
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. | -| `.frontend.whiteList.useXForwardedFor=true` | Use `X-Forwarded-For` header as valid source of IP for the white list. | +| Label | Description | +|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `.enable=false` | Disables this container in Træfik. | +| `.protocol=https` | Overrides the default `http` protocol. | +| `.weight=10` | Assigns this weight to the container. | +| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | +| `.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` | +| `.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | +| `.backend.healthcheck.interval=1s` | Defines the health check interval. | +| `.backend.healthcheck.port=8080` | Sets a different port for the health check. | +| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | +| `.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | +| `.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | +| `.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm. | +| `.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions. | +| `.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions. | +| `.backend.loadbalancer.sticky=true` | Enables backend sticky sessions. (DEPRECATED) | +| `.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | +| `.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.
Must be used in conjunction with the above label to take effect. | +| `.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | +| `.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | +| `.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. | +| `.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | +| `.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. | +| `.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. | +| `.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | +| `.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | +| `.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | +| `.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. | +| `.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | +| `.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | +| `.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | +| `.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | +| `.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | +| `.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | +| `.frontend.priority=10` | Overrides default frontend priority. | +| `.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS). | +| `.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.replacement`. | +| `.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.regex`. | +| `.frontend.redirect.permanent=true` | Returns 301 instead of 302. | +| `.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`. | +| `.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.
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. | +| `.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. | ### Custom Headers diff --git a/docs/configuration/backends/docker.md b/docs/configuration/backends/docker.md index 436c9c0df..b6092db66 100644 --- a/docs/configuration/backends/docker.md +++ b/docs/configuration/backends/docker.md @@ -207,63 +207,77 @@ services: Labels can be used on containers to override default behavior. -| Label | Description | -|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.docker.network` | Override the default docker network to use for connections to this container. [1] | -| `traefik.domain` | Default domain used for frontend rules. | -| `traefik.enable=false` | Disable this container in Træfik | -| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | -| `traefik.protocol=https` | Override the default `http` protocol | -| `traefik.weight=10` | Assign this weight to the container | -| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create 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.interval=1s` | Define the health check interval. | -| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | -| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | -| `traefik.backend.loadbalancer.swarm=true` | Use Swarm's inbuilt load balancer (only relevant under Swarm Mode). | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
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.
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.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `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.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
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` | Use `X-Forwarded-For` header as valid source of IP for the white list. | +| Label | Description | +|------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.docker.network` | Overrides the default docker network to use for connections to the container. [1] | +| `traefik.domain` | Sets the default domain for the frontend rules. | +| `traefik.enable=false` | Disables this container in Træfik. | +| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. | +| `traefik.protocol=https` | Overrides the default `http` protocol | +| `traefik.weight=10` | Assigns this weight to the container | +| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. | +| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | +| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. | +| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | +| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | +| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | +| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | +| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | +| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions | +| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) | +| `traefik.backend.loadbalancer.swarm=true` | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode). | +| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | +| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2] (DEPRECATED). | +| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2]. | +| `traefik.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | +| `traefik.frontend.auth.digest.usersfile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. | +| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | +| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. | +| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | +| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header user to pass the authenticated user to the application. | +| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | +| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | +| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | +| `traefik.frontend.priority=10` | Overrides default frontend priority | +| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..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.
Must be set with `traefik.frontend.redirect.replacement`. | +| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
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.
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. | [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 `) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. Or if your service references external network use it's name instead. -[2] `traefik.frontend.auth.basic=EXPR`: -To create `user:password` pair, it's possible to use this command `echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g`. +[2] `traefik.frontend.auth.basic.users=EXPR `: +To create `user:password` pair, it's possible to use this command: +`echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g`. The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additional symbol `$` makes escaping. + #### Custom Headers | Label | Description | @@ -304,32 +318,44 @@ You can define as many segments as ports exposed in a container. Segment labels override the default behavior. -| Label | Description | -|---------------------------------------------------------------------------|-------------------------------------------------------------| -| `traefik..backend=BACKEND` | Same as `traefik.backend` | -| `traefik..domain=DOMAIN` | Same as `traefik.domain` | -| `traefik..port=PORT` | Same as `traefik.port` | -| `traefik..protocol=http` | Same as `traefik.protocol` | -| `traefik..weight=10` | Same as `traefik.weight` | -| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | -| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | -| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | -| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | -| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | -| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | -| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | -| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | -| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | -| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | -| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | -| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | -| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | -| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | -| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | -| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | -| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | -| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | -| `traefik..frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | +| Label | Description | +|---------------------------------------------------------------------------|---------------------------------------------------------------| +| `traefik..backend=BACKEND` | Same as `traefik.backend` | +| `traefik..domain=DOMAIN` | Same as `traefik.domain` | +| `traefik..port=PORT` | Same as `traefik.port` | +| `traefik..protocol=http` | Same as `traefik.protocol` | +| `traefik..weight=10` | Same as `traefik.weight` | +| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | +| `traefik..frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` | +| `traefik..frontend.auth.basic.usersfile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersfile` | +| `traefik..frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` | +| `traefik..frontend.auth.digest.usersfile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersfile` | +| `traefik..frontend.auth.forward.address=https://example.com`| Same as `traefik.frontend.auth.forward.address` | +| `traefik..frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` | +| `traefik..frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` | +| `traefik..frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` | +| `traefik..frontend.auth.forward.tls.insecureSkipVerify=true`| Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`| +| `traefik..frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` | +| `traefik..frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` | +| `traefik..frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` | +| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | +| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | +| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | +| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | +| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | +| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | +| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | +| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | +| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | +| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | +| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | +| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | +| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | +| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | +| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | +| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | +| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | +| `traefik..frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | #### Custom Headers diff --git a/docs/configuration/backends/ecs.md b/docs/configuration/backends/ecs.md index 29b3d9248..dbcaec8d4 100644 --- a/docs/configuration/backends/ecs.md +++ b/docs/configuration/backends/ecs.md @@ -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: -| Label | Description | -|------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Default domain used for frontend rules. | -| `traefik.enable=false` | Disable this container in Træfik | -| `traefik.port=80` | Override the default `port` value. Overrides `NetworkBindings` from Docker Container | -| `traefik.protocol=https` | Override the default `http` protocol | -| `traefik.weight=10` | Assign this weight to the container | -| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create 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.interval=1s` | Define the health check interval. (Default: 30s) | -| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | -| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | -| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
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.
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.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{instance_name}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
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` | Use `X-Forwarded-For` header as valid source of IP for the white list. | +| Label | Description | +|------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.domain` | Sets the default domain for frontend rules. | +| `traefik.enable=false` | Disables this container in Træfik. | +| `traefik.port=80` | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container | +| `traefik.protocol=https` | Overrides the default `http` protocol | +| `traefik.weight=10` | Assigns this weight to the container | +| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. | +| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | +| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) | +| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | +| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | +| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | +| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | +| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | +| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions | +| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) | +| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | +| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | +| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | +| `traefik.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | +| `traefik.frontend.auth.digest.usersfile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. | +| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | +| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. | +| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | +| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | +| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | +| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | +| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | +| `traefik.frontend.priority=10` | Overrides default frontend priority | +| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..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.
Must be set with `traefik.frontend.redirect.replacement`. | +| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
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.
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 diff --git a/docs/configuration/backends/kubernetes.md b/docs/configuration/backends/kubernetes.md index 5dc699b4c..e11ca7325 100644 --- a/docs/configuration/backends/kubernetes.md +++ b/docs/configuration/backends/kubernetes.md @@ -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-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-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-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. | diff --git a/docs/configuration/backends/marathon.md b/docs/configuration/backends/marathon.md index 98ce7ed3b..775de201a 100644 --- a/docs/configuration/backends/marathon.md +++ b/docs/configuration/backends/marathon.md @@ -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. -| Label | Description | -|------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Default domain used for frontend rules. | -| `traefik.enable=false` | Disable this container in Træfik | -| `traefik.port=80` | Register 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.protocol=https` | Override the default `http` protocol | -| `traefik.weight=10` | Assign this weight to the container | -| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create 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.interval=1s` | Define the health check interval. (Default: 30s) | -| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | -| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
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.
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.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{sub_domain}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
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` | Use `X-Forwarded-For` header as valid source of IP for the white list. | +| Label | Description | +|------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.domain` | Sets the default domain used for the frontend rules. | +| `traefik.enable=false` | Disables this container in Træfik. | +| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. | +| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. | +| `traefik.protocol=https` | Overrides the default `http` protocol. | +| `traefik.weight=10` | Assigns this weight to the container. | +| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. | +| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | +| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) | +| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | +| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | +| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | +| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | +| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | +| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions | +| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) | +| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | +| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | +| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | +| `traefik.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | +| `traefik.frontend.auth.digest.usersfile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. | +| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | +| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. | +| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | +| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | +| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | +| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | +| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | +| `traefik.frontend.priority=10` | Overrides default frontend priority | +| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..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.
Must be set with `traefik.frontend.redirect.replacement`. | +| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
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.
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 diff --git a/docs/configuration/backends/mesos.md b/docs/configuration/backends/mesos.md index 2a51c0d04..51734e523 100644 --- a/docs/configuration/backends/mesos.md +++ b/docs/configuration/backends/mesos.md @@ -106,52 +106,64 @@ domain = "mesos.localhost" The following labels can be defined on Mesos tasks. They adjust the behavior for the entire application. -| Label | Description | -|------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Default domain used for frontend rules. | -| `traefik.enable=false` | Disable this container in Træfik | -| `traefik.port=80` | Register 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.portIndex=1` | Register 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.weight=10` | Assign this weight to the container | -| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create 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.interval=1s` | Define the health check interval. (Default: 30s) | -| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | -| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
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.
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.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{discovery_name}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
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` | Use `X-Forwarded-For` header as valid source of IP for the white list. | +| Label | Description | +|------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.domain` | Sets the default domain for the frontend rules. | +| `traefik.enable=false` | Disables this container in Træfik. | +| `traefik.port=80` | Registers this port. Useful when the application exposes multiple ports. | +| `traefik.portName=web` | Registers port by name in the application's ports array. Useful when the application exposes multiple ports. | +| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. | +| `traefik.protocol=https` | Overrides the default `http` protocol | +| `traefik.weight=10` | Assigns this weight to the container | +| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. | +| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | +| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) | +| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | +| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | +| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | +| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | +| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | +| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions | +| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | +| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | +| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | +| `traefik.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | +| `traefik.frontend.auth.digest.usersfile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. | +| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | +| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. | +| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | +| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | +| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | +| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | +| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | +| `traefik.frontend.priority=10` | Overrides default frontend priority | +| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..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.
Must be set with `traefik.frontend.redirect.replacement`. | +| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
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.
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 diff --git a/docs/configuration/backends/rancher.md b/docs/configuration/backends/rancher.md index f761fbbba..74e8266fe 100644 --- a/docs/configuration/backends/rancher.md +++ b/docs/configuration/backends/rancher.md @@ -138,51 +138,63 @@ secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" Labels can be used on task containers to override default behavior: -| Label | Description | -|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Default domain used for frontend rules. | -| `traefik.enable=false` | Disable this container in Træfik | -| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | -| `traefik.protocol=https` | Override the default `http` protocol | -| `traefik.weight=10` | Assign this weight to the container | -| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create 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.interval=1s` | Define the health check interval. | -| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Override the server URL scheme. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | -| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
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.
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.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{service_name}.{stack_name}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
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` | Use `X-Forwarded-For` header as valid source of IP for the white list. | +| Label | Description | +|------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.domain` | Sets the default domain for the frontend rules. | +| `traefik.enable=false` | Disables this container in Træfik. | +| `traefik.port=80` | Registers this port. Useful when the container exposes multiple ports. | +| `traefik.protocol=https` | Overrides the default `http` protocol. | +| `traefik.weight=10` | Assigns this weight to the container. | +| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. | +| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | +| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | +| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. | +| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | +| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | +| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | +| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | +| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | +| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions | +| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) | +| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | +| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | +| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` . | +| `traefik.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | +| `traefik.frontend.auth.digest.usersfile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | +| `traefik.frontend.auth.forward.address=https://example.com`| Sets the URL of the authentication server. | +| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | +| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true`| If set to true invalid SSL certificates are accepted. | +| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | +| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | +| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | +| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | +| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | +| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | +| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | +| `traefik.frontend.priority=10` | Overrides default frontend priority | +| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | +| `traefik.frontend.rateLimit.rateSet..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.
Must be set with `traefik.frontend.redirect.replacement`. | +| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
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.
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 @@ -224,32 +236,44 @@ You can define as many segments as ports exposed in a container. Segment labels override the default behavior. -| Label | Description | -|---------------------------------------------------------------------------|-------------------------------------------------------------| -| `traefik..backend=BACKEND` | Same as `traefik.backend` | -| `traefik..domain=DOMAIN` | Same as `traefik.domain` | -| `traefik..port=PORT` | Same as `traefik.port` | -| `traefik..protocol=http` | Same as `traefik.protocol` | -| `traefik..weight=10` | Same as `traefik.weight` | -| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | -| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | -| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | -| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | -| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | -| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | -| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | -| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | -| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | -| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | -| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | -| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | -| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | -| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | -| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | -| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | -| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | -| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | -| `traefik..frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | +| Label | Description | +|---------------------------------------------------------------------------|---------------------------------------------------------------| +| `traefik..backend=BACKEND` | Same as `traefik.backend` | +| `traefik..domain=DOMAIN` | Same as `traefik.domain` | +| `traefik..port=PORT` | Same as `traefik.port` | +| `traefik..protocol=http` | Same as `traefik.protocol` | +| `traefik..weight=10` | Same as `traefik.weight` | +| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | +| `traefik..frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` | +| `traefik..frontend.auth.basic.usersfile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersfile` | +| `traefik..frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` | +| `traefik..frontend.auth.digest.usersfile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersfile` | +| `traefik..frontend.auth.forward.address=https://example.com`| Same as `traefik.frontend.auth.forward.address` | +| `traefik..frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` | +| `traefik..frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` | +| `traefik..frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` | +| `traefik..frontend.auth.forward.tls.insecureSkipVerify=true`| Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify`| +| `traefik..frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` | +| `traefik..frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` | +| `traefik..frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` | +| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | +| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | +| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | +| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | +| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | +| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | +| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | +| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | +| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | +| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | +| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | +| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | +| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | +| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | +| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | +| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | +| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | +| `traefik..frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | #### Custom Headers diff --git a/docs/user-guide/kv-config.md b/docs/user-guide/kv-config.md index 9a42491d8..1a1008393 100644 --- a/docs/user-guide/kv-config.md +++ b/docs/user-guide/kv-config.md @@ -266,10 +266,11 @@ Here is the toml configuration we would like to store in the store : backend = "backend1" passHostHeader = true priority = 10 - basicAuth = [ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - ] + [frontends.frontend2.auth.basic] + users = [ + "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", + ] entrypoints = ["https"] # overrides defaultEntryPoints [frontends.frontend2.routes.test_1] 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/passhostheader` | `true` | | `/traefik/frontends/frontend2/priority` | `10` | -| `/traefik/frontends/frontend2/basicauth/0` | `test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/` | -| `/traefik/frontends/frontend2/basicauth/1` | `test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | +| `/traefik/frontends/frontend2/auth/basic/users/0` | `test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/` | +| `/traefik/frontends/frontend2/auth/basic/users/1` | `test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | | `/traefik/frontends/frontend2/entrypoints` | `http,https` | | `/traefik/frontends/frontend2/routes/test_2/rule` | `PathPrefix:/test` | diff --git a/integration/access_log_test.go b/integration/access_log_test.go index eaaca7ede..27da9adb8 100644 --- a/integration/access_log_test.go +++ b/integration/access_log_test.go @@ -102,7 +102,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) { formatOnly: false, code: "401", user: "-", - frontendName: "Basic Auth for frontend-Host-frontend-auth-docker-local", + frontendName: "Auth for frontend-Host-frontend-auth-docker-local", backendURL: "/", }, } diff --git a/provider/consulcatalog/config.go b/provider/consulcatalog/config.go index ad3b4b599..73d8c37e1 100644 --- a/provider/consulcatalog/config.go +++ b/provider/consulcatalog/config.go @@ -38,7 +38,8 @@ func (p *Provider) buildConfigurationV2(catalog []catalogUpdate) *types.Configur // Frontend functions "getFrontendRule": p.getFrontendRule, - "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), + "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated + "getAuth": label.GetAuth, "getFrontEndEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), "getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), diff --git a/provider/consulcatalog/config_test.go b/provider/consulcatalog/config_test.go index 4b9f09dea..70bc96f5d 100644 --- a/provider/consulcatalog/config_test.go +++ b/provider/consulcatalog/config_test.go @@ -57,7 +57,7 @@ func TestProviderBuildConfiguration(t *testing.T) { label.TraefikBackendCircuitBreakerExpression + "=NetworkErrorRatio() > 0.5", label.TraefikBackendMaxConnAmount + "=1000", 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{ @@ -90,8 +90,13 @@ func TestProviderBuildConfiguration(t *testing.T) { Rule: "Host:test.localhost", }, }, + Auth: &types.Auth{ + Basic: &types.Basic{ + Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, + }, + }, EntryPoints: []string{}, - BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, }, }, 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", nodes: []catalogUpdate{ @@ -144,6 +348,19 @@ func TestProviderBuildConfiguration(t *testing.T) { label.TraefikBackendBufferingRetryExpression + "=IsNetworkError() && Attempts() <= 2", 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.TraefikFrontendPassHostHeader + "=true", label.TraefikFrontendPassTLSCert + "=true", @@ -244,9 +461,13 @@ func TestProviderBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{ @@ -389,7 +610,7 @@ func TestProviderBuildConfiguration(t *testing.T) { label.TraefikBackendCircuitBreakerExpression + "=NetworkErrorRatio() > 0.5", label.TraefikBackendMaxConnAmount + "=1000", 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{ @@ -439,8 +660,13 @@ func TestProviderBuildConfiguration(t *testing.T) { Rule: "Host:test.localhost", }, }, + Auth: &types.Auth{ + Basic: &types.Basic{ + Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, + }, + }, EntryPoints: []string{}, - BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, }, }, expectedBackends: map[string]*types.Backend{ diff --git a/provider/docker/config.go b/provider/docker/config.go index 75331c97c..002d1f115 100644 --- a/provider/docker/config.go +++ b/provider/docker/config.go @@ -47,7 +47,8 @@ func (p *Provider) buildConfigurationV2(containersInspected []dockerData) *types "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), - "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), + "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated + "getAuth": label.GetAuth, "getFrontendRule": p.getFrontendRule, "getRedirect": label.GetRedirect, "getErrorPages": label.GetErrorPages, diff --git a/provider/docker/config_container_docker_test.go b/provider/docker/config_container_docker_test.go index 50cc52676..7d284d579 100644 --- a/provider/docker/config_container_docker_test.go +++ b/provider/docker/config_container_docker_test.go @@ -44,7 +44,6 @@ func TestDockerBuildConfiguration(t *testing.T) { Backend: "backend-test", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-Host-test-docker-localhost-0": { Rule: "Host:test.docker.localhost", @@ -63,7 +62,201 @@ func TestDockerBuildConfiguration(t *testing.T) { 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", containers: []docker.ContainerJSON{ containerJSON( @@ -80,7 +273,6 @@ func TestDockerBuildConfiguration(t *testing.T) { Backend: "backend-test", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-Host-test-docker-localhost-0": { Rule: "Host:test.docker.localhost", @@ -121,7 +313,6 @@ func TestDockerBuildConfiguration(t *testing.T) { Backend: "backend-test", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-Host-test-docker-localhost-0": { Rule: "Host:test.docker.localhost", @@ -193,7 +384,20 @@ func TestDockerBuildConfiguration(t *testing.T) { label.TraefikBackendBufferingMemRequestBodyBytes: "2097152", 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.TraefikFrontendPassHostHeader: "true", label.TraefikFrontendPassTLSCert: "true", @@ -265,9 +469,13 @@ func TestDockerBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, @@ -438,7 +646,6 @@ func TestDockerBuildConfiguration(t *testing.T) { Backend: "backend-myService-myProject", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-Host-myService-myProject-docker-localhost-0": { Rule: "Host:myService.myProject.docker.localhost", @@ -449,7 +656,6 @@ func TestDockerBuildConfiguration(t *testing.T) { Backend: "backend-myService2-myProject", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-Host-myService2-myProject-docker-localhost-2": { Rule: "Host:myService2.myProject.docker.localhost", diff --git a/provider/docker/config_container_swarm_test.go b/provider/docker/config_container_swarm_test.go index ad982ecfd..4c9676951 100644 --- a/provider/docker/config_container_swarm_test.go +++ b/provider/docker/config_container_swarm_test.go @@ -46,7 +46,6 @@ func TestSwarmBuildConfiguration(t *testing.T) { Backend: "backend-test", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-Host-test-docker-localhost-0": { 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", services: []swarm.Service{ @@ -125,6 +329,19 @@ func TestSwarmBuildConfiguration(t *testing.T) { label.TraefikBackendBufferingMemRequestBodyBytes: "2097152", 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.TraefikFrontendEntryPoints: "http,https", label.TraefikFrontendPassHostHeader: "true", @@ -194,9 +411,13 @@ func TestSwarmBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, diff --git a/provider/docker/config_segment_test.go b/provider/docker/config_segment_test.go index c9c00e71c..210663e9e 100644 --- a/provider/docker/config_segment_test.go +++ b/provider/docker/config_segment_test.go @@ -46,7 +46,6 @@ func TestSegmentBuildConfiguration(t *testing.T) { Backend: "backend-foo-sauternes", PassHostHeader: true, EntryPoints: []string{"http", "https"}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-sauternes-foo-sauternes": { 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", containers: []docker.ContainerJSON{ @@ -76,6 +282,19 @@ func TestSegmentBuildConfiguration(t *testing.T) { label.Prefix + "sauternes." + label.SuffixProtocol: "https", 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.SuffixFrontendEntryPoints: "http,https", label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true", @@ -142,9 +361,13 @@ func TestSegmentBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, @@ -285,7 +508,12 @@ func TestSegmentBuildConfiguration(t *testing.T) { PassHostHeader: false, Priority: 5000, 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{ EntryPoint: "https", }, @@ -299,7 +527,6 @@ func TestSegmentBuildConfiguration(t *testing.T) { Backend: "backend-test2-anothersauternes", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route-frontend-anothersauternes-test2-anothersauternes": { Rule: "Path:/anotherpath", @@ -360,7 +587,6 @@ func TestSegmentBuildConfiguration(t *testing.T) { PassHostHeader: true, Priority: 5000, EntryPoints: []string{"http", "https"}, - BasicAuth: []string{}, Redirect: &types.Redirect{ EntryPoint: "https", }, @@ -375,7 +601,6 @@ func TestSegmentBuildConfiguration(t *testing.T) { PassHostHeader: true, Priority: 3000, EntryPoints: []string{"http", "https"}, - BasicAuth: []string{}, Redirect: &types.Redirect{ EntryPoint: "https", }, @@ -432,7 +657,6 @@ func TestSegmentBuildConfiguration(t *testing.T) { PassHostHeader: true, Priority: 5000, EntryPoints: []string{"http", "https"}, - BasicAuth: []string{}, Redirect: &types.Redirect{ EntryPoint: "https", }, @@ -447,7 +671,6 @@ func TestSegmentBuildConfiguration(t *testing.T) { PassHostHeader: true, Priority: 3000, EntryPoints: []string{"http", "https"}, - BasicAuth: []string{}, Redirect: &types.Redirect{ EntryPoint: "https", }, diff --git a/provider/ecs/config.go b/provider/ecs/config.go index 282dfc3ae..09dd8c2a9 100644 --- a/provider/ecs/config.go +++ b/provider/ecs/config.go @@ -46,7 +46,8 @@ func (p *Provider) buildConfigurationV2(instances []ecsInstance) (*types.Configu "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "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), "getRedirect": label.GetRedirect, "getErrorPages": label.GetErrorPages, diff --git a/provider/ecs/config_test.go b/provider/ecs/config_test.go index dac1dfb1d..57c0ecd85 100644 --- a/provider/ecs/config_test.go +++ b/provider/ecs/config_test.go @@ -56,7 +56,6 @@ func TestBuildConfiguration(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, }, }, }, @@ -103,7 +102,216 @@ func TestBuildConfiguration(t *testing.T) { }, }, 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.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.TraefikFrontendPassHostHeader: aws.String("true"), label.TraefikFrontendPassTLSCert: aws.String("true"), @@ -257,9 +478,13 @@ func TestBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, @@ -381,7 +606,7 @@ func TestBuildConfiguration(t *testing.T) { label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"), 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.TraefikFrontendPassHostHeader: aws.String("true"), label.TraefikFrontendPassTLSCert: aws.String("true"), @@ -588,9 +813,11 @@ func TestBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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"}, + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, diff --git a/provider/kv/keynames.go b/provider/kv/keynames.go index 16efdcbd7..7dfb292c2 100644 --- a/provider/kv/keynames.go +++ b/provider/kv/keynames.go @@ -33,22 +33,41 @@ const ( pathFrontendPassTLSCert = "/passtlscert" pathFrontendWhiteListSourceRange = "/whitelist/sourcerange" pathFrontendWhiteListUseXForwardedFor = "/whitelist/usexforwardedfor" - pathFrontendBasicAuth = "/basicauth" - 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" + + pathFrontendBasicAuth = "/basicauth" // Deprecated + pathFrontendAuth = "/auth/" + pathFrontendAuthBasic = pathFrontendAuth + "basic/" + pathFrontendAuthBasicUsers = pathFrontendAuthBasic + "users" + pathFrontendAuthBasicUsersFile = pathFrontendAuthBasic + "usersfile" + pathFrontendAuthDigest = pathFrontendAuth + "digest/" + pathFrontendAuthDigestUsers = pathFrontendAuthDigest + "users" + pathFrontendAuthDigestUsersFile = pathFrontendAuthDigest + "usersfile" + pathFrontendAuthForward = pathFrontendAuth + "forward/" + pathFrontendAuthForwardAddress = pathFrontendAuthForward + "address" + pathFrontendAuthForwardTLS = pathFrontendAuthForward + "tls/" + pathFrontendAuthForwardTLSCa = pathFrontendAuthForwardTLS + "ca" + pathFrontendAuthForwardTLSCaOptional = pathFrontendAuthForwardTLS + "caoptional" + pathFrontendAuthForwardTLSCert = pathFrontendAuthForwardTLS + "cert" + 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/" pathFrontendCustomResponseHeaders = "/headers/customresponseheaders/" diff --git a/provider/kv/kv_config.go b/provider/kv/kv_config.go index d8faa52a1..a2242ac6b 100644 --- a/provider/kv/kv_config.go +++ b/provider/kv/kv_config.go @@ -46,7 +46,8 @@ func (p *Provider) buildConfiguration() *types.Configuration { "getPassHostHeader": p.getPassHostHeader(), "getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert), "getEntryPoints": p.getFuncList(pathFrontendEntryPoints), - "getBasicAuth": p.getFuncList(pathFrontendBasicAuth), + "getBasicAuth": p.getFuncList(pathFrontendBasicAuth), // Deprecated + "getAuth": p.getAuth, "getRoutes": p.getRoutes, "getRedirect": p.getRedirect, "getErrorPages": p.getErrorPages, @@ -368,6 +369,78 @@ func (p *Provider) getTLSSection(prefix string) []*tls.Configuration { 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 { var routes map[string]types.Route diff --git a/provider/kv/kv_config_test.go b/provider/kv/kv_config_test.go index d8f200b79..bc8bb4e88 100644 --- a/provider/kv/kv_config_test.go +++ b/provider/kv/kv_config_test.go @@ -52,7 +52,6 @@ func TestProviderBuildConfiguration(t *testing.T) { Backend: "backend.with.dot.too", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{}, Routes: map[string]types.Route{ "route.with.dot": { 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", kvPairs: filler("traefik", @@ -96,7 +246,21 @@ func TestProviderBuildConfiguration(t *testing.T) { withList(pathFrontendEntryPoints, "http", "https"), withList(pathFrontendWhiteListSourceRange, "1.1.1.1/24", "1234:abcd::42/32"), withPair(pathFrontendWhiteListUseXForwardedFor, "true"), + 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(pathFrontendRedirectRegex, "nope"), withPair(pathFrontendRedirectReplacement, "nope"), @@ -200,7 +364,14 @@ func TestProviderBuildConfiguration(t *testing.T) { SourceRange: []string{"1.1.1.1/24", "1234:abcd::42/32"}, 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{ EntryPoint: "https", 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) { testCases := []struct { desc string diff --git a/provider/label/names.go b/provider/label/names.go index 8cf4ad9fd..ddb1aacaa 100644 --- a/provider/label/names.go +++ b/provider/label/names.go @@ -2,151 +2,183 @@ package label // Traefik labels const ( - Prefix = "traefik." - SuffixBackend = "backend" - SuffixDomain = "domain" - SuffixEnable = "enable" - SuffixPort = "port" - SuffixPortName = "portName" - SuffixPortIndex = "portIndex" - SuffixProtocol = "protocol" - SuffixTags = "tags" - SuffixWeight = "weight" - SuffixBackendID = "backend.id" - SuffixBackendCircuitBreaker = "backend.circuitbreaker" - SuffixBackendCircuitBreakerExpression = "backend.circuitbreaker.expression" - SuffixBackendHealthCheckScheme = "backend.healthcheck.scheme" - SuffixBackendHealthCheckPath = "backend.healthcheck.path" - SuffixBackendHealthCheckPort = "backend.healthcheck.port" - SuffixBackendHealthCheckInterval = "backend.healthcheck.interval" - SuffixBackendHealthCheckHostname = "backend.healthcheck.hostname" - SuffixBackendHealthCheckHeaders = "backend.healthcheck.headers" - SuffixBackendLoadBalancer = "backend.loadbalancer" - SuffixBackendLoadBalancerMethod = SuffixBackendLoadBalancer + ".method" - SuffixBackendLoadBalancerSticky = SuffixBackendLoadBalancer + ".sticky" - SuffixBackendLoadBalancerStickiness = SuffixBackendLoadBalancer + ".stickiness" - SuffixBackendLoadBalancerStickinessCookieName = SuffixBackendLoadBalancer + ".stickiness.cookieName" - SuffixBackendMaxConnAmount = "backend.maxconn.amount" - SuffixBackendMaxConnExtractorFunc = "backend.maxconn.extractorfunc" - SuffixBackendBuffering = "backend.buffering" - SuffixBackendBufferingMaxRequestBodyBytes = SuffixBackendBuffering + ".maxRequestBodyBytes" - SuffixBackendBufferingMemRequestBodyBytes = SuffixBackendBuffering + ".memRequestBodyBytes" - SuffixBackendBufferingMaxResponseBodyBytes = SuffixBackendBuffering + ".maxResponseBodyBytes" - SuffixBackendBufferingMemResponseBodyBytes = SuffixBackendBuffering + ".memResponseBodyBytes" - SuffixBackendBufferingRetryExpression = SuffixBackendBuffering + ".retryExpression" - SuffixFrontend = "frontend" - SuffixFrontendAuthBasic = "frontend.auth.basic" - SuffixFrontendEntryPoints = "frontend.entryPoints" - SuffixFrontendHeaders = "frontend.headers." - SuffixFrontendRequestHeaders = SuffixFrontendHeaders + "customRequestHeaders" - SuffixFrontendResponseHeaders = SuffixFrontendHeaders + "customResponseHeaders" - SuffixFrontendHeadersAllowedHosts = SuffixFrontendHeaders + "allowedHosts" - SuffixFrontendHeadersHostsProxyHeaders = SuffixFrontendHeaders + "hostsProxyHeaders" - SuffixFrontendHeadersSSLForceHost = SuffixFrontendHeaders + "SSLForceHost" - SuffixFrontendHeadersSSLRedirect = SuffixFrontendHeaders + "SSLRedirect" - SuffixFrontendHeadersSSLTemporaryRedirect = SuffixFrontendHeaders + "SSLTemporaryRedirect" - SuffixFrontendHeadersSSLHost = SuffixFrontendHeaders + "SSLHost" - SuffixFrontendHeadersSSLProxyHeaders = SuffixFrontendHeaders + "SSLProxyHeaders" - SuffixFrontendHeadersSTSSeconds = SuffixFrontendHeaders + "STSSeconds" - SuffixFrontendHeadersSTSIncludeSubdomains = SuffixFrontendHeaders + "STSIncludeSubdomains" - SuffixFrontendHeadersSTSPreload = SuffixFrontendHeaders + "STSPreload" - SuffixFrontendHeadersForceSTSHeader = SuffixFrontendHeaders + "forceSTSHeader" - SuffixFrontendHeadersFrameDeny = SuffixFrontendHeaders + "frameDeny" - SuffixFrontendHeadersCustomFrameOptionsValue = SuffixFrontendHeaders + "customFrameOptionsValue" - SuffixFrontendHeadersContentTypeNosniff = SuffixFrontendHeaders + "contentTypeNosniff" - SuffixFrontendHeadersBrowserXSSFilter = SuffixFrontendHeaders + "browserXSSFilter" - SuffixFrontendHeadersCustomBrowserXSSValue = SuffixFrontendHeaders + "customBrowserXSSValue" - SuffixFrontendHeadersContentSecurityPolicy = SuffixFrontendHeaders + "contentSecurityPolicy" - SuffixFrontendHeadersPublicKey = SuffixFrontendHeaders + "publicKey" - SuffixFrontendHeadersReferrerPolicy = SuffixFrontendHeaders + "referrerPolicy" - SuffixFrontendHeadersIsDevelopment = SuffixFrontendHeaders + "isDevelopment" - SuffixFrontendPassHostHeader = "frontend.passHostHeader" - SuffixFrontendPassTLSCert = "frontend.passTLSCert" - SuffixFrontendPriority = "frontend.priority" - SuffixFrontendRateLimitExtractorFunc = "frontend.rateLimit.extractorFunc" - SuffixFrontendRedirectEntryPoint = "frontend.redirect.entryPoint" - SuffixFrontendRedirectRegex = "frontend.redirect.regex" - SuffixFrontendRedirectReplacement = "frontend.redirect.replacement" - SuffixFrontendRedirectPermanent = "frontend.redirect.permanent" - SuffixFrontendRule = "frontend.rule" - SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange" // Deprecated - SuffixFrontendWhiteList = "frontend.whiteList." - SuffixFrontendWhiteListSourceRange = SuffixFrontendWhiteList + "sourceRange" - SuffixFrontendWhiteListUseXForwardedFor = SuffixFrontendWhiteList + "useXForwardedFor" - TraefikDomain = Prefix + SuffixDomain - TraefikEnable = Prefix + SuffixEnable - TraefikPort = Prefix + SuffixPort - TraefikPortName = Prefix + SuffixPortName - TraefikPortIndex = Prefix + SuffixPortIndex - TraefikProtocol = Prefix + SuffixProtocol - TraefikTags = Prefix + SuffixTags - TraefikWeight = Prefix + SuffixWeight - TraefikBackend = Prefix + SuffixBackend - TraefikBackendID = Prefix + SuffixBackendID - TraefikBackendCircuitBreaker = Prefix + SuffixBackendCircuitBreaker - TraefikBackendCircuitBreakerExpression = Prefix + SuffixBackendCircuitBreakerExpression - TraefikBackendHealthCheckScheme = Prefix + SuffixBackendHealthCheckScheme - TraefikBackendHealthCheckPath = Prefix + SuffixBackendHealthCheckPath - TraefikBackendHealthCheckPort = Prefix + SuffixBackendHealthCheckPort - TraefikBackendHealthCheckInterval = Prefix + SuffixBackendHealthCheckInterval - TraefikBackendHealthCheckHostname = Prefix + SuffixBackendHealthCheckHostname - TraefikBackendHealthCheckHeaders = Prefix + SuffixBackendHealthCheckHeaders - TraefikBackendLoadBalancer = Prefix + SuffixBackendLoadBalancer - TraefikBackendLoadBalancerMethod = Prefix + SuffixBackendLoadBalancerMethod - TraefikBackendLoadBalancerSticky = Prefix + SuffixBackendLoadBalancerSticky - TraefikBackendLoadBalancerStickiness = Prefix + SuffixBackendLoadBalancerStickiness - TraefikBackendLoadBalancerStickinessCookieName = Prefix + SuffixBackendLoadBalancerStickinessCookieName - TraefikBackendMaxConnAmount = Prefix + SuffixBackendMaxConnAmount - TraefikBackendMaxConnExtractorFunc = Prefix + SuffixBackendMaxConnExtractorFunc - TraefikBackendBuffering = Prefix + SuffixBackendBuffering - TraefikBackendBufferingMaxRequestBodyBytes = Prefix + SuffixBackendBufferingMaxRequestBodyBytes - TraefikBackendBufferingMemRequestBodyBytes = Prefix + SuffixBackendBufferingMemRequestBodyBytes - TraefikBackendBufferingMaxResponseBodyBytes = Prefix + SuffixBackendBufferingMaxResponseBodyBytes - TraefikBackendBufferingMemResponseBodyBytes = Prefix + SuffixBackendBufferingMemResponseBodyBytes - TraefikBackendBufferingRetryExpression = Prefix + SuffixBackendBufferingRetryExpression - TraefikFrontend = Prefix + SuffixFrontend - TraefikFrontendAuthBasic = Prefix + SuffixFrontendAuthBasic - TraefikFrontendEntryPoints = Prefix + SuffixFrontendEntryPoints - TraefikFrontendPassHostHeader = Prefix + SuffixFrontendPassHostHeader - TraefikFrontendPassTLSCert = Prefix + SuffixFrontendPassTLSCert - TraefikFrontendPriority = Prefix + SuffixFrontendPriority - TraefikFrontendRateLimitExtractorFunc = Prefix + SuffixFrontendRateLimitExtractorFunc - TraefikFrontendRedirectEntryPoint = Prefix + SuffixFrontendRedirectEntryPoint - TraefikFrontendRedirectRegex = Prefix + SuffixFrontendRedirectRegex - TraefikFrontendRedirectReplacement = Prefix + SuffixFrontendRedirectReplacement - TraefikFrontendRedirectPermanent = Prefix + SuffixFrontendRedirectPermanent - TraefikFrontendRule = Prefix + SuffixFrontendRule - 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" + Prefix = "traefik." + SuffixBackend = "backend" + SuffixDomain = "domain" + SuffixEnable = "enable" + SuffixPort = "port" + SuffixPortName = "portName" + SuffixPortIndex = "portIndex" + SuffixProtocol = "protocol" + SuffixTags = "tags" + SuffixWeight = "weight" + SuffixBackendID = "backend.id" + SuffixBackendCircuitBreaker = "backend.circuitbreaker" + SuffixBackendCircuitBreakerExpression = "backend.circuitbreaker.expression" + SuffixBackendHealthCheckScheme = "backend.healthcheck.scheme" + SuffixBackendHealthCheckPath = "backend.healthcheck.path" + SuffixBackendHealthCheckPort = "backend.healthcheck.port" + SuffixBackendHealthCheckInterval = "backend.healthcheck.interval" + SuffixBackendHealthCheckHostname = "backend.healthcheck.hostname" + SuffixBackendHealthCheckHeaders = "backend.healthcheck.headers" + SuffixBackendLoadBalancer = "backend.loadbalancer" + SuffixBackendLoadBalancerMethod = SuffixBackendLoadBalancer + ".method" + SuffixBackendLoadBalancerSticky = SuffixBackendLoadBalancer + ".sticky" + SuffixBackendLoadBalancerStickiness = SuffixBackendLoadBalancer + ".stickiness" + SuffixBackendLoadBalancerStickinessCookieName = SuffixBackendLoadBalancer + ".stickiness.cookieName" + SuffixBackendMaxConnAmount = "backend.maxconn.amount" + SuffixBackendMaxConnExtractorFunc = "backend.maxconn.extractorfunc" + SuffixBackendBuffering = "backend.buffering" + SuffixBackendBufferingMaxRequestBodyBytes = SuffixBackendBuffering + ".maxRequestBodyBytes" + SuffixBackendBufferingMemRequestBodyBytes = SuffixBackendBuffering + ".memRequestBodyBytes" + SuffixBackendBufferingMaxResponseBodyBytes = SuffixBackendBuffering + ".maxResponseBodyBytes" + SuffixBackendBufferingMemResponseBodyBytes = SuffixBackendBuffering + ".memResponseBodyBytes" + SuffixBackendBufferingRetryExpression = SuffixBackendBuffering + ".retryExpression" + SuffixFrontend = "frontend" + SuffixFrontendAuth = SuffixFrontend + ".auth" + SuffixFrontendAuthBasic = SuffixFrontendAuth + ".basic" + SuffixFrontendAuthBasicUsers = SuffixFrontendAuthBasic + ".users" + SuffixFrontendAuthBasicUsersFile = SuffixFrontendAuthBasic + ".usersFile" + SuffixFrontendAuthDigest = SuffixFrontendAuth + ".digest" + SuffixFrontendAuthDigestUsers = SuffixFrontendAuthDigest + ".users" + SuffixFrontendAuthDigestUsersFile = SuffixFrontendAuthDigest + ".usersFile" + SuffixFrontendAuthForward = SuffixFrontendAuth + ".forward" + SuffixFrontendAuthForwardAddress = SuffixFrontendAuthForward + ".address" + SuffixFrontendAuthForwardTLS = SuffixFrontendAuthForward + ".tls" + SuffixFrontendAuthForwardTLSCa = SuffixFrontendAuthForwardTLS + ".ca" + SuffixFrontendAuthForwardTLSCaOptional = SuffixFrontendAuthForwardTLS + ".caOptional" + SuffixFrontendAuthForwardTLSCert = SuffixFrontendAuthForwardTLS + ".cert" + SuffixFrontendAuthForwardTLSInsecureSkipVerify = SuffixFrontendAuthForwardTLS + ".insecureSkipVerify" + SuffixFrontendAuthForwardTLSKey = SuffixFrontendAuthForwardTLS + ".key" + SuffixFrontendAuthForwardTrustForwardHeader = SuffixFrontendAuthForward + ".trustForwardHeader" + SuffixFrontendAuthHeaderField = SuffixFrontendAuth + ".headerField" + SuffixFrontendEntryPoints = "frontend.entryPoints" + SuffixFrontendHeaders = "frontend.headers." + SuffixFrontendRequestHeaders = SuffixFrontendHeaders + "customRequestHeaders" + SuffixFrontendResponseHeaders = SuffixFrontendHeaders + "customResponseHeaders" + SuffixFrontendHeadersAllowedHosts = SuffixFrontendHeaders + "allowedHosts" + SuffixFrontendHeadersHostsProxyHeaders = SuffixFrontendHeaders + "hostsProxyHeaders" + SuffixFrontendHeadersSSLForceHost = SuffixFrontendHeaders + "SSLForceHost" + SuffixFrontendHeadersSSLRedirect = SuffixFrontendHeaders + "SSLRedirect" + SuffixFrontendHeadersSSLTemporaryRedirect = SuffixFrontendHeaders + "SSLTemporaryRedirect" + SuffixFrontendHeadersSSLHost = SuffixFrontendHeaders + "SSLHost" + SuffixFrontendHeadersSSLProxyHeaders = SuffixFrontendHeaders + "SSLProxyHeaders" + SuffixFrontendHeadersSTSSeconds = SuffixFrontendHeaders + "STSSeconds" + SuffixFrontendHeadersSTSIncludeSubdomains = SuffixFrontendHeaders + "STSIncludeSubdomains" + SuffixFrontendHeadersSTSPreload = SuffixFrontendHeaders + "STSPreload" + SuffixFrontendHeadersForceSTSHeader = SuffixFrontendHeaders + "forceSTSHeader" + SuffixFrontendHeadersFrameDeny = SuffixFrontendHeaders + "frameDeny" + SuffixFrontendHeadersCustomFrameOptionsValue = SuffixFrontendHeaders + "customFrameOptionsValue" + SuffixFrontendHeadersContentTypeNosniff = SuffixFrontendHeaders + "contentTypeNosniff" + SuffixFrontendHeadersBrowserXSSFilter = SuffixFrontendHeaders + "browserXSSFilter" + SuffixFrontendHeadersCustomBrowserXSSValue = SuffixFrontendHeaders + "customBrowserXSSValue" + SuffixFrontendHeadersContentSecurityPolicy = SuffixFrontendHeaders + "contentSecurityPolicy" + SuffixFrontendHeadersPublicKey = SuffixFrontendHeaders + "publicKey" + SuffixFrontendHeadersReferrerPolicy = SuffixFrontendHeaders + "referrerPolicy" + SuffixFrontendHeadersIsDevelopment = SuffixFrontendHeaders + "isDevelopment" + SuffixFrontendPassHostHeader = "frontend.passHostHeader" + SuffixFrontendPassTLSCert = "frontend.passTLSCert" + SuffixFrontendPriority = "frontend.priority" + SuffixFrontendRateLimitExtractorFunc = "frontend.rateLimit.extractorFunc" + SuffixFrontendRedirectEntryPoint = "frontend.redirect.entryPoint" + SuffixFrontendRedirectRegex = "frontend.redirect.regex" + SuffixFrontendRedirectReplacement = "frontend.redirect.replacement" + SuffixFrontendRedirectPermanent = "frontend.redirect.permanent" + SuffixFrontendRule = "frontend.rule" + SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange" // Deprecated + SuffixFrontendWhiteList = "frontend.whiteList." + SuffixFrontendWhiteListSourceRange = SuffixFrontendWhiteList + "sourceRange" + SuffixFrontendWhiteListUseXForwardedFor = SuffixFrontendWhiteList + "useXForwardedFor" + TraefikDomain = Prefix + SuffixDomain + TraefikEnable = Prefix + SuffixEnable + TraefikPort = Prefix + SuffixPort + TraefikPortName = Prefix + SuffixPortName + TraefikPortIndex = Prefix + SuffixPortIndex + TraefikProtocol = Prefix + SuffixProtocol + TraefikTags = Prefix + SuffixTags + TraefikWeight = Prefix + SuffixWeight + TraefikBackend = Prefix + SuffixBackend + TraefikBackendID = Prefix + SuffixBackendID + TraefikBackendCircuitBreaker = Prefix + SuffixBackendCircuitBreaker + TraefikBackendCircuitBreakerExpression = Prefix + SuffixBackendCircuitBreakerExpression + TraefikBackendHealthCheckScheme = Prefix + SuffixBackendHealthCheckScheme + TraefikBackendHealthCheckPath = Prefix + SuffixBackendHealthCheckPath + TraefikBackendHealthCheckPort = Prefix + SuffixBackendHealthCheckPort + TraefikBackendHealthCheckInterval = Prefix + SuffixBackendHealthCheckInterval + TraefikBackendHealthCheckHostname = Prefix + SuffixBackendHealthCheckHostname + TraefikBackendHealthCheckHeaders = Prefix + SuffixBackendHealthCheckHeaders + TraefikBackendLoadBalancer = Prefix + SuffixBackendLoadBalancer + TraefikBackendLoadBalancerMethod = Prefix + SuffixBackendLoadBalancerMethod + TraefikBackendLoadBalancerSticky = Prefix + SuffixBackendLoadBalancerSticky + TraefikBackendLoadBalancerStickiness = Prefix + SuffixBackendLoadBalancerStickiness + TraefikBackendLoadBalancerStickinessCookieName = Prefix + SuffixBackendLoadBalancerStickinessCookieName + TraefikBackendMaxConnAmount = Prefix + SuffixBackendMaxConnAmount + TraefikBackendMaxConnExtractorFunc = Prefix + SuffixBackendMaxConnExtractorFunc + TraefikBackendBuffering = Prefix + SuffixBackendBuffering + TraefikBackendBufferingMaxRequestBodyBytes = Prefix + SuffixBackendBufferingMaxRequestBodyBytes + TraefikBackendBufferingMemRequestBodyBytes = Prefix + SuffixBackendBufferingMemRequestBodyBytes + TraefikBackendBufferingMaxResponseBodyBytes = Prefix + SuffixBackendBufferingMaxResponseBodyBytes + TraefikBackendBufferingMemResponseBodyBytes = Prefix + SuffixBackendBufferingMemResponseBodyBytes + TraefikBackendBufferingRetryExpression = Prefix + SuffixBackendBufferingRetryExpression + TraefikFrontend = Prefix + SuffixFrontend + TraefikFrontendAuth = Prefix + SuffixFrontendAuth + TraefikFrontendAuthBasic = Prefix + SuffixFrontendAuthBasic + TraefikFrontendAuthBasicUsers = Prefix + SuffixFrontendAuthBasicUsers + TraefikFrontendAuthBasicUsersFile = Prefix + SuffixFrontendAuthBasicUsersFile + TraefikFrontendAuthDigest = Prefix + SuffixFrontendAuthDigest + TraefikFrontendAuthDigestUsers = Prefix + SuffixFrontendAuthDigestUsers + TraefikFrontendAuthDigestUsersFile = Prefix + SuffixFrontendAuthDigestUsersFile + TraefikFrontendAuthForward = Prefix + SuffixFrontendAuthForward + TraefikFrontendAuthForwardAddress = Prefix + SuffixFrontendAuthForwardAddress + TraefikFrontendAuthForwardTLS = Prefix + SuffixFrontendAuthForwardTLS + TraefikFrontendAuthForwardTLSCa = Prefix + SuffixFrontendAuthForwardTLSCa + TraefikFrontendAuthForwardTLSCaOptional = Prefix + SuffixFrontendAuthForwardTLSCaOptional + TraefikFrontendAuthForwardTLSCert = Prefix + SuffixFrontendAuthForwardTLSCert + TraefikFrontendAuthForwardTLSInsecureSkipVerify = Prefix + SuffixFrontendAuthForwardTLSInsecureSkipVerify + TraefikFrontendAuthForwardTLSKey = Prefix + SuffixFrontendAuthForwardTLSKey + TraefikFrontendAuthForwardTrustForwardHeader = Prefix + SuffixFrontendAuthForwardTrustForwardHeader + TraefikFrontendAuthHeaderField = Prefix + SuffixFrontendAuthHeaderField + TraefikFrontendEntryPoints = Prefix + SuffixFrontendEntryPoints + TraefikFrontendPassHostHeader = Prefix + SuffixFrontendPassHostHeader + TraefikFrontendPassTLSCert = Prefix + SuffixFrontendPassTLSCert + TraefikFrontendPriority = Prefix + SuffixFrontendPriority + TraefikFrontendRateLimitExtractorFunc = Prefix + SuffixFrontendRateLimitExtractorFunc + TraefikFrontendRedirectEntryPoint = Prefix + SuffixFrontendRedirectEntryPoint + TraefikFrontendRedirectRegex = Prefix + SuffixFrontendRedirectRegex + TraefikFrontendRedirectReplacement = Prefix + SuffixFrontendRedirectReplacement + TraefikFrontendRedirectPermanent = Prefix + SuffixFrontendRedirectPermanent + TraefikFrontendRule = Prefix + SuffixFrontendRule + 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" ) diff --git a/provider/label/partial.go b/provider/label/partial.go index 797286e2b..0723e6c57 100644 --- a/provider/label/partial.go +++ b/provider/label/partial.go @@ -60,6 +60,73 @@ func GetRedirect(labels map[string]string) *types.Redirect { 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 func GetErrorPages(labels map[string]string) map[string]*types.ErrorPage { prefix := Prefix + BaseFrontendErrorPage diff --git a/provider/label/partial_test.go b/provider/label/partial_test.go index 0ff7497f1..f6d3f9998 100644 --- a/provider/label/partial_test.go +++ b/provider/label/partial_test.go @@ -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) + }) + } +} diff --git a/provider/marathon/config.go b/provider/marathon/config.go index cb3c265eb..8b0f61af9 100644 --- a/provider/marathon/config.go +++ b/provider/marathon/config.go @@ -48,7 +48,8 @@ func (p *Provider) buildConfigurationV2(applications *marathon.Applications) *ty "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), - "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), + "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated + "getAuth": label.GetAuth, "getRedirect": label.GetRedirect, "getErrorPages": label.GetErrorPages, "getRateLimit": label.GetRateLimit, diff --git a/provider/marathon/config_test.go b/provider/marathon/config_test.go index 7e33cf49d..ae9ec6d2e 100644 --- a/provider/marathon/config_test.go +++ b/provider/marathon/config_test.go @@ -51,7 +51,6 @@ func TestBuildConfiguration(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, }, @@ -84,7 +83,6 @@ func TestBuildConfiguration(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, }, @@ -110,7 +108,6 @@ func TestBuildConfiguration(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, }, @@ -143,7 +140,6 @@ func TestBuildConfiguration(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []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", applications: withApplications( @@ -193,6 +371,19 @@ func TestBuildConfiguration(t *testing.T) { withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"), 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.TraefikFrontendPassHostHeader, "true"), withLabel(label.TraefikFrontendPassTLSCert, "true"), @@ -258,9 +449,13 @@ func TestBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, @@ -424,7 +619,6 @@ func TestBuildConfiguration(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, }, }, expectedBackends: map[string]*types.Backend{ @@ -495,7 +689,6 @@ func TestBuildConfigurationSegments(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, "frontend-app-service-admin": { @@ -506,7 +699,6 @@ func TestBuildConfigurationSegments(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, }, @@ -633,9 +825,11 @@ func TestBuildConfigurationSegments(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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"}, + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, diff --git a/provider/mesos/config.go b/provider/mesos/config.go index 13e66e654..7a379b3a1 100644 --- a/provider/mesos/config.go +++ b/provider/mesos/config.go @@ -43,7 +43,8 @@ func (p *Provider) buildConfigurationV2(tasks []state.Task) *types.Configuration "getSegmentNameSuffix": getSegmentNameSuffix, "getFrontEndName": getFrontendName, "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), "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), diff --git a/provider/mesos/config_test.go b/provider/mesos/config_test.go index 904c446fd..8f52baeab 100644 --- a/provider/mesos/config_test.go +++ b/provider/mesos/config_test.go @@ -65,7 +65,6 @@ func TestBuildConfiguration(t *testing.T) { "frontend-ID1": { Backend: "backend-name1", EntryPoints: []string{}, - BasicAuth: []string{}, PassHostHeader: true, Routes: map[string]types.Route{ "route-host-ID1": { @@ -76,7 +75,6 @@ func TestBuildConfiguration(t *testing.T) { "frontend-ID3": { Backend: "backend-name2", EntryPoints: []string{}, - BasicAuth: []string{}, PassHostHeader: true, Routes: map[string]types.Route{ "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", tasks: []state.Task{ @@ -142,6 +327,19 @@ func TestBuildConfiguration(t *testing.T) { withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"), 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.TraefikFrontendPassHostHeader, "true"), withLabel(label.TraefikFrontendPassTLSCert, "true"), @@ -213,9 +411,13 @@ func TestBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, @@ -398,7 +600,6 @@ func TestBuildConfigurationSegments(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, "frontend-app-taskID-service-admin": { @@ -409,7 +610,6 @@ func TestBuildConfigurationSegments(t *testing.T) { }, }, PassHostHeader: true, - BasicAuth: []string{}, EntryPoints: []string{}, }, }, @@ -478,6 +678,19 @@ func TestBuildConfigurationSegments(t *testing.T) { withSegmentLabel(label.TraefikWeight, "12", "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.TraefikFrontendPassHostHeader, "true", "containous"), withSegmentLabel(label.TraefikFrontendPassTLSCert, "true", "containous"), @@ -544,10 +757,15 @@ func TestBuildConfigurationSegments(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, + WhiteList: &types.WhiteList{ SourceRange: []string{"10.10.10.10"}, UseXForwardedFor: true, diff --git a/provider/rancher/config.go b/provider/rancher/config.go index e52405edb..6b913333d 100644 --- a/provider/rancher/config.go +++ b/provider/rancher/config.go @@ -34,7 +34,8 @@ func (p *Provider) buildConfigurationV2(services []rancherData) *types.Configura "getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), "getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), "getEntryPoints": label.GetFuncSliceString(label.TraefikFrontendEntryPoints), - "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), + "getBasicAuth": label.GetFuncSliceString(label.TraefikFrontendAuthBasic), // Deprecated + "getAuth": label.GetAuth, "getErrorPages": label.GetErrorPages, "getRateLimit": label.GetRateLimit, "getRedirect": label.GetRedirect, diff --git a/provider/rancher/config_test.go b/provider/rancher/config_test.go index 93853345c..57c67ea81 100644 --- a/provider/rancher/config_test.go +++ b/provider/rancher/config_test.go @@ -59,7 +59,20 @@ func TestProviderBuildConfiguration(t *testing.T) { label.TraefikBackendBufferingMemRequestBodyBytes: "2097152", 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.TraefikFrontendPassHostHeader: "true", label.TraefikFrontendPassTLSCert: "true", @@ -129,9 +142,13 @@ func TestProviderBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{ @@ -271,8 +288,20 @@ func TestProviderBuildConfiguration(t *testing.T) { label.Prefix + "sauternes." + label.SuffixProtocol: "https", label.Prefix + "sauternes." + label.SuffixWeight: "12", - 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.SuffixFrontendRule: "Host:traefik.wtf", + 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.SuffixFrontendPassHostHeader: "true", label.Prefix + "sauternes." + label.SuffixFrontendPassTLSCert: "true", @@ -338,9 +367,13 @@ func TestProviderBuildConfiguration(t *testing.T) { PassHostHeader: true, PassTLSCert: true, Priority: 666, - 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", + }, }, WhiteList: &types.WhiteList{ SourceRange: []string{ @@ -438,7 +471,8 @@ func TestProviderBuildConfiguration(t *testing.T) { Name: "test/service", Labels: map[string]string{ 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", }, Health: "healthy", @@ -450,8 +484,14 @@ func TestProviderBuildConfiguration(t *testing.T) { Backend: "backend-test-service", PassHostHeader: true, EntryPoints: []string{}, - BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, - Priority: 0, + Auth: &types.Auth{ + Basic: &types.Basic{ + Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, + UsersFile: ".htpasswd", + }, + }, + Priority: 0, Redirect: &types.Redirect{ 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 { diff --git a/templates/consul_catalog.tmpl b/templates/consul_catalog.tmpl index 76320afff..72ebb2357 100644 --- a/templates/consul_catalog.tmpl +++ b/templates/consul_catalog.tmpl @@ -74,9 +74,47 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $service.TraefikLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $service.TraefikLabels }} + + {{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 }} {{if $whitelist }} diff --git a/templates/docker.tmpl b/templates/docker.tmpl index 847be8bda..0161ac058 100644 --- a/templates/docker.tmpl +++ b/templates/docker.tmpl @@ -75,9 +75,46 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $container.SegmentLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $container.SegmentLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} diff --git a/templates/ecs.tmpl b/templates/ecs.tmpl index d6bfadb27..0e13c31f6 100644 --- a/templates/ecs.tmpl +++ b/templates/ecs.tmpl @@ -74,9 +74,46 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $instance.TraefikLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $instance.TraefikLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} diff --git a/templates/kubernetes.tmpl b/templates/kubernetes.tmpl index 08cdc41c6..011e3e25c 100644 --- a/templates/kubernetes.tmpl +++ b/templates/kubernetes.tmpl @@ -52,10 +52,6 @@ "{{.}}", {{end}}] - basicAuth = [{{range $frontend.BasicAuth }} - "{{.}}", - {{end}}] - {{if $frontend.Auth }} [frontends."{{ $frontendName }}".auth] headerField = "X-WebAuth-User" diff --git a/templates/kv.tmpl b/templates/kv.tmpl index cb79d9107..733a9cba2 100644 --- a/templates/kv.tmpl +++ b/templates/kv.tmpl @@ -74,9 +74,46 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $frontend }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $frontend }} + {{if $auth }} + [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 }} {{if $whitelist }} diff --git a/templates/marathon.tmpl b/templates/marathon.tmpl index 23a1522dd..379495ede 100644 --- a/templates/marathon.tmpl +++ b/templates/marathon.tmpl @@ -77,9 +77,46 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $app.SegmentLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $app.SegmentLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} diff --git a/templates/mesos.tmpl b/templates/mesos.tmpl index 92b75ef68..79b3af440 100644 --- a/templates/mesos.tmpl +++ b/templates/mesos.tmpl @@ -77,10 +77,47 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $app.TraefikLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $app.TraefikLabels }} + {{if $auth }} + [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 }} {{if $whitelist }} [frontends."frontend-{{ $frontendName }}".whiteList] diff --git a/templates/rancher.tmpl b/templates/rancher.tmpl index fc3ea275e..13384296b 100644 --- a/templates/rancher.tmpl +++ b/templates/rancher.tmpl @@ -75,9 +75,46 @@ "{{.}}", {{end}}] - basicAuth = [{{range getBasicAuth $service.SegmentLabels }} - "{{.}}", - {{end}}] + {{ $auth := getAuth $service.SegmentLabels }} + {{if $auth }} + [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 }} {{if $whitelist }}