TP16.3 §5 durch: vier Namen auf bf-public + 10-Sekunden-DNS-Fund behoben

FLIP (User-Freigabe, vorgezogen)
n8n / gitea / hass / vw laufen jetzt ueber bf-public, der oeffentliche Verkehr
geht damit erstmals ueber Caddy statt an ihm vorbei. Je Name einzeln geflippt und
dazwischen gemessen; Antwortzeiten vorher/nachher unveraendert. Nachweise:
gitea echte Gitea-Antwort, hass WebSocket 101 Switching Protocols (der
Companion-App-Pfad, den das Runbook als "nur vom User pruefbar" fuehrte),
vw /alive + /api/config 200 und WS-Hub 401 von Vaultwarden selbst, n8n vom User
im Browser bestaetigt (von aussen nicht bis zum Origin pruefbar, s. TP14.4).
Die drei Alttunnel bleiben als Rueckfallebene stehen -- §6 ist NICHT Teil davon.

10-SEKUNDEN-ZOLL AUF gitea/vw/hass -- Ursache gefunden und behoben
gitea hing bei ~10% der Anfragen exakt 10,1 s, quer ueber Web-UI, /api/healthz
und den Git-Pfad. MariaDB (LXC 302) hatte skip-name-resolve auskommentiert und
machte bei JEDER NEUEN Verbindung einen Reverse-Lookup, waehrend ihr resolv.conf
auf den toten 10.40.41.254 zeigte: 10.010 ms je Lookup, Pool-Verbindungen
schnell -- daher wirkte es sporadisch. An derselben DB haengen Vaultwarden, Home
Assistant und gitea (per Verbindungstabelle belegt, nicht vermutet; die erste
Annahme "vaultwarden nutzt SQLite" war falsch und wurde vom User korrigiert).
Fix: nameserver 10.40.20.1 + Reboot fuer fuenf LXCs (302, 102, 106, 107, 150).
Nachher 21-24 ms und 0 von 25 Proben langsam.
Offen: skip-name-resolve selbst -- bricht Hostname-basierte Grants, vorher
mysql.user lesen (DB-Zugang fehlt).

LATENT, NICHT VON DIESER SESSION VERURSACHT
networking.service + ifupdown-wait-online.service sind in 101/102/106/107
failed; influxdb2 kam nach dem Reboot nicht hoch (Unit enabled, kein
Startversuch im Journal). 101 wurde nie angefasst und zeigt dasselbe -- die
Container liefen nur 13+ Tage ohne Neustart.

RUNBOOK-KORREKTUREN
§5.3 "Caddy sieht den Request" konnte nie funktionieren: im Caddyfile steht keine
log-Direktive, ein erfolgreicher Request hinterlaesst nichts. Ersetzt durch die
Werkzeuge, die tatsaechlich etwas beweisen -- erzwungener oeffentlicher Weg per
curl --resolve (Pflicht wegen Split-Horizon), Verbindungstabelle am Core statt
Firewall-Zaehler (cloudflared haelt die Origin-Verbindung offen, der Zaehler
steht still obwohl alles laeuft), Antwort-Fingerabdruck, WebSocket mit --http1.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 00:25:39 +02:00
parent f6283fd813
commit 73fec72abe
4 changed files with 202 additions and 4 deletions

View File

@@ -31,6 +31,66 @@ Mgmt (VLAN99, Ist 2026-08-16): core `.99.1` · branch `.99.2` · ap1 `.99.11` ·
**Compliance am 2026-08-31 nach vollem Refresh (Backup→Intended→Compliance) gelesen: 128/135.**
*(Die Fassung vom 2026-08-16 stand bis zum 18. hier und war an vier Stellen überholt. Wer diesen Block
liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur die TP-Abschnitte.)*
- 🆕 **TP16.3 §5 DURCH (2026-09-01): `n8n`/`gitea`/`hass`/`vw` laufen über `bf-public`** — der
öffentliche Verkehr geht damit erstmals über **Caddy** statt an ihm vorbei, und die
Host→Origin-Zuordnung lebt nur noch im `Caddyfile`. Je Name einzeln geflippt, dazwischen gemessen;
Antwortzeiten vorher/nachher **unverändert** (Caddy im Pfad kostet nichts Messbares).
Nachweise: `gitea` echte Gitea-Antwort · `hass` **WebSocket `101 Switching Protocols`** (= der
Companion-App-Pfad, den das Runbook als „nur vom User prüfbar" führte) · `vw` `/alive` + `/api/config`
200, WS-Hub `401` von Vaultwarden selbst · `n8n` von Christoph im Browser bestätigt.
🚫 **§6 (Abbau) bewusst NICHT** — die drei Alttunnel bleiben als Rückfallebene (healthy/8).
🔴 **Christoph hat den Flip ausdrücklich vorgezogen freigegeben** („aus Gründen"); die 7-Tage-Regel
betrifft ohnehin §6, nicht den Flip.
- ✅ **GELÖST 2026-09-01: der 10-Sekunden-Zoll auf `gitea`/`vw`/`hass` — es war Reverse-DNS auf einen
toten Resolver.** MariaDB (LXC **302**, `10.40.20.23`) hatte `skip-name-resolve` **auskommentiert**
und machte damit bei **jeder neuen Verbindung** einen Reverse-Lookup; ihr `/etc/resolv.conf` zeigte
auf **`10.40.41.254`** — den toten VLAN1-Resolver aus dem alten Schema (`nc` bestätigt tot).
**Gemessen im Container: 10.010 ms je Lookup.** Bestehende Pool-Verbindungen waren schnell, neue
kosteten 10 s — daher wirkte es sporadisch und unerklärlich.
🔑 **Die Blast-Radius war größer als gedacht:** an derselben DB hängen **Vaultwarden (`.127`),
Home Assistant (`.105`) und gitea (`.157`)** — belegt über die Verbindungstabelle, nicht vermutet.
*(Die erste Zuschreibung „vaultwarden nutzt SQLite, also nicht betroffen" war eine **Annahme** und
falsch — Christoph hat sie korrigiert, die Verbindungsliste hat es bewiesen.)*
**Fix (Wartungsfenster, User-Freigabe):** `pct set <id> --nameserver 10.40.20.1` + Reboot für
**fünf** LXCs — `302 mariadb`, `102 mqtt5`, `106 influxdb2`, `107 redis`, `150 iob-exposed`.
**Nachher: Lookup 21–24 ms statt 10.010 ms; gitea 0 von 25 Proben langsam** (vorher ~10 % bei
10,1 s), langsamste Probe 75 ms. Alle drei Dienste wieder verbunden.
⚠️ **Strukturell offen:** `skip-name-resolve` ist weiterhin aus — der Lookup ist jetzt nur schnell,
nicht abgeschafft. Ihn zu setzen bricht alle Grants, die auf **Hostnamen** statt IPs lauten; das
gehört vorher gegen `mysql.user` geprüft (DB-Zugang fehlt: `root@localhost` ohne Passwort verweigert).
- 🔴 **Latenter Fund aus demselben Wartungsfenster: `networking.service` und
`ifupdown-wait-online.service` sind in `101`, `102`, `106`, `107` fehlgeschlagen.** Folge:
Dienste mit `After=network-online.target` starten nach einem Reboot **nicht von selbst** —
**influxdb2 kam nach dem Neustart nicht hoch**, Unit `enabled`, aber **kein einziger Startversuch
im Journal**. Von Hand gestartet lief es sofort.
🔑 **Nicht durch diese Session verursacht:** `101 iob-master` wurde nie angefasst und zeigt dieselben
fehlgeschlagenen Units — die Container liefen nur 13+ Tage ohne Neustart, deshalb fiel es niemandem
auf. **Merkregel: diese vier Container sind einen Reboot davon entfernt, still Dienste zu verlieren.**
- 🔴 **Befund am Rand des Flips, NICHT von ihm verursacht: `gitea` hängt sporadisch exakt ~10,2 s.**
~10 % der Anfragen, quer über Web-UI, **`/api/healthz`** und den **Git-Pfad** (`info/refs`) — also
kein Rendering-Problem. `vw` und `hass` über **dieselbe** Strecke: **0 von 30**. Damit sind CF-Edge,
AP-Connector, Firewall und Caddy entlastet; übrig bleibt **Caddy → `10.40.20.157:3000`** oder gitea
selbst. **Immer ~10,15–10,43 s** = Timeout-Signatur (klassisch: ein toter Resolver, s. den
VLAN20-Docker-DNS-Gotcha in der CLAUDE.md), kein Lastproblem. Weiter nur mit LAN-Zugriff.
- 📎 **Drei Messfallen, die diese Session gekostet haben** (alle drei sind Standort-, keine Netzfehler):
1. **Split-Horizon macht Tests von zuhause wertlos:** der Haus-Resolver liefert für alle vier Namen
direkt `10.40.20.40`, die Anfrage sieht Cloudflare **nie**. Prüfen geht nur mit festgenagelter
CF-Edge-IP (`curl --resolve <name>:443:188.114.96.10`) oder von außerhalb.
2. **Access antwortet je nach Standpunkt verschieden:** `n8n` gibt aus dem Haus **200** (die
`bf4`-Policy trägt die WAN-IP), von außen **302** zum Login. Beides gesund. Für die drei
`bypass`-Namen (`hass`/`vw`/`gitea`) gibt es gar keinen Login — die Access-App heisst zu Recht
`hass, vw, gitea`, sie führt alle drei in `self_hosted_domains` (das Feld `domain` zeigt nur den
ersten). **Ein Rename wäre eine Verschlechterung gewesen.**
3. 🔴 **„Der Host ist ausgefallen" war der eigene Standortwechsel.** Ping/SSH/Caddy waren tot,
weil die Session-Maschine auf einen **Hotspot** gewandert war (Default-GW `172.20.10.1`) —
dieselbe Klasse wie die WARP-Falle von 2026-08-13, nur ohne WARP. Es wurde daraufhin ein bereits
erfolgreicher `n8n`-Flip **grundlos zurückgerollt**. **Merkregel: bevor ein Ausfall gemeldet wird,
`route -n get default` lesen** — ein Standortwechsel sieht exakt aus wie ein Totalausfall.
- ⚠️ **Nebenbefund: Caddy führt gar kein Access-Log.** Im `Caddyfile` steht keine `log`-Direktive, im
Journal landen nur `info`/`warn`. Der Abnahmepunkt „Caddy sieht den Request" (Runbook §5.3) **kann
nicht funktionieren** — ein erfolgreicher Request hinterlässt dort nichts, und leere Ausgabe liest
sich wie „kam nie an". Dass der öffentliche Reverse Proxy keine Requests protokolliert, ist für sich
eine Lücke (gehört zu TP31/TP34).
- 🆕 **TP16.3: die sechs AP-Drifts sind ins Soll gehoben (2026-08-31) — Compliance 139/140.**
`veth` / `ip address` / `ip firewall nat` der drei cloudflared-Connectoren stehen jetzt im
**AP-Template** (Block `[7]`) und im ConfigContext `ap-common` (`ap.container`), **nicht** in einer
@@ -336,7 +396,7 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
> | TP14.4 | 🔜 | CF-Access-Token | — |
> | TP16 | ✅ | CF-Tunnel HA wieder voll | 2026-08-24 |
> | TP16.2 | 🔜 | Härtung bypass-Dienste | — |
> | TP16.3 | ⏳ | cloudflared-Reduktion (14 Hostnames geschnitten 08-30, F1 durch; §1–§3 durch 08-31, `bf-public` healthy/12; **Drift ins Soll 08-31 ⇒ 139/140** — offen: Flip §5, Abbau §6) | — |
> | TP16.3 | ⏳ | cloudflared-Reduktion (§1–§3 durch 08-31; Drift ins Soll ⇒ 139/140; **§5 FLIP DURCH 09-01: alle vier Namen auf `bf-public`** — offen: nur noch §6 Abbau) | — |
> | TP17.1 | ❌ | Shelly Gen4 → Zigbee | 2026-08-23 |
> | TP17.3 | ✅ | Shelly-Regression behoben | 2026-08-23 |
> | TP18 | 🔜 | Garage-Objektspeicher | — |