Traefik giving 401 instead of redirecting to Authelia

I've setup Traefik and Authelia for authentication. However, when I navigate to any of my self-hosted sites that should integrate with Authelia I get a 401 Unauthorised instead of being redirected to Authelia. Is there anything I'm doing wrong?

I'm hosting my environment with Docker in Swam mode on 3 hosts.

traefic_networks.yml

version: "3.2"

services:
  scratch:
    image: scratch
    deploy:
      replicas: 0
    networks:
      - public

networks:
  public:
    driver: overlay
    attachable: true
    ipam:
      config:
        - subnet: 172.16.200.0/24

traeficv2.yml

version: "3.2"

services:
  app:
    image: traefik:v2.9
    env_file: /var/config/traefik/traefik.env
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
      - target: 8080
        published: 8080
        protocol: tcp
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /var/data/traefik/config:/etc/traefik
      - /var/data/traefik/traefik.log:/traefik.log
      - /var/data/traefik/acme.json:/acme.json
      - /var/data/traefik/traefik.toml:/traefik.toml
      - /var/data/traefik/traefik_dynamic.toml:/traefik_dynamic.toml
    networks:
      - traefik_networks_public
    deploy:
      mode: global
      labels:
        - "traefik.docker.network=traefik_networks_public"
        - "traefik.http.routers.api.rule=Host(`traefik.example.com`)"
        - "traefik.http.routers.api.entrypoints=https"
        - "traefik.http.routers.api.tls.domains[0].main=example.com"
        - "traefik.http.routers.api.tls.domains[0].sans=*.example.com"
        - "traefik.http.routers.api.tls=true"
        - "traefik.http.routers.api.tls.certresolver=main"
        - "traefik.http.routers.api.service=api@internal"
        - "traefik.http.services.dummy.loadbalancer.server.port=9999"
        #- "traefik.http.routers.traefik-rtr.tls.certresolver=dns-cloudflare" # Comment out this line after first run of traefik to force the use of wildcard certs
        
        - "traefik.http.routers.api.middlewares=authelia@docker"
      placement:
        constraints:
          - node.role == manager

networks:
  traefik_networks_public:
    external: true

traefic.toml

[global]
  checkNewVersion = true

# Enable the Dashboard
[api]
  dashboard = true

# Write out Traefik logs
[log]
  level = "INFO"
  filePath = "/traefik.log"

[entryPoints.http]
  address = ":80"
  # Redirect to HTTPS
  [entryPoints.http.http.redirections.entryPoint]
    to = "https"
    scheme = "https"

[entryPoints.https]
  address = ":443"
  [entryPoints.https.http.tls]
    certResolver = "main"

# Let's Encrypt
[certificatesResolvers.main.acme]
  email = "richard@thepriddyhouse.co.uk"
  storage = "acme.json"
  [certificatesResolvers.main.acme.dnsChallenge]
    provider = "cloudflare"

# Docker Traefik provider
[providers.docker]
  endpoint = "unix:///var/run/docker.sock"
  swarmMode = true
  watch = true

[providers.file]
  filename = "traefik_dynamic.toml"

traefik_dynamic.toml

[http]
  [http.services]
    [http.services.transmission.loadBalancer]
      [[http.services.transmission.loadBalancer.servers]]
        url = "http://10.10.69.20:9091/"

  [http.routers]
     [http.routers.transmission]
      rule = "Host(`transmission.example.com`)"
      middlewares = ["authelia@docker"]
      service = "transmission"

authelia.yml

version: "3.2"

services:
  authelia:
    image: authelia/authelia
    volumes:
      - /var/data/authelia/config:/config
    env_file: /var/config/organizr/organizr.env
    networks:
      - traefik_networks_public
    deploy:
      labels:
        - traefik.enable=true
        - traefik.docker.network=traefik_networks_public
        - "traefik.http.routers.authelia.rule=Host(`authelia.example.com`)"
        - "traefik.http.routers.authelia.entrypoints=https"
        - "traefik.http.services.authelia.loadbalancer.server.port=9091"

        - 'traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/verify?rd=https%3A%2F%authelia.example.com%2F'
        - 'traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true'
        - 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
        
  whoami: 
    image: containous/whoami
    networks:
      - traefik_networks_public
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=traefik_networks_public"
        - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
        - "traefik.http.routers.whoami.entrypoints=https"
        - "traefik.http.routers.whoami.middlewares=authelia@docker"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

networks:
  traefik_networks_public:
    external: true 

At the moment, the only logs I'm getting from Traefic are:

time="2023-09-27T12:52:02Z" level=info msg="Configuration loaded from file: /traefik.toml

Authelia Logs:

time="2023-09-27T14:15:31+01:00" level=error msg="Request timeout occurred while handling request from client." error="read tcp 172.16.200.7:9091->172.16.200.10:45732: i/o timeout" method=GET path=/ remote_ip=172.16.200.10 stack="github.com/authelia/authelia/v4/internal/server/handlers.go:71 handleError.func2\ngithub.com/valyala/fasthttp@v1.43.0/server.go:2824             (*Server).writeErrorResponse\ngithub.com/valyala/fasthttp@v1.43.0/server.go:2266             (*Server).serveConn\ngithub.com/valyala/fasthttp@v1.43.0/workerpool.go:224          (*workerPool).workerFunc\ngithub.com/valyala/fasthttp@v1.43.0/workerpool.go:196          (*workerPool).getCh.func1\nruntime/asm_amd64.s:1594                                       goexit" status_code=408

Any help you can provide would be brilliant.

You are using 3 hosts. Are all 3 hosts Swarm manager nodes, is Traefik running on all nodes, are config files synced and how do you manage DNS for this?

Hi,
Yes, 3 nodes, all are managers.
Config files are all stored on my NAS and mounted to /var/config to all nodes.
Container data is also on my NAS and also mounted as NFS to /var/data.
DNS is cloudflare.
Thanks for your help

How do you manage you DNS, does your domain point to all 3 hosts?

Usually Traefik LetsEncrypt is a challenge with multiple Traefik instances running.

It seems authelia has no deploy mode or replicas set. Is there an instance running?

Ah, OK, I understand.

I'm using a virtual IP that points to all three hosts. I've been following this guide to get things setup Make docker swarm HA with keepalived |・∀・

If I go to authelia.example.com I get a login screen, then if I authenticate I can get to all my services.

Just for a bit of extra information, when I head to one of my services that requires authelia authentication, the logs show:

time="2023-09-28T08:50:33+01:00" level=info msg="Access to https://whoami.example.com/favicon.ico (method GET) is not authorized to user , responding with status code 401" method=GET path=/api/verify remote_ip=77.111.247.119

This suggests that Traefik is forwarding the request onto Authelia, but instead of prompting for authentication, Authelia just responds with a 401.

So, I've resolved the issue. Turns out having single quotes around:

    - 'traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/verify?rd=https%3A%2F%authelia.example.com%2F'
    - 'traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true'
    - 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'

has broken it. Replacing the single quotes with double fixed the issue.

1 Like