Joaquin Diaz
Joaquin Diaz

Reputation: 175

Basic auth is not working for Traefik v2.1

my issue is that I cannot set the basic authentication for my frontend app throught traefik

This is how I have configured my traefik

traefik.yml

global:
  checkNewVersion: true
  sendAnonymousUsage: false

entryPoints:
  https:
    address: :443
  http:
    address: :80
  traefik:
    address: :8080

tls:
  options:
    foo:
      minVersion: VersionTLS12
      cipherSuites:
        - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        - "TLS_RSA_WITH_AES_256_GCM_SHA384"

providers:
  providersThrottleDuration: 2s
  docker:
    watch: true
    endpoint: unix:///var/run/docker.sock
    exposedByDefault: false
    network: web

api:
  insecure: true
  dashboard: true

log:
  level: INFO

certificatesResolvers:
  default:
    acme:
      storage: /acme.json
      httpChallenge:
        entryPoint: http

docker-compose.yml

version: '3'
services:
  traefik:
    image: traefik:v2.0
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "/srv/traefik/traefik.yml:/etc/traefik/traefik.yml"
      - "/srv/traefik/acme.json:/acme.json"
    networks:
      - web

networks:
  web:
    external: true

And here is where I have my frontend app running as a traefik provider and where I have my basic auth label

version: '3.7'
services:
  frontend:
    image: git.xxxx.com:7000/dockerregistry/registry/xxxx
    restart: "always"
    networks:
      - web
    volumes:
      - "/srv/config/api.js:/var/www/htdocs/api.js"
      - "/srv/efs/workspace:/var/www/htdocs/stock"
    labels:
      - traefik.enable=true
      - traefik.http.routers.frontend-http.rule=Host(`test.xxxx.com`)
      - traefik.http.routers.frontend-http.service=frontend
      - traefik.http.routers.frontend-http.entrypoints=http
      - traefik.http.routers.frontend.tls=true
      - traefik.http.routers.frontend.tls.certresolver=default
      - traefik.http.routers.frontend.entrypoints=http
      - traefik.http.routers.frontend.rule=Host(`test.xxxx.com`)
      - traefik.http.routers.frontend.service=frontend
      - traefik.http.middlewares.frontend.basicAuth.users=test:$$2y$$05$$c45HvbP0Sq9EzcfaXiGNsuuWMfPhyoFZVYgiTylpMMLtJY2nP1P6m
      - traefik.http.services.frontend.loadbalancer.server.port=8080

networks:
  web:
    external: true

I cannot get the login prompt, so Im wondering if I missing some container label for this.

Thanks in advance! Joaquin

Upvotes: 4

Views: 14665

Answers (4)

Enkuushka
Enkuushka

Reputation: 425

Regarding this part of the documentation.

If you are using Docker scripts for settings. Configure as the following. For example:

    labels:
      - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
      - "traefik.http.routers.router1.middlewares=foo-add-prefix@docker"

I had same issue and I was missing namespace name @docker in the middleware name.

Upvotes: 0

Jimmy Adaro
Jimmy Adaro

Reputation: 1405

In your Docker Compose file don't add the "middlewares" label for traefik, instead do it using a traefik.yml file passing the providers.file option, where you should define the routers, services, middlewares, etc. In that "providers file" you should set middlewares under http.routes.traefik – This may sound super confuse at the beginning but is not that hard, trust me.

Let's do a YAML case (you can convert it to "TOML" here).

This example assumes you have a Docker Compose file specifically for Traefik – I haven't tried using the same Docker Compose file with any other services in it (like Wordpress, databases or whatever) since I already have a different path for those files.

docker-compose.yml

version: '3.1'

services:
  reverse-proxy:
    image: traefik:v2.4
    [ ... ]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # Map the dynamic conf into the container
      - ./traefik/config.yml:/etc/traefik/config.yml:ro
      # Map the static conf into the container
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      # Note you don't use "traefik.http.routers.<service>.middlewares etc." here
[ ... ]

In this case I set/get the config files for Traefik in ./traefik (relative to the docker-compose.yml file).

./traefik/config.yml

http:
  routers:
    traefik:
      middlewares: "basicauth"
      [ ... ]
  middlewares:
    basicauth:
      basicAuth:
        removeHeader: true
        users:
          - <user>:<password>
          # password should be generated using `htpasswd` (md5, sha1 or bcrypt)
[ ... ]

Here you can set the basicauth name as you wish (since that's the middleware name you'll see in the Dashboard), so you could do:

http:
  routers:
    traefik:
      middlewares: "super-dashboard-auth"
      [ ... ]
  middlewares:
    super-dashboard-auth:
      basicAuth:
        removeHeader: true
        users:
          - <user>:<password>
          # password should be generated using `htpasswd` (md5, sha1 or bcrypt)
[ ... ]

Note that basicAuth must remain as is. Also, here you don't need to use the "double dollar method" to scape it (as in the label approach), so after creating the user password you should enter it exactly like htpasswd created it.

# BAD
user:$$2y$$10$$nRLqyZT.64JI/CD/ym65UGDn8HaY0D6CBTxhe6JXf9u4wi5bEMdh.

# GOOD
user:$2y$10$nRLqyZT.64JI/CD/ym65UGDn8HaY0D6CBTxhe6JXf9u4wi5bEMdh.

Of course you may want to get this data from an .env file and not hardcode those strings, in that case you need to pass the environmental variable from the docker-compose.yml using environment like this:

services:
  reverse-proxy:
    image: traefik:v2.4
    container_name: traefik
    [ ... ]
    environment:
      TRAEFIK_DASHBOARD_USER: "${TRAEFIK_DASHBOARD_USER}"
      TRAEFIK_DASHBOARD_PWD: "${TRAEFIK_DASHBOARD_PWD}"
      # And any other env. var. you may need
[ ... ]

and use it like this in you traefik/config.yml file:

[ ... ]
middlewares:
    super-dashboard-auth:
      basicAuth:
        removeHeader: true
        users:
          - "{{env "TRAEFIK_DASHBOARD_USER"}}:{{env "TRAEFIK_DASHBOARD_PWD"}}"
[ ... ]

After that include the previous file in the providers.file.filename

./traefik/traefik.yml

[ ... ]

api:
  dashboard: true
  insecure: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    [ ... ]

  file:
    filename: /etc/traefik/config.yml
    watch: true

[ ... ]

And then simply docker-compose up -d

Upvotes: 7

Hind
Hind

Reputation: 333

firstly , the labels should be in quotation marks like this ""

secondly, I think you are missing a label in the frontend app . when using basic auth it takes two steps and should look like this :

  - "traefik.http.routers.frontend.middlewares=frontend-auth"
  - "traefik.http.middlewares.frontend-auth.basicauth.users=test:$$2y$$05$$c45HvbP0Sq9EzcfaXiGNsuuWMfPhyoFZVYgiTylpMMLtJY2nP1P6m"

Upvotes: 11

JanuszO
JanuszO

Reputation: 1240

I configure it this way:

  1. generate password by apache2-utils e.g.
htpasswd -nb admin secure_password
  1. setup traefik.toml
[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

[api]
  dashboard = true

[certificatesResolvers.lets-encrypt.acme]
  email = "your_email@your_domain"
  storage = "acme.json"
  [certificatesResolvers.lets-encrypt.acme.tlsChallenge]

[providers.docker]
  watch = true
  network = "web"

[providers.file]
  filename = "traefik_dynamic.toml"
  1. setup traefik_dynamic.toml
[http.middlewares.simpleAuth.basicAuth]
  users = [
    "admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/"
  ]

[http.routers.api]
  rule = "Host(`monitor.your_domain`)"
  entrypoints = ["websecure"]
  middlewares = ["simpleAuth"]
  service = "api@internal"
  [http.routers.api.tls]
    certResolver = "lets-encrypt"
  1. setup traefik service
services:
  reverse-proxy:
    image: traefik:v2.3
    restart: always
    command:
      - --api.insecure=true
      - --providers.docker
    ports:
      - "80:80"
      - "443:443"
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/traefik.toml
      - ./traefik_dynamic.toml:/traefik_dynamic.toml
      - ./acme.json:/acme.json

Upvotes: 2

Related Questions