Vom Chaos zur Kontrolle: Headscale statt Tailscale?

Oder: Wie wir dachten, in fünf Minuten ein dezentrales VPN zu bauen – und dann fünf Stunden lang Debug-Logs lasen.
🧪 Das Experiment beginnt
Die Idee war einfach – fast schon zu einfach: Statt dem vertrauten Tailscale-Client wollten wir Headscale nutzen, das Open-Source-Gegenstück zur Verwaltung eines eigenen Tailnets.
Unsere Motivation:
- volle Kontrolle über das Mesh-Netz
- kein Vendor-Lock-in
- und natürlich: nerdiger Selbstausbau einer Exit-Node in den USA
🛠️ Der Plan
- Headscale als Docker-Container auf dem ARM-VPS deployen
- Tailscale-Clients mit
--login-server=https://mesh.pixli.li
verbinden - Zugriff über die eigene Domain
mesh.pixli.li
via Caddy sichern - Preauth-Key erstellen, Node verbinden, Exit-Node aktivieren
- (Optional) Schöne UI mit
headscale-ui
hinzufügen
Klingt überschaubar, oder?
😵💫 Was schiefging – und warum
Error: fetch control key: 502 Bad Gateway
Error: AuthKey not found
Error: unknown flag: --user
Kleine Ursachen, große Wirkung:
- FRISCHER API-Bruch:
Die Headscale-Versionv0.25.1
hatte mehrere Breaking Changes.
Flags wie--wg
,--user
oderwg-config
? Weg.
Stattdessen neue Syntax & Subkommandos. - UI-Probleme:
Die Docker-Images fürheadscale-ui
wurden zwischenzeitlich aus dem GitHub Container Registry entfernt (403: denied
), wodurch die Web-Oberfläche nicht mehr startete. - HTTPS-Verwirrung:
Der Server meldete500 Internal Server Error
, wennconfig.yaml
aufhttp://
stand – obwohl TLS über Caddy lief.
Lösung: immerhttps://
inserver_url
. - Preauth-Key-Lebensdauer:
Standardmäßig 1 Stunde – zu knapp für Test-Marathons.
Wir mussten mehrfach neue Keys generieren. - Tailscale-Windows-Client:
Reagierte oft gar nicht oder mit kryptischem Timeout – vermutlich wegen--force-reauth
und fehlender ACL-Konfiguration.
✅ Was jetzt funktioniert
Headscale läuft stabil als Container mit eigenem config.yaml
, inklusive:
server_url: https://mesh.pixli.li
prefixes.v4: 100.64.0.0/10
dns.magic_dns: false
enable_wg_listener: true
- Authentifizierung über Preauth-Key (
--reusable
,--expiration 24h
) - Alle Dienste wieder wie vorher erreichbar – inkl. der lokalen GPT- und Flux-Bildgeneratoren.
- Daily-Status-Report & Backups weiterhin aktiv
Exit-Node auf dem US-VPS erfolgreich aktiviert:
tailscale up --login-server=https://mesh.pixli.li --auth-key=... \
--advertise-exit-node --hostname=us-vps --ssh
📚 Lessons learned
- Tailscale ist komfortabel – und Headscale eine Wissenschaft.
- Wer volle Kontrolle will, bekommt sie. Und die Verantwortung dazu.
- Die Doku hinkt manchmal der Realität hinterher.
- Wer updated, muss changelogs lesen.
- Docker ist cool. Aber Configs bleiben Königsdisziplin.
Wir bleiben vorerst bei Tailscale – und basteln mit Headscale weiter in der Sandbox.
🚀 Und jetzt?
- Einrichten eines dedizierten WireGuard-Clients mit Config-Export aus Headscale
- Aufbau einer zweiten, redundanten Exit-Node
- Interne Dienste per ACL absichern und Tags testen
Bleib dran – das war nur der Anfang unserer Self-Hosting-Mesh-Mission.
☕ Gebaut mit Kaffee. ⚡ Angetrieben von Neugier.
Small pixels, big ideas. ✨