CallMeTechie
EN Anmelden
Home Produkte Blog Über mich Kontakt

Routes & HTTPS

v1.x · Updated vor 3 Wochen

HTTP vs. L4 Routing

GateControl unterstützt zwei grundlegend verschiedene Routing-Typen:

  • HTTP-Routing (Layer 7): Caddy analysiert den HTTP-Request, matched nach Domain-Name und leitet an das Backend weiter. Voller Zugriff auf alle HTTP-Features.
  • L4-Routing (Layer 4): Caddy leitet rohen TCP/UDP-Traffic weiter, ohne den Inhalt zu inspizieren. Matching nach Port, nicht nach Domain.

HTTP-Routing

Client  →  https://app.example.com  →  Caddy (matched Domain "app.example.com")  →  Backend 10.8.0.3:8080
Client  →  https://api.example.com  →  Caddy (matched Domain "api.example.com")  →  Backend 10.8.0.4:3000
                                         ↑ Beide auf Port 443, unterschieden durch Domain

L4-Routing

Client  →  server.example.com:25565  →  Caddy (matched Port 25565)  →  Backend 10.8.0.5:25565
Client  →  server.example.com:2222   →  Caddy (matched Port 2222)   →  Backend 10.8.0.6:22
                                         ↑ Verschiedene Ports, Domain ist egal

HTTP-Routing (Layer 7) im Detail

HTTP-Routing ist der Standard-Modus. Caddy terminiert TLS, liest HTTP-Header und matched anhand des Host-Headers.

Funktionsweise:

  1. Client verbindet sich mit Port 443 (oder 80)
  2. TLS-Handshake — Caddy wählt das richtige Zertifikat per SNI
  3. Caddy liest den HTTP Host Header
  4. Match auf konfigurierte Domain → Weiterleitung an Backend
  5. Volle HTTP-Verarbeitung: Header-Manipulation, Compression, Auth, etc.

Alle Route-Features stehen zur Verfügung:

  • Force HTTPS mit Let's Encrypt
  • Backend HTTPS
  • Compression (Gzip/Zstd)
  • Rate Limiting
  • Basic Auth / Route Auth
  • Peer ACL
  • IP Access Control
  • Request Mirroring
  • Retry on Error
  • Circuit Breaker
  • Custom Headers
  • Load Balancing (mehrere Backends)
  • Uptime Monitoring (HTTP Check)
  • Sticky Sessions

L4-Routing (Layer 4) im Detail

L4-Routing leitet rohen TCP- oder UDP-Traffic weiter. Caddy öffnet einen eigenen Port und tunnelt den Traffic zum Backend.

Protocol: TCP oder UDP

ProtocolUse Cases
TCPSSH, Minecraft, SMTP, Datenbanken, die meisten Dienste
UDPDNS, Game-Server (manche), VoIP, WireGuard

Listen Port

Der Port den Caddy auf dem GateControl-Server öffnet. Das ist der Port zu dem sich Clients verbinden.

  • Nicht der Target Port (der Port auf dem Backend)
  • Kann gleich oder unterschiedlich zum Target Port sein
  • Muss auf dem GateControl-Server frei sein

TLS-Modus

ModusBeschreibungCaddy-Verhalten
NoneKein TLSCaddy leitet rohen TCP/UDP Traffic weiter
PassthroughTLS DurchleitungCaddy matched per SNI, leitet verschlüsselten Traffic weiter ohne zu entschlüsseln
TerminateTLS TerminierungCaddy entschlüsselt TLS (mit LE-Zertifikat), leitet dann unverschlüsselten TCP an Backend

Target Port vs. Listen Port

FeldGilt fürBeschreibung
Target PortAlle Routen (HTTP + L4)Der Port auf dem Backend-Peer wo der Dienst läuft
Listen PortNur L4-RoutenDer Port den Caddy auf dem GateControl-Server öffnet

Beispiel 1: Gleiche Ports

Listen Port 25565 (GateControl)  →  Target Port 25565 (Minecraft auf Peer 10.8.0.4)
Client verbindet sich mit: server.example.com:25565

Beispiel 2: Unterschiedliche Ports

Listen Port 8022 (GateControl)  →  Target Port 22 (SSH auf Peer 10.8.0.2)
Client verbindet sich mit: server.example.com:8022
SSH-Befehl: ssh -p 8022 user@server.example.com

Beispiel 3: Mehrere Dienste, verschiedene Ports

Listen Port 25565  →  Target Port 25565 (Minecraft auf 10.8.0.4)
Listen Port 2222   →  Target Port 22 (SSH auf 10.8.0.2)
Listen Port 5433   →  Target Port 5432 (PostgreSQL auf 10.8.0.3)

Bei HTTP-Routen gibt es keinen Listen Port — alle HTTP-Routen teilen sich Port 80/443 und werden per Domain unterschieden.

TLS-Modi im Detail

None — Kein TLS

Client  ──TCP/UDP──→  Caddy:25565  ──TCP/UDP──→  Backend:25565
         unverschlüsselt             unverschlüsselt
  • Kein TLS-Handshake, kein SNI
  • Einfachstes Setup, kein Zertifikat nötig
  • Use Cases: Minecraft, Game-Server, DNS, plain SMTP, Datenbanken im VPN

Passthrough — TLS Durchleitung

Client  ──TLS──→  Caddy:443  ──TLS──→  Backend:443
         verschlüsselt         verschlüsselt (gleiche Verbindung)
  • Caddy liest nur den SNI (Server Name) aus dem TLS ClientHello
  • Der TLS-Tunnel wird nicht aufgebrochen — End-to-End Verschlüsselung
  • Das Backend muss ein eigenes gültiges Zertifikat haben
  • Use Cases: Backend mit eigenem LE-Zertifikat, strenge E2E-Verschlüsselungsanforderungen

Terminate — TLS Terminierung

Client  ──TLS──→  Caddy:993  ──TCP──→  Backend:143
         verschlüsselt          unverschlüsselt
         (Let's Encrypt)
  • Caddy terminiert TLS mit einem Let's Encrypt Zertifikat
  • Der Traffic zum Backend ist unverschlüsselt (aber im VPN)
  • Use Cases: TLS für Dienste die es nicht nativ unterstützen, IMAPS/SMTPS vor plaintext Backend

Blockierte Ports

PortVerwendung
80Caddy HTTP (ACME Challenge + Redirect)
443Caddy HTTPS (HTTP-Routen)
2019Caddy Admin API
3000GateControl Web UI
51820WireGuard VPN

Use Cases

Minecraft Server (TCP, Port 25565, TLS: None)

Spieler verbindet sich mit: mc.example.com:25565
L4-Route: Listen Port 25565 → Peer "Gaming-Server" Target Port 25565
Protocol: TCP, TLS: None

SSH-Zugang (TCP, Port 2222 → 22, TLS: None)

ssh -p 2222 admin@server.example.com
L4-Route: Listen Port 2222 → Peer "Homeserver" Target Port 22
Protocol: TCP, TLS: None

Port 22 wird nicht als Listen Port verwendet um Konflikte mit dem SSH des GateControl-Servers zu vermeiden.

Datenbank (TCP, Port 5433 → 5432, TLS: None)

psql -h server.example.com -p 5433 -U myuser mydb
L4-Route: Listen Port 5433 → Peer "DB-Server" Target Port 5432
Protocol: TCP, TLS: None

Game Server (UDP)

Spieler verbindet sich mit: game.example.com:27015
L4-Route: Listen Port 27015 → Peer "Game-Server" Target Port 27015
Protocol: UDP, TLS: None

Feature-Vergleich: HTTP vs. L4

FeatureHTTP (Layer 7)L4 (Layer 4)
Routing-MethodeDomain-basiertPort-basiert
HTTPS / Let's EncryptJaNur mit TLS Terminate
Compression (Gzip/Zstd)JaNein
Rate LimitingJaNein
Custom HeadersJaNein
Basic AuthJaNein
Route AuthJaNein
Peer ACLJaNein
IP Access ControlJaNein
Request MirroringJaNein
Retry on ErrorJaNein
Circuit BreakerJaNein
Uptime MonitoringHTTP CheckTCP Check
Mehrere BackendsJa (Load Balancing)Nein
Sticky SessionsJaNein
WebSocketJa (automatisch)Ja (als TCP)
ProtokollHTTP/HTTPSTCP / UDP

WebSocket bei HTTP-Routen: WebSocket-Verbindungen starten als normaler HTTP-Request mit einem speziellen Connection: Upgrade Header. Caddy erkennt diesen Header automatisch und schaltet die Verbindung auf eine persistente WebSocket-Verbindung um. Es ist keine zusätzliche Konfiguration nötig — das funktioniert out-of-the-box bei jeder HTTP-Route.

WebSocket bei L4-Routen: Da L4 den rohen TCP-Stream weiterleitet ohne den Inhalt zu inspizieren, funktioniert WebSocket hier ebenfalls — Caddy sieht nur TCP-Pakete und leitet sie 1:1 weiter.

Einrichtung

HTTP-Route erstellen (UI)

  1. Route Type: HTTP (Standard)
  2. Domain eingeben (z.B. app.example.com)
  3. Target Peer auswählen
  4. Target Port eingeben (z.B. 8080)
  5. Features konfigurieren (HTTPS, Auth, etc.)
  6. Speichern

L4-Route erstellen (UI)

  1. Route Type: L4 umschalten
  2. Domain eingeben (wird für TLS Passthrough/Terminate benötigt, bei TLS None optional)
  3. Target Peer auswählen
  4. Target Port eingeben (Port auf dem Backend)
  5. Protocol: TCP oder UDP auswählen
  6. Listen Port eingeben (Port auf dem GateControl-Server)
  7. TLS Mode auswählen (None, Passthrough, Terminate)
  8. Speichern

Über die API

# HTTP-Route erstellen
curl -X POST https://gatecontrol.example.com/api/v1/routes \
  -H "Authorization: Bearer gc_..." \
  -H "Content-Type: application/json" \
  -d '{"route_type":"http","domain":"app.example.com","peer_id":1,"target_port":8080,"https_enabled":true}'

# L4-Route erstellen (Minecraft)
curl -X POST https://gatecontrol.example.com/api/v1/routes \
  -H "Authorization: Bearer gc_..." \
  -H "Content-Type: application/json" \
  -d '{"route_type":"l4","domain":"mc.example.com","peer_id":2,"target_port":25565,"l4_protocol":"tcp","l4_listen_port":"25565","l4_tls_mode":"none"}'

Wichtige Hinweise

  • L4-Routen belegen exklusive Ports. Jede L4-Route (ohne TLS) braucht einen eigenen Listen Port.
  • Mehrere L4-Routen mit TLS (Passthrough oder Terminate) können sich denselben Port teilen — Caddy unterscheidet sie per SNI.
  • Port-Ranges sind möglich (z.B. 25565-25575 für mehrere Minecraft-Server).
  • UDP-Routen unterstützen kein TLS (TLS läuft über TCP).
  • L4-Routen haben keine HTTP-Features.

Force HTTPS

Aktiviert automatische TLS-Verschlüsselung mit Let's Encrypt Zertifikaten — HTTP-Anfragen werden per 301 auf HTTPS umgeleitet, Zertifikate werden automatisch erneuert.

Wie funktioniert es?

Ohne Force HTTPS:

Client  →  http://app.example.com:80   →  Caddy  →  Backend
             ↑ unverschlüsselt, Daten im Klartext

Mit Force HTTPS:

Client  →  http://app.example.com:80   →  301 Redirect → https://...
Client  →  https://app.example.com:443 →  Caddy (TLS)  →  Backend
             ↑ verschlüsselt mit Let's Encrypt Zertifikat

Wenn https_enabled aktiv ist:

  1. Listener: Caddy lauscht auf Port :443 statt :80
  2. TLS-Zertifikat: Caddy nutzt die ACME HTTP-01 Challenge
  3. HTTP → HTTPS Redirect: Caddy leitet alle HTTP-Anfragen automatisch per 301 auf HTTPS um
  4. Auto-Renewal: Caddy erneuert Zertifikate automatisch (30 Tage vor Ablauf)

TLS-Konfiguration (falls Email gesetzt):

{
  "apps": {
    "tls": {
      "automation": {
        "policies": [{
          "issuers": [{
            "module": "acme",
            "email": "admin@example.com"
          }]
        }]
      }
    }
  }
}

Custom ACME CA: Über die Umgebungsvariable GC_CADDY_ACME_CA kann eine alternative ACME CA konfiguriert werden.

ACME Email konfigurieren

# In docker-compose.yml oder .env
GC_CADDY_EMAIL=admin@example.com

# Optionale alternative ACME CA
GC_CADDY_ACME_CA=https://acme-staging-v02.api.letsencrypt.org/directory

Troubleshooting

ProblemUrsacheLösung
Zertifikat wird nicht ausgestelltDNS zeigt nicht auf ServerA-Record prüfen, dig oder nslookup verwenden
ACME Challenge fehlgeschlagenPort 80 blockiertFirewall / Router prüfen, Port 80 freigeben
Too many certificatesLet's Encrypt Rate Limit1 Stunde warten, dann erneut versuchen
Zertifikat abgelaufenCaddy konnte nicht erneuernCaddy Logs prüfen, DNS und Port 80 prüfen

Wichtige Hinweise zu Force HTTPS

  • DNS muss korrekt zeigen. Die Domain muss per A/AAAA-Record auf die öffentliche IP des GateControl-Servers zeigen.
  • Ports 80 und 443 müssen offen sein.
  • Kein Cloudflare Proxy. Verwende DNS Only (graue Wolke).
  • Rate Limits beachten. Max 50 Zertifikate pro registrierter Domain pro Woche.
  • Zertifikate werden in /data/caddy/ gespeichert und überleben Container-Neustarts.

Backend HTTPS

Verbindet Caddy per HTTPS mit dem Backend — für Dienste die selbst-signierte Zertifikate verwenden und HTTPS erzwingen (z.B. Synology DSM, Proxmox, UniFi Controller).

Ohne Backend HTTPS (Backend erzwingt HTTPS):

Client  →  Caddy  →  http://10.8.0.3:5001  →  Backend lehnt HTTP ab  ✕

Mit Backend HTTPS:

Client  →  Caddy (Let's Encrypt)  →  https://10.8.0.3:5001  →  Backend (Self-Signed)  ✓
           ↑ gültiges Zertifikat      ↑ insecure_skip_verify: true

Technische Details

{
  "handler": "reverse_proxy",
  "upstreams": [{ "dial": "10.8.0.3:5001" }],
  "transport": {
    "protocol": "http",
    "tls": { "insecure_skip_verify": true }
  }
}

Typische Use Cases

DienstPortBeschreibung
Synology DSM5001NAS Web UI mit Self-Signed Zertifikat
Proxmox VE8006Hypervisor Web UI
UniFi Controller8443Netzwerk-Management
Portainer9443Docker Management UI

Wichtige Hinweise zu Backend HTTPS

  • Nur aktivieren wenn das Backend HTTPS erzwingt. Wenn HTTP auch funktioniert, ist es unnötig.
  • insecure_skip_verify vertraut jedem Zertifikat — im VPN-Kontext akzeptabel.
  • Backend HTTPS betrifft nur die Verbindung Caddy → Backend.
  • Bei Load Balancing: alle Backends müssen HTTPS unterstützen.
  • Nur für HTTP-Routen verfügbar, nicht für L4.

Compression

Komprimiert HTTP-Antworten mit Gzip und Zstd — reduziert die übertragene Datenmenge um 60-80% bei Textinhalten.

Ohne Compression:

Client  ←  500 KB HTML  ←  Caddy  ←  500 KB HTML  ←  Backend

Mit Compression:

Client  ←  120 KB gzip  ←  Caddy (komprimiert)  ←  500 KB HTML  ←  Backend
           76% gespart

Algorithmen

AlgorithmusBrowser-SupportKompressionGeschwindigkeit
ZstdChrome 123+, Firefox 112+BesserSchneller
GzipAlle BrowserGutStandard

Caddy wählt Zstd wenn der Client es unterstützt, andernfalls Gzip.

Typische Einsparungen

Content-TypeUnkomprimiertGzipZstdEinsparung
HTML100 KB25 KB20 KB75-80%
CSS200 KB35 KB28 KB82-86%
JavaScript500 KB120 KB95 KB76-81%
JSON1 MB150 KB110 KB85-89%
PNG (Bild)300 KB295 KB295 KB~2%

Caddy JSON-Konfiguration

{
  "handler": "encode",
  "encodings": {
    "zstd": {},
    "gzip": {}
  }
}

Wichtige Hinweise zu Compression

  • Nicht empfohlen für bereits komprimierte Inhalte. Bilder (JPEG, PNG, WebP), Videos, Archive und Schriftarten (WOFF2) sind bereits komprimiert.
  • Caddy komprimiert nur wenn der Client Accept-Encoding sendet.
  • Wenn das Backend bereits komprimierte Antworten liefert (Content-Encoding: gzip), komprimiert Caddy nicht doppelt.
  • Nur für HTTP-Routen verfügbar, nicht für L4.

Cookie Settings

Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Essentielle Cookies sind immer aktiv.

Datenschutzerklärung
ESC
↑↓ navigate open esc close