Wer einen Homelab-Server betreibt, kennt das Dilemma: Die selbst gehosteten Dienste sollen auch von unterwegs erreichbar sein – aber Port-Forwarding am Router öffnet Ports direkt ins Internet, DynDNS ist fehleranfällig, und ein falsches Nginx-Config-Häkchen reicht, um sensible Dienste ungewollt zu exponieren. Es muss einen besseren Weg geben.

Den gibt es: Cloudflare Zero Trust Tunnel. Seit ich meinen Homeserver damit betreibe, habe ich keine einzige Firewall-Regel für eingehenden Traffic mehr – und trotzdem sind alle meine Dienste weltweit erreichbar.

Das Prinzip: Ausgehend statt eingehend

Der entscheidende Unterschied zu klassischem Port-Forwarding ist die Richtung der Verbindung. Beim klassischen Ansatz öffnet man Ports nach außen und hofft, dass der eigene Server sicher genug ist. Beim Cloudflare Tunnel dreht sich das Prinzip um:

  • Ein kleiner Daemon (cloudflared) läuft auf dem Homeserver
  • Dieser baut eine ausgehende verschlüsselte Verbindung zu Cloudflares Edge-Netzwerk auf
  • Eingehende Anfragen an die Domain werden über diese Verbindung zum Server weitergeleitet
  • Der Router muss keinen einzigen Port öffnen

Das Resultat: Kein offener Port, keine DynDNS-Probleme, kein direkter Zugriff auf die Heimnetz-IP von außen. Cloudflare sitzt als Proxy davor und übernimmt SSL-Terminierung, DDoS-Schutz und Rate-Limiting gleich mit.

Setup auf NixOS

Voraussetzung ist eine bei Cloudflare verwaltete Domain. Der kostenlose Plan reicht vollständig aus. Auf NixOS wird cloudflared deklarativ konfiguriert:

services.cloudflared = {
  enable = true;
  tunnels."mein-tunnel" = {
    credentialsFile = "/var/lib/cloudflared/tunnel-credentials.json";
    ingress = {
      "app.example.com" = "http://localhost:8000";
      "wiki.example.com" = "http://localhost:8080";
    };
  };
};

Auf anderen Systemen reicht cloudflared tunnel login, um den Browser zur Autorisierung zu öffnen, gefolgt von cloudflared tunnel create mein-tunnel.

Public Hostnames konfigurieren

Im Cloudflare-Dashboard unter Zero Trust → Networks → Tunnels legt man pro Subdomain eine Route an:

  • Public Hostname: Die externe Domain, z.B. app.example.com
  • Service: Die interne Adresse des Dienstes auf dem Server

Nginx auf dem Server übernimmt dann das Host-based Routing – je nach Host-Header wird die Anfrage an den richtigen Dienst weitergeleitet. Ein Tunnel, beliebig viele Domains.

Zusätzliche Absicherung: Access Policies

Cloudflare Zero Trust erlaubt es, einzelne Dienste hinter einer Authentifizierungsschicht zu sperren. Für interne Tools (Wiki, Monitoring-Dashboards) habe ich Access Policies eingerichtet, die nur nach E-Mail-OTP Zugriff gewähren:

# Zero Trust → Access → Applications → Add Application
# Policy: Allow users matching "email is [email protected]"
# Methode: One-Time PIN per E-Mail

Damit ist das Wiki von außen erreichbar, aber ohne Authentifizierung kommt niemand rein.

Was es nicht löst

  • UDP / nicht-HTTP-Protokolle: Für reine TCP/UDP-Dienste braucht man Cloudflare Spectrum (kostenpflichtig) oder einen anderen Ansatz wie WireGuard
  • Cloudflare als Mittelsmann: Traffic läuft über Cloudflares Infrastruktur – wer das nicht möchte, ist mit einem WireGuard-VPN besser bedient
  • Latenz: Für latenzempfindliche Anwendungen kann der Umweg über Cloudflares Edge messbar sein

Fazit

Cloudflare Zero Trust Tunnel ist die eleganteste Lösung, die ich für das Problem „Homelab von außen erreichbar machen" kenne. Null offene Ports, SSL inklusive, kostenlos für private Nutzung. Der Tunnel läuft als systemd-Dienst, der bei jedem Boot automatisch startet und sich bei Verbindungsabbrüchen selbst neu verbindet.

Kombiniert mit den Sicherheitshärtungen am Homeserver ergibt sich ein Setup, das ich bedenkenlos produktiv einsetze – für alle Webdienste, die ich für Kunden betreibe.