Zweifaktor wäre nicht schlecht

Wenn ich Services ans Internet hänge, dann möchte ich schon Zweifaktor-Authentifizierung haben. Authentik schien mir mit seiner Enterprise-Ausrichtung sinnvoller, als Authelia. Wie sich das schlägt sieht man in diesem Beitrag.

Authentik konfigurieren

Zuerst einmal einen Snapshot erstellen, dann kann man einfach und komfortabel den ganzen Container zurückrollen, falls etwas schief geht bei der Konfiguration:

Bei Zeile drei braucht es den Fully Qualified Domain Name (FQDN), anstelle der lokalen IP-Adresse:

Aber warum überhaupt? Das habe ich den GPT-4o-Bot gefragt und das war die Antwort:

Und speziell für diesen Fall:

Und was passiert, wenn man in so einem Fall (Caddy + Tailscale) von IP-Adresse auf FQDN wechselt:

Also entsprechend die Angaben ändern, dann im LXC Container die Docker Container runterfahren mit docker compose down und gegebenenfalls gleich Updaten mit docker compose pull

… und wieder hochfahren mit docker compose up -d:

Dann funktioniert hoffentlich noch alles. Der “Connection error, reconnecting…” Fehler ist leider noch immer da:

Aber schauen wir uns das später an. Jetzt geht es daran Paperless ngx einzubinden.

Paperless ngx in Authentik einbinden

Paperless ngx ist eine Dokumentenverwaltungssoftware für den Heimserver. Um dieses Programm einzubinden bietet sich die offizielle Dokumentation von Authentik an.

Zuerst einen neuen “provider” hinzufügen, hier laut Anleitung “OAuth2/OpenID Provider”…

… mit dem Namen Paperless Redirect URI: https://paperless.company/accounts/oidc/authentik/login/callback/ (paperless.company durch den eigenen FQDN ersetzen) und am Besten bei “Authorization flow” die explizite Option auswählen. Das gibt mehr Transparenz, auch wenn die Nutzer beim ersten Mal explizit Zustimmung geben müssen, dass Paperless Zugriff auf ihren Authentik-Account bekommt. Dieses Fenster…

… mit den besagten Daten ausfüllen. Bei “Redirect URIs/Origins (RegEx)” kann und soll man den Weiterleitungsweg explizit angeben, in dieser RegEx-freundlichen Art und Weise: ^https://paperless\.mywebsite\.com/accounts/oidc/authentik/login/callback/$.

Anschließend kann man die “Application” hinzufügen…

… und wie folgt ausfüllen:

Name: Paperless Slug: paperless Provider: den gerade erstellen Provider auswählen

Und Speichern.

Paperless sagen wo der Token den Most holt

Jetzt müssen wir noch Paperless NGX beibringen, dass sich jetzt Authentik um die Anmeldescherereien kümmert. Dazu erstellen wir vorher wieder einen Snapshot vom Container, damit man bei Fehlkonfigurationen leicht auf einen funktionalen Stand zurückkehren kann:

Dann kann man sich die docker-compose.yml von Paperless NGX vorknüpfen und mit diesen Zeilen erweitern:

environment:
  PAPERLESS_APPS: allauth.socialaccount.providers.openid_connect
  PAPERLESS_SOCIALACCOUNT_PROVIDERS: >
    {
      "openid_connect": {
        "APPS": [
          {
            "provider_id": "authentik",
            "name": "Authentik",
            "client_id": "<Client ID>",
            "secret": "<Client Secret>",
            "settings": {
              "server_url": "https://auth.mywebsite.com/application/o/paperless/.well-known/openid-configuration"
            }
          }
        ],
        "OAUTH_PKCE_ENABLED": "True"
      }
    }
 

Das relevante Teil der yaml-Config schaut dann so aus:

{...}
 
  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
      - gotenberg
      - tika
    ports:
      - "8000:8000"
    volumes:
      - data:/usr/src/paperless/data
      - media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - /home/paperless/paperless-ngx/consume:/usr/src/paperless/consume
    env_file: docker-compose.env
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
      PAPERLESS_TIKA_ENABLED: 1
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
      PAPERLESS_TIKA_ENDPOINT: http://tika:9998
      # OAuth2 Configuration
      PAPERLESS_APPS: allauth.socialaccount.providers.openid_connect
      PAPERLESS_SOCIALACCOUNT_PROVIDERS: >
        {
          "openid_connect": {
            "APPS": [
              {
                "provider_id": "authentik",
                "name": "Authentik",
                "client_id": "your-client-id",
                "secret": "your-client-secret",
                "settings": {
                  "server_url": "https://auth.mywebsite.com/application/o/paperless/.well-known/openid-configuration"
                }
              }
            ],
            "OAUTH_PKCE_ENABLED": "True"
          }
        }
 
 
{...}
 

Die server_url, client_id und secret müssen angepasst werden. Letztere finden sich unter dem vorhin erstellten Paperless Provider in Authentik und müssen eingefügt werden. Diese kann man, wenn man möchte auch in die docker-compose.env Umgebungsvariablen-Konfig-Datei auslagern, hier dazu die offizielle Docker-Doku. Ich habe es aber einmal so gelassen und die Umgebungsvariablen sind direkt in der yaml-Konfig drinnen.

Nun kann man den Paperless-Container neustarten.

Caddy konfigurieren

Jetzt müssen wir noch Caddy, bzw. das Caddyfile, anpassen. Das kann so aussehen:

paperless.website.at {
    route {
        # Forward authentication to Authentik's Embedded Outpost
        forward_auth https://auth.website.at {
            uri /application/o/paperless/authenticate/
            copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt
            trusted_proxies private_ranges
        }

        # Proxy authenticated requests to Paperless NGX
        reverse_proxy 101.71.84.52:8000 {
            header_up X-Forwarded-Proto {scheme}
            header_up X-Forwarded-For {remote_host}
            header_up Host {host}
        }
    }
}

Und mit caddy reload die Konfiguration aktualisieren.

Outpost aktualisieren? Oder halt nicht..

Der Versuch dem Outpost beizubringen, dass er jetzt für Paperless zuständig ist, kann ich mir in die Haare schmieren, denn es fehlt einfach die Application-Auswahl:

Ob das mit diesem Bug zu tun hat? Keine Ahnung, aber es will nicht. Es ist schon etwas ärgerlich. Die Komplexität von Authentik lässt mich fast wieder zu Authelia wechseln. Aber ich werde es noch weiter probieren. Irgendwann muss es ja doch funktionieren.

Fazit

Mit Mehrfaktor-Authentifizierung kann man sehr schnell sehr viel Zeit versenken. Besonders Authentik mit seinen unzähligen Ansätzen können einen schon mal fast wahnsinnig werden lassen. Aber schauen wir uns das ein andermal an.