NetBird selbst hosten: Fernwartung mehrerer Kundennetze über einen einzigen Browser-Desktop
NetBird 0.83.0 hinter einem vorhandenen Nginx Proxy Manager selbst hosten, einen Webtop als Admin-Desktop für alle Kunden nutzen und jedes Kundennetz über einen Routing-Peer mit engen Regeln anbinden. Mit der trustedPeers-Falle, Lösungen für mehrfach genutzte 192.168.178.0/24, Backup und Restore.
Mit KI erstellt – redaktionelle Prüfung ausstehend
Werbung Mit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Statt je Kunde eigenem Tunnel, Client und Admin-Desktop nutzt diese Anleitung eine selbst gehostete NetBird-Steuerzentrale hinter einem vorhandenen Nginx Proxy Manager (NPM), einen einzigen Browser-Desktop (Webtop) für alle Kunden und je Kunde einen Routing-Peer im Kunden-LAN. Grundlage sind NetBird 0.83.0 mit dem kombinierten Container netbirdio/netbird-server, Dashboard v2.97.0 und NPM 2.17.0. Dafür betreiben Sie den Server selbst und brauchen laut Doku zusätzlich UDP-Port 3478.
Voraussetzungen
- Linux-Server mit öffentlicher IPv4, laut NetBird-Doku mindestens 1 CPU und 2 GB RAM, dazu Reserve für den Webtop:
nproc; free -h - Docker mit Compose-Plugin:
docker compose version - Nginx Proxy Manager 2.x in Docker auf demselben Server:
docker ps --filter ancestor=jc21/nginx-proxy-manager - Eine Domain, deren A-Record auf den Server zeigt:
dig +short netbird.example.com - Offene Ports: TCP 443 über NPM, TCP 80 für die Let’s-Encrypt-Anfrage des NPM und laut NetBird-Doku UDP 3478 direkt zum NetBird-Server
- Je Kunde ein Docker-Host im Kunden-LAN, zum Beispiel ein NAS oder Mini-PC
curlundjqauf dem Server:jq --version
Getestet mit NetBird 0.83.0 (Server und Client), Dashboard v2.97.0, Nginx Proxy Manager 2.17.0 und dem Image lscr.io/linuxserver/webtop:debian-xfce-670099a5-ls221. Grundlagen ohne vorhandenen Proxy: NetBird mit Docker installieren.
Schritt 1: Docker-Netz des NPM ermitteln
NetBird tritt dem Docker-Netz des NPM bei. Ermitteln Sie Netz und Adressbereich:
$ docker network ls
$ docker network inspect npm_default -f '{{(index .IPAM.Config 0).Subnet}}'Der Befehl gibt genau ein Netz in CIDR-Schreibweise aus, im Test:
172.19.0.0/16Schritt 2: NetBird-Server anlegen und starten
Die Dateien entsprechen der Ausgabe von getting-started.sh v0.83.0 mit Option „Nginx Proxy Manager“, mit festen Versionen und korrigierter Vertrauensliste.
$ mkdir -p /opt/netbird && cd /opt/netbirdservices:
# UI dashboard
dashboard:
image: netbirdio/dashboard:v2.97.0
container_name: netbird-dashboard
restart: unless-stopped
networks: [netbird, npm_default]
ports:
- '127.0.0.1:8080:80'
env_file:
- ./dashboard.env
logging:
driver: "json-file"
options:
max-size: "500m"
max-file: "2"
# Combined server (Management + Signal + Relay + STUN)
netbird-server:
image: netbirdio/netbird-server:0.83.0
container_name: netbird-server
restart: unless-stopped
networks: [netbird, npm_default]
ports:
- '127.0.0.1:8081:80'
- '3478:3478/udp'
volumes:
- netbird_data:/var/lib/netbird
- ./config.yaml:/etc/netbird/config.yaml
command: ["--config", "/etc/netbird/config.yaml"]
logging:
driver: "json-file"
options:
max-size: "500m"
max-file: "2"
volumes:
netbird_data:
networks:
netbird:
npm_default:
external: trueserver:
listenAddress: ":80"
exposedAddress: "https://netbird.example.com:443"
stunPorts:
- 3478
metricsPort: 9090
healthcheckAddress: ":9000"
logLevel: "info"
logFile: "console"
authSecret: "RELAY_SECRET"
dataDir: "/var/lib/netbird"
auth:
issuer: "https://netbird.example.com/oauth2"
signKeyRefreshEnabled: true
sessionCookieEncryptionKey: "COOKIE_KEY"
dashboardRedirectURIs:
- "https://netbird.example.com/nb-auth"
- "https://netbird.example.com/nb-silent-auth"
cliRedirectURIs:
- "http://localhost:53000/"
reverseProxy:
trustedHTTPProxies:
- "172.19.0.0/16"
trustedPeers:
- "172.19.0.0/16"
store:
engine: "sqlite"
encryptionKey: "STORE_KEY"Erzeugt getting-started.sh die Datei (Option 3), steht unter trustedHTTPProxies fest 172.30.0.10/32, die Adresse des mitgelieferten Traefik, und trustedPeers fehlt, solange Sie nicht NETBIRD_TRUSTED_PEERS setzen. Dann vertraut der Server weitergereichten Client-Adressen von überall und warnt beim Start vor IP-Spoofing. Tragen Sie in beiden Listen das NPM-Netz ein.
NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com
NETBIRD_MGMT_GRPC_API_ENDPOINT=https://netbird.example.com
AUTH_AUDIENCE=netbird-dashboard
AUTH_CLIENT_ID=netbird-dashboard
AUTH_CLIENT_SECRET=
AUTH_AUTHORITY=https://netbird.example.com/oauth2
USE_AUTH0=false
AUTH_SUPPORTED_SCOPES=openid profile email groups
AUTH_REDIRECT_URI=/nb-auth
AUTH_SILENT_REDIRECT_URI=/nb-silent-auth
NGINX_SSL_PORT=443
LETSENCRYPT_DOMAIN=none$ chmod 600 config.yaml
$ docker compose up -dDer Server antwortet lokal, und im Log steht keine Spoofing-Warnung:
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8081/oauth2/.well-known/openid-configuration
$ docker compose logs netbird-server | grep -ci spoof200
0Schritt 3: Proxy-Host im Nginx Proxy Manager
NPM leitet alles an das Dashboard, die eigene Nginx-Konfiguration zweigt Relay, gRPC, API und Anmeldung zum Server ab. Legen Sie unter Hosts → Proxy Hosts einen neuen Host an: Domain netbird.example.com, Schema http, Ziel netbird-dashboard, Port 80, Block Common Exploits an.

Im Reiter SSL wählen Sie das Zertifikat und schalten HTTP/2 Support ein, sonst scheitert gRPC.

Unter dem Zahnrad oben rechts (Custom Nginx Configuration) tragen Sie diesen Block ein, das Skript erzeugt ihn als npm-advanced-config.txt:
client_header_timeout 1d;
client_body_timeout 1d;
location ~ ^/(relay|ws-proxy/) {
proxy_pass http://netbird-server:80;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1d;
}
location ~ ^/(signalexchange\.SignalExchange|management\.ManagementService)/ {
grpc_pass grpc://netbird-server:80;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_read_timeout 1d;
grpc_send_timeout 1d;
grpc_socket_keepalive on;
}
location ~ ^/(api|oauth2)/ {
proxy_pass http://netbird-server:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}UDP 3478 läuft nicht über NPM. Geben Sie den Port in der Firewall des Servers und beim Hoster direkt frei.
Die Anmeldung antwortet über NPM mit HTTP/2:
$ curl -s -o /dev/null -w '%{http_code} %{http_version}\n' https://netbird.example.com/oauth2/.well-known/openid-configuration200 2Schritt 4: Ersten Admin und Grundregeln anlegen
Rufen Sie https://netbird.example.com auf. Solange kein Benutzer existiert, leitet NetBird laut Doku auf /setup um, wo Sie den ersten Admin anlegen. Danach erscheint die Anmeldung des eingebauten Identitätsanbieters.

Die weiteren Schritte nutzen die REST-API, damit jeder Kunde gleich angelegt wird. Den ersten Admin mit Personal Access Token legt statt /setup auch /api/setup an, wenn netbird-server vorübergehend NB_SETUP_PAT_ENABLED=true in environment hat:
curl -s -X POST https://netbird.example.com/api/setup -H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","name":"Admin","password":"IhrAdminPasswort","create_pat":true,"pat_expire_in":30}'{"email":"admin@example.com","personal_access_token":"nbp_…","user_id":"…"}Danach legen Sie die Gruppe admins an und schalten die Richtlinie Default ab, die allen alles erlaubt:
export NB_PAT=nbp_IhrToken
NB=https://netbird.example.com
ADMINS=$(curl -s -X POST $NB/api/groups -H "Authorization: Token $NB_PAT" -H 'Content-Type: application/json' -d '{"name":"admins"}' | jq -r .id)
DEF=$(curl -s $NB/api/policies -H "Authorization: Token $NB_PAT" | jq -r '.[] | select(.name=="Default") | .id')
curl -s $NB/api/policies/$DEF -H "Authorization: Token $NB_PAT" \
| jq '.enabled=false | {name,description,enabled,rules:[.rules[]|{name,description,enabled,action,bidirectional,protocol,sources:[.sources[]?.id],destinations:[.destinations[]?.id]}]}' \
| curl -s -X PUT $NB/api/policies/$DEF -H "Authorization: Token $NB_PAT" -H 'Content-Type: application/json' -d @- | jq -c '{name,enabled}'Die Richtlinie ist aus, ohne gültigen Token antwortet die API mit 401, mit Token mit 200:
$ curl -s -o /dev/null -w '%{http_code}\n' $NB/api/users -H 'Authorization: Token nbp_falsch'
$ curl -s -o /dev/null -w '%{http_code}\n' $NB/api/users -H "Authorization: Token $NB_PAT"{"name":"Default","enabled":false}
401
200Schritt 5: Admin-Webtop mit NetBird-Sidecar
Einen Setup-Key, der Geräte der Gruppe admins zuordnet, liefert die API. ADMINS ist die ID, die der Gruppenaufruf in Schritt 4 ausgegeben hat::
curl -s -X POST $NB/api/setup-keys -H "Authorization: Token $NB_PAT" -H 'Content-Type: application/json' \
-d '{"name":"admin-webtop","type":"reusable","expires_in":604800,"auto_groups":["'$ADMINS'"],"usage_limit":0,"ephemeral":false}' | jq -r .keyDer Webtop nutzt das Netz des NetBird-Containers, alles im Browser-Desktop läuft durch den Tunnel.
services:
netbird:
image: netbirdio/netbird:0.83.0
hostname: admin-webtop
cap_add:
- NET_ADMIN
- SYS_ADMIN
- SYS_RESOURCE
devices:
- /dev/net/tun
environment:
- NB_MANAGEMENT_URL=https://netbird.example.com
- NB_SETUP_KEY=${NB_SETUP_KEY}
volumes:
- netbird-client:/var/lib/netbird
ports:
- "127.0.0.1:3001:3001"
restart: unless-stopped
webtop:
image: lscr.io/linuxserver/webtop:debian-xfce-670099a5-ls221
network_mode: service:netbird
depends_on:
netbird:
condition: service_started
restart: true
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
- CUSTOM_USER=admin
- PASSWORD=${WEBTOP_PASSWORD}
volumes:
- ./config:/config
shm_size: "1gb"
restart: unless-stopped
volumes:
netbird-client:NB_SETUP_KEY=IHR-SETUP-KEY
WEBTOP_PASSWORD=IhrWebtopPasswort$ mkdir -p /opt/admin-webtop && cd /opt/admin-webtop
$ chmod 600 .env
$ docker compose up -dDie Ports des Webtops stehen beim NetBird-Dienst. Docker veröffentlicht Port 3001 nur auf 127.0.0.1, Sie erreichen den Webtop per SSH-Tunnel (ssh -L 3001:127.0.0.1:3001 admin@server.example.com) unter https://localhost:3001. depends_on mit restart: true startet den Webtop mit, wenn Compose den NetBird-Container neu startet; im Test hatte er danach wieder sein Netz. Startet der NetBird-Container ohne Compose neu, etwa per docker restart, behält der Webtop nur lo.
Der Client ist verbunden, und der Webtop verlangt eine Anmeldung:
$ docker compose exec netbird netbird status -d
$ curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1:3001/Management: Connected to https://netbird.example.com:443
Signal: Connected to https://netbird.example.com:443
…
FQDN: admin-webtop.netbird.selfhosted
NetBird IP: 100.90.54.179/16
…
Interface type: Kernel
…
401Schritt 6: Kunden mit Routing-Peer anbinden
Je Kunde entstehen zwei Gruppen, ein Netzwerk mit dem Kunden-LAN als Ressource, ein Routing-Peer und eine einseitige Regel: nur admins, nur TCP, nur die angegebenen Ports. Im Test lief ein Aufruf vom Routing-Peer zum Webtop in den Timeout. Das Skript erledigt das in einem Durchgang:
#!/bin/bash
set -euo pipefail
NB=https://netbird.example.com
KUNDE=$1
NETZ=$2
PORTS='["80","443","5000","5001"]'
api() {
if [ -n "${3:-}" ]; then
curl -fsS -X "$1" "$NB/api$2" -H "Authorization: Token $NB_PAT" -H 'Content-Type: application/json' -d "$3"
else
curl -fsS -X "$1" "$NB/api$2" -H "Authorization: Token $NB_PAT"
fi
}
ADMINS=$(api GET /groups | jq -r '.[] | select(.name=="admins") | .id')
G_ROUTER=$(api POST /groups "{\"name\":\"$KUNDE-router\"}" | jq -r .id)
G_NETZ=$(api POST /groups "{\"name\":\"$KUNDE-netz\"}" | jq -r .id)
NET=$(api POST /networks "{\"name\":\"$KUNDE\"}" | jq -r .id)
api POST "/networks/$NET/resources" "{\"name\":\"$KUNDE-lan\",\"address\":\"$NETZ\",\"enabled\":true,\"groups\":[\"$G_NETZ\"]}" >/dev/null
api POST "/networks/$NET/routers" "{\"peer_groups\":[\"$G_ROUTER\"],\"metric\":9999,\"masquerade\":true,\"enabled\":true}" >/dev/null
api POST /policies "{\"name\":\"admins-zu-$KUNDE\",\"enabled\":true,\"rules\":[{\"name\":\"admins-zu-$KUNDE\",\"enabled\":true,\"action\":\"accept\",\"bidirectional\":false,\"protocol\":\"tcp\",\"ports\":$PORTS,\"sources\":[\"$ADMINS\"],\"destinations\":[\"$G_NETZ\"]}]}" >/dev/null
KEY=$(api POST /setup-keys "{\"name\":\"$KUNDE\",\"type\":\"reusable\",\"expires_in\":604800,\"auto_groups\":[\"$G_ROUTER\"],\"usage_limit\":0,\"ephemeral\":false}" | jq -r .key)
echo "Kunde $KUNDE angelegt: Netz $NETZ, Gruppen $KUNDE-router und $KUNDE-netz"
echo "Setup-Key für den Routing-Peer: $KEY"Das Skript braucht NB_PAT aus Schritt 4 in derselben Shell.
$ cd /opt/netbird && chmod 700 kunde-anlegen.sh
$ ./kunde-anlegen.sh kunde-a 192.168.178.0/24PORTS (Web, HTTPS, DSM) passen Sie je Kunde an. Den Setup-Key löschen Sie nach der Einrichtung. Auf dem Docker-Host beim Kunden legen Sie /opt/netbird-router an und starten dort diesen Container mit docker compose up -d. Im Test hing der Routing-Peer in einem Docker-Netz, das das Kunden-LAN darstellte, auf einem echten Gerät sorgt network_mode: host für den Zugang zum LAN.
services:
netbird:
image: netbirdio/netbird:0.83.0
hostname: ${PEER_NAME}
network_mode: host
cap_add:
- NET_ADMIN
- SYS_ADMIN
- SYS_RESOURCE
devices:
- /dev/net/tun
environment:
- NB_MANAGEMENT_URL=https://netbird.example.com
- NB_SETUP_KEY=${NB_SETUP_KEY}
- NB_WG_KERNEL_DISABLED=true
volumes:
- netbird-client:/var/lib/netbird
restart: unless-stopped
volumes:
netbird-client:NB_SETUP_KEY=SETUP-KEY-AUS-DEM-SKRIPT
PEER_NAME=kunde-a-routerNB_WG_KERNEL_DISABLED=true lässt WireGuard im Userspace laufen. Laut Client-Doku ist das für Systeme gedacht, deren WireGuard-Kernelmodul fehlt, defekt ist oder mit anderer Software kollidiert. Für Synology nennt die NetBird-Doku ein Startskript, weil dort nach einem Neustart /dev/net/tun fehlen kann.
Befehl 1 läuft beim Kunden, die anderen auf dem Webtop-Server. Im Test antwortete ein Webserver auf 192.168.178.10 auf Port 80, der nicht freigegebene Port 8080 lief in den Timeout (Exit-Code 28):
$ docker compose exec netbird netbird status | grep 'Interface type'
$ docker compose -f /opt/admin-webtop/compose.yaml exec webtop curl -s -m 8 http://192.168.178.10/
$ docker compose -f /opt/admin-webtop/compose.yaml exec webtop curl -s -m 8 -o /dev/null -w '%{http_code}' http://192.168.178.10:8080/; echo " rc=$?"Interface type: Userspace
NAS Kunde A
000 rc=28Schritt 7: Gleiche Adressbereiche bei mehreren Kunden
Kündigen zwei Routing-Peers dasselbe Netz an, etwa das FRITZ!Box-Standardnetz 192.168.178.0/24, gibt es im Webtop nur eine Route dafür. Im Test war nach dem Anlegen von Kunde B nur Kunde A erreichbar. Welches Netz aktiv ist, legen Sie im Client fest:
$ cd /opt/admin-webtop
$ docker compose exec netbird netbird networks select kunde-b-lan
$ docker compose exec netbird netbird networks listNetworks selected successfully.
Available Networks:
- ID: kunde-a-lan
Network: 192.168.178.0/24
Status: Not Selected
- ID: kunde-b-lan
Network: 192.168.178.0/24
Status: Selectedselect erwartet die ID aus networks list, also den Namen der Ressource. Danach antwortete im Test nur noch das Gerät von Kunde B, nach select kunde-a-lan wieder nur Kunde A. Brauchen Sie beide gleichzeitig, installieren Sie NetBird direkt auf dem Zielgerät, mit eigener Gruppe, eigenem Setup-Key und einer Regel von admins auf diese Gruppe wie im Skript. Das Gerät bekommt eine eigene Adresse und einen Namen wie kunde-b-nas.netbird.selfhosted, im Test parallel zu Kunde A. Alternativ stellen Sie ein Kundennetz um, von NAT-Umschreibungen auf dem Routing-Peer rät die NetBird-Doku ab.
Das direkt angebundene Gerät antwortet über seinen NetBird-Namen:
$ cd /opt/admin-webtop
$ docker compose exec webtop curl -s -m 8 http://kunde-b-nas.netbird.selfhosted/NAS Kunde B direktSchritt 8: Sicherung, Wiederherstellung und Update
Die Sicherung folgt der Herstellerdoku. Das Archiv enthält alle Schlüssel, bewahren Sie es entsprechend geschützt auf.
cd /opt/netbird
( umask 077; mkdir -p backup
docker compose stop
cp docker-compose.yml config.yaml dashboard.env backup/
docker compose cp -a netbird-server:/var/lib/netbird/ backup/
docker compose start
tar czf netbird-backup.tar.gz -C backup . )Zur Wiederherstellung kopieren Sie das Archiv nach /opt/netbird (auf einem neuen Server vorher NPM und Schritt 1 erledigen), legen den Container an, ohne ihn zu starten, und kopieren die Daten hinein:
$ mkdir -p /opt/netbird/restore && cd /opt/netbird
$ tar xzf netbird-backup.tar.gz -C restore
$ cp restore/docker-compose.yml restore/config.yaml restore/dashboard.env .
$ docker compose create netbird-server
$ docker compose cp -a restore/netbird/. netbird-server:/var/lib/netbird/
$ docker compose up -d
$ docker restart npmNginx im NPM löst netbird-server nur beim Start auf: Im Test hatte der neue Container eine andere Adresse, NPM lieferte 404, nach dem Neustart 200. Für ein Update tauschen Sie die Tags in der docker-compose.yml, dann folgen docker compose pull, docker compose up -d und ein Neustart von NPM. Beim Update von 0.82.1 und v2.96.1 auf 0.83.0 und v2.97.0 lief der Verkehr zu Kunde A im Test weiter, die API über NPM antwortete direkt danach aber nicht korrekt. Die danach erstellte Sicherung enthielt alle Gruppen und Regeln.
Nach dem Restore waren Gruppen, Regeln, Netzwerke und Peers wieder da, ohne neue Setup-Keys:
$ curl -s https://netbird.example.com/api/peers -H "Authorization: Token $NB_PAT" | jq -c '.[] | {name,connected}'{"name":"admin-webtop","connected":true}
{"name":"kunde-a-router","connected":true}
…Datenschutz und Nachweise
Selbst gehostet in einem deutschen Rechenzentrum bleiben Peers, Schlüssel und Regeln bei Ihnen. Der Fernzugriff ist trotzdem Auftragsverarbeitung: Schließen Sie mit jedem Kunden einen Auftragsverarbeitungsvertrag nach Art. 28 DSGVO und beschreiben Sie dort den Zugang über NetBird. Das Audit-Log der freien Version hält Änderungen fest, im Test etwa Peer added und Policy added mit Zeitstempel, bei Änderungen per API mit Benutzer. Verbindungen zeigen erst die Traffic Events, laut Doku nur in der Cloud und in lizenzierten Enterprise-Installationen. Führen Sie daher ein eigenes Zugriffsprotokoll (Kunde, Zeit, Anlass); das ist keine Rechtsberatung.
Typische Fehler
transport: authentication handshake failed: remote error: tls: no application protocolHTTP/2 ist im Proxy-Host nicht eingeschaltet. Der Client meldet dann
Management: Disconnected. Im Reiter SSL HTTP/2 Support aktivieren.TrustedPeers contains the default route 0.0.0.0/0, which trusts X-Forwarded-For from every client and allows connection IP spoofing.trustedPeersfehlt in derconfig.yaml. Beide Listen auf das NPM-Netz setzen unddocker compose restart netbird-server. Ältere Warnungen bleiben im Log stehen, prüfen Sie mitdocker compose logs --since 1m netbird-server.couldn't add peer: setup key is invalidDer Setup-Key ist falsch, abgelaufen oder gelöscht. Neuen Key anlegen und in die
.enveintragen.- Webtop zeigt nur noch die Schnittstelle
lo Der NetBird-Container wurde ohne Compose neu gestartet, etwa mit
docker restart. Der Webtop hängt dann am alten Netz.docker compose restart webtopbehebt es.- NPM liefert nach dem Restore 404 auf
/oauth2 Nginx im NPM hat noch die alte Adresse des NetBird-Containers. NPM neu starten, ebenso nach einem Update.
Häufige Fragen
Muss ich beim Kunden Ports freigeben?
Nein. Der Routing-Peer verbindet sich von innen, ohne direkte Verbindung laufen die Daten über das Relay /relay auf Ihrem Server.
Fazit
Ein NetBird-Server hinter NPM und ein Webtop machen aus vielen Kundenzugängen einen, mit einem Skript je neuem Kunden. Die Stolperstellen sind HTTP/2 im NPM und die Vertrauensliste in der config.yaml, gleiche Adressbereiche lösen netbird networks select oder NetBird direkt auf dem Gerät.
Weiterführende Anleitungen und Quellen
- NetBird mit Docker installieren: Zero-Trust-Overlay-Netzwerk selbst hosten
- Docker und Docker Compose auf Linux installieren
- Docker Compose absichern: Secrets, Healthchecks, Non-Root
- NetBird: Self-Hosting Quickstart
- NetBird: External Reverse Proxy
- NetBird: Backup
- NetBird: Overlapping Routes
- NetBird: Overlapping IPs for Resources
- NetBird v0.83.0 Release Notes
- linuxserver.io: Webtop


