0

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"
  - "--certificatesresolvers.letsencrypt.acme.email=email@email.com"
  - "--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?

Amadeaus
  • 43
  • 1
  • 7

3 Answers3

4

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

Amadeaus
  • 43
  • 1
  • 7
1

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"
Al-waleed Shihadeh
  • 2,697
  • 2
  • 8
  • 22
  • From my understanding services are used mainly for layer 4/7 loadbalancing and they have to be specified in a separate dynamic config file. In any case specifying a service just returns a "the service \"servicename@docker\" does not exist" error and it seems to overcomplicate the setup in general. – Amadeaus Jun 14 '20 at 12:29
  • You can specify the services either with labels or by `dynamic config file.`. if you do it with dynamic files, you need to reference it as service@${provider}. see this for more info https://medium.com/better-programming/traefik-2-1-as-a-reverse-proxy-c9e274da0a32 – Al-waleed Shihadeh Jun 14 '20 at 19:45
0

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 route, traefik would basically ignore the admin route as it has a short rule.

John Doe
  • 2,746
  • 2
  • 35
  • 50