Das ultimative Self-Hosted Zero-Trust VPN mit SSO! | NetBird + Authentik
Übersicht
NetBird ist eine moderne, leichtgewichtige Zero-Trust-Networking-Lösung, mit der du ein sicheres, privates Netzwerk über das Internet aufbauen kannst, ohne die typische Komplexität klassischer VPNs. In diesem Beitrag zeige ich dir Schritt für Schritt, wie du NetBird komplett selbst hostest und zusammen mit Authentik als Identity-Provider und Caddy als Reverse Proxy auf einem einzigen Host betreibst. Das Ergebnis ist ein „All-in-One"-Setup: automatische TLS-Zertifikate, saubere OIDC-Login-Integration, eine übersichtliche Management-Oberfläche und ein sicher angebundenes Netzwerk für deine Server, Dienste und Clients, ideal für dein Homelab oder eine kleine Umgebung, in der du volle Kontrolle über Identität, Zugriff und Daten behalten möchtest.
Das passende Video zum Beitrag findest du hier: https://youtu.be/MllCo5sZAnU
Server
Damit wir das heutige Setup bauen können, brauchen wir einen Server, den wir von überall erreichen können. Am besten macht sich hier ein VPS bei einem beliebigen Hoster. Nach wie vor ist meine Empfehlung hier ganz klar Netcup, da ihr dort die günstigsten, aber zuverlässigen Server bekommt.
Recht versteckt findet ihr auf der Seite einen VPS mit 2 CPUs & 2 GB RAM für 2 € im Monat. Das ist super günstig und reicht für unser heutiges Vorhaben.
Wenn ihr mich ein wenig unterstützen wollt, für zukünftige Videos und euch für einen Server bei Netcup entscheidet, bestellt diesen gerne über meinen untenstehenden Link.
Gerne könnt ihr auch den Gutschein unten verwenden. Bei dem genannten Server gibt dieser leider keinen Rabatt, aber er unterstützt die Zuordnung, dass ihr über meine Empfehlung einen Server dort geordert habt.
Natürlich könnt ihr auch einen Server von anderen Hostern problemlos verwenden.
- 5 € Gutschein-Code: 36nc17222595270
- Günstige VPS-Server bei Netcup hier
*Es handelt sich hierbei um einen Affiliate-Link
Für den 2 € VPS bei Netcup navigiert zum Reiter Server, geht auf Weitere Angebote und wählt dort Weitere vServer Produkte.

DNS-Einträge
Bevor wir mit der Einrichtung starten, sollten wir schon einmal entsprechende DNS-Einträge für die beiden Services hinterlegen. Je nach Provider, wo ihr eure Domain habt, könnt ihr dort A-Records mit der/den entsprechenden IP/s für die gewünschten Subdomains hinterlegen.
In meinem Fall verwalte ich die DNS-Einträge via Cloudflare und habe die Einträge wie folgt erstellt.

Installation
Docker & Docker Compose
Als Erstes benötigen wir Docker & Docker Compose. Das installieren wir am einfachsten mit dem offiziellen Installations-Script von Docker.
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
jq
Damit die Einrichtungs-Scripts richtig funktionieren, benötigen wir das Tool jq. Das installieren wir über apt.
sudo apt install jq
GitHub Repository
Um es möglichst einfach zu machen, habe ich mithilfe der offiziellen Dokumentationen versucht, die Installation der Komponenten so weit wie möglich zu automatisieren. Um die Scripte für die Einrichtung zu nutzen, laden wir als Erstes die GitHub Repository von mir herunter, worin sich alle nötigen Komponenten befinden.
git clone https://github.com/jusecdev/netbird-authentik-setup.git
cd netbird-authentik-setup
Caddy
Um später auf Authentik und auch Netbird zugreifen zu können, ohne viele Ports freigeben zu müssen, nutzen wir Caddy als Reverse-Proxy. Zusätzlich kümmert sich Caddy für uns um die SSL-Zertifikate für die beiden Domains.
Alles, was wir für Caddy benötigen, befindet sich in dem Caddy-Ordner der Repo. Wir finden dort eine bereits fertig nutzbare docker-compose.yml und ein Script, mit dem wir uns ein Caddyfile generieren können, das schon einmal den Eintrag für Authentik hat. Netbird folgt später bei der Einrichtung von Netbird ebenfalls voll automatisiert.
Ich lege nach wie vor am liebsten meine Docker-Compose-Projekte unter /opt an. Also kopieren wir uns einfach den Caddy-Ordner aus unserem aktuellen Verzeichnis nach /opt/.
sudo cp -r caddy /opt/ && cd /opt/caddy
Docker Compose
Die Docker Compose von Caddy ist super simpel und kurz gehalten. Wir geben an, dass Caddy auf den Ports 443 (https), 80 (http) und 443/udp (http3 Protokoll) erreichbar sein soll und wo das Caddyfile liegt. Außerdem hinterlegen wir noch ein Docker-Netzwerk, das wir später für die beiden Services verwenden können, um untereinander eine Verbindung herzustellen. Die fertige Compose haben wir bereits in unserem Verzeichnis liegen.
Caddyfile
Das Caddyfile erstellen wir ganz einfach mit dem Script im Verzeichnis. Das Script fragt uns nach unserer gewünschten Domain für Authentik, hier tragen wir die Domain ein, die wir anfangs im DNS hinterlegt haben, und fragt nach dem Containernamen von Authentik. Diese Einstellung könnt ihr beim Default belassen, wenn ihr Authentik wie nachfolgend einrichtet. Anschließend erhalten wir das Caddyfile mit einigen Security-Headern und einem Eintrag für Authentik.
sudo bash generate-authentik-caddyfile.sh

Start
Caddy ist damit soweit eingerichtet und kann schon mal gestartet werden.
sudo docker compose up -d

Authentik
Weiter geht es mit Authentik. Authentik nutzen wir als Identity Provider für die Anmeldung an Netbird. Wir haben auch die Möglichkeit, weitere Services an Authentik anzubinden.
Bevor wir starten, kopieren wir uns wieder den authentik-Ordner nach /opt/ und navigieren dorthin.
sudo cp -r ~/netbird-authentik-setup/authentik /opt/ && cd /opt/authentik
Einrichtung via authentik-init.sh
Authentik lässt sich super einfach mit wenigen Befehlen und der offiziellen Dokumentation einrichten. Allerdings müssten wir dort einige Änderungen an der Compose vornehmen, um Authentik über Caddy erreichbar zu machen. Also habe ich mir die offizielle docker-compose von der Authentik-Seite genommen und die Anpassungen wie bspw. das Vergeben von Containernamen, Bind-Mount für die Datenbank und vor allem das Hinzufügen des caddy_net bereits vorgenommen.
Damit ihr trotzdem zu jeder Zeit die aktuellste Version nutzt, habe ich das authentik-init.sh Script erstellt, das übernimmt zum einen das Erstellen der Random-Secrets für Authentik & Postgresql, wie in der Dokumentation beschrieben, gleicht gleichzeitig aber auch noch die Image-Tags gegen Authentik ab und bietet euch an, diese via Environment-Variable auf die neuesten anzupassen.
Das Script führen wir wie folgt aus:
sudo bash authentik-init.sh
Anschließend geben wir unsere Authentik-URL ein, dies dient nur dazu, um die korrekte URL zu erhalten, zu der wir danach navigieren müssen, um den initialen Account zu erstellen.

Je nachdem, ob ein neueres Authentik-Image vorhanden ist, werden wir noch gefragt, ob wir updaten wollen.

Zu guter Letzt fragt das Script, ob es Authentik für uns starten soll.

Nachdem Authentik dann gestartet wurde, erhalten wir die URL, unter der wir gleich nach kurzem Warten, bis die erste Initialisierung durch ist, unseren Admin-Account erstellen können.

Jetzt heißt es ein wenig Geduld haben, der erste Start von Authentik dauert einige Minuten.

Erster Login
Nachdem alles gestartet ist, können wir unseren Account erstellen.

Netbird Provider in Authentik
Als Nächstes erstellen wir für Netbird einen Provider in Authentik. Den Provider benötigen wir später für die Authentifizierung mit unserem Benutzer in Authentik.
- Navigiere zu Applications → Providers
- Klicke auf Erstellen
- Wähle OAuth2/OpenID

Konfiguriere den Provider wie folgt:
- Provider Name: Netbird
- Autorisierungs-Flow: default-provider-authorization-explicit-consent (Authorize Application)
- Clienttyp: Öffentlich
- Redirect URIs/Origins:
- Regex: https://auth.deine-domain.de/.*
- Strict: http://localhost:53000
- Signaturschlüssel: authentik Self-signed Certificate

Unter Erweiterte Flow-Einstellungen
- Authentifizierungs-Flow: default-authentication-flow (Welcome to authentik!)

Unter Erweiterte Protokolleinstellungen
-
Den ersten Wert von minutes=1 auf minutes=10

-
Umfang → API & offline_access zu den Scopes hinzufügen

-
Betreffmodus: Basierend auf ID des Benutzers

Speichern
Netbird Applikation in Authentik
Als Nächstes erstellen wir die zugehörige Applikation für den Provider. Hier muss nicht so viel konfiguriert werden.
- Navigiere zu Applications → Applications
- Wähle Erstellen
- Gebe folgendes an:
Name: Netbird
Slug: netbird
Schnittstelle: Netbird

Speichern
Service Account für Netbird
Jetzt erstellen wir noch einen Service Account für Netbird, den wir dann später mit Netbird verwenden, um die Benutzer zu überprüfen.
- Navigiere zu Directory → Users
- Wähle New Service Account
- Anmeldename → netbird
- Haken für Ablaufend entfernen
- Speichern

Das Passwort tauschen wir nachher nochmal aus, mit einem App-Passwort.
Berechtigungen Service Account
In der offiziellen Dokumentation von Netbird soll der Service Account zu der Authentik Admin Gruppe hinzugefügt werden. Da ich im produktiven Umfeld Authentik auch für andere Applikationen nutze, erschien mir diese Berechtigung recht hoch, daher habe ich experimentiert.
Das Ergebnis ist, dass es vollkommen ausreicht, dem Service Account das Recht **can view user** zu geben.
- Navigiere zu Directory → Users
- Gehe auf Root → goauthentik.io
- Wähle den Netbird User
- Gehe auf den Reiter Berechtigung und auf Berechtigung zuweisen

Suche in den Berechtigungen nach can view user und wähle die Berechtigung aus

Speichern
Device Code Flow
Als Letztes konfigurieren wir noch den Device Code Flow. Den benötigen wir für die SSO-Authentifizierung mit Geräten.
- Navigiere zu Flows and Stages → Flows
- Gehe auf Erstellen und gebe folgendes ein
Name: default-device-code-flow
Titel: Device Code Flow
Bezeichnung: Stage Configuration
Authentifizierung: Erfordert Authentifizierung

Jetzt müssen wir den Flow noch zur default-brand hinzufügen.
- Navigiere zu System → Brands
- Gehe auf Bearbeiten bei authentik-default
- Klappe Standard-Flows auf und füge unter Device-Code-Flow den Flow hinzu

Netbird
Kommen wir zum heutigen Herzstück, Netbird. Ich habe hier mit der offiziellen Dokumentation herumexperimentiert und meine Probleme gehabt, das Ganze hinter Caddy zum Laufen zu bringen. Wenn wir nach dem offiziellen Weg gehen würden, müssten wir im Nachgang relativ viel manuell anpassen. Um uns das zu ersparen, habe ich das configure.sh Script von Netbird genommen und verfeinert.
Wir haben jetzt die Möglichkeit, über die setup.env verschiedene Deployment-Methoden zu wählen. Unter anderem natürlich unsere heutige Methode mit einem separat laufenden Caddy auf demselben Host.
Wenn ihr bspw. aber Authentik bereits auf einem anderen Host laufen lassen habt, könnt ihr bspw. auch den Deployment Mode proxy_docker_caddy nutzen, dieser deployed Netbird mit integriertem Caddy.
Solltet ihr keinen Reverse-Proxy nutzen wollen oder einen externen Reverse-Proxy haben, gibt es dafür ebenfalls Deployment Modes.
Außerdem habe ich ein setup.env Example hinzugefügt, das bereits auf Authentik angepasst ist und die Einrichtung damit einfacher gestaltet.
Als Erstes kopieren wir den Ordner netbird ebenfalls nach /opt/ und navigieren dorthin.
sudo cp -r ~/netbird-authentik-setup/netbird /opt/ && cd /opt/netbird
setup.env
Der Großteil der Einrichtung geschieht über die setup.env. Hier geben wir alle Variablen an, die das Script am Ende braucht, um uns Netbird so aufzubauen, wie wir es haben wollen. Für die setup.env gibt es 2 Vorlagen, wir nutzen die auf Authentik abgestimmte Vorlage dafür.
sudo cp setup.env.authentik.example setup.env
sudo nano setup.env
Deployment Mode
Als Erstes wählen wir den Deployment mode proxy_docker. Unser Reverse-Proxy-Netzwerk heißt caddy_net.

Image Tags
Die Tags können wir leer lassen, dann werden automatisch immer die neuesten genommen.

Domains
Unter Domains brauchen wir bloß die Netbird-Domain angeben, dies wird die Domain, wo wir Netbird später erreichen.

OIDC - Authentik
Der spannende Teil OIDC, hier konfigurieren wir alles für Authentik, dass die Anmeldung darüber später klappt. Auch hier habe ich mit der Wiederverwendung der Client-ID-Variable dafür gesorgt, dass wir diese nur einmal hinterlegen müssen.
Es sieht erstmal viel aus, effektiv anpassen müssen wir aktuell nur noch 3 Variablen:
NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT Hier passt ihr den Anfang der Domain auf eure Authentik-Domain an, falls die Applikation anders heißt, müsst ihr den Applikationsnamen ebenfalls anpassen.

Unter Punkt 2. NETBIRD_AUTH_CLIENT_ID hier kommt die Client-ID vom Authentik-Provider rein.

Als Letztes müssen wir ganz unten noch das Passwort vom erstellten Netbird-Benutzer aus Authentik hinterlegen. Dafür erstellen wir uns jetzt nochmal ein ordentliches App-Passwort, das nicht abläuft.
In Authentik unter Directory → Tokens and App Passwords
Hier können wir als Erstes das automatisch erstellte Passwort entfernen, da dieses nach 365 Tagen abläuft.

Jetzt erstellen wir über den Button Erstellen ein neues.

Jetzt können wir das Passwort kopieren, indem wir ganz rechts auf die beiden Seiten gehen.

Das fügen wir jetzt bei der Variable NETBIRD_IDP_MGMT_EXTRA_PASSWORD ganz unten ein.

Am Ende sollte der OIDC-Part ungefähr so bei euch aussehen.

LetsEncrypt / ReverseProxy
In dem Abschnitt solltet ihr nur sicherstellen, dass die Variable NETBIRD_DISABLE_LETSENCRYPT auf true steht. Zertifikate holen wir uns später nämlich über Caddy.
Den Rest könnt ihr so lassen, wie er ist, die Ports werden entsprechend eingetragen, später automatisch im Caddyfile berücksichtigt.

Data paths (bind mounts)
Hier braucht ihr keine Änderungen vornehmen. Das Verzeichnis mit allen Daten landet am Ende in ./artifacts, das Verzeichnis ist so von der offiziellen Doku übernommen. Das Script ist so umgeschrieben, dass es für alle Container Bind-Mounts erstellt, also direkt dort im Verzeichnis können alle Daten gefunden werden, das finde ich persönlich immer ein wenig besser, da es das Backupen simpler macht, da alles beisammen ist.

Extra settings
Hier könnt ihr die interne Netbird-Domain anpassen. In Netbird erhält jeder Peer am Ende einen Namen mit einer Domain, default netbird.selfhosted über diese Domain könnt ihr die Geräte ebenfalls erreichen, wenn ihr das Gerät, an dem ihr seid, mit Netbird verbunden ist. also bspw.
client1.netbird.selfhosted

Relay settings
Auch hier könnt ihr die Variablen einfach leer lassen.

Store config (database)
Ein Part, den ich ebenfalls im verfeinerten Script hinzugefügt habe. Netbird wird default mit sqlite ausgeliefert, es gibt aber auch die Möglichkeit, eine PostgreSQL-Datenbank zu nutzen. Ich persönlich bin eher PostgreSQL-Fan, weshalb ich die Option mit eingebaut habe.
Wenn ihr es bei den Defaults belasst, also die Auswahl auf postgres und die Variable NETBIRD_USE_INTERNAL_POSTGRES=true, wird ein Postgres-Container mit in die Compose gepackt, der dann intern genutzt wird. Wenn ihr Postgres nicht mögt, könnt ihr die obere Variable einfach auf sqlite ändern und den Rest so belassen.
Bei Postgres müsst ihr die Variable NETBIRD_POSTGRES_PASSWORD nicht ausfüllen, ein sicheres Passwort wird im Hintergrund automatisch generiert. NETBIRD_STORE_ENGINE_POSTGRES_DSN kann ebenfalls leer bleiben und wird automatisch ermittelt.

Jetzt nur noch speichern und wir können mit dem Script fortfahren.
configure.sh
Alle Variablen sind jetzt gesetzt und wir können das angepasste configure.sh Script starten. Dies nimmt die Einrichtung für Netbird vor, am Ende gibt es uns die Möglichkeit, das Caddyfile um die Netbird-Einstellungen zu ergänzen, diese sind etwas komplexer, da verschiedene Pfade zu verschiedenen Containern müssen, weshalb ich mich entschlossen habe, den Teil ebenfalls automatisch erstellen zu lassen.
sudo bash configure.sh
Das Script läuft durch und wir sehen unten das Caddy-Snippet, dies können wir jetzt automatisch hinzufügen lassen und Caddy neustarten.

Start
Zu guter Letzt können wir nun auch Netbird starten. Dafür nutzen wir entweder den Befehl, der uns gezeigt wurde.
sudo docker compose -f ./artifacts/docker-compose.yml up -d
Oder navigieren in ./artifacts und starten die Container mit docker compose up
cd ./artifacts
sudo docker compose up -d

Login in Netbird
Nachdem alle Container gestartet sind, können wir jetzt zu unserer Netbird-Domain im Browser navigieren und uns mit unserem Authentik-Account anmelden.

Mit Zustimmung und Klick auf Weiter landen wir dann auf unserem Netbird-Dashboard.

Peer hinzufügen
Neue Peers können wir über 2 Wege hinzufügen. Entweder per SSO mit unserem Account oder via Setup Keys
SSO
Wenn wir im Dashboard auf Add Peer gehen, sehen wir die Installationsanleitung für alle Betriebssysteme und die URL, die wir angeben müssen, um uns an unserer Instanz anzumelden.

Bei allen Geräten mit GUI und Zugriff auf einen Browser werden wir dann weitergeleitet zur Anmeldung, wo wir uns mit unserem Authentik-Account autorisieren. Bei Linux bspw. erhalten wir eine URL, die wir in einem Browser öffnen müssen. Hierfür haben wir den Device Code Flow konfiguriert.



Setup Key
Setup Keys sind sehr praktisch für Linux-Server und Co. Diese können im Dashboard im Reiter Setup Keys erstellt werden und direkt mit bspw. entsprechenden Gruppen vorkonfiguriert werden.

Wenn wir einen Key erstellen, wird uns der Key angezeigt. Um zu wissen, wie wir den verwenden können, klicken wir auf Install NetBird

Dort erhalten wir die genauen Befehle/Anweisungen.



Firewall
Unter einem meiner letzten Videos gab es einen Kommentar dazu, dass der Server ohne Firewall am Netz hängt. Für dieses Video habe ich ein Firewall-Script erstellt, das ebenfalls im Repository enthalten ist. Das führen wir jetzt noch einmal aus, damit werden alle nötigen Ports freigegeben und der Rest blockiert. Auch IPv6 wird komplett geblockt und Docker hat keine Chance, sich vor die Regeln zu drängen.
cd ~/netbird-authentik-setup
sudo bash firewall.sh

Damit sind nur noch die benötigten Ports auf dem Server erreichbar.
SSH könnt ihr weiter absichern mit 2-Faktor-Authentifizierung usw. mit diesem Guide hier.