Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Server & Netzwerk 04.06.2026 · 11 min Lesezeit

Headscale selbst hosten: Tailscale-Mesh-VPN ohne Cloud-Abhängigkeit für KMU

Headscale ist eine Open-Source-Reimplementierung des Tailscale Control Servers – du bekommst den vollen Komfort eines Mesh-VPN (automatische NAT-Traversal, ACL-Policies, MagicDNS) ohne Cloud-Abhängigkeit, ohne Geräte-Limits und DSGVO-konform auf eigener Infrastruktur.

Leuchtendes Mesh-Netzwerk aus verbundenen Knoten im Serverraum

Wer sein Netzwerk mit WireGuard aufbaut, kennt das Problem: Jedes neue Gerät erfordert manuell ein Schlüsselpaar, einen Eintrag auf jedem Peer, Port-Forwarding-Regeln und iptables-Anpassungen. Tailscale löst das elegant – aber auf US-amerikanischen Servern, mit Metadaten-Exposition und monatlichen Pro-Nutzer-Kosten. Headscale schließt diese Lücke: Die Open-Source-Reimplementierung des Tailscale Control Servers läuft auf deinem eigenen VPS, gibt dir den vollen Mesh-VPN-Komfort (automatische NAT-Traversal, zentrale ACL-Policies, MagicDNS, Subnet-Router) und hält alle Verbindungsmetadaten auf deiner Infrastruktur – DSGVO-konform, ohne Geräte-Limits, für rund 3–10 EUR/Monat VPS-Kosten.

Voraussetzungen

  • Ubuntu-Server 22.04 LTS oder 24.04 LTS (VPS oder dediziert, öffentlich erreichbar) – empfohlen: Hetzner CX11 (~3 EUR/Monat)
  • Öffentliche IPv4-Adresse und ein FQDN (z. B. hs.example.com) mit DNS-A-Eintrag
  • Gültiges TLS-Zertifikat – Let's Encrypt via Certbot (Nginx) oder automatisch via Caddy
  • Eingehend offene Ports: TCP/443 (HTTPS), UDP/3478 (STUN, nur bei aktiviertem eingebettetem DERP-Server)
  • Mindestens 1 vCPU, 1 GB RAM, 10 GB SSD (reicht für bis zu 100 Geräte)
  • Tailscale-Client auf jedem Endgerät (Windows, macOS, Linux, iOS, Android – kostenlos)
  • Grundkenntnisse Linux-Serverbetrieb und Nginx/Caddy-Konfiguration

Schritt 1: Headscale vs. Tailscale-Cloud vs. WireGuard – die richtige Wahl treffen

Bevor du loslegst, lohnt ein kurzer Blick auf die Entscheidungsmatrix. Alle drei Optionen bauen im Kern auf WireGuard auf, unterscheiden sich aber erheblich in Verwaltungsaufwand, Datensouveränität und Kosten:

KriteriumWireGuard (rein)Tailscale CloudHeadscale (self-hosted)
Peer-VerwaltungManuell je GerätAutomatischAutomatisch
NAT-TraversalManuell/keinAutomatisch (DERP)Automatisch (DERP)
DatensouveränitätVollständigUS-ServerVollständig
DSGVO-RisikoGeringMetadaten auf US-ServernGering (eigene Infra)
Geräte-LimitsKeine100 (Free Tier)Keine
Kosten0 € (eigene Infra)0–15 USD/User/Monat~3–10 EUR/Monat VPS
EinrichtungsaufwandHochMinimalMittel (~90 Min.)

Empfehlung: Headscale eignet sich für KMU, die mehr als 3 Nutzer haben, Wert auf Datensouveränität legen und bereit sind, einen einfachen Linux-Server zu betreiben. Tailscale-Cloud bleibt die bessere Wahl, wenn das IT-Team sehr klein ist und SSO-Integration (Azure AD, Google) ohne eigene OIDC-Infrastruktur benötigt wird. Reines WireGuard ist dann sinnvoll, wenn ausschließlich Server-zu-Server-Verbindungen mit statischen IPs nötig sind.

Schritt 2: Headscale installieren

Headscale wird als einzelnes Debian-Paket ausgeliefert und bringt alle Abhängigkeiten mit. SQLite (Standard) wird automatisch eingerichtet – eine separate Datenbankinstallation ist nicht nötig.

# Headscale v0.28.0 herunterladen und installieren (Ubuntu 22.04/24.04)
HEADSCALE_VERSION="0.28.0"
wget -O headscale.deb "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_amd64.deb"
sudo dpkg -i headscale.deb
sudo systemctl enable --now headscale

Nach der Installation lauscht Headscale per Default nur auf 127.0.0.1:8080 (HTTP), 127.0.0.1:9090 (Metriken) und 127.0.0.1:50443 (gRPC). TLS wird nicht direkt in Headscale terminiert, sondern an den Reverse Proxy ausgelagert – das ist die empfohlene und einzig praktikable Variante.

Schritt 3: Headscale konfigurieren

Die zentrale Konfigurationsdatei liegt unter /etc/headscale/config.yaml. Passe mindestens server_url und base_domain an deinen FQDN an:

# /etc/headscale/config.yaml (minimale Produktionskonfiguration)
server_url: https://hs.example.com
listen_addr: 127.0.0.1:8080
metrics_listen_addr: 127.0.0.1:9090
grpc_listen_addr: 127.0.0.1:50443
tls_cert_path: ""
tls_key_path: ""
private_key_path: /var/lib/headscale/private.key
noise:
  private_key_path: /var/lib/headscale/noise_private.key
ip_prefixes:
  - 100.64.0.0/10
  - fd7a:115c:a1e0::/48
database:
  type: sqlite
  sqlite:
    path: /var/lib/headscale/db.sqlite
log:
  level: info
acl_policy_path: /etc/headscale/acl.json
dns_config:
  magic_dns: true
  base_domain: vpn.example.com
  nameservers:
    - 1.1.1.1
derp:
  server:
    enabled: false
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  auto_update_enabled: true
  update_frequency: 3h

Wichtig: base_domain für MagicDNS (hier vpn.example.com) muss sich von der Server-URL-Domain (hs.example.com) unterscheiden. Laufen beide unter example.com, entstehen DNS-Loops. Kein abschließender Punkt im FQDN. Nach Änderungen an der Konfiguration immer neu starten: sudo systemctl restart headscale.

Schritt 4: Reverse Proxy mit TLS einrichten

Tailscale-Clients bestehen auf HTTPS mit einem gültigen Zertifikat – HTTP-only funktioniert nicht. Du hast zwei solide Optionen:

Option A: Nginx mit Certbot

# /etc/nginx/sites-available/headscale
server {
  listen 443 ssl;
  server_name hs.example.com;
  ssl_certificate /etc/letsencrypt/live/hs.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/hs.example.com/privkey.pem;

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    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_set_header Host $host;
    proxy_buffering off;
  }
}

Zwingend erforderlich: proxy_http_version 1.1, die Upgrade/Connection-Header und proxy_buffering off. Fehlt einer davon, brechen langlebige WebSocket-Verbindungen ab. Eine detaillierte Nginx-Konfiguration für weitere Dienste findest du in der Anleitung Nginx als Reverse Proxy mit TLS einrichten.

Option B: Caddy (empfohlen – automatisches TLS)

# /etc/caddy/Caddyfile
hs.example.com {
  reverse_proxy 127.0.0.1:8080
}

Caddy holt und erneuert das Let's-Encrypt-Zertifikat automatisch und unterstützt WebSocket out-of-the-box. Für neue Installationen ist Caddy die einfachere Wahl. Cloudflare-Proxy (oranges Wolkensymbol) ist explizit nicht unterstützt – Cloudflare leitet keine WebSocket-POST-Anfragen weiter, was Headscale-Verbindungen bricht. Nur DNS-only (graues Symbol) verwenden.

Schritt 5: Nutzer, Gruppen und Pre-Auth-Keys anlegen

In Headscale entsprechen „Users" den Tailscale-Namespaces. Jedes Gerät gehört genau einem User. Für Abteilungstrennung legst du je Abteilung einen eigenen User an:

# Nutzer (Abteilungen) anlegen
sudo headscale users create marketing
sudo headscale users create buchhaltung
sudo headscale users create it-admin

# Einmaliger Pre-Auth-Key (24 Stunden gültig)
sudo headscale preauthkeys create --user marketing --expiration 24h

# Wiederverwendbarer Key (z. B. für automatisiertes Onboarding, 30 Tage)
sudo headscale preauthkeys create --user marketing --reusable --expiration 720h

# Alle Keys eines Users auflisten
sudo headscale preauthkeys list --user marketing

Sicherheitshinweis: Wiederverwendbare Keys mit langer Laufzeit sind ein Sicherheitsrisiko. Im Produktionsbetrieb lieber kurzlebige Einmal-Keys nutzen oder das Ablaufdatum bewusst kurz halten.

Schritt 6: Geräte verbinden

Auf dem Client-Gerät ist der offizielle Tailscale-Client installiert. Der einzige Unterschied zu Tailscale-Cloud: Der Login-Server wird als Parameter mitgegeben.

# Linux / macOS: Interaktiver Login (öffnet Browser-Authentifizierung)
tailscale up --login-server https://hs.example.com

# Mit Pre-Auth-Key (kein Browser-Login, ideal für Server-Onboarding)
tailscale up --login-server https://hs.example.com --authkey <PREAUTHKEY>

# Wenn kein Pre-Auth-Key: Node serverseitig manuell registrieren
# (den nodekey aus dem Client-Output kopieren)
sudo headscale nodes register --user marketing --key nodekey:<KEY_AUS_OUTPUT>

# Alle verbundenen Nodes anzeigen
sudo headscale nodes list

Auf Windows und macOS gibt es GUI-Clients; auf iOS/Android muss der Custom Control Server in den App-Einstellungen unter „Account" → „Use custom coordination server" eingetragen werden.

Schritt 7: ACL-Policies für Abteilungstrennung

Headscale verwendet das gleiche HuJSON-Format wie Tailscale für ACL-Policies. Ohne explizite accept-Regel gilt Default-Deny – Gruppen sehen sich gegenseitig nicht. IT-Admins erhalten vollen Zugriff, Marketing und Buchhaltung kommunizieren nur intern:

// /etc/headscale/acl.json
{
  "groups": {
    "group:it-admin":    ["it-admin"],
    "group:marketing":   ["marketing"],
    "group:buchhaltung": ["buchhaltung"]
  },
  "acls": [
    // IT-Admin darf alles
    { "action": "accept", "src": ["group:it-admin"], "dst": ["*:*"] },
    // Marketing darf nur innerhalb der eigenen Gruppe kommunizieren
    { "action": "accept", "src": ["group:marketing"], "dst": ["group:marketing:*"] },
    // Buchhaltung darf nur innerhalb der eigenen Gruppe kommunizieren
    { "action": "accept", "src": ["group:buchhaltung"], "dst": ["group:buchhaltung:*"] }
  ]
}
# Policy laden / neu einlesen (ohne Neustart)
sudo headscale policy apply --file /etc/headscale/acl.json

Die Policy-Datei kann jederzeit angepasst und neu eingespielt werden, ohne Headscale neu zu starten. Für eine detaillierte Absicherung der Server-Infrastruktur empfiehlt sich ergänzend die Anleitung Linux-Server absichern mit UFW und Fail2ban.

Schritt 8: Subnet-Router – LAN-Subnetz ins Tailnet einbinden

Ein Subnet-Router macht ein komplettes lokales Netz (z. B. Büro-LAN 192.168.10.0/24) für alle Tailnet-Teilnehmer erreichbar, ohne auf jedem Gerät im LAN Tailscale installieren zu müssen:

# IP-Forwarding aktivieren (persistent via sysctl)
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

# Subnetz bekanntmachen (auf dem Node, der das LAN sieht)
sudo tailscale up --login-server https://hs.example.com --advertise-routes=192.168.10.0/24

# Serverseitig: Route genehmigen
sudo headscale routes list
sudo headscale routes enable -r <ROUTE_ID>

Fallstrick: Wird IP-Forwarding nur transient aktiviert (echo 1 > /proc/sys/net/ipv4/ip_forward), geht die Einstellung beim nächsten Neustart verloren. Immer den /etc/sysctl.d/-Pfad nutzen.

Schritt 9: Exit-Node konfigurieren

Ein Exit-Node leitet den gesamten Internet-Traffic eines Clients über einen bestimmten Knoten – nützlich für Homeoffice-Nutzer, die scheinbar aus dem Büronetz agieren wollen:

# Auf dem Node, der als Exit-Node dienen soll:
sudo tailscale up --login-server https://hs.example.com --advertise-exit-node

# Serverseitig freischalten (zwei Routen: 0.0.0.0/0 und ::/0)
sudo headscale routes list
sudo headscale routes enable -r <ID_IPv4>
sudo headscale routes enable -r <ID_IPv6>

# Auf dem Client-Gerät den Exit-Node nutzen:
sudo tailscale up --exit-node=<TAILSCALE-IP-DES-EXIT-NODES>

Schritt 10: DERP-Relay und Node-Verwaltung

DERP löst NAT-Traversal in rund 95 % der Fälle. Headscale nutzt per Default die öffentliche DERP-Map von Tailscale, die alle 3 Stunden automatisch aktualisiert wird. Für vollständige DSGVO-Konformität (keine Metadaten über US-Infrastruktur) betreibst du eigene DERP-Server und setzt urls: [] in der Konfiguration.

# DERP-Status auf einem Client prüfen
tailscale debug derp-map
tailscale debug derp headscale

# Alle Nodes auflisten
sudo headscale nodes list

# Einzelnen Node manuell ablaufen lassen (z. B. bei Gerätetausch)
sudo headscale nodes expire --identifier <NODE_ID>

# Alle Routen prüfen
sudo headscale routes list

Key-Expiry: In Headscale laufen Nodes per Default nie ab (Expiry = 0), anders als bei Tailscale-Cloud mit 180 Tagen. Pre-Auth-Keys laufen standardmäßig nach 1 Stunde ab. Wer automatisches Ablaufen erzwingen möchte, setzt das Ablaufdatum beim Node-Register oder nutzt headscale nodes expire.

Troubleshooting / Typische Fehler

  • Client verbindet sich nicht / „Invalid server URL": TLS-Zertifikat prüfen – selbstsignierte Zertifikate werden von Tailscale-Clients abgelehnt. Certbot-Erneuerung mit sudo certbot renew --dry-run testen.
  • WebSocket-Verbindung bricht ab: Nginx-Konfiguration prüfen – proxy_http_version 1.1, Upgrade/Connection-Header und proxy_buffering off müssen gesetzt sein.
  • Cloudflare-Proxy (orange) aktiv: Cloudflare blockiert WebSocket-POST-Requests. DNS auf „DNS only" (grau) umschalten.
  • MagicDNS löst Hostnamen nicht auf: base_domain und server_url-Domain dürfen nicht übereinstimmen. Kein abschließender Punkt im FQDN. Nach Änderung Headscale neu starten.
  • Subnet-Router funktioniert nach Neustart nicht mehr: IP-Forwarding persistent in /etc/sysctl.d/99-tailscale.conf speichern, nicht nur transient setzen.
  • Exit-Node-Route verschwindet aus der Liste: Bekannte Regression in v0.25.0 (Bug #2433), in v0.28 behoben. Auf die aktuelle Patch-Version upgraden.
  • Headscale und Tailscale-Client auf demselben Host: Nicht unterstützt. Entstehen Konflikte bei Subnet-Routing, MagicDNS und Traffic-Relay. Headscale-Server und Tailscale-Client auf getrennten Hosts betreiben.
  • PostgreSQL geplant: Headscale stuft PostgreSQL offiziell als „maintenance mode" ein. Neue Instanzen immer mit SQLite (Standard) aufsetzen.
  • DERP-Relay nicht erreichbar / keine Verbindung hinter doppeltem NAT: Eingebetteten DERP-Server aktivieren (derp.server.enabled: true) und UDP/3478 in der Firewall freigeben, oder eigene derper-Instanz betreiben.

Häufige Fragen

Kann ich die offiziellen Tailscale-Apps mit Headscale nutzen?

Ja. Headscale ist vollständig kompatibel mit den offiziellen Tailscale-Clients auf allen Plattformen (Windows, macOS, Linux, iOS, Android). Der Login-Server wird beim Aufruf als Parameter übergeben (--login-server https://hs.example.com). Auf mobilen Geräten trägt man den Custom Control Server in den App-Einstellungen ein.

Wie groß muss der Server für Headscale sein?

Für ein KMU mit bis zu 50–100 Geräten reicht ein kleines VPS-Paket: 1 vCPU, 1–2 GB RAM, 20 GB SSD (z. B. Hetzner CX11 für ca. 3 EUR/Monat). Der Headscale-Prozess selbst verbraucht unter 100 MB RAM. Der Großteil der Netzwerklast läuft direkt Peer-to-Peer zwischen den Nodes – der Control Server ist kein Datenpfad-Flaschenhals.

Was passiert, wenn mein Headscale-Server ausfällt?

Bestehende Peer-to-Peer-Verbindungen bleiben aktiv, solange die WireGuard-Sessions nicht ablaufen. Neue Verbindungsaufbauten und NAT-Traversal schlagen fehl, bis der Server wieder erreichbar ist. Ein regelmäßiges Backup von /var/lib/headscale/ (SQLite-Datenbank, Private Keys) ist daher Pflicht. Wie du automatisierte Backups einrichtest, zeigt die Anleitung Restic-Backup unter Linux und Windows automatisieren.

Brauche ich einen eigenen DERP-Server für vollständige DSGVO-Konformität?

Wenn nur der Control Server relevant ist, reicht das Selbsthosten von Headscale. Nutzt du aber die Standard-DERP-Map von Tailscale, werden Relay-Verbindungen über Tailscale-Infrastruktur in den USA abgewickelt. Für vollständige Datenlokalisierung musst du auch eigene DERP-Server (tailscale/derper) betreiben und urls: [] setzen.

Wie vergleicht sich die Performance gegenüber reinem WireGuard?

Im direkten Peer-to-Peer-Pfad liegt der Durchsatz unter 3 % unter dem von reinem WireGuard auf Linux – der Datenpfad ist identisch (WireGuard-Kernel-Modul). Auf DERP-Relay-Pfaden gelten Relay-Bandbreite und geografische Latenz als Engpass, nicht Headscale selbst.

Wann sollte ich lieber bei Tailscale-Cloud bleiben?

Tailscale-Cloud ist sinnvoll, wenn schnelles Onboarding wichtiger ist als Datensouveränität, das IT-Team sehr klein ist und die Gerätezahl im Free-Tier (3 User, 100 Geräte) bleibt, oder SSO-Integration (Google, Azure AD) ohne eigene OIDC-Infrastruktur benötigt wird.

Was bedeutet „Key-Expiry" in Headscale konkret?

In Headscale laufen Node-Keys per Default nie ab (Expiry = 0) – anders als Tailscale-Cloud mit 180 Tagen. Pre-Auth-Keys dagegen laufen standardmäßig nach 1 Stunde ab. Wer Tailscale-SaaS-ähnliches automatisches Ablaufen möchte, muss das manuell konfigurieren oder per headscale nodes expire erzwingen. Reusable Keys mit zu langer Laufzeit stellen ein Sicherheitsrisiko dar.

Fazit

Headscale ist für KMU der pragmatische Mittelweg zwischen manuellem WireGuard-Management und der Cloud-Abhängigkeit von Tailscale: Du bekommst automatische Peer-Discovery, NAT-Traversal, ACL-basierte Abteilungstrennung und MagicDNS – auf eigener Infrastruktur, ohne Geräte-Limits, für die Kosten eines kleinen Hetzner-VPS. Der Einrichtungsaufwand von rund 90 Minuten amortisiert sich schnell, wenn das Netz wächst oder DSGVO-Anforderungen eine klare Datenlokalisierung verlangen. Die wichtigsten Fallstricke – TLS-Pflicht, kein Cloudflare-Proxy, MagicDNS-Domain-Trennung, persistentes IP-Forwarding – sind gut dokumentiert und mit dieser Anleitung vermeidbar.

Weiterführende Anleitungen und Quellen

Quellen: Headscale GitHub Repository (juanfont/headscale) · Headscale-Dokumentation (headscale.net) · Headscale FAQ · MassiveGRID Blog: Self-Host Headscale on Ubuntu VPS · netguardia.com: Tailscale vs. WireGuard vs. Headscale