Headscale/Tailscale: Einen VPS als Exit Node einrichten

Headscale/Tailscale: Einen VPS als Exit Node einrichten
Photo by Andrew Teoh / Unsplash

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.