Forward Auth with Authentik via Traefik

Desired Goal

  • Have a SSO authentication page that is SSL secured for all of my services. Authentication will be controlled on a per-service basis using Authentik Application level proxy provider (not using Authentik as a reverse proxy, just as an SSO service)

Authentik Implementation

Provider

  • Name: freshrss
  • Auhorization Flow: Authorize Application
  • Provider Type: Proxy Provider: Forward Auth (single application)
  • External host: https://freshrss.mydomain.com

Application

  • Name: freshrss
  • Slug: freshrss
  • Provider: freshrss
  • No policies attached

Outpost

  • Name: Authentik Embedded Outpost
  • Type: Proxy
  • Applications: freshrss (https://freshrss.mydomain.com)

Traefik Implementation

  • I am using the base Traefik configuration method (non-docker-label)
  • I am using Traefik for all of my SSL

Static Configuration (traefik.yml)

entryPoints: # Defines 2 entry points into traefik (requests made to this host on port 80/443)
  http:
    address: ":80" # Create the HTTP entrypoint on port 80
    http:
      redirections:
        entryPoint:
          to: https
  https:
    address: ":443" # Create the HTTPS entrypoint on port 443
    http:
      tls:
        certResolver: cloudflare
        domains:
          - main: "mydomain.com"
            sans:
              - "*.mydomain.com"

Dynamic Configuration (config.yml)

http: # Config for reverse proxy
  services:
    #region services
    authentik:
      loadBalancer:
        servers:
          - url: "http://authentik-host.site.mydomain.com:9000"
        passHostHeader: true
    freshrss:
      loadBalancer:
        servers:
          - url: "http://freshrss-host.klaus.mydomain.com"
        passHostHeader: true

...

  routers:
    authentik-auth-outpost:
      rule: "PathPrefix(`/outpost.goauthentik.io/`)"
      service: authentik

    authentik-router:
      rule: "Host(`authentik.mydomain.com`)"
      tls: {}
      service: authentik

    freshrss:
      rule: "Host(`freshrss.mydomain.com`)"
      middlewares:
        - default
      tls: {}
      service: freshrss

...


  middlewares:
    authentikAuth:
      forwardAuth:
        address: "http://authentik-host.site.mydomain.com:9000/outpost.goauthentik.io/auth/traefik"
        trustForwardHeader: true
        authResponseHeaders:
          - "X-authentik-username"
          - "X-authentik-groups"
          - "X-authentik-email"
          - "X-authentik-name"
          - "X-authentik-uid"
          - "X-authentik-jwt"
          - "X-authentik-meta-jwks"
          - "X-authentik-meta-outpost"
          - "X-authentik-meta-provider"
          - "X-authentik-meta-app"
          - "X-authentik-meta-version"

Docker Compose (docker-compose.yml)

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443
    environment:
      - CF_API_EMAIL={{ cloudflare_email }}
      - CF_DNS_API_TOKEN={{ cloudflare_api_token }}
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /run/user/{{ docker_user_info.uid }}/docker.sock:/var/run/docker.sock:ro
      - '/srv/{{ service_name }}/data/traefik.yml:/traefik.yml:ro'
      - '/srv/{{ service_name }}/data/acme.json:/acme.json'
      - '/srv/{{ service_name }}/data/config.yml:/config.yml:ro'

Issues

Issues with above implementation

  • Implementation works for users internal to the network (due to the forwardAuth middleware address being resolvable). authentik-host.site.mydomain.com is an static DNS entry on my PFSense host. The authentik-router traefik router provides SSL to when users directyl access the Authentik service.
  • Authentik forwardAuth SSO page is not SSL secured since the forward auth address points directly to the backend service (rather than through the traefik router which provides SSL).

Issue when forwardAuth address as http://authentik.mydomain.com/outpost.goauthentik.io/auth/traefik

  • Idea: the idea with the implementation is that the forwardAuth page will be resolvable by outside hosts since the SSO page is now routed through the Traefik reverse proxy. Additionally, the SSO page will also get SSL since traefik is routing.
  • Issue: Because traefik is now routing the forwardAuth request, it is modifying the X-Forwarded* headers to point back to authentik.mydomain.com rather than freshrss.mydomain.com. This causes the Authentik when the forwardAuth request is routed to it to fail with Unknown app since it is looking for an authentik application (in the Authentik terminology) rathern than freshrss
    • Note that if you add an Authentik application + provider + outpost, it will correctly resolve but authentik will SSO auth to itself (will not forward back to freshrss).
  • I think this is the right idea though, I just need to fix the X-Forwarded issue

Atttempt 1 to fix: Edit traefik entrypoints with forwardedHeaders

  • Expectation: the forwardAuth will use the existing freshrss X-Forwarded added by Traefik by default.
    • Known: This opens security issues but we can fix those with forwardedHeaders.trustedIPs instead
  • Result/Issue: This appears to do nothing? I am not sure why.
Implementation
entryPoints: # Defines 2 entry points into traefik (requests made to this host on port 80/443)
  http:
    address: ":80" # Create the HTTP entrypoint on port 80
    http:
      redirections:
        entryPoint:
          to: https
    forwardedHeaders:
      insecure: true
  https:
    address: ":443" # Create the HTTPS entrypoint on port 443
    forwardedHeaders:
      insecure: true
Edit Report
Pub: 20 Feb 2022 21:08 UTC
Views: 111