Tailscale Alternative einrichten Teil 4 / 4

Teil 4: Eigene Web-Anwendungen freigeben

Angenommen, du hast irgendwo in deinem Zuhause (auf einem NAS, Raspberry Pi, alten PC, o. ä.) bereits Tailscale installiert und mit deinem Headscale-Server verbunden (siehe Teil 3). Jetzt willst du eine dort laufende Web-Anwendung erreichbar machen, entweder nur für Geräte in deinem Tailnet, oder für die ganze Welt.

Nimm als Beispiel an, das Gerät hat die Tailscale-IP 100.64.0.10, und eine Anwendung läuft dort auf Port 9000.

Fall 1: Schöne URL, nur im Tailnet, ganz ohne Portnummer

Headscale kann eigene DNS-Einträge für dein Tailnet vergeben ("Extra DNS Records"). Der Trick, um die Portnummer wegzubekommen: Der Eintrag zeigt nicht direkt auf die App-IP, sondern auf die Tailscale-IP deines Headscale-Servers selbst, und Caddy übernimmt dort die Portweiterleitung.

Ergänze in ~/headscale/headscale/config/config.yaml, innerhalb des dns:-Blocks:

YAML
dns:
  # ... bestehende Einträge ...
  extra_records:
    - name: "meineapp.internal.example.com"
      type: "A"
      value: "100.64.0.1"   # Tailscale-IP DEINES Headscale-Servers, nicht der App

⚠️ Der Block muss wirklich innerhalb von dns: stehen. Außerhalb wird er von Headscale stillschweigend ignoriert, auch wenn die Datei syntaktisch gültig bleibt.

Terminal
cd ~/headscale
docker compose up -d --force-recreate headscale

In der Caddyfile (/etc/caddy/Caddyfile), mit explizitem http://, damit Caddy kein Zertifikat versucht:

/etc/caddy/Caddyfile
# /etc/caddy/Caddyfile
http://meineapp.internal.example.com {
    reverse_proxy 100.64.0.10:9000
}
Terminal
sudo systemctl reload caddy

Test von einem Tailnet-Gerät:

Terminal
curl -I http://meineapp.internal.example.com

Fall 2: Öffentlich erreichbar, auch ohne VPN

⚠️ Verwende dafür niemals deine MagicDNS-Basisdomain (internal.example.com in dieser Anleitung). Nutze eine andere Subdomain oder deine Hauptdomain direkt.

  1. DNS-Eintrag anlegen: A-Record, z. B. meineapp.example.com, zeigt auf die öffentliche IP deines Headscale-Servers.

  2. Caddy-Block, dieses Mal ohne http://-Präfix, damit Caddy automatisch ein Let's-Encrypt-Zertifikat holt:

/etc/caddy/Caddyfile
# /etc/caddy/Caddyfile
meineapp.example.com {
    reverse_proxy 100.64.0.10:9000
}
Terminal
sudo systemctl reload caddy
  1. Testen:
Terminal
curl -I https://meineapp.example.com

Möglicher Stolperstein: Manche Apps prüfen den Host-Header (CSRF-Schutz) und lehnen Anfragen unter einer unbekannten Domain ab. Falls Login/Formulare nach dem Umstieg fehlschlagen, meist hilft eine Umgebungsvariable wie CSRF_TRUSTED_ORIGINS in der jeweiligen App-Konfiguration.

Entscheidungshilfe

Situation Lösung
Familie soll sich einen Namen merken, kein Zugriff von außerhalb des Tailnets nötig Fall 1
Zugriff auch ohne VPN/unterwegs nötig Fall 2

Das war's mit dem Kern der Anleitung! Falls du auch einen Unraid-Server einbinden willst, gibt's dafür noch einen Bonus-Teil.