Homelab-Identitätsschutz mit Authentik und Nginx Proxy Manager
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.defür Authentik,homeassistant.deinedomain.defü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_devicesDiese 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 derdocker-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.100oderhomeassistant) - 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_requestURL in der Advanced-Konfiguration deines Proxy Hosts zeigt auf eine falsche Adresse oder der Authentik Outpost ist nicht erreichbar. - Lösung:
- Vergewissere dich, dass der Outpost-Proxy-