I am using Traefik 2.2 with the Docker and dynamic providers. I am new to Traefik, so I am guessing I have somehow screwed up my configuration, but for the life of me, I cannot understand what is causing this issue.
I am trying to add some headers for STS into some docker containers via header labels. The middleware is an on-the-fly created middleware using the docker service name. That works just fine. However, if I add in Basic Auth also, suddenly Traefik complains about the middlewares conflicting. I can do either the STS headers or the auth, and each works fine on its own, but I cannot use them both. I am confused because I thought they were part of the same middleware. Here's an example problematic docker-compose file:
version: "3.8"
services:
whoami:
image: containous/whoami
restart: unless-stopped
networks:
- traefik_internal
expose:
- "80/tcp"
labels:
- "traefik.enable=true"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=https"
- "traefik.http.routers.whoami.tls.certresolver=le"
- "traefik.http.routers.whoami.middlewares=whoami"
- "traefik.http.middlewares.whoami.headers.stsSeconds=31536000"
- "traefik.http.middlewares.whoami.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.whoami.headers.stsPreload=true"
- "traefik.http.middlewares.whoami.headers.forceSTSHeader=true"
- "traefik.http.middlewares.whoami.basicauth.users=test:$$2y$$05$$43393mPT5a4.jZNTKYwYruATHG83KwAWI1HdwMAgbleoH1rI/6Hyu"
networks:
traefik_internal:
external:
name: traefik_internal
That file will not work. I have to remove either the headers or the auth. If I have both, I get the following error from Traefik:
level=error msg="cannot create middleware: multi-types middleware not supported, consider declaring two different pieces of middleware instead" routerName=whoami@docker entryPointName=https
I have also tried making separate middleware in the dynamic provider which provides the STS headers, and simply declaring that the whoami service uses both middlewares, using something akin to this:
- "traefik.http.routers.whoami.middlewares=whoami,sts@file"
- "traefik.http.middlewares.whoami.basicauth.users=test:$$2y$$05$$43393mPT5a4.jZNTKYwYruATHG83KwAWI1HdwMAgbleoH1rI/6Hyu"
But I got the same error.
I am hoping somebody can tell me what I have configured incorrectly, and why, and how to gain the ability to set headers as well as use basic auth in the same service.
Below is my config file:
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[log]
filePath = "/proc/self/fd/1"
format = "common"
level = "ERROR"
[acme]
entryPoint = "https"
OnHostRule = true
[Global]
CheckNewVersion = false
SendAnonymousUsage = true
[ServersTransport]
InsecureSkipVerify = true
[providers.docker]
watch = true
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false
[providers.file]
watch = true
filename = "/etc/traefik/dynamic.toml"
[certificatesResolvers.le.acme]
email = "myemail@example.com"
storage = "/letsencrypt/acme.json"
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
caServer = "https://acme-v02.api.letsencrypt.org/directory"
[certificatesResolvers.le.acme.httpChallenge]
entryPoint = "http"
And here is my dynamic provider file:
[http.routers]
[http.routers.redirecttohttps]
entryPoints = ["http"]
middlewares = ["httpsredirect"]
rule = "HostRegexp(`{host:.+}`)"
service = "noop"
[http.services]
[http.services.noop.loadBalancer]
[[http.services.noop.loadBalancer.servers]]
url = "http://0.0.0.0"
[http.middlewares]
[http.middlewares.httpsredirect.redirectScheme]
scheme = "https"
[http.middlewares.server-header]
[http.middlewares.auth]
[http.middlewares.default.headers]
[tls.options]
[tls.options.default]
minVersion = "VersionTLS12"
cipherSuites = [
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
"TLS_AES_256_GCM_SHA384",
"TLS_CHACHA20_POLY1305_SHA256"
]
curvePreferences = [
"CurveP521",
"CurveP384"
]
sniStrict = true
As you can see, I have some sections for headers and auth that I was initially trying to configure here, but eventually gave up. I have left them in here, since that's what's in my current file, but removing them did not change anything; I still got the above error.
I simply don't understand where the conflict is happening. From my view, I am creating this new "whoami" middleware on the fly when the docker service is started. Then I am assigning the various properties to that middleware, which include headers and auth. The middleware then adds those properties to the requests/responses, since it's "in the middle" between the router and the service. That makes logic sense to me. But is that not what's happening? Am I understanding it wrong?