Help please: Dashboard authentication is getting bypassed using forward slash at the end of url

Do you want to request a feature or report a bug ?

Bug

What did you do?

I added the docker provider config labels for basic auth middleware and then I run the traefik service in swarm mode to access the dashboard in my browser at the exposed port 9191

What did you expect to see?

I expected to see the basic authentication form when my url ends with or without a trailing forward slash. Eg. Both domain.traefik.com:9191/dashboard and domain.traefik.com:9191/dashboard/ must request for user authentication.

What did you see instead?

When i access the url like this domain.traefik.com:9191/dashboard , it asks for authentication but when I access the url with a trailing slash at the end like this domain.traefik.com:9191/dashboard/ , it bypasses the authentication and goes to dashboard straight away.

Output of traefik version : ( What version of Traefik are you using? )

2.0

What is your environment & configuration (arguments, toml, provider, platform, ...)?

version: '3'

services:
  reverse-proxy:
    # The official v2.0 Traefik docker image
    image: traefik:v2.0
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker --providers.docker.swarmMode=true
    ports:
      # The HTTP port
      - "91:80"
      # The Web UI (enabled by --api.insecure=true)
      - "9191:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
        - traefik-stack
    deploy:
        labels:
            - "traefik.http.services.reverse-proxy.loadbalancer.server.port=91"
            - "traefik.docker.network=traefik-stack"
            - "traefik.http.routers.api.service=api@internal"
            - "traefik.http.routers.api.middlewares=secured"
            - "traefik.http.routers.api.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
            - "traefik.http.middlewares.auth.basicauth.users=test:$apr1$bqEWT0Z2$yUFoM5U9X/FbaSmx5v6ib."
            - "traefik.http.middlewares.replacepath.replacepath.path=/dashboard/" #without this line, error 404 occurs
            - "traefik.http.middlewares.secured.chain.middlewares=auth,replacepath"

        placement:
            constraints:
                - node.role == manager

networks:
   traefik-stack:
      external: true

Hello,

version: '3'

services:
  reverse-proxy:
    image: traefik:v2.1.3
    command:
    - --entrypoints.web.address=:80
    - --api=true
    - --providers.docker
    - --providers.docker.swarmMode=true
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
        - traefik-stack
    deploy:
      labels:
        traefik.docker.network: traefik-stack

        traefik.http.routers.api.rule: PathPrefix(`/api`) || PathPrefix(`/dashboard`)
        traefik.http.routers.api.entrypoints: web
        traefik.http.routers.api.service: api@internal
        traefik.http.routers.api.middlewares: auth
        
        traefik.http.middlewares.auth.basicauth.users: user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/ # user/password
        
        traefik.http.services.reverse-proxy.loadbalancer.server.port: 91

      placement:
        constraints:
           - node.role == manager

networks:
   traefik-stack:
      external: true

https://docs.traefik.io/v2.1/operations/dashboard/#secure-mode

I would try it and revert with feedback. Thank you for support @ldez

Hi @ldez

Thank you very much for the support. Your code works like magic!! I had to change the colons(:) in the deploy labels to equal signs (=)

Also i am running Traefik behind a reverse proxy so i made some slight changes to suit my environment. I would share my config here in order to help anyone who falls into this problem in the future.

my working traefik config for secured dashboard and swarm mode behind nginx reverse proxy server:

version: '3'

services:
  reverse-proxy:
    # The official v2.1.3 Traefik docker image
    image: traefik:v2.1.3

    # Enables the secured web UI and tells Traefik to listen to docker
    command:
      - --api=true 
      - --providers.docker 
      - --providers.docker.swarmMode=true
    
    ports:
      # The traefik reverse proxy loadbalancer and dashboard are all handled by port 91. Access the dashboard using path domain.com:91/dashboard/
      - "91:80"
    
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
    
    networks:
        - traefik-stack
    
    deploy:
        labels: 
            - "traefik.docker.network=traefik-stack"

            - "traefik.http.routers.api.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
            - "traefik.http.routers.api.service=api@internal"
            - "traefik.http.routers.api.middlewares=auth"
            
            - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$bqEWT0Z2$$yUFoM5U9X/FbaSmx5v6ib."            

            - "traefik.http.services.reverse-proxy.loadbalancer.server.port=91"
            
        placement:
            constraints:
                - node.role == manager

networks:
   traefik-stack:
      external: true

my working traefik config for non-secured dashboard and swarm mode behind nginx reverse proxy server:

version: '3'

services:
  reverse-proxy:
    # The official v2.1.3 Traefik docker image
    image: traefik:v2.1.3
    
    # Enables the non secured web UI and tells Traefik to listen to docker
    command:
      - --api.insecure=true 
      - --providers.docker 
      - --providers.docker.swarmMode=true
    
    ports:
      # The http port for the loadbalancer. When not running behing a reverse proxy, use 80:80
      - "91:80"
      # Exposing the non secured port 8080 to host port 9191. When host port 8080 is free, use 8080:8080 
      - "9191:8080"
    
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
    
    networks:
        - traefik-stack
    
    deploy:
        labels:
            - "traefik.docker.network=traefik-stack"

            - "traefik.http.routers.api.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
            #- "traefik.http.routers.api.service=api@internal"
            #- "traefik.http.routers.api.middlewares=auth"
            
            #- "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$bqEWT0Z2$$yUFoM5U9X/FbaSmx5v6ib."            

            # This line is mandatory when using swarm mode.
            - "traefik.http.services.reverse-proxy.loadbalancer.server.port=91"
            
        placement:
            constraints:
                - node.role == manager

networks:
   traefik-stack:
      external: true

1 Like

@ldez,

I marked your reply as the solution. Could you please edit your config to such that the docker labels uses equal signs instead of colons? The colons (:slight_smile: broke the code but when i changed to equal signs(=), it worked.

the syntax of the labels I used is valid:

In YAML, you can use both syntax to define the value of a map (labels are a map)

Syntax with - at the beginning of the line and = as separator between the key and the value:

myMap:
  - "key1=value1"
  - "key2=value2"
  - "key3=value3"

Syntax without - and with : as separator between the key and the value:

myMap:
  key1: value1
  key2: value2
  key3: value3

I prefer the second syntax because, for me, it's a better representation of the real type (a map).

Oh I see. Good job. @ldez, you are the man! :wink: