Zum Inhalt

Subdomain Registry und Caddy

Diese Seite beschreibt das Routing-Konzept für HTTP/S-Dienste. Sie erklärt die Abgrenzung zwischen der zentralen Subdomain Registry, Caddy, CaddyManager und den bewusst manuell gepflegten Mail-Routen.

Grundprinzip

Caddy ist der öffentliche HTTP/S-Einstiegspunkt des Servers. Für normale Webdienste wird Caddy nicht direkt pro Dienst von Hand erweitert, sondern aus der zentralen Registry generiert:

/opt/selfhost/registry/routes.json

Der Generator:

/opt/selfhost/tools/selfhost-routes

liest diese Registry und erzeugt daraus unter anderem:

Artefakt Pfad Zweck
Caddy-Snippet /opt/selfhost/generated/caddy/routes.caddy aktive Nicht-Mail-Routen für Caddy
Homepage-Liste /opt/selfhost/generated/homepage/services.yaml Einträge für das Dashboard
Registry-Doku /opt/selfhost/generated/docs/subdomains.md generierte technische Übersicht
Portliste /opt/selfhost/generated/docs/ports.csv generierte Portübersicht
DNS-Hinweise /opt/selfhost/generated/docs/dns-records.txt generierte DNS-Liste
Web-Übersicht /opt/selfhost/generated/routes/index.html lesende Tabellenansicht der Registry

Das Haupt-Caddyfile importiert das generierte Snippet:

import /opt/selfhost/generated/caddy/routes.caddy

Warum eine Registry?

Die Registry verhindert, dass Subdomains an mehreren Stellen mit widersprüchlichen Informationen gepflegt werden. Sie bündelt:

  • Hostname oder Subdomain
  • Zieltyp: Reverse Proxy, statische Seite oder Redirect
  • Upstream und Port
  • Kategorie für Dashboard und Dokumentation
  • Beschreibung
  • Hinweise, ob ein Hostname auch in der Zielanwendung konfiguriert werden muss
  • Tailnet-Schutzregeln für ausgewählte Oberflächen

Dadurch kann ein neuer normaler Webdienst mit einem kontrollierten Ablauf veröffentlicht werden.

Route-Typen

Typ Bedeutung Beispiel
reverse_proxy Caddy leitet an einen lokalen Dienst weiter Open WebUI auf 127.0.0.1:3020
static Caddy liefert Dateien aus einem lokalen Ordner aus Dokumentation aus /opt/selfhost/site
redirect Caddy leitet auf einen anderen Host/Pfad um Provider-Hostname auf VPS-Landing

Zugriffsschutz nach Authentik

Authentik ist aus der aktiven Infrastruktur entfernt. Die Registry verwendet deshalb keinen produktiven Forward-Auth-Mechanismus mehr.

Aktuelle Zugriffsmuster:

Muster Bedeutung
eigene Dienst-Auth Der Dienst hat Login, API-Keys oder eigene Sessionverwaltung
Tailnet-only Caddy erlaubt den eigentlichen Dienst nur für Tailscale-Quell-IP-Bereiche
öffentlich bewusst öffentlich erreichbar, typischerweise Website oder öffentliche Mail-bezogene Endpunkte

Für Tailnet-only-Routen wird außerhalb des Tailnets die vorhandene OpenClaw-Hinweisseite ausgeliefert:

/opt/selfhost/generated/openclaw-error/

Dabei werden aktuell die Tailscale-IP-Bereiche 100.64.0.0/10 und fd7a:115c:a1e0::/48 verwendet.

Wichtig: Die Tailnet-Erkennung basiert auf der Quell-IP, die bei Caddy ankommt. Ein Client ist nur dann als Tailnet-Client erkennbar, wenn er den Server auch über die Tailscale-Adresse erreicht. Wenn ein Browser trotz aktivem Tailscale über den öffentlichen DNS-A-Record 62.141.32.194 verbindet, sieht Caddy nur die normale öffentliche Client-IP und liefert bewusst die Fallback-Seite aus. Für komfortable Nutzung mit normalen Hostnames sollten Tailnet-only-Hostnames zusätzlich einen DNS-Eintrag auf die Tailscale-Adresse des VPS haben, idealerweise als AAAA auf fd7a:115c:a1e0::1c34:af3e. Dann verwenden Tailnet-Clients die Tailscale-Verbindung, während externe Clients weiterhin über den öffentlichen A-Record die harmlose Fallback-Seite erreichen können.

Beispiel einer Tailnet-only Static Route

Die Serverdokumentation wird als statische MkDocs-Seite veröffentlicht und per Tailnet geschützt:

{
  "id": "serverdocs",
  "enabled": true,
  "title": "Serverdokumentation",
  "hostname": "serverdocs.marcosudau.com",
  "type": "static",
  "root": "/opt/selfhost/site",
  "auth": "none",
  "category": "Administration",
  "dashboard": true,
  "caddy": {
    "tailnetOnly": {
      "fallbackRoot": "/opt/selfhost/generated/openclaw-error",
      "remoteIpRanges": ["100.64.0.0/10", "fd7a:115c:a1e0::/48"]
    }
  }
}

Standardablauf bei Änderungen

Nach einer Änderung an /opt/selfhost/registry/routes.json:

sudo /opt/selfhost/tools/selfhost-routes validate
sudo /opt/selfhost/tools/selfhost-routes generate --apply-homepage
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

Wenn die Dokumentation betroffen ist, zusätzlich:

cd /opt/selfhost
/opt/selfhost/tools/mkdocs-venv/bin/mkdocs build --strict

Mail-Routen sind bewusst ausgenommen

Mail-nahe Routen bleiben aus der Registry ausgeschlossen und werden direkt in /etc/caddy/Caddyfile gepflegt. Das betrifft unter anderem:

  • mail.marcosudau.com
  • autoconfig.marcosudau.com
  • autodiscover.marcosudau.com
  • mta-sts.marcosudau.com
  • stalwart.marcosudau.com
  • adminmail.marcosudau.com
  • mailadmin.marcosudau.com
  • bulwark.marcosudau.com
  • webmail.marcosudau.com

Der Grund ist, dass Mail-Routen neben normalem Reverse Proxy zusätzliche Besonderheiten haben: Autoconfig/Autodiscover, CORS für Webmail, Admin-Redirects und das Zusammenspiel mit Stalwart. Diese Logik soll nicht in den allgemeinen Generator gezwungen werden.

Abgrenzung zu CaddyManager

CaddyManager ist eine Anwendung, die Caddy-Konfiguration bzw. Caddy-API-Zugriff visualisieren oder verwalten kann. Das Routing-Konzept bleibt davon unabhängig.

Wichtige Abgrenzung:

  • Die Registry ist die verbindliche Quelle für normale Nicht-Mail-Routen.
  • Der Generator schreibt das Caddy-Snippet und die Dashboard-Übersichten.
  • CaddyManager ist ein Dienst und wird auf seiner Dienstseite dokumentiert.
  • Änderungen an Registry-Routen sollen nicht heimlich nur in CaddyManager oder direkt im generierten Snippet erfolgen.

Wenn CaddyManager für Kontrolle oder Diagnose verwendet wird, muss trotzdem geprüft werden, ob die dauerhafte Quelle der Änderung routes.json oder, bei Mail, /etc/caddy/Caddyfile ist.

Hostname-Änderungen

Einige Routen haben hostnameChangeRequiresServiceConfig: true. Das bedeutet nicht, dass der Hostname unveränderlich ist. Es bedeutet: Eine Änderung in Caddy/Registry reicht nicht aus.

Beispiele:

  • Hermes API: externe Clients oder OpenWebUI-Konfiguration können den Hostnamen verwenden.
  • Open WebUI: Base-URLs, Sessions oder Backend-Konfigurationen können betroffen sein.
  • LiteLLM: API-Clients und UI-Redirects können den Hostnamen kennen.
  • CaddyManager: CORS-Konfiguration hängt am Hostnamen.

Solche Routen dürfen geändert werden, aber nur zusammen mit den betroffenen Dienstkonfigurationen.