Tailscale · Architektur

🕸️Tailscale – WireGuard als Mesh

WireGuard verschlüsselt, aber es verteilt keine Schlüssel, findet keine Wege durch NAT und kennt keine Benutzer. Genau das ergänzt Tailscale: Ein Koordinationsserver übernimmt die Schlüsselverteilung, NAT-Traversal baut direkte Verbindungen auf, DERP-Relays springen ein, wenn nichts anderes geht.

🧠Control Plane vs. Data Plane

Die wichtigste Idee: Steuerung zentral, Daten dezentral.
🧠 KoordinationsserverTailscale oder Headscale💻 Laptop100.101.12.4🖥️ Server100.101.12.9📱 Handy100.101.12.21🗄️ NAS100.101.12.40
Control Plane (Stern)

Jeder Knoten hält eine Verbindung zum Koordinationsserver: Anmeldung, Node-Keys, Netmap, ACLs, DNS-Einstellungen. Nur Metadaten – wenige Kilobyte, kein Nutzverkehr.

🔐Drei Schlüssel pro Gerät

Alle privaten Schlüssel entstehen auf dem Gerät und verlassen es nie. Der Koordinationsserver sieht nur öffentliche Schlüssel – er ist ein „Briefkasten für öffentliche Schlüssel“ und kann den Verkehr nicht entschlüsseln.
🏷️
Machine-Key

Identifiziert das Gerät gegenüber dem Koordinationsserver. Damit wird die verschlüsselte Control-Verbindung (Noise-Protokoll) aufgebaut. Bleibt über Neuanmeldungen hinweg bestehen.

🔑
Node-Key

Der eigentliche WireGuard-Schlüssel. Der öffentliche Teil wird über den Koordinationsserver an alle berechtigten Peers verteilt. Läuft standardmäßig nach 180 Tagen ab (Key Expiry) und wird dann durch erneute Anmeldung ersetzt.

🪩
Disco-Key

Nur für „Discovery“-Nachrichten beim NAT-Traversal (Ping/Pong, CallMeMaybe). So bleiben diese Steuerpakete authentisch, ohne den WireGuard-Handshake zu stören.

🕳️NAT-Traversal und DERP

Die meisten Geräte stecken hinter NAT und Firewalls. Tailscale probiert deshalb mehrere Wege gleichzeitig.
1 · STUN
Das Gerät fragt einen STUN-Server „Unter welcher ip:port siehst du mich?“. Fragt es zwei Server und bekommt verschiedene Ports, sitzt es hinter einem „harten“ NAT (Endpoint-Dependent Mapping).
2 · Hole Punching
Beide Seiten tauschen ihre Kandidaten-Endpunkte aus und senden gleichzeitig UDP-Pakete zueinander. Jedes ausgehende Paket öffnet die eigene Firewall für die Antwort der Gegenseite. Bei einem harten NAT hilft zusätzliches Port-Raten (Geburtstagsparadoxon).
3 · DERP als Rückfallebene
DERP („Designated Encrypted Relay for Packets“) leitet Pakete anhand des öffentlichen Node-Keys über HTTPS weiter. Die Pakete bleiben WireGuard-verschlüsselt – das Relay sieht nur Absender, Empfänger und Größe. DERP dient anfangs auch als Seitenkanal für den Endpunkt-Austausch.

🏷️MagicDNS und Adressen

  • Jedes Gerät bekommt eine feste Adresse aus 100.64.0.0/10 (Carrier-Grade-NAT-Bereich, RFC 6598) und eine IPv6-Adresse aus fd7a:115c:a1e0::/48.
  • MagicDNS registriert automatisch Namen wie laptop bzw. laptop.<tailnet>.ts.net. Der Resolver läuft lokal im Client unter 100.100.100.100 – Anfragen verlassen das Gerät für Tailnet-Namen gar nicht.
  • Tunnel-MTU standardmäßig 1280 (IPv6-Minimum) statt 1420 – etwas weniger effizient, dafür robust auf Strecken mit zusätzlichem Overhead.
$ tailscale status
100.101.12.4   laptop   alice@   linux   -
100.101.12.9   server   alice@   linux   active; direct 203.0.113.50:41641
100.101.12.21  handy    alice@   android active; relay "fra"

$ ping server            # MagicDNS löst auf 100.101.12.9 auf
$ tailscale ping handy   # zeigt, ob direkt oder über DERP

🛂ACLs und Grants

Die Zugriffsregeln stehen zentral in einer Policy-Datei (HuJSON = JSON mit Kommentaren) und werden an alle Knoten verteilt – durchgesetzt werden sie auf jedem Gerät selbst. Mit Policy gilt: alles verboten, was nicht erlaubt ist.
{
  "groups":    { "group:admins": ["alice@example.com"] },
  "tagOwners": { "tag:server":   ["group:admins"] },
  "grants": [
    // Admins dürfen per SSH und HTTPS auf alle Server
    { "src": ["group:admins"],     "dst": ["tag:server"],          "ip": ["tcp:22", "tcp:443"] },
    // Alle Mitglieder dürfen einen Exit-Node benutzen
    { "src": ["autogroup:member"], "dst": ["autogroup:internet"],  "ip": ["*"] }
  ]
}
Grants – die neuere Syntax
Grants vereinen Netzwerkzugriff (ip) und Anwendungsrechte (app) in einer Regel mit src und dst. Die ältere acls-Syntax (action: accept) wird weiter unterstützt.
Tags statt Personen
Server bekommen Tags wie tag:server. Regeln hängen dann an der Rolle, nicht an einem Benutzerkonto – wichtig für Maschinen ohne Besitzer.

🚪Subnet-Router und Exit-Nodes

🧱 Subnet-Router

Ein Tailscale-Gerät macht ein ganzes LAN erreichbar, auf dem kein Tailscale läuft (Drucker, NAS, Kameras). Technisch: das Präfix landet in den AllowedIPs dieses Peers – Cryptokey Routing wie auf der WireGuard-Seite.

# auf dem Router-Gerät (IP-Forwarding aktivieren!)
sudo tailscale up --advertise-routes=192.168.178.0/24
# Route in der Admin-Konsole freigeben;
# Linux-Clients: tailscale up --accept-routes
🌍 Exit-Node

Ein Gerät bietet sich als Ausgang ins Internet an – der Peer erhält dann 0.0.0.0/0 und ::/0 als AllowedIPs. Praktisch im fremden WLAN oder um „von zu Hause aus“ zu surfen.

# Exit-Node anbieten
sudo tailscale up --advertise-exit-node
# auf dem Client benutzen
tailscale set --exit-node=server

🏠Headscale – die Control Plane selbst betreiben

Headscale ist eine unabhängige Open-Source-Implementierung (BSD-3-Clause) des Tailscale-Koordinationsservers. Die offiziellen Tailscale-Clients verbinden sich per tailscale up --login-server https://… damit statt mit dem Tailscale-Dienst.

  • Öffentliche Schlüssel, Gerätelisten und Policies liegen auf dem eigenen Server.
  • Unterstützt u. a. Pre-Auth-Keys, OIDC-Anmeldung, ACL-Policies, MagicDNS, Subnet-Router und Exit-Nodes.
  • Ein eingebauter DERP-Server kann aktiviert werden – oder man nutzt die öffentlichen DERP-Relays von Tailscale.
  • Ausgelegt für ein einzelnes Tailnet (Selbsthoster, kleine Teams), nicht für einen Mehrmandanten-Dienst.
Aus der Praxis
Auch auf dem Server, auf dem diese Sammlung läuft, arbeitet Headscale in einem Docker-Container als selbst gehostete Control Plane. Die Daten-Ebene bleibt dabei unverändert: WireGuard zwischen den Geräten, Ende-zu-Ende verschlüsselt.