← Zurück zum Blog

Headscale statt Tailscale – mein privates Mesh-VPN ohne fremden Server

Headscale statt Tailscale – mein privates Mesh-VPN ohne fremden Server

Tailscale kannte ich schon länger, habe es aber immer ignoriert. Jetzt hatte ich endlich Zeit, mir einen Probeaccount gemacht und gemerkt: Das läuft richtig flüssig und passt gut in mein Setup.

Zwei Dinge haben mich aber gestört. Erstens erlaubt Tailscale keinen Login per Custom-E-Mail – ich musste meinen verwaisten Google-Account ausgraben, was ich nicht mag. Zweitens widerspricht es meiner Philosophie, für so etwas Zentrales den Server einer externen Firma zu nutzen.

Hier kommt Headscale ins Spiel: eine Open-Source-Implementierung des Tailscale-Koordinationsservers. Für meinen simplen Einsatzzweck reicht der Funktionsumfang allemal – im Enterprise-Umfeld mag das anders aussehen, aber privat fehlt mir nichts.

Was macht Tailscale eigentlich?

Tailscale spannt ein privates Peer-to-Peer-Netz auf Basis von WireGuard zwischen allen beteiligten Rechnern auf. Jeder Knoten baut einen verschlüsselten Tunnel zu jedem anderen Knoten auf – die Kommunikation ist also von Haus aus sicher, und alle Teilnehmer erreichen sich in einem eigenen Netzsegment.

Durch die spezielle Architektur lassen sich auch Rechner hinter Firewall, NAT oder CGNAT einbinden, ohne explizites Portforwarding. Genau das ist meine Hoffnung: den letzten verbliebenen Portforward in mein Heimnetz loszuwerden.

Ein internes DNS-System vergibt Namen für die Knoten, sodass man sie bequem ansprechen kann. Auch SSH soll damit einfacher werden – der Dienst verwaltet dann die Schlüssel selbst. Das habe ich aber noch nicht ausprobiert, meine Testrechner hatten ohnehin schon Schlüssel getauscht.

Tailscale vs. Headscale

Aspekt Tailscale (SaaS) Headscale (self-hosted)
Koordinationsserver Bei Tailscale Inc. Auf meinem Server
Login Google, GitHub, etc. Eigene User, per CLI
Custom-E-Mail Nein Ja (kein Login-Provider nötig)
Funktionsumfang Voll (inkl. Enterprise) Kern-Features, für privat ausreichend
Client Original Tailscale-Client Original Tailscale-Client
Datenhoheit Bei der Firma Bei mir

Der Clou: Als Client nutzt man den ganz normalen Tailscale-Client. Nur der Koordinationsserver wird durch Headscale ersetzt.

Installation

Den Headscale-Server installiere ich am einfachsten per Docker – wie üblich in einem Incus-Container (Alpine) unter /opt/headscale.

services:
  headscale:
    container_name: headscale
    image: headscale/headscale:v0.26.0
    restart: unless-stopped
    ports:
      - '8080:8080'
      - '9090:9090'
    volumes:
      - './config:/etc/headscale'
      - './data:/var/lib/headscale'
    environment:
      TZ: 'Europe/Berlin'
    command: serve

Dann noch die Beispielkonfiguration herunterladen, unter config/config.yml ablegen und anpassen:

# URL, mit der sich die Clients verbinden (hier eure Domain)
server_url: https://headscale.frischux.de

listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090

database:
  sqlite:
    write_ahead_log: true

policy:
  # "file" oder "database" – legt fest, wo die ACL-Policies liegen
  mode: database
  path: "/etc/headscale/acl.hujson"

dns:
  magic_dns: true
  base_domain: fx.de            # Domain, unter der ihr die Knoten ansprecht
                                 # (Kurz absichtlich gewählt – 2-stellige
                                 # Domains bekommt man heutzutage nicht mehr)
  override_local_dns: true
  nameservers:
    global:
      - 1.1.1.1
      - 9.9.9.9

Man kann noch viel mehr konfigurieren, aber zum Ausprobieren reicht das. Dann:

docker compose up -d

Netzwerk aufbauen

Jeder Knoten muss dem Server bekannt sein. Um den Rechner test1 anzumelden:

docker exec headscale headscale users create test1

Auf test1 den Tailscale-Client installieren:

curl -fsSL https://tailscale.com/install.sh | sh

Wer sich unwohl fühlt, ein Shellscript aus dem Netz auszuführen, kann den Client auch händisch über die offiziellen Repositories und den Paketmanager installieren – dazu gibt es für nahezu jedes Betriebssystem eine Anleitung.

Dann den Client mit dem eigenen Server verbinden:

tailscale up --login-server https://headscale.frischux.de

Es wird eine URL angezeigt, die das Registrierungskommando ausgibt:

headscale nodes register --key XXXXXXXXXXXXXX --user test1

Wenn alles klappt, ist test1 registriert, hat eine IP im privaten Tailnet und ist ab sofort im ganzen Netz unter dieser IP oder einem freien Namen erreichbar. Sehr praktisch.

tailscale status

zeigt auf jedem Knoten die anderen Knoten an.

Es gibt auch ein hübsches Frontend für den Server: Headplane – nicht das einzige, aber wohl das bekannteste. Damit beschäftige ich mich in einem der nächsten Posts. Im Moment reicht mir die Kommandozeile.

Fazit

Der große Gewinn: Kein fremder Koordinationsserver, kein Google-Login, kein Portforward mehr in mein Heimnetz. WireGuard-Sicherheit, eigene Kontrolle, Original-Client – genau so, wie ich mir das vorstelle.