TP31: Caddy abgenommen (16/16), hass-400 praezisiert statt geraten

Schritt 3 ist durch: Token liegt, deploy.sh gelaufen, Dienst active+enabled.
Abnahme ueber den Host-Header von einem zweiten Host (pve): 11x 200,
nautobot 302, Antwortzeiten 0,02-0,11 s.

Zwei Funde, die man sonst falsch ablegt:
- pve-mcp 400 / ha-mcp 403 / gitea-mcp 404 sind KEINE Proxy-Fehler - die
  Gegenprobe direkt am Origin liefert dieselben Codes. Es sind die Antworten
  der MCP-Server auf ein nacktes GET /.
- hass bleibt 400, aber die Logzeile sagt "untrusted proxy 10.40.20.40" und
  nicht "not set-up for reverse proxies": use_x_forwarded_for greift also,
  nur die Liste zieht nicht. Zwei volle Neustarts, Config-Check valid.
  Naechster Schritt notiert; die atime taugt unter relatime nicht als Beweis.

Ist-Stand-Block mitgezogen (Projektregel).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 22:46:54 +02:00
parent b77deed46c
commit fef2582174

View File

@@ -60,6 +60,11 @@ ab jetzt bei jeder Änderung mitgezogen, nicht nur die TP-Abschnitte.)*
Details als Gotcha in `CLAUDE.md`. ⚠️ **Der Fall hatte zwei unabhängige Ursachen** — nach der
Relay-Reparatur suchte die **App** immer noch nicht (macOS-Local-Network-Gate stand auf „an" und
griff nicht; Fix war Schalter aus/ein + Neustart, User-bestätigt 08-25). **Beide sind erledigt.**
- **Reverse Proxy = `caddy-bf1`** (LXC 130 auf pve, **`10.40.20.40`**, TP31 ✅ Schritt 1–3 seit
2026-08-25): Caddy 2.11.4, **16 Sites**, Zertifikate ausschliesslich per **DNS-01** mit einem eng
geschnittenen `Zone:DNS:Edit`-Token (`CF_DNS_API_TOKEN`, **nicht** das account-weite). Abnahme über
den Host-Header von einem zweiten Host: 11× 200, `nautobot` 302. **Offen: `hass` 400** (HA
`trusted_proxies` greift noch nicht) sowie Schritt 4–6 (Split-Horizon, Tunnel `bf-public`, Abbau).
- **Ausgebaut / gelöscht:** ALLNET-`sw1` und Omada-`sw2` sind **physisch weg** (2026-08-08 bzw. 2026-07-23,
in Nautobot *Decommissioned*); Omada-Controller + `omada-mcp` gelöscht (2026-07-16); FritzBox 6660 raus
seit 2026-07-01 (Liwest-Tausch auf Arris). **VLAN1 ist leer** (`/ip arp` auf `bridge` = 0 Einträge,
@@ -1419,13 +1424,13 @@ Alles andere ist intern; **19 Ingress-Zeilen über drei Tunnel werden EINE Catch
nach TP32), 4 GB / 512 MB, 2 Cores. In den Backup-Job `backup-6dcf5c10-610f` aufgenommen.
**Caddy v2.11.4** installiert, Modul **`dns.providers.cloudflare`** verifiziert vorhanden.
Egress geprüft (DNS, HTTPS, CF-API) — TP5 lässt VLAN20 nach draußen.
3. ⏳ **Konfiguration liegt, Dienst läuft noch nicht — es fehlt genau ein Credential.**
3. ✅ **ERLEDIGT 2026-08-25 — Token da, `deploy.sh` durchgelaufen, Proxy verifiziert.**
**`caddy/Caddyfile` im Repo** (17 Sites: 4 öffentlich `vw`/`hass`/`n8n`/`gitea`, 13 intern inkl.
der vier MCP-Endpunkte und drei HTTPS-Backends mit `tls_insecure_skip_verify`), Syntaxprüfung
läuft durch. Zertifikate ausschließlich per **DNS-01**, damit auch rein interne Namen gültige
Zertifikate bekommen.
🔑 **Offen: das eng geschnittene Token** — `Zone:DNS:Edit`, Zone-Resource auf `emsenhuber.net`
begrenzt, **nicht** das account-weite `CF_API_TOKEN` ⇒ Posten für **TP30**. Ablage als
🔑 **Das eng geschnittene Token liegt** — `Zone:DNS:Edit`, Zone-Resource auf `emsenhuber.net`
begrenzt, **nicht** das account-weite `CF_API_TOKEN` (Fingerprint gegengeprüft). Ablage als
`CF_DNS_API_TOKEN` in `~/.secrets/credentials.env`, Ausrollen per **`caddy/deploy.sh`** — das
liest den Wert von dort und schreibt ihn in die Container-Env, **ohne ihn je auf stdout oder in
eine Kommandozeile zu bringen** (dieselbe Regel wie `sshpass -e`).
@@ -1460,9 +1465,35 @@ sieht monatelang gesund aus.** ⇒ Caddy-Zeile entfernt (16 Sites), **LXC 104 ze
Backup-Job genommen — die **14 PBS-Snapshots bleiben bewusst stehen**, sie sind die einzige Kopie
etwaiger Dashboards. Wiederaufbau spaeter als eigener Punkt, dann nach TP32-Systematik.
🟡 **`hass` liefert 400** — der bekannte offene Punkt aus TP16: Home Assistant braucht
`10.40.20.40` in `http.trusted_proxies` plus `use_x_forwarded_for: true`, sonst weist es den neuen
Proxy ab. **Gehoert vor die CNAME-Umstellung von `hass`.**
#### ✅ Abnahme 2026-08-25 (spaet) — 16 von 16 Sites gegen den Host-Header gemessen
Dienst `active`+`enabled`, Probe von einem **zweiten Host** (pve, VLAN20) mit
`curl --resolve <fqdn>:443:10.40.20.40`, also ueber den echten Namen statt ueber die IP:
**11x 200** (`vw` `n8n` `gitea` `ds-bf` `ccu` `iobroker` `z2m25` `n8n-mcp` `pve` `portainer` `pbs`),
`nautobot` **302** (Login-Redirect, erwartet), Antwortzeiten 0,02–0,11 s.
- ✅ **Die drei „Fehlercodes" der MCP-Endpunkte sind KEINE:** `pve-mcp` 400, `ha-mcp` 403,
`gitea-mcp` 404 kommen **identisch auch direkt vom Origin** (gegengemessen ohne Caddy). Es sind die
Antworten der MCP-Server auf ein nacktes `GET /` — der Proxy reicht sie unveraendert durch.
⇒ **Merkregel: einen Statuscode nie ohne Gegenprobe am Origin als Proxy-Fehler lesen** — sonst
jagt man einen Fehler, der keiner ist (dieselbe Klasse wie der `grafana`-Fall eine Zeile hoeher,
nur andersherum).
- 🧹 **Rest: ein verwaistes Zertifikat.** Der Store haelt **17** Zertifikate, die Config nur 16 Sites —
`grafana.emsenhuber.net` liegt noch da. Harmlos (Caddy erneuert es nicht mehr), beim
Grafana-Wiederaufbau nach TP32 mit aufraeumen.
🔴 **`hass` liefert weiterhin 400 — und der Fix ist NICHT der erwartete Einzeiler.**
Der `http:`-Block ist eingetragen (`use_x_forwarded_for: true` + `trusted_proxies` mit
`10.40.20.40`/`.10`/`.167`, Sicherung `configuration.yaml.bak-20260825-tp31`), Config-Check `valid`,
**HA zweimal voll neu gestartet** — trotzdem antwortet es 400.
- 🔎 **Der Logtext ist der Befund:** `Received X-Forwarded-For header from an untrusted proxy
10.40.20.40`. Das ist **nicht** die Meldung „not set-up for reverse proxies", die bei
abgeschaltetem `use_x_forwarded_for` kommt ⇒ **die Option greift, nur die Liste zieht nicht.**
- ⚠️ **Was als Beweis NICHT taugt:** die `atime` der `configuration.yaml`. Sie steht auf dem
Schreibzeitpunkt, aber unter **`relatime`** wird sie nur nachgezogen, wenn sie *aelter* als die
`mtime` ist — bei `atime == mtime` bleibt sie stehen. „Datei seit dem Schreiben nicht gelesen"
laesst sich daraus **nicht** ableiten.
- ⏭️ **Naechster Schritt (offen):** Block testweise auf `10.40.20.0/24` verbreitern und neu starten —
faellt der 400 dann weg, liegt es an der Listenauswertung; bleibt er, liest HA eine andere Datei
als die unter `/homeassistant/configuration.yaml`. **Gehoert vor die CNAME-Umstellung von `hass`.**
🎯 **Kernabnahme: WAN trennen, dann alle Dienste per FQDN.** Das ist die Autarkie, um die es geht.
⚠️ **Preis, offen benannt:** mit Split-Horizon greift **Access innerhalb des Netzes nicht mehr**; dort