Headscale/Tailscale: Einen VPS als Exit Node einrichten
In diesem Beitrag beschreibe ich, wie man einen Ubuntu-Server als Tailscale-Client an eine eigene Headscale-Instanz anbinden kann um diese anschließend als Exit Node zu betreiben..
Headscale ist eine selbst gehostete Implementierung des Tailscale-Control-Servers. Damit lassen sich private WireGuard-basierte Mesh-Netzwerke betreiben, ohne den offiziellen Tailscale-Control-Plane-Dienst nutzen zu müssen.
Das Ziel in diesem Setup:
- Ubuntu-Server als Tailscale-Node registrieren
- Headscale als Login-Server verwenden
- Server mit Tags versehen
- Server als Exit Node bereitstellen
- IP-Forwarding für IPv4 und IPv6 aktivieren
- Headscale-Nodes und Routen prüfen
Ausgangssituation
Der Server läuft auf Ubuntu 24.04 oder Ubuntu 26.04. Die Headscale-Instanz ist bereits vorhanden und unter einer eigenen URL erreichbar:
https://headscale.example.org
Der neue Server soll unter folgendem Hostnamen im Tailnet erscheinen:
vps-tailscale-01
Zusätzlich soll er als Exit Node dienen.
Tailscale Repository hinzufügen
Ubuntu 24.04 Noble
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
Anschließend wird das Tailscale-Repository hinzugefügt:
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
Danach wird die Paketliste aktualisiert:
sudo apt-get update
Ubuntu 26.04 Resolute
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/resolute.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
Anschließend wird das Tailscale-Repository hinzugefügt:
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/resolute.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
Danach wird die Paketliste aktualisiert:
sudo apt get update
Tailscale installieren
Die Installation erfolgt direkt über apt:
sudo apt-get install tailscale
Damit ist der Tailscale-Client auf dem Server installiert.
Server mit Headscale verbinden
Der Server wird nun gegen die eigene Headscale-Instanz registriert.
sudo tailscale up \
--login-server https://headscale.example.org \
--authkey <AUTHKEY> \
--hostname vps-tailscale-01 \
--advertise-tags=tag:server,tag:egress \
--advertise-exit-node \
--accept-routes \
--accept-dns=false
Die wichtigsten Optionen im Überblick:
| Option | Bedeutung |
|---|---|
| --login-server | Verweist auf die eigene Headscale-Instanz |
| --authkey | Registriert den Node ohne interaktiven Login |
| --hostname | Name des Servers im Tailnet |
| --advertise-tags | Weist dem Node Tags zu |
| --advertise-exit-node | Bietet den Server als Exit Node an |
| --accept-routes | Akzeptiert angekündigte Routen anderer Nodes |
| --accept-dns=false | Übernimmt keine DNS-Einstellungen aus Tailscale/Headscale |
Ich habe hier bewusst --accept-dns=false gesetzt, da ich die DNS-Konfiguration des Servers nicht durch Tailscale überschreiben lassen möchte.
IP-Forwarding aktivieren
Damit der Server sauber als Exit Node arbeiten kann, muss IP-Forwarding aktiviert werden.
Für IPv4:
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
Anwenden der Einstellung:
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
Für IPv6:
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
Auch diese Einstellung wird anschließend geladen:
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
Die Datei /etc/sysctl.d/99-tailscale.conf enthält danach:
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
Status prüfen
Nach der Registrierung sollte der Node im Tailnet sichtbar sein:
tailscale status
Ob der Exit Node korrekt erkannt wird, lässt sich mit folgendem Befehl prüfen:
tailscale debug exit-node-status
Falls Änderungen an der Konfiguration notwendig sind, kann der Client neu verbunden werden:
sudo tailscale down
sudo tailscale up \
--login-server https://headscale.example.org \
--authkey <AUTHKEY> \
--hostname vps-tailscale-01 \
--advertise-tags=tag:server,tag:egress \
--advertise-exit-node \
--accept-routes \
--accept-dns=false
Headscale prüfen
Die Logs lassen sich wie gewohnt verfolgen:
docker compose logs -f
Fazit
Mit wenigen Schritten lässt sich ein Ubuntu-Server als Tailscale-Node an eine eigene Headscale-Instanz anbinden. Durch die Option --advertise-exit-node kann der Server zusätzlich als Exit Node dienen und damit ausgehenden Traffic anderer Tailnet-Clients übernehmen.
Wichtig sind dabei vor allem drei Punkte:
Erstens muss der Node korrekt gegen Headscale registriert werden. Zweitens muss IP-Forwarding für IPv4 und optional IPv6 aktiviert sein. Drittens sollte man die Funktion über tailscale status, tailscale debug exit-node-status und die Headscale-CLI prüfen.
Für produktive Setups sollte der Auth-Key natürlich nicht dauerhaft in der Shell-History oder in Skripten liegen. Außerdem lohnt es sich, die Tags sauber zu planen, damit später ACLs und Berechtigungen nachvollziehbar bleiben.