Ein NetBird mit zehn Peers und drei Policies hat man im Kopf. Bei hundert Peers, zwanzig Gruppen und Policies mit mehreren Regeln, Port-Listen und Posture Checks ist das vorbei. Die Frage „Kommt der Laptop aus dem Vertrieb an die Datenbank?" lässt sich dann nur noch beantworten, indem man Gruppenmitgliedschaften und Regeln von Hand gegeneinander abgleicht. Spätestens im Audit wird das unangenehm.
Stylite betreibt das Team-VPN auf einem selbst gehosteten NetBird, die Gründe stehen im Beitrag Von ZeroTier zu NetBird . Rund um diesen Betrieb sind Werkzeuge entstanden, die wir als birdseye auf GitHub pflegen. Heute ist Version 1.0.0 erschienen, die erste stabile Version: Open Source und MIT-lizenziert.
Das Problem: Regeln sichtbar, Wirkung nicht#
Das NetBird-Dashboard listet Gruppen und Policies sauber auf. Was es nicht zeigt, ist das Ergebnis: welcher Peer am Ende welchen anderen Peer auf welchem Port erreicht. Diese Wirkung ergibt sich erst aus dem Zusammenspiel von Gruppen, Regeln, Ressourcen und Posture Checks. Wer eine Gruppe ändert, ändert damit unter Umständen Zugriffe in mehreren Policies gleichzeitig, und sieht davon vorher nichts.
Was birdseye ist#
birdseye besteht aus zwei Docker-Images, die neben einer bestehenden NetBird-Installation laufen:
- birdseye-web: eine Web-Oberfläche mit Zugriffsmatrix, Editoren mit Vorschau, Erreichbarkeitsprüfung, Anomalien, Audit-Log und Config-History.
- birdseye: ein Hintergrunddienst, der Audit-Events weiterleitet, Aufräumjobs erledigt, Konventionen durchsetzt sowie Backups und einen Standby-Klon pflegt.

Beide lassen sich einzeln einsetzen. Zusammen liefern sie in der Web-Oberfläche zusätzlich Config-History und Job-Übersicht, denn die Snapshots und den Job-Status schreibt der Container birdseye. Matrix, Editoren, Erreichbarkeit, Anomalien und Audit-Log funktionieren auch ohne ihn.
birdseye ist für selbst gehostetes NetBird gebaut, nicht für NetBird Cloud. Die Web-Oberfläche setzt den eingebetteten Identity Provider von NetBird voraus; Installationen mit externem IdP wie Zitadel oder Keycloak sind damit nicht abgedeckt. Das Projekt ist von Stylite entwickelt und weder mit NetBird verbunden noch von NetBird offiziell unterstützt. Für den API-Zugriff nutzt birdseye ein inoffizielles, von der Community gepflegtes Python-SDK.
Die Zugriffsmatrix#
Die Startseite von birdseye-web beantwortet die Frage „Wer darf wen erreichen?" als Tabelle. Zeilen sind Quellen, Spalten Ziele, jede Zelle zeigt den erlaubten Dienst: alle Protokolle, bestimmte Ports, nur ICMP oder NetBird SSH. Eine Markierung in der Ecke kennzeichnet Zugriffe, die an einen Posture Check gebunden sind.

Neben Gruppe × Gruppe gibt es die Sichten Peer × Peer, Gruppe × Ressource, Peer × Ressource und Benutzer × Ziel. Filter nach Name, Protokoll und Port grenzen die Tabelle ein. Ein Klick auf eine Zelle zeigt, welche Policy und welche Regel den Zugriff erlaubt. Admins bekommen so einen schnellen Überblick, Auditoren einen Stand, den sie nachprüfen können.
Jede Änderung mit Vorschau#
In birdseye-web lassen sich Gruppen, Policies, Benutzer, Peers, Setup-Keys und Netzwerke bearbeiten. Bevor etwas gespeichert wird, zeigt jeder Editor, welche Verbindungen dadurch hinzukommen und welche wegfallen, aufgelöst auf Peer-Paare und Dienste. Wer eine Gruppe ändert, sieht vor dem Speichern, was das im Netz bewirkt.

In den Gruppen-Sichten der Matrix geht das auch direkt aus einer Zelle heraus: Zugriff entziehen oder erteilen, jeweils mit derselben Vorschau.
Erreichbarkeit: „Kommt X an Y auf tcp/5432?"#
Für die konkrete Einzelfrage gibt es die Erreichbarkeitsprüfung. Quelle, Ziel, Protokoll und Port auswählen, und birdseye-web antwortet mit Ja oder Nein samt Begründung: welche Policies den Zugriff erlauben, über welche Gruppen, und ob ein Posture Check greift.

Ergänzend listet die Seite Anomalien Auffälligkeiten in der Konfiguration: Regeln, die auf einzelne Peers statt auf Gruppen zielen, Geräte, deren Gruppen vom Benutzer-Standard abweichen, Ressourcen ohne Router oder ohne Zugriff, ungenutzte Gruppen, riskante Setup-Keys und veraltete Peers. Jeder Eintrag verlinkt auf den Editor, der ihn behebt.
Audit-Log, Config-History und Restore#
birdseye-web zeigt das NetBird-Audit-Log mit Namen statt IDs und mit Filtern. Ist im Hintergrunddienst die Config-History aktiviert, entsteht kurz nach jeder Änderung ein Snapshot der Konfiguration; mehrere schnelle Änderungen landen in einem gemeinsamen Snapshot. Zwei Snapshots lassen sich feldgenau vergleichen, und eine einzelne Policy oder Gruppe kann auf einen älteren Stand zurückgesetzt werden. Auch hier zeigt die Oberfläche vorher, welche Zugriffe sich dadurch ändern.

Anmeldung mit dem eigenen NetBird-Konto#
birdseye-web hat keinen eigenen API-Key und keine eigene Benutzerverwaltung. Die Anmeldung läuft über den eingebetteten Identity Provider von NetBird, jeder API-Aufruf erfolgt mit dem Token der angemeldeten Person. Das hat zwei Folgen:
- Rollen bleiben wirksam: NetBird prüft jede Aktion gegen die Rolle. Wer im NetBird-Dashboard keine Policies ändern darf, kann es in birdseye-web auch nicht. Auditoren lesen fast alles und schreiben nichts, normale Benutzer sehen höchstens ihre eigenen Geräte und deren Zugriffe, sofern NetBird ihnen das erlaubt.
- Das Audit-Log zeigt die echte Person: Im NetBird-Audit-Log steht, wer die Änderung gemacht hat, nicht ein anonymer Service-Key mit Vollzugriff.
Ein zentraler Admin-Key in einem Web-Tool wäre ein lohnendes Angriffsziel und würde jede Änderung hinter einer gemeinsamen Identität verstecken. Dieses Risiko entfällt. Eine Einschränkung gehört dazu: Die Anmeldung nutzt denselben Weg wie das NetBird-Dashboard, der aber keine dokumentierte Schnittstelle für Dritte ist. Nach NetBird-Updates sollte die Anmeldung deshalb kurz geprüft werden.
Der Hintergrunddienst birdseye arbeitet dagegen unbeaufsichtigt und braucht dafür NetBird-API-Keys.
Der Hintergrunddienst#
Der Container birdseye übernimmt, was ohne Oberfläche laufen soll. Jeder optionale Job bleibt aus, bis seine Umgebungsvariablen gesetzt sind.
- Audit-Events weiterleiten: NetBird-Audit-Events gehen an Mattermost, per Mail und nach stdout, mit Filtern pro Ziel. Nach einem Neustart setzt der Dienst dort fort, wo er aufgehört hat.
- Aufräumen: Veraltete ephemere Peers werden regelmäßig gelöscht.
- Konventionen durchsetzen: Posture Checks werden an Policies gehängt, ICMP-Begleit-Policies für Ping bleiben mit den eigentlichen Policies synchron.
- Backups: wöchentlich zwei verschlüsselte Archive per Mail, ein Volume-Snapshot für die bytegenaue Wiederherstellung und ein lesbarer JSON-Export der Konfiguration. Dazu kommen datierte Archive per SSH auf einen anderen Host.
- Standby-Klon: Ein zweites System wird als Klon gepflegt und bei jedem Lauf testweise gestartet.
Beim Standby-Klon liegt der Unterschied zu einem gewöhnlichen Backup-Skript: Der Klon wird bei jedem Lauf gestartet, gegen das Primärsystem geprüft (Account-ID und Anzahl der Objekte) und wieder gestoppt. Dass der Standby mit den Daten des letzten Laufs startet, steht damit fest, bevor er gebraucht wird. Der Testlauf prüft allerdings weder die DNS-Umstellung noch die Zertifikate im Ernstfall. Und Peers, die seit dem letzten Lauf hinzugekommen sind, fehlen auf dem Standby. Unbeaufsichtigte Jobs melden Fehler per Mail und auf Wunsch über einen Checkmk-Local-Check.
NetBird Cloud bietet Event-Streaming an externe Systeme, im Self-Hosting fehlt das. birdseye schließt diese Lücke für Audit-Events teilweise: Der Dienst fragt das Audit-Log regelmäßig ab und leitet die Events an Mattermost und per Mail weiter, nicht an ein SIEM oder einen Cloud-Speicher. Netzwerk-Traffic-Events stellt NetBird nur in der Cloud bereit, die kann birdseye nicht ersetzen.
Ausprobieren#
Einstieg ist das README im Repository
: oben eine Kurzfassung, dann eine Feature-Tabelle und der Quick Start. Die Images liegen auf Docker Hub und GHCR als styliteag/birdseye und styliteag/birdseye-web.
Die Web-Oberfläche braucht drei Werte in der .env:
cd docker/web
cp .env.example .env # WEB_NB_URL, WEB_BASE_URL, WEB_SESSION_SECRET
docker compose up -d
Auf NetBird-Seite muss einmalig die Callback-URL von birdseye-web beim Identity Provider eingetragen werden. Das beschreibt docs/web-ui.md , zusammen mit Reverse Proxy, lokalem Test und Fehlersuche. Alle Ansichten mit Beschreibung zeigt die Screenshot-Galerie . Die Screenshots stammen aus einer Demo-Umgebung der fiktiven Firma „Acme" und enthalten keine Kundendaten.
Open Source, MIT, Beiträge willkommen#
birdseye steht unter MIT-Lizenz. Ab 1.0.0 folgt die Versionierung strikt Semantic Versioning: Inkompatible Änderungen an Konfiguration oder Verhalten erhöhen die Hauptversion. Was sich geändert hat, steht im CHANGELOG . Issues, Ideen und Pull Requests sind im GitHub-Repository willkommen.
Wir sind auch offen dafür, birdseye zu erweitern, etwa um weitere Benachrichtigungsziele oder um die Anbindung externer Identity Provider wie Zitadel oder Keycloak an die Web-Oberfläche. Wer so etwas braucht, kann ein Issue eröffnen oder gleich einen Pull Request schicken. Patches welcome!
Für Fragen zum Betrieb eines selbst gehosteten NetBird steht Stylite gerne zur Verfügung.
Wim Bonis ist CTO bei Stylite AG und beschäftigt sich schwerpunktmäßig mit Storage-Architekturen, IT-Sicherheit und Open-Source-Infrastruktur.