From ec8051508ef1f7030fc56938c410e6e623673603 Mon Sep 17 00:00:00 2001 From: Christoph Emsenhuber Date: Mon, 24 Aug 2026 10:33:43 +0200 Subject: [PATCH] TP16.3: nautobot aus dem CF-Ingress geschnitten, Probe laeuft Runbook ausgefuehrt. Vorbedingungen alle erfuellt, Testclient hing im Hotspot-Netz 172.20.10.13 mit aktivem WARP -- also nicht im BF-LAN, der einzige Aufbau der fuer Vorbedingung 2 etwas beweist. Schnitt: nautobot.emsenhuber.net aus bf-nas (8 -> 7 Regeln), Catch-all bleibt letzte. Rollback-Sicherung in docs/cf-backup/. Gegenprobe durch Zuruecklesen der Config, nicht am Statuscode. Abnahme vollstaendig, inkl. des uebersehenen Punktes: Golden Config lief durch (Backup -> Intended -> Compliance, 104/104, 0 Drifts). Die uebrigen fuenf bf-nas-Hostnames unveraendert. Befund, der die Abnahmetabelle des Runbooks korrigiert: der oeffentliche FQDN taugt nicht als Test. Er liefert vor UND nach dem Schnitt 302, weil der von Cloudflare Access kommt, nicht vom Origin -- Access greift vor dem Tunnel (JWT: auth_status NONE bei is_warp true). Damit auch eine ehrlichere Erwartung: nautobot war nie ohne Access-Login oeffentlich erreichbar, der Schnitt entfernt die zweite Tuer, nicht die erste. Paragraph 7 des Runbooks ist ueberholt -- die HA-Degradierung ist am selben Tag repariert, der Fall steht auf dem verbliebenen Argument. Co-Authored-By: Claude Opus 5 --- .../bf-nas-ingress-20260824-vor-tp16.3.json | 1 + docs/teilprojekte.md | 27 +++++++- docs/tp16.3-nautobot-mesh-only-runbook.md | 65 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json diff --git a/docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json b/docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json new file mode 100644 index 0000000..9a7b244 --- /dev/null +++ b/docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json @@ -0,0 +1 @@ +{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"220c9958-401b-4111-9451-f3db09bba2d5","version":4,"config":{"ingress":[{"service":"http://10.40.20.157:3000","hostname":"gitea.emsenhuber.net"},{"service":"http://10.40.20.109:3000","hostname":"grafana.emsenhuber.net"},{"service":"http://10.40.20.173:3000","hostname":"pve-mcp.emsenhuber.net"},{"service":"http://10.40.20.127","hostname":"vw.emsenhuber.net"},{"service":"http://10.40.20.10:8080","hostname":"ds-bf.emsenhuber.net"},{"service":"ssh://10.40.20.10:22","hostname":"3k23uow7.emsenhuber.net"},{"service":"http://10.40.20.30:8080","hostname":"nautobot.emsenhuber.net","originRequest":{}},{"service":"http_status:404"}],"warp-routing":{"enabled":true}},"source":"cloudflare","created_at":"2026-07-23T09:35:13.907313Z"}} \ No newline at end of file diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 342da3a..7e07522 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -340,7 +340,32 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na - **Reihenfolge:** (1) Client-IP-Weitergabe fixen (inkl. HA `trusted_proxies`) → (2) `/admin`-Pfade path-scoped schützen → (3) App-Limits + 2FA → (4) Edge-Rules → (5) CrowdSec/fail2ban mit CF-Bouncer. - **Abh.:** TP16 ✅ (Tunnel-HA). Verwandt: **TP20.1** (vw wandert auf Platform-Postgres — DB-HA ≠ Access, getrennt halten), **TP23** (dessen WARP-Managed-Network-Idee ist durch diesen Constraint **entlastet**: `vw` verlangt keine Device-Identity, also kollidiert „WARP zuhause aus" nicht mehr mit dem Access-Strang). -### TP16.3 — cloudflared-Reduktion: was der Mesh als Datenpfad kann (und was nicht) ▸ 🔜 **AUSFÜHRBAR (Runbook 2026-08-19)** — `docs/tp16.3-nautobot-mesh-only-runbook.md` +### TP16.3 — cloudflared-Reduktion: was der Mesh als Datenpfad kann (und was nicht) ▸ ⏳ **PROBE LÄUFT SEIT 2026-08-24** — `docs/tp16.3-nautobot-mesh-only-runbook.md §8` +- ▶️ **Schnitt ausgeführt 2026-08-24:** `nautobot.emsenhuber.net` ist aus dem Ingress von `bf-nas` + entfernt (**8 → 7 Regeln**, Catch-all weiterhin letzte). Rollback-Sicherung liegt unter + `docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json` — Rückweg ist ein `PUT`, eine Minute. + **Abnahme vollständig:** private IP mit WARP von außerhalb des LAN 302 in 0,16 s · die übrigen fünf + `bf-nas`-Hostnames unverändert · und der Punkt, den man übersieht — **Golden Config lief durch: + Backup → Intended → Compliance, 104/104, 0 Drifts.** + - 🎯 **Der Testaufbau war der einzige, der etwas beweist:** die Session lief auf einem Host im + Hotspot-Netz `172.20.10.13` mit aktivem WARP, also **nicht im BF-LAN**. Aus dem LAN heraus wäre + der Zugriff ohnehin gegangen und hätte nichts gezeigt (Merkregel `feedback_adresse_lesen_nicht_ansagen`). + - 🔴 **Befund, der die Abnahmetabelle des Runbooks korrigiert: der öffentliche FQDN taugt nicht als + Test.** `nautobot.emsenhuber.net` liefert **vor und nach** dem Schnitt HTTP 302 — der kommt von + **Cloudflare Access**, nicht vom Origin (`location: emsenhuber.cloudflareaccess.com/cdn-cgi/access/…`, + JWT `auth_status: NONE` bei `is_warp: true`). Access greift **vor** dem Tunnel. ⇒ Gültiger Nachweis + ist **das Zurücklesen der Ingress-Config**, nicht die Antwort des Frontends — dieselbe TP22/TP23-Regel. + - 📌 **Und die Erwartung wird damit ehrlicher:** Nautobot war nie ohne Access-Login öffentlich + erreichbar. Der Schnitt schließt **keine offene Tür**, er entfernt eine **überflüssige zweite**. + - ⚠️ **Vorprüfung, die vor jedem weiteren Schnitt zu wiederholen ist:** hängt Werkzeug am + öffentlichen Namen? Hier nein — `gc-configplan.py` spricht `http://10.40.20.30:8080/api`, und + kein Repo-Skript nutzt den FQDN. +- ⏳ **Offen: das Betriebsfenster.** Eine Woche fahren (bis ~**2026-08-31**), dann entscheiden, ob es so + bleibt und ob `pve`/`portainer`/`grafana`/`pve-mcp`/`ha-mcp`/`gitea-mcp`/`ds-bf`/`ccu`/`iobroker`/`z2m25` + folgen. +- 📌 **Ein Argument des TP ist entfallen:** die HA-Degradierung, die §7 als Nebeneffekt anführte, ist am + **selben Tag repariert** (TP16 ✅). Der Fall steht damit allein auf dem eigentlichen Argument — + **weniger bewegliche Teile für Dienste, die öffentlich nicht gebraucht werden.** > 📌 Der Schnitt (`nautobot` aus dem `bf-nas`-Ingress) ist ausformuliert inkl. Vorbedingungen, PUT-Ablauf > und Rollback. Zwei Punkte stehen dort explizit, weil sie den TP sonst kippen: **Mesh-Hostname-Routes > sind Egress und veröffentlichen nichts** (wer das verwechselt, baut den Public-Strang ab), und diff --git a/docs/tp16.3-nautobot-mesh-only-runbook.md b/docs/tp16.3-nautobot-mesh-only-runbook.md index 421027a..1ffc154 100644 --- a/docs/tp16.3-nautobot-mesh-only-runbook.md +++ b/docs/tp16.3-nautobot-mesh-only-runbook.md @@ -119,3 +119,68 @@ nach dem Schnitt gehört ein Job-Lauf zur Abnahme, nicht nur ein Browser-Aufruf. Die **TP16-HA-Degradierung** (`bf-nas` und `bf-pve` haben je nur **einen** Connector, Befund 2026-08-16) verliert an Gewicht, je weniger Dienste an cloudflared hängen. Das ersetzt die Reparatur nicht — aber es verkleinert, was der SPOF trifft. + +--- + +## 8. ▶️ AUSGEFÜHRT 2026-08-24 — der Schnitt sitzt, Probe läuft + +**Vorbedingungen (§3), alle erfüllt:** + +| Prüfung | Ergebnis | +|---|---| +| vnet-Route `10.40.0.0/16` → `bf-core-mesh` | ✅ vorhanden (CF `teamnet/routes`) | +| `cf-mesh` am Core | ✅ `R`, last-handshake 33 s, 198 MiB rx / 738 MiB tx | +| `http://10.40.20.30:8080` **von außerhalb des LAN, WARP aktiv** | ✅ HTTP 302 in 0,18–0,36 s | +| ICMP zu `10.40.20.30` | ✅ 0 % Loss *(kein Beweis, aber es schließt die WARP-Falle aus)* | + +🎯 **Der Testclient war zufällig genau der richtige:** die Session lief auf einem Host im +**Hotspot-Netz `172.20.10.13`** mit aktivem WARP — also *nicht* im BF-LAN. Das ist der einzige Aufbau, +der für Vorbedingung 2 etwas beweist; aus dem LAN heraus geht es ohnehin. + +**Der Schnitt:** `nautobot.emsenhuber.net` aus dem Ingress von `bf-nas` +(`220c9958-401b-4111-9451-f3db09bba2d5`) entfernt, **8 → 7 Regeln**, Catch-all weiterhin letzte. +Rollback-Sicherung: **`docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json`**. +Gegenprobe **durch Zurücklesen der Config vom Dienst**, nicht am Statuscode: `nautobot noch drin? False`. + +**Abnahme (§5):** + +| Prüfung | Ergebnis | +|---|---| +| `10.40.20.30:8080` mit WARP von außerhalb | ✅ 302 in 0,16–0,17 s | +| `gitea` / `grafana` / `pve-mcp` / `vw` / `ds-bf` | ✅ je 3 Läufe, unverändert (200/302/302/200/302) | +| **Golden-Config-Pipeline** | ✅ Backup → Intended → Compliance, **104/104 compliant, 0 Drifts** | +| Öffentlicher FQDN nicht mehr bedient | ⚠️ **so nicht testbar — s.u.** | + +### 🔴 Befund: die erste Abnahmezeile aus §5 ist als Test untauglich +`https://nautobot.emsenhuber.net/` antwortet **vor und nach** dem Schnitt mit **HTTP 302** — und zwar +identisch, weil der 302 **nicht vom Origin kommt, sondern von Cloudflare Access**: +`location: https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/login/nautobot.emsenhuber.net`. +Access greift **vor** dem Tunnel; der Request erreicht den Ingress gar nicht, solange keine +Access-Session besteht. Im mitgelieferten JWT steht `"auth_status":"NONE"` bei gleichzeitig +`"is_warp":true` — **WARP-Identität allein erfüllt die Policy für `nautobot` nicht**, es braucht den +interaktiven Login. + +⇒ **Konsequenzen, beide wichtig:** +1. **Der Statuscode des öffentlichen FQDN kann diesen Schnitt weder belegen noch widerlegen.** Der + gültige Nachweis ist das **Zurücklesen der Ingress-Config** (oben) — dieselbe Regel wie in + TP22/TP23: nicht die Antwort des Frontends zählt, sondern der Zustand am Dienst. +2. **Der öffentliche Weg war schon vorher zu.** Nautobot war nie ohne Access-Login erreichbar; der + Schnitt entfernt also die *zweite* von zwei Türen, nicht die erste. Das schmälert den Gewinn nicht + (eine Ingress-Zeile und ein Connector-Paar weniger), aber es korrigiert die Erwartung: **hier wurde + keine offene Tür geschlossen, sondern eine überflüssige entfernt.** + +📌 **Nebenprüfung, die den Schnitt hätte kippen können:** `nautobot/gc-configplan.py` spricht +`http://10.40.20.30:8080/api` — die **private** IP. Kein Repo-Skript benutzt den öffentlichen Namen +(`grep` über `*.py`/`*.sh`/`*.yml`/`*.env`: kein Treffer). Die Werkzeugkette hängt also nicht am +gekappten Weg. **Das gehört vor jeden weiteren Schnitt der rechten Spalte geprüft.** + +### ⏳ Offen: das Betriebsfenster +**Eine Woche fahren (bis ~2026-08-31), dann entscheiden.** Rollback = die gesicherte Config +zurückschreiben, eine Minute. Danach steht die Frage, ob `pve`, `portainer`, `grafana`, `pve-mcp`, +`ha-mcp`, `gitea-mcp`, `ds-bf`, `ccu`, `iobroker`, `z2m25` folgen. + +### 📌 §7 ist überholt +Der dort beschriebene Nebeneffekt („die HA-Degradierung verliert an Gewicht") ist gegenstandslos: +**TP16 ist am selben Tag repariert** — alle drei bf-Tunnel laufen wieder auf 2 Connectoren +(`cf-tunnel-mapping.md §15`). Der Fall für TP16.3 steht damit auf dem verbliebenen Argument, und das +ist das eigentliche: **weniger bewegliche Teile für Dienste, die öffentlich nicht gebraucht werden.**