🌐 Netzwerk

Homelab-Identitätsschutz mit Authentik und Nginx Proxy Manager

Homelab-Identitätsschutz mit Authentik und Nginx Proxy Manager
⚠️ Hinweis: Alle Guides auf smoth.me dienen ausschließlich zu Informations- und Lernzwecken. Die Umsetzung erfolgt auf eigene Gefahr. Wir übernehmen keine Haftung für Schäden, Datenverluste oder Systemausfälle, die durch die Anwendung dieser Anleitungen entstehen können. → Vollständiger Haftungsausschluss

Moin, liebe Admins und Homelab-Enthusiasten!

Heute tauchen wir in ein Thema ein, das in der Enterprise-Welt unter dem Namen "Entra ID mit Conditional Access Policies" bekannt ist, aber dessen Kernprinzipien für uns Heimlaboranten genauso relevant sind: Der Schutz unserer Identitäten und der Zugriff auf unsere Dienste. Wenn du wie ich seit Jahren mit Proxmox, Docker, Home Assistant und N8N arbeitest, weißt du, wie schnell sich die Anzahl der Dienste und damit auch die Angriffsfläche erhöht. Ein zentraler, sicherer Zugang ist da Gold wert.

Die Idee hinter Entra ID (dem früheren Azure Active Directory) und Conditional Access ist simpel, aber mächtig: Wer darf wann, von wo und mit welchem Gerät auf welche Ressource zugreifen? Das ist der Kern der Zero-Trust-Architektur, bei der keinem Nutzer oder Gerät per se vertraut wird, sondern jeder Zugriff explizit verifiziert wird. Während Entra ID ein mächtiges Cloud-Tool für große Unternehmen ist, können wir diese Philosophie auch in unserem Homelab umsetzen. Und genau das machen wir heute!

In meiner Erfahrung stolpern viele, die ihre Dienste im Homelab absichern wollen, über die Komplexität der verschiedenen Authentifizierungsmethoden. Jeder Dienst hat seine eigene Benutzerverwaltung, was schnell unübersichtlich wird. Mein Tipp: Zentralisiere deine Identitäten! Wir nutzen dafür Authentik als unseren Identity Provider (IdP) – quasi unser eigenes kleines Entra ID für zu Hause. Und um die Zugriffe dann auch wirklich auf Basis von Bedingungen zu steuern, setzen wir Nginx Proxy Manager (NPM) als Reverse Proxy und Authentifizierungs-Gateway ein.

Dieses Setup ermöglicht uns, Multi-Faktor-Authentifizierung (MFA) zu erzwingen, Zugriffe auf bestimmte IP-Bereiche zu beschränken oder sogar spezifische Benutzergruppen für bestimmte Dienste zu definieren – alles zentral und übersichtlich. Klingt gut? Dann legen wir los!

Voraussetzungen – Was du mitbringen solltest

Bevor wir loslegen, hier eine Checkliste, damit du optimal vorbereitet bist:

  • Ein laufender Docker-Host: Egal ob auf einem Proxmox LXC, einer VM oder direkt auf einem Raspberry Pi – du brauchst einen Server, auf dem Docker und Docker Compose läuft.
  • Grundlagenwissen Docker Compose: Wir werden beide Dienste (Authentik und Nginx Proxy Manager) über Docker Compose bereitstellen.
  • Eine eigene Domain: Auch wenn es nur eine Subdomain von DuckDNS oder eine Free-Domain ist. Wir brauchen sie, um Let's Encrypt-Zertifikate zu nutzen und die Dienste sauber über URLs zu erreichen. Beispiel: auth.deinedomain.de für Authentik, homeassistant.deinedomain.de für Home Assistant.
  • DNS-Einträge: Stelle sicher, dass deine Domain bzw. Subdomains auf die öffentliche IP-Adresse deines Homelabs (oder auf die lokale IP deines Reverse Proxys, wenn du nur intern arbeitest) zeigen.
  • Netzwerkkenntnisse: Port-Weiterleitungen (80/443 TCP) auf deinem Router sind notwendig, wenn du von außen auf deine Dienste zugreifen möchtest.
  • Ein bestehender Dienst: Am besten einen, den du absichern möchtest, z.B. Home Assistant, N8N, Portainer oder eine eigene Webanwendung.

Das Konzept: Zero Trust im Homelab mit Authentik und NPM

Bevor wir in die Befehle springen, lass uns kurz das zugrundeliegende Konzept skizzieren. Wir wollen die Prinzipien von Entra ID Conditional Access auf unser Homelab übertragen:

  • Authentik als zentraler Identitätsprovider (IdP): Hier verwalten wir alle Benutzer, Gruppen und legen fest, welche Authentifizierungsmethoden (Passwort, MFA) erlaubt sind. Authentik spricht Standards wie OAuth2 und OpenID Connect (OIDC).
  • Nginx Proxy Manager als Reverse Proxy und Policy Enforcement Point: Alle Anfragen an unsere internen Dienste laufen zuerst über NPM. NPM ist nicht nur für das Routing und SSL-Zertifikate zuständig, sondern auch dafür, zu prüfen, ob ein Zugriff überhaupt erlaubt ist. Dafür leitet er Authentifizierungsanfragen an Authentik weiter.
  • Conditional Access durch Authentik-Policies: In Authentik definieren wir Regeln. Zum Beispiel: "Benutzer X darf nur zugreifen, wenn er MFA verwendet UND seine IP-Adresse aus dem internen Netzwerk stammt." Diese Policies werden durch Authentik überprüft, wenn NPM eine Anfrage stellt.

Wichtig zu wissen: Der Dienst selbst (z.B. Home Assistant) muss nicht unbedingt wissen, wer der Benutzer ist oder welche komplexen Regeln gelten. Er vertraut darauf, dass der Reverse Proxy (NPM) die Authentifizierung und Autorisierung bereits durchgeführt hat und ihm die Benutzerinformationen in Headern übermittelt.

Schritt-für-Schritt-Anleitung: Identitäten schützen

Schritt 1: Authentik installieren

Wir starten mit der Installation von Authentik. Das geht am einfachsten mit Docker Compose. Erstelle einen Ordner, z.B. /opt/authentik, und darin eine docker-compose.yml:

version: '3.8'

services:
  authentik:
    image: goauthentik/authentik:2023.10.3 # Prüfe die aktuelle Version!
    restart: unless-stopped
    command: server
    environment:
      AUTHENTIK_SECRET_KEY: <EIN_SEHR_LANGER_ZUFALLSSTRING> # Wichtig: Hier einen sicheren, langen String einfügen!
      AUTHENTIK_POSTGRESQL__HOST: postgres
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_LOG_LEVEL: info
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
    ports:
      - "9000:9000" # Web-Interface
      - "9443:9443" # Outpost HTTPS (wird später von NPM genutzt)
    depends_on:
      - postgres
      - redis

  worker:
    image: goauthentik/authentik:2023.10.3 # Gleiche Version wie oben
    restart: unless-stopped
    command: worker
    environment:
      AUTHENTIK_SECRET_KEY: <GLEICHER_ZUFALLSSTRING_WIE_OBEN>
      AUTHENTIK_POSTGRESQL__HOST: postgres
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_LOG_LEVEL: info
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:15-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: authentik
      POSTGRES_USER: authentik
      POSTGRES_PASSWORD: <EIN_SICHERES_PASSWORT> # Sicheres Passwort für die DB
    volumes:
      - ./database:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    restart: unless-stopped

Wichtig: Ersetze <EIN_SEHR_LANGER_ZUFALLSSTRING> und <EIN_SICHERES_PASSWORT> durch echte, sichere Werte! Ich nutze dafür gerne einen Passwortmanager oder generiere sie direkt im Terminal mit openssl rand -base64 64.

Speichere die Datei und starte Authentik im Verzeichnis mit:

docker compose up -d

Nach ein paar Minuten sollte Authentik laufen. Du kannst es unter http://<deine_server_ip>:9000 erreichen. Beim ersten Start wirst du aufgefordert, einen Admin-Benutzer zu erstellen. Mach das und merke dir die Zugangsdaten gut!

Schritt 2: Authentik konfigurieren – Dein erster Dienst

Jetzt konfigurieren wir Authentik, um einen Dienst abzusichern. Als Beispiel nehmen wir Home Assistant. Logge dich in die Authentik UI ein.

2.1. Eine Anwendung erstellen

Gehe zu Applications -> Applications und klicke auf Create.

  • Name: Home Assistant
  • Slug: homeassistant (wird für URLs genutzt)

Klicke auf Next.

2.2. Einen Provider erstellen (OpenID Connect)

Wähle OpenID Connect Provider aus. Dies ist der Standard, den viele Dienste und auch unser Reverse Proxy verstehen.

  • Name: Home Assistant OIDC Provider
  • Authorization flow: default-authorization-flow (oder einen eigenen, falls du schon einen hast)
  • Client ID: Generiere eine zufällige ID (Authentik macht das meist automatisch)
  • Client Secret: Generiere ein zufälliges Secret (Authentik macht das auch automatisch). Dieses Secret ist wichtig – kopiere es dir!
  • Redirect URIs: Hier tragen wir die URLs ein, zu denen Authentik den Benutzer nach erfolgreicher Anmeldung zurückleiten darf. Das ist ein wichtiger Sicherheitsmechanismus. Für NPM ist das normalerweise https://<deine_homeassistant_domain>/outpost.goauthentik.io/auth/oauth/callback. Wenn du Home Assistant selbst direkt mit Authentik verbinden würdest, bräuchtest du auch die Home Assistant Callback-URL hier. Für unser Setup mit NPM reicht die NPM Outpost URL.

Klicke auf Finish.

Jetzt hast du eine Anwendung und einen zugehörigen OIDC Provider. Die Client ID und das Client Secret des Providers werden wir später für NPM benötigen.

2.3. Eine Policy für Conditional Access erstellen

Gehe zu Policies -> Policies und klicke auf Create. Wähle Expression Policy.

  • Name: Require MFA for Home Assistant
  • Execution Stage: authentication
  • Expression:
    return ak_user.is_authenticated and ak_user.has_mfa_devices

    Diese Policy prüft, ob der Benutzer angemeldet ist UND mindestens ein MFA-Gerät registriert hat. Nur dann ist der Zugriff erlaubt.

Klicke auf Finish.

Als Alternative könntest du auch eine IP-basierte Policy erstellen:

  • Name: Allow Internal IPs
  • Execution Stage: authentication
  • Expression:
    
    # Beispiel: Erlaube nur IPs aus dem 192.168.1.0/24 Netz
    # Die IP-Adresse, von der die Anfrage kommt, ist in 'request.ip'
    internal_ips = ["192.168.1.0/24"]
    for ip_range in internal_ips:
        if request.ip.is_in(ip_range):
            return True
    return False # Standardmäßig verweigern
            

2.4. Flow mit Policy verknüpfen

Damit die Policy auch angewendet wird, müssen wir sie einem Flow zuweisen. Gehe zu Flows & Stages -> Flows. Wähle den default-authentication-flow (oder den Flow, den du beim Provider ausgewählt hast) und bearbeite ihn. Unter Policy Bindings fügst du deine neu erstellte Policy hinzu.

Mein Tipp: Erstelle für jede Anwendung einen separaten Authorization Flow und weise diesem Flow dann die spezifischen Policies zu. Das macht das Management später übersichtlicher.

Schritt 3: Nginx Proxy Manager installieren

Nun installieren wir Nginx Proxy Manager (NPM). Auch hier wieder mit Docker Compose. Erstelle einen Ordner, z.B. /opt/nginx-proxy-manager, und darin eine docker-compose.yml:

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80' # HTTP-Zugriff
      - '443:443' # HTTPS-Zugriff
      - '81:81' # Admin-Interface von NPM
    environment:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: <EIN_SICHERES_PASSWORT_FUER_NPM_DB>
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db

  db:
    image: 'mariadb:10'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: <EIN_SEHR_SICHERES_ROOT_PASSWORT> # Sicheres Root-Passwort
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: <EIN_SICHERES_PASSWORT_FUER_NPM_DB> # Gleiches Passwort wie oben
    volumes:
      - ./mysql:/var/lib/mysql

Ersetze die Passwörter durch sichere Werte. Speichere und starte NPM:

docker compose up -d

Nach dem Start ist das Admin-Interface unter http://<deine_server_ip>:81 erreichbar. Die Standardzugangsdaten sind admin@example.com / changeme. Ändere diese sofort!.

Schritt 4: Nginx Proxy Manager als Authentifizierungs-Gateway einrichten

Jetzt kommt der spannende Teil: Wir bringen NPM dazu, Authentik zur Authentifizierung zu nutzen.

4.1. Proxy Host für Authentik erstellen

Bevor wir Dienste absichern, muss Authentik selbst über NPM erreichbar sein. Das ist wichtig, da NPM die Authentifizierungsanfragen an Authentik weiterleiten muss.

Gehe in NPM zu Hosts -> Proxy Hosts und klicke auf Add Proxy Host.

  • Domain Names: auth.deinedomain.de (oder wie du deine Authentik-URL nennen möchtest)
  • Scheme: http
  • Forward Hostname / IP: authentik (der Name des Authentik-Containers aus der docker-compose.yml)
  • Forward Port: 9000
  • Block Common Exploits: Ja
  • Cache Assets: Nein
  • Websockets Support: Ja

Unter dem Tab SSL:

  • SSL Certificate: Request a new SSL Certificate (Let's Encrypt)
  • Force SSL: Ja
  • Email Address: Deine E-Mail-Adresse für Let's Encrypt
  • I Agree to the Let's Encrypt Terms of Service: Ja

Speichere den Host. Nach kurzer Zeit sollte dein Authentik-Interface unter https://auth.deinedomain.de erreichbar sein, inklusive gültigem SSL-Zertifikat.

4.2. Authentik Outpost in NPM integrieren

Authentik nutzt sogenannte Outposts, um die Authentifizierung zu handeln. Der Nginx-Outpost ist in unserem Authentik-Docker-Compose bereits integriert und lauscht auf Port 9443.

Wir benötigen einen weiteren Proxy Host in NPM, der speziell für den Outpost zuständig ist.

Gehe in NPM zu Hosts -> Proxy Hosts und klicke auf Add Proxy Host.

  • Domain Names: outpost.deinedomain.de (oder eine andere Subdomain für den Outpost)
  • Scheme: https
  • Forward Hostname / IP: authentik
  • Forward Port: 9443

Unter dem Tab SSL: Wieder ein Let's Encrypt-Zertifikat anfordern und Force SSL aktivieren.

Speichere den Host.

4.3. Proxy Host für Home Assistant mit Authentik-Schutz

Jetzt erstellen wir den eigentlichen Proxy Host für Home Assistant, der Authentik zur Authentifizierung nutzt.

Gehe in NPM zu Hosts -> Proxy Hosts und klicke auf Add Proxy Host.

  • Domain Names: homeassistant.deinedomain.de
  • Scheme: http (Home Assistant läuft intern meist über HTTP)
  • Forward Hostname / IP: Die interne IP oder der Docker-Container-Name von Home Assistant (z.B. 192.168.1.100 oder homeassistant)
  • Forward Port: 8123 (Standardport von Home Assistant)

Unter dem Tab SSL: Wieder ein Let's Encrypt-Zertifikat anfordern und Force SSL aktivieren.

Jetzt kommt der entscheidende Teil: Unter dem Tab Advanced fügen wir die Nginx-Konfiguration ein, die die Authentifizierung an Authentik delegiert:

# Authentik Outpost Konfiguration für Nginx Proxy Manager
# Ersetze outpost.deinedomain.de durch die Domain deines Authentik Outposts

auth_request https://outpost.deinedomain.de/outpost.goauthentik.io/auth/nginx;
error_page 401 = /outpost.goauthentik.io/auth/nginx;

auth_request_set $auth_authentik_result $upstream_http_x_authentik_auth_result;
auth_request_set $auth_authentik_name $upstream_http_x_authentik_auth_user_name;
auth_request_set $auth_authentik_groups $upstream_http_x_authentik_auth_user_groups;
auth_request_set $auth_authentik_email $upstream_http_x_authentik_auth_user_email;
auth_request_set $auth_authentik_uid $upstream_http_x_authentik_auth_user_id;

proxy_set_header X-Authentik-Auth-Result $auth_authentik_result;
proxy_set_header X-Authentik-Auth-User-Name $auth_authentik_name;
proxy_set_header X-Authentik-Auth-User-Groups $auth_authentik_groups;
proxy_set_header X-Authentik-Auth-User-Email $auth_authentik_email;
proxy_set_header X-Authentik-Auth-User-ID $auth_authentik_uid;

proxy_pass_header Set-Cookie;
proxy_pass_request_headers on;

Ganz wichtig: Ersetze https://outpost.deinedomain.de mit der tatsächlichen URL deines Authentik Outposts, die du in Schritt 4.2 konfiguriert hast!

Diese Konfiguration sorgt dafür, dass jede Anfrage an homeassistant.deinedomain.de zuerst an den Authentik Outpost zur Prüfung geschickt wird. Ist der Benutzer nicht authentifiziert oder erfüllt die Policies nicht, wird er auf die Authentik-Anmeldeseite umgeleitet. Nach erfolgreicher Anmeldung leitet Authentik ihn zurück zu Home Assistant und sendet die Benutzerinformationen in HTTP-Headern, die Home Assistant (oder andere Dienste) dann nutzen können.

Speichere den Proxy Host.

Schritt 5: Dienste hinter Authentik absichern (Beispiel Home Assistant)

Jetzt ist dein Home Assistant unter https://homeassistant.deinedomain.de erreichbar. Wenn du versuchst, darauf zuzugreifen, solltest du automatisch auf die Anmeldeseite deines Authentik-Servers umgeleitet werden.

Logge dich mit einem Benutzer ein, der die von dir definierte Policy (z.B. MFA) erfüllt. Wenn alles korrekt konfiguriert ist, wirst du nach erfolgreicher Anmeldung zu Home Assistant weitergeleitet.

Herzlichen Glückwunsch! Du hast erfolgreich eine Zero-Trust-Architektur für dein Homelab implementiert, die deine Identitäten schützt und den Zugriff auf deine Dienste basierend auf Bedingungen steuert – ganz im Sinne der Conditional Access Policies, die du vielleicht aus der Enterprise-Welt kennst.

Häufige Fehler und Lösungen

Bei so einem komplexen Setup kann immer mal etwas schiefgehen. Hier sind ein paar typische Stolpersteine, über die ich selbst schon gestolpert bin:

1. Falsche Redirect URIs in Authentik

  • Problem: Nach der Anmeldung in Authentik landest du auf einer Fehlerseite mit "Invalid redirect_uri" oder ähnlichem.
  • Ursache: Die in Authentik für den OIDC Provider hinterlegten Redirect URIs stimmen nicht mit der tatsächlichen Callback-URL deines Nginx Proxy Managers überein.
  • Lösung: Überprüfe im Authentik Admin-Interface unter Applications -> Providers deinen OIDC Provider. Stelle sicher, dass die Redirect URI für NPM korrekt ist, typischerweise https://<deine_dienst_domain>/outpost.goauthentik.io/auth/oauth/callback. Achte auf HTTPS und die korrekte Subdomain.

2. Nginx Proxy Manager `auth_request` Probleme

  • Problem: Du wirst nicht zur Authentik-Anmeldeseite umgeleitet, sondern siehst einen Nginx-Fehler (z.B. 500 Bad Gateway oder 401 Unauthorized), oder die Seite lädt endlos.
  • Ursache: Die auth_request URL in der Advanced-Konfiguration deines Proxy Hosts zeigt auf eine falsche Adresse oder der Authentik Outpost ist nicht erreichbar.
  • Lösung:
    1. Vergewissere dich, dass der Outpost-Proxy-

Weitere Guides aus "Netzwerk"

Dein Heimnetz auf Überholspur: Glasfaser-Speed richtig nutzen
Dieser Praxis-Guide zeigt dir, wie du dein Heimnetzwerk optimierst, um die volle Geschwindigkeit dei…
Dein Heim als KI-Wächter: Anomalien im Netzwerk erkennen
Lerne, wie du ein verteiltes Sensornetzwerk in deinem Heim aufbaust, um ungewöhnliche Aktivitäten un…
AdGuard Home im Docker: Dein DNS-Filter für das Heimnetz
Richte AdGuard Home in einem Docker-Container auf deinem Proxmox-Server ein, um dein gesamtes Heimne…
Entra ID: Identitäten mit Conditional Access Policies schützen
Lerne, wie du mit Conditional Access Policies in Entra ID eine robuste Zero-Trust-Architektur aufbau…