Authentik in Kombination mit traefik

Hier auf meiner Quarkdose-Domain nutze ich aktuell Authelia als Auth-Dienst für die Dinge, die keinen eigenen Login mitbringen oder die ich gesondert zusätzlich absichern möchte (z.B. mit 2FA). Bei der Einrichtung von Authelia haben mir die Tutorials von goNeuland geholfen.

Jetzt bin ich aber kürzlich über die Alternative authentik gestoßen. Diese wollte ich auch einmal ausprobieren. Und da ich meinen zweiten Server eh komplett neu aufsetzen wollte, war jetzt der passende Zeitpunkt hierfür.

Als erstes habe ich nach dieser Anleitung traefik eingerichtet. Nachdem hier alles sauber ohne Probleme lief und das traefik-Dashboard mit BasicAuth abgesichert war, ging es an die Recherche zur Integration von authentik. Nach einigem Suchen bin ich auf den Blog IBRACORP gestoßen. Die dortige Anleitung hat mir zusammen mit der Dokumentation auf der authentik-Seite schlussendlich den Erfolg beschert.

Nachfolgend die ersten Schritte:

mkdir -p authentik/{certs,custom-templates,media} && cd ./authentik

sudo apt install -y pwgen

echo "PG_PASS=$(pwgen -s 40 1)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(pwgen -s 50 1)" >> .env
echo "AUTHENTIK_ERROR_REPORTING__ENABLED=true" >> .env

Zusätzlich habe ich noch die Email-Konfiguration und die Default-Port der Vollständigkeit halber der .env Datei hinzugefügt:

AUTHENTIK_PORT_HTTP=9000
AUTHENTIK_PORT_HTTPS=9443

# SMTP Host Emails are sent to
AUTHENTIK_EMAIL__HOST=localhost
AUTHENTIK_EMAIL__PORT=25
# Optionally authenticate (don't add quotation marks to your password)
AUTHENTIK_EMAIL__USERNAME=
AUTHENTIK_EMAIL__PASSWORD=
# Use StartTLS
AUTHENTIK_EMAIL__USE_TLS=false
# Use SSL
AUTHENTIK_EMAIL__USE_SSL=false
AUTHENTIK_EMAIL__TIMEOUT=10
# Email address authentik will send from, should have a correct @domain
AUTHENTIK_EMAIL__FROM=authentik@localhost

Anschließend habe ich das docker-compose.yml angelegt:

---
version: '3.4'

services:
  postgresql:
    image: postgres:15-alpine
    restart: unless-stopped
    container_name: authentik-postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 5s
    volumes:
      - database:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${PG_PASS}
      - POSTGRES_USER=${PG_USER:-authentik}
      - POSTGRES_DB=${PG_DB:-authentik}
    env_file:
      - .env
    networks:
      - default

  redis:
    image: redis:alpine
    restart: unless-stopped
    container_name: authentik-redis
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    networks:
      - default

  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.4}
    restart: unless-stopped
    container_name: authentik-server
    command: server
    environment:
      AUTHENTIK_REDIS__HOST: authentik-redis
      AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
    env_file:
      - .env
    ports:
      - "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000"
      - "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443"
    networks:
      - proxy
      - default
    labels:
      traefik.enable: true
      traefik.http.routers.authentik.entryPoints: websecure
      traefik.http.routers.authentik.rule: Host(`auth.deine-domain.de`) || HostRegexp(`{subdomain:[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?}.deine-domain.de`) && PathPrefix(`/outpost.goauthentik.io/`)
      traefik.http.routers.authentik.tls: true
      traefik.http.routers.authentik.tls.certresolver: http_resolver
      traefik.http.routers.authentik.service: authentik
      traefik.http.services.authentik.loadbalancer.server.port: 9000
      traefik.docker.network: proxy

  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.4}
    restart: unless-stopped
    container_name: authentik-worker
    command: worker
    environment:
      AUTHENTIK_REDIS__HOST: authentik-redis
      AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    user: root
    volumes:
      - ./media:/media
      - ./certs:/certs
      - /var/run/docker.sock:/var/run/docker.sock
      - ./custom-templates:/templates
    env_file:
      - .env
    networks:
      - default

volumes:
  database:
    driver: local

networks:
  proxy:
    external: true

Aktuell ist fast alles der Docker-Compose-Datei von IBRACORP-Anleitung übernommen. Ich habe nur die weiteren traefik-Labels hinzugefügt, damit ich dann über die Seite https://auth.deine-domain.de auch sauber via traefik geroutet werde. Ohne diese Teile hat das bei mir – warum auch immer – leider nicht funktioniert.
Für den authentik-server und den authentik-worker habe ich auch noch die Version auf die – Stand heute – aktuelle Version 2023.5.4 angehoben.
Die PostgreSQL Datenbank habe ich ebenfalls auf die neuste Version 15 aktualisiert.
Und ich habe einzig dem Service authentik-server Zugriff auf das Proxy-Netzwerk gewährt. Zusätzlich haben alle Zugriff auf default innerhalb des compose-Files.

Nachdem nun für den ersten Schritt alles fertig vorbereitet ist, wird alles mit docker compose up -d gestartet. Nachdem alle Container sauber gestartet sind, kann das initiale Setup im Browser fortgesetzt werden: auth.deine-domain.de/if/flow/initial-setup.

Nachdem wir nun als Admin im authentik-Backend angemeldet sind, legen wir als erstes einen neuen Provider an: Anwendungen => Anbieter => Erstellen => Proxy Provider

Als Namen habe ich Application ForwardAuth gewählt. Den Authentifizierungsablauf habe ich leer gelassen. Beim Autorisierungsablauf habe ich default-provider-authorization-explicit-consent ausgewählt.
Im zweiten Teil der Konfiguration habe ich Forward Auth (einzelne Anwendung) ausgewählt. Als externer Host dient hier zu Testzwecken das traefik-Dashboard: https://traefik.deine-domain.de.
Weitere Einstellungen habe ich hier aktuell nicht vorgenommen und mit einem Klick auf Erstellen den neuen Provider erstellt.

Im Anschluss habe ich eine neue Application erstellt: Anwendungen => Anwendungen => Erstellen

Als Name habe ich hier Traefik Dashboard gewählt. Als Provider (Schnittstellen) den zuvor erstellten Forward Auth Provider.

Last but not least musste ich dann noch unter Anwendungen => Outposts den vorhandenen Embedded Outpost bearbeiten.
Die Integration habe ich auf Local Docker connection gestellt und bei den Anwendungen habe ich die neu erstellte Anwendung Traefik Dashboard markiert.
Den Outpost noch flugs mit einem Klick auf aktualisieren gespeichert und damit ist die Konfiguration im authentik-Backend soweit fertig.

Als nächster Schritt müssen wir eine neue Middleware für traefik anlegen. Hierzu wird die vorhandene Datei traefik-crowdsec-stack/traefik/dynamic_conf.yml um folgenden Inhalt ergänzt (analog zum vorhanden traefikAuth-Block, unterhalb eben jenes Blockes):

authentik:
  forwardauth:
    address: http://authentik-server: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

Als letzten Konfigurationsschritt wird nun die traefikAuth Middleware durch die authentik Middleware in der Datei traefik-crowdsec-stack/docker-compose.yml verändert:

Vorher:
traefik.http.routers.traefik.middlewares: default@file,traefikAuth@file
Nachher:
traefik.http.routers.traefik.middlewares: default@file,authentik@file

Nun noch abschließend traefik mit docker compose up -d --force-recreate neu starten und anschließen auf https://traefic.deine-domain.de wechseln. Wenn bis hier nichts schief gegangen ist, wird man nun zunächst auf die Loginseite von authentik geleitet und erst nach dem Login auf das Dashboard zurückgeleitet.

Ich werde jetzt auf meinem zweiten Server damit mal ein wenig herumexperimentieren 🙂

Sternmiere
Ehemann, Vater, Nerd, Aikidoka, Bogenschütze, Technikbegeisterer, verrückter Typ — sucht es Euch das passende aus. Es gibt bestimmt noch mehr Attribute, die zu mir passen. Aber für den Moment muss das genügen.