From 73fec72abec4d876306e06e06b286edd7ef34782 Mon Sep 17 00:00:00 2001 From: Christoph Emsenhuber Date: Tue, 1 Sep 2026 00:25:39 +0200 Subject: [PATCH] =?UTF-8?q?TP16.3=20=C2=A75=20durch:=20vier=20Namen=20auf?= =?UTF-8?q?=20bf-public=20+=2010-Sekunden-DNS-Fund=20behoben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- CLAUDE.md | 22 +++++ ...f-20260901-tp16.3-paragraph5-flip-durch.md | 95 +++++++++++++++++++ docs/teilprojekte.md | 62 +++++++++++- docs/tp16.3-bf-public-ap-connector-runbook.md | 27 +++++- 4 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md diff --git a/CLAUDE.md b/CLAUDE.md index 6e6c8b7..d0e795d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,6 +9,9 @@ DNS/DHCP-Ablösung, WLAN via **CAPsMAN auf dem Core** (TP28, 2026-08-17 — der 1. **`docs/teilprojekte.md`** (Quick-Index-Block) — kanonischer Stand, Scope, Abhängigkeiten, **offene** TPs. **1 Read reicht.** 2. **`docs/handoff-*.md`** (neueste) — wo die letzte Session aufgehört hat. 3. Bei Live-Writes oder Inventur: **`docs/cf-tunnel-mapping.md`**, **`docs/teilprojekte-archiv.md`**. +4. ✅ **TP16.3 §5 durch (2026-09-01):** [`docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md`](docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md) + — alle vier oeffentlichen Namen laufen ueber `bf-public`/Caddy; Alttunnel bleiben als Rueckfallebene + (§6 offen). Enthaelt den 10-Sekunden-DNS-Fund und drei Messfallen. 4. 🔴 **WLAN/Fund E — HEBEL 1 GESCHEITERT + TP27 durchgezogen:** [`docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md`](docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md) — `ft-over-ds=no` hat **nicht** gegriffen (124 `reauthenticating` nach dem Eingriff, zwei erlebte @@ -206,6 +209,25 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`, Gesetz** — und ob sie dem konkreten Dienst überhaupt gilt. - **Schwere Container laufen weiterhin auf NAS/pve**, nicht am Router (Caddy, AdGuard: die eine Config ändert sich staendig, die andere schreibt dauernd Logs auf NAND). +- ⏱️ **Ein konstanter 10-Sekunden-Hänger ist ein DNS-Timeout, kein Lastproblem** (Fund 2026-09-01, + TP16.3-Randbefund). `gitea` hing bei ~10 % der Anfragen exakt 10,1 s — quer über Web-UI, + `/api/healthz` **und** den Git-Pfad, also kein Rendering. Ursache: **MariaDB (LXC 302) hatte + `skip-name-resolve` auskommentiert** und machte bei **jeder neuen Verbindung** einen + Reverse-Lookup, während ihr `/etc/resolv.conf` noch auf den toten `10.40.41.254` zeigte + (glibc: 5 s × 2 Versuche = 10 s). Pool-Verbindungen waren schnell ⇒ es wirkte sporadisch. + 🔑 **Drei Merkregeln daraus:** (a) **immer gegen eine zweite Sache messen, die denselben Weg + nimmt** — `vw`/`hass` über dieselbe Strecke hatten 0 von 30 Hängern, das hat CF, Tunnel, Firewall + und Caddy in einem Schritt entlastet; (b) **wer an einer DB hängt, sagt die Verbindungstabelle** + (`ss -tn | grep 3306`), nicht die Vermutung — hier hingen **Vaultwarden, Home Assistant und gitea** + an derselben MariaDB, und die Annahme „Vaultwarden nutzt SQLite" war schlicht falsch; + (c) **ein toter Resolver ist selten allein** — der Sweep über alle LXCs fand **fünf** Container mit + `10.40.41.254`. Sweep: `for c in $(pct list|awk 'NR>1{print $1}'); do pct exec $c -- grep ^nameserver /etc/resolv.conf; done` +- 🔌 **`networking.service` kann in einem LXC dauerhaft `failed` sein, ohne dass das Netz fehlt** — + und dann startet alles mit `After=network-online.target` nach einem Reboot **nicht** + (Fund 2026-09-01: `101`, `102`, `106`, `107`; **influxdb2 kam nach dem Neustart nicht hoch**, + Unit `enabled`, **kein Startversuch im Journal**). Fällt nur auf, wenn man neu startet — die + Container liefen 13+ Tage. **Vor jedem geplanten LXC-Neustart `systemctl --failed` lesen und + danach die Ports gegen vorher vergleichen**, sonst verliert man still einen Dienst. - **VLAN20-Docker-Hosts: Host-DNS nach dem Umzug prüfen (2026-07-10, TP14.2a):** NAS + pve-LXC zeigten `/etc/resolv.conf` noch auf totes `.41.254` → `docker pull` ghcr scheitert (`EAI_AGAIN`, aber Egress ok!). Fix = `.20.1`: LXC `pct set 400 --nameserver 10.40.20.1`; **Synology-Falle: DSM-„Allgemein"-DNS ≠ was `dockerd` liest** — Interface zieht DNS per DHCP → Fix an der *Netzwerkschnittstelle* „DNS manuell". Laufende Container frieren den `127.0.0.11`-Upstream zum Erstellzeitpunkt ein (Recreate nötig). Merkregel: `docker-pull-hängt` + `dns.lookup EAI_AGAIN` aber `TCP zu ghcr-IP:443 ok` = toter Resolver, nicht Egress. - 📜 **~~ALLNET VLAN-DB (TP1)~~ — historisch.** Die VLAN-Semantik gilt weiter (**40=MEDIA, 50=UNTRUSTED**), die Portangaben (GE1/GE2/GE8) beziehen sich auf ein ausgebautes Gerät. - **ap2 hängt an `crs326-branch ether24`** (Trunk, native VLAN1 + tagged 10-99); **branch-Uplink `ether1` → `crs326-core ether8`** (korrigiert 2026-08-16 — die frühere Angabe „→ sw1 GE8" stammt aus der Zeit vor dem Core-Tausch; MAC-hart belegt in TP22 Schritt 5). diff --git a/docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md b/docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md new file mode 100644 index 0000000..85b3eb2 --- /dev/null +++ b/docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md @@ -0,0 +1,95 @@ +# Handoff — TP16.3 §5 durch: alle vier Namen auf `bf-public`, plus ein 10-Sekunden-Fund + +> **2026-08-31/09-01.** Nachfolger von +> [`handoff-20260831-tp16.3-paragraph2-3-durch.md`](handoff-20260831-tp16.3-paragraph2-3-durch.md). +> **Nicht** Teil dieser Session: §6 (Abbau). + +--- + +## 1. Was jetzt steht + +**Alle vier öffentlichen Namen laufen über `bf-public`** — der öffentliche Verkehr geht damit +erstmals über **Caddy** statt an ihm vorbei. + +| Name | Nachweis von außen | Origin bewiesen? | +|---|---|---| +| `gitea` | 200, `i_like_gitea`-Cookie = echte Gitea-Antwort | ✅ | +| `hass` | 200 + `manifest.json` 200 + **WebSocket `101 Switching Protocols`** | ✅ inkl. Companion-App-Pfad | +| `vw` | `/`, `/alive`, `/api/config` je 200; WS-Hub `401` **von Vaultwarden** | ✅ | +| `n8n` | 302 zum Access-Login (vor *und* nach dem Flip) | ❌ — vom User im Browser bestätigt | + +Antwortzeiten vorher/nachher unverändert ⇒ **Caddy im Pfad kostet nichts Messbares.** +🚫 **Die drei Alttunnel stehen bewusst weiter** (`bf-mm`/`bf-nas`/`bf-pve`, je healthy/8) — sie sind +die Rückfallebene. Rückweg je Name = ein `PATCH` auf die alte Tunnel-ID. + +**Schicht davor, ebenfalls durch:** die sechs AP-Drifts sind ins Soll gehoben, **Compliance 139/140** +(28 Regeln × 5 Geräte). Übrig bleibt genau `crs326-core`/`wifi-security` = offene Transaktion +`TP25-fund-e-ft-over-ds`. Neu: ComplianceRule **`interface-veth`** + zwei `ConfigReplace`-Regeln, die +die gerätevergebenen veth-MACs normalisieren (`nautobot/ingest-veth-rule.py`). + +--- + +## 2. 🔴 Der eigentliche Fund der Nacht: ein 10-Sekunden-Zoll auf drei Diensten + +`gitea` hing bei ~10 % der Anfragen **exakt 10,1 s** — quer über Web-UI, `/api/healthz` **und** den +Git-Pfad. **Ursache:** MariaDB (LXC **302**) hatte `skip-name-resolve` auskommentiert und machte bei +**jeder neuen Verbindung** einen Reverse-Lookup, während ihr `/etc/resolv.conf` auf den **toten** +`10.40.41.254` zeigte. Gemessen: **10.010 ms je Lookup**. + +**An derselben DB hängen `Vaultwarden` (.127), `Home Assistant` (.105) und `gitea` (.157)** — +über die Verbindungstabelle belegt. + +**Fix (User-Freigabe, Wartungsfenster):** `pct set --nameserver 10.40.20.1` + Reboot für +`302 mariadb`, `102 mqtt5`, `106 influxdb2`, `107 redis`, `150 iob-exposed`. +**Nachher: Lookup 21–24 ms; gitea 0 von 25 Proben langsam**, langsamste 75 ms. + +⚠️ **Strukturell offen:** `skip-name-resolve` ist weiter **aus**. Setzen bricht alle Grants, die auf +**Hostnamen** statt IPs lauten ⇒ vorher `mysql.user` lesen. **DB-Zugang fehlt** (`root@localhost` +ohne Passwort verweigert) — das ist der nächste konkrete Schritt. + +--- + +## 3. 🔴 Latenter Fund: vier Container überleben keinen Reboot sauber + +`networking.service` und `ifupdown-wait-online.service` sind in **`101`, `102`, `106`, `107`** +fehlgeschlagen. Folge: alles mit `After=network-online.target` startet nach einem Reboot **nicht** — +**influxdb2 kam nicht hoch**, Unit `enabled`, **kein Startversuch im Journal**. Von Hand sofort ok. + +🔑 **Nicht von dieser Session verursacht:** `101` wurde nie angefasst und zeigt dieselben Units. +Die Container liefen nur 13+ Tage ohne Neustart. **Diese vier sind einen Reboot davon entfernt, +still einen Dienst zu verlieren.** + +--- + +## 4. Drei Messfallen, die diese Session Zeit gekostet haben + +1. **Split-Horizon:** der Haus-Resolver liefert für alle vier Namen direkt `10.40.20.40` — ein Test + von zuhause sieht Cloudflare **nie**. Prüfen nur mit `curl --resolve :443:188.114.96.10` + oder von außerhalb. *(Guter Nebeneffekt: ein misslungener Flip bricht intern nichts.)* +2. **Access antwortet je nach Standort verschieden:** `n8n` aus dem Haus 200 (`bf4`-Policy), + von außen 302. `hass`/`vw`/`gitea` stehen auf **`bypass`** — dort **nie** ein Login. + ⚠️ Die App `hass, vw, gitea` heisst **zu Recht** so: 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 (`route -n get default` = `172.20.10.1`). + Daraufhin wurde ein **bereits erfolgreicher `n8n`-Flip grundlos zurückgerollt**. + **Merkregel: vor jeder Ausfallmeldung die eigene Default-Route lesen.** + +Dazu zwei Werkzeug-Befunde: **der Zähler der Blocker-B-Firewallregel taugt nicht als Wegbeweis** +(cloudflared hält die Origin-Verbindung offen ⇒ kaum neue Verbindungen ⇒ Zähler steht still, obwohl +alles läuft; richtig ist die **Verbindungstabelle**), und **Caddy führt gar kein Access-Log** ⇒ der +alte §5.3-Punkt „Caddy sieht den Request" konnte nie funktionieren. + +--- + +## 5. Nächste Schritte + +1. **§6 Abbau** — sechs Container + drei Alttunnel. Frühestens nach störungsfreiem Betrieb; + Christoph hat den **Flip** vorgezogen freigegeben, **nicht** den Abbau. + 🚫 `terpene-cloudflared` (LXC 400) und `fm.emsenhuber.net` bleiben. **Namen lesen, nicht Zeilen zählen.** +2. **`skip-name-resolve`** auf der MariaDB — vorher `mysql.user` gegen Hostname-Grants prüfen. +3. **`networking.service`** in `101`/`102`/`106`/`107` reparieren (Punkt 3). +4. **TP30:** die zwei Nautobot-Tokens rotieren (vom User vertagt, weiterhin offen). +5. **TP14.4:** ohne Service-Token für die Wildcard-App ist `n8n` von außen nicht bis zum Origin prüfbar. +6. **Caddy-Access-Log** (TP31/TP34): der öffentliche Reverse Proxy protokolliert keine Requests. +7. `mcp/mikromcp/config/routers.yaml` meldet weiter `rosVersion: "7.24"`, live ist `7.24.1`. diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 4884b94..9ac91b4 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -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 --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 :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 | — | diff --git a/docs/tp16.3-bf-public-ap-connector-runbook.md b/docs/tp16.3-bf-public-ap-connector-runbook.md index 2461f97..a322a68 100644 --- a/docs/tp16.3-bf-public-ap-connector-runbook.md +++ b/docs/tp16.3-bf-public-ap-connector-runbook.md @@ -3,7 +3,8 @@ > **§1–§3 AUSGEFÜHRT 2026-08-31.** Drei Connectoren laufen, `bf-public` healthy/12. > §2.2, §3.4 und §3.5 sind unten **korrigiert** — die ursprüngliche Fassung war an drei > Stellen falsch (Flash-Budget, `docker save`-Format, `envs`-Parametername). -> Offen bleiben **§5 (Flip)** und **§6 (Abbau)**. +> ✅ **§5 (Flip) AUSGEFÜHRT 2026-09-01** — alle vier Namen auf `bf-public`. +> Offen bleibt nur **§6 (Abbau)**. > **Löst [`tp31-schritt5-runbook.md`](tp31-schritt5-runbook.md) ab** (Stand 08-27). Jenes Dokument > kennt ap3 nicht, unterstellt einen Registry-Pull (geht bei `fetch: no` nicht) und enthält **eine > nachweislich falsche Freigabe-Behauptung** (§8 Falle 2). Es bleibt als Historie liegen, ist aber @@ -491,7 +492,7 @@ für die Strecke bis Caddy ist §5.1, nicht diese Zahl. Genau diese Verwechslung --- -## §5 CNAME-Flip — einzeln, mit Abnahme dazwischen +## §5 CNAME-Flip — ✅ **AUSGEFÜHRT 2026-09-01** (einzeln, mit Abnahme dazwischen) **Reihenfolge: `n8n` → `gitea` → `hass` → `vw`** (steigende Kritikalität; `vw` zuletzt). Zone-ID `1b5bc02fdf61b6b989afde543f3f4134`. @@ -540,9 +541,29 @@ curl -s -X PATCH -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: appl - [ ] Aufruf über Mobilfunk (oder anderer Standort) → Access-Login → **200** - [ ] **Kein** `ERR_TOO_MANY_REDIRECTS` (das wäre Blocker A) -- [ ] Caddy sieht den Request: `ssh root@10.40.20.100 'pct exec 130 -- journalctl -u caddy -n 20'` - [ ] 15 min beobachten, kein 530/1033 +🔴 **KORRIGIERT 2026-09-01 — der frühere Punkt „Caddy sieht den Request: +`journalctl -u caddy -n 20`" funktioniert NICHT.** Im `Caddyfile` steht keine `log`-Direktive; im +Journal landen nur `info`/`warn`. Ein **erfolgreicher** Request hinterlässt dort **nichts**, und die +leere Ausgabe liest sich wie „kam nie an". *(Dass der öffentliche Reverse Proxy überhaupt keine +Requests protokolliert, ist eine eigene Lücke — gehört zu TP31/TP34.)* + +**Was stattdessen funktioniert — und 2026-09-01 auch benutzt wurde:** + +| Werkzeug | Beweist | +|---|---| +| `curl --resolve :443:188.114.96.10` | Erzwingt den **öffentlichen** Weg. 🔴 **Pflicht**, denn der Haus-Resolver liefert für alle vier Namen direkt `10.40.20.40` (Split-Horizon) — ein Test von zuhause sieht Cloudflare **nie**. | +| Verbindungstabelle am Core (`/ip firewall connection`) | Zeigt `10.40.99.x → 10.40.20.40` = ein AP-Connector redet mit Caddy. **Der Zähler der Blocker-B-Regel taugt dafür NICHT**: `cloudflared` hält die Origin-Verbindung offen, es entstehen kaum neue — der Zähler steht still, obwohl alles läuft. | +| Antwort-Fingerabdruck | z.B. `i_like_gitea`-Cookie = echte Gitea-Antwort, nicht CF/Caddy. | +| WebSocket-Handshake **mit `--http1.1`** | `101 Switching Protocols` = der Companion-App-Pfad steht. ⚠️ Über HTTP/2 gibt es keinen klassischen Upgrade — ein `400` ist dann der eigene Testfehler, nicht der Dienst. | + +⚠️ **Access antwortet je nach Standort verschieden, beides gesund:** `n8n` liefert aus dem Haus +**200** (die `bf4`-Policy trägt die WAN-IP), von außen **302** zum Login. `hass`/`vw`/`gitea` stehen +auf **`bypass`** (App `hass, vw, gitea`, alle drei in `self_hosted_domains`) — dort kommt **nie** ein +Login. Ein Service-Token für die Wildcard-App gibt es nicht (**TP14.4**), deshalb ist `n8n` von außen +**nicht** bis zum Origin prüfbar — das musste der User im Browser bestätigen. + 🔴 **WARP muss aus sein.** Mit aktivem WARP läuft der Test über den Mesh und beweist den öffentlichen Weg **nicht** — dieselbe Klasse Fehldiagnose wie beim ICMP-Fall 2026-08-13.