Traefik basic auth on path

4.8k Views Asked by At

I'm trying to password protect a specific path for an app, but it seems I am missing something and the traefik documentation is not helpful:

Paste from docker-compose:

traefik:

command:
  - "--log.level=INFO"
  - "--providers.docker=true"
  - "--providers.docker.exposedbydefault=false"
  - "--entrypoints.web.address=:80"
  - "--entrypoints.websecure.address=:443"
  - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
  - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
  - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
  - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
  - "[email protected]"
  - "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme.json"

service:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.service.middlewares=service"
  - "traefik.http.routers.service.rule=Host(`domain.example.com`)"
  - "traefik.http.middlewares.service.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.service.headers.forceSTSHeader=true"
  - "traefik.http.middlewares.service.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.service.headers.stsPreload=true"
  - "traefik.http.middlewares.service.headers.referrerPolicy=no-referrer"
  - "traefik.http.middlewares.service.headers.browserXssFilter=true"
  - "traefik.http.middlewares.service.headers.customRequestHeaders.X-Forwarded-Proto=https"
  - "traefik.http.routers.service.tls.certresolver=letsencrypt"

If I add the following labels basic auth is working but it's enabled on the whole website:

  • "traefik.http.middlewares.service-auth.basicauth.usersfile=/etc/traefik/auth"

  • "traefik.http.routers.service.middlewares=service,service-auth"

I played around with adding a second router like so, but that doesn't seem to work:

  • "traefik.http.routers.service-admin.rule=Host(domain.example.com) && PathPrefix(/somepath)"

  • "traefik.http.middlewares.service-auth.basicauth.usersfile=/etc/traefik/auth"

  • "traefik.http.routers.service-admin.middlewares=service-auth"

What am I missing?

3

There are 3 best solutions below

0
On BEST ANSWER

I managed to figure it out with some "educated" guesses. It seems the order of the labels and the spacing between them plays a vital role. Adding a second router (without a service) was indeed the correct way of accomplishing this but separating the routers and middlewares code blocks was important:

  - "traefik.enable=true"

  - "traefik.http.routers.service.rule=Host(`example.example.com`)"
  - "traefik.http.routers.service-admin.rule=Host(`example.example.com`) && PathPrefix(`/somepath`)"
  - "traefik.http.routers.service.tls.certresolver=letsencrypt"
  - "traefik.http.routers.service-admin.tls.certresolver=letsencrypt"
  - "traefik.http.routers.service.middlewares=service"
  - "traefik.http.routers.service-admin.middlewares=service-admin"

  - "traefik.http.middlewares.service.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.service.headers.forceSTSHeader=true"
  - "traefik.http.middlewares.service.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.service.headers.stsPreload=true"
  - "traefik.http.middlewares.service.headers.referrerPolicy=no-referrer"
  - "traefik.http.middlewares.service.headers.browserXssFilter=true"
  - "traefik.http.middlewares.service.headers.customRequestHeaders.X-Forwarded-Proto=https"
  - "traefik.http.middlewares.service-admin.basicauth.usersfile=/etc/traefik/auth"

Note: traefik version used is 2.2.1

0
On

I just had the same problem and the solution seems to be related to the priority given for a route, see https://doc.traefik.io/traefik/routing/routers/#priority.

The routes to consider are ordered by priority by traefik. The priority is, by default, determined by the length of the rule of the route. That is the reason why the accepted answer was working. The rule for the admin route is longer.

I would suggest to set a very high priority for such cases manually, because if you add more hosts or other expressions to your original non-admin route, traefik would basically ignore the admin route as it has a shorter rule.

2
On

I think that you are misconfiguring the second router, try to do it like this

"traefik.http.routers.service-admin.rule=Host(domain.example.com) && PathPrefix(/somepath)"
"traefik.http.middlewares.service-admin.basicauth.usersfile=/etc/traefik/auth"
"traefik.http.routers.service-admin.middlewares=service-admin"
"traefik.http.routers.service-admin.service=$yourservice"