TP16.3 §5: die sechs AP-Drifts ins Soll, 28. Regel interface-veth
veth / ip address / ip firewall nat der drei cloudflared-Connectoren standen seit
der Vor-Ort-Session per Direkt-Write am Geraet (Runbook §3.4), waehrend /ip address
und /ip firewall unter GC-Drift-Kontrolle stehen: sechs extra-Drifts, Compliance
128/135. Sie sind inhaltlich richtig und sollen DAUERHAFT gelten -- deshalb ins
Template und nicht in eine gc-transaktion (die ist fuer befristete Versuche).
Kein Re-Baseline, kein Rueckbau, keine Zeile aufs Geraet: nur die SoT nachgezogen.
Neu ist die 28. ComplianceRule interface-veth. Vorher gab es fuer /interface veth
keine Regel -- das tragende Stueck des ganzen Aufbaus haette geloescht werden
koennen, ohne dass irgendetwas meldet.
Zwei Funde:
(a) Der veth-Export traegt zwei geraetevergebene MACs (mac-address,
container-mac-address), auf jedem AP anders. Eine nackte Regel haette damit
Dauer-Drift auf allen drei APs erzeugt, also genau die immer-rote Zahl, die
niemand mehr liest. Zwei eng auf die veth-Zeile verankerte ConfigReplace-Regeln
normalisieren sie im Backup (Lookbehind haelt container-mac-address heraus,
[^\n]*? haelt die Regel in der Zeile; Selbsttest mit Negativfaellen im Skript).
Bewusst mit der vorhandenen Maske <<REDACTED>> statt einer eigenen: sie ist im
Repo zugleich die Push-Sperre (gc-configplan.py verweigert config_set damit) --
eine Zeile mac-address=<<...>> darf nie aufs Geraet.
Kostet Backup-Treue: die veth-MACs stehen in bf-golden-config nicht mehr im
Klartext. Vertretbar, RouterOS vergibt sie beim Neuanlegen ohnehin neu.
Verworfene Alternative: MACs je Geraet modellieren -- widerspricht der
Begruendung, die fuer die VAP-MACs schon im ConfigContext-Skript steht.
(b) Der erste Compliance-Lauf meldete SUCCESS und war trotzdem unvollstaendig:
139 statt 140 Eintraege, crs326-core/interface-veth fehlte, im Job-Log
"RENDER COMPLIANCE TASK GROUP failed: Broken pipe". Zweiter Lauf sauber.
Merkregel im Runbook (Falle 16): Abnahme ist die ANZAHL der Eintraege
(Regeln x Geraete), nicht die Konformitaetsquote.
Stand danach: 139/140. Uebrig bleibt genau crs326-core/wifi-security -- die offene
Transaktion TP25-fund-e-ft-over-ds einer laufenden Messung, die bleiben muss.
Ausserdem: frischer Ingress-Snapshot von bf-public vor §5 und das geschaerfte
§5.1-Erfolgskriterium (200 mit leerem Body + server: Caddy = Strecke bewiesen,
404 = Ingress-Regel fehlt) -- am Live-System gemessen, nicht angenommen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"48d3b0b6-7233-4781-a76a-1de4a5e957ce","version":3,"config":{"ingress":[{"service":"https://10.40.20.40:443","hostname":"vw.emsenhuber.net","originRequest":{"originServerName":"vw.emsenhuber.net"}},{"service":"https://10.40.20.40:443","hostname":"hass.emsenhuber.net","originRequest":{"originServerName":"hass.emsenhuber.net"}},{"service":"https://10.40.20.40:443","hostname":"n8n.emsenhuber.net","originRequest":{"originServerName":"n8n.emsenhuber.net"}},{"service":"https://10.40.20.40:443","hostname":"gitea.emsenhuber.net","originRequest":{"originServerName":"gitea.emsenhuber.net"}},{"service":"http_status:404"}],"warp-routing":{"enabled":false}},"source":"cloudflare","created_at":"2026-08-31T05:56:47.739644Z"}}
|
||||
@@ -31,6 +31,23 @@ 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: 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
|
||||
`gc-transaktion`: ein Dauerzustand gehört ins Soll, eine Transaktion ist ein befristeter Versuch.
|
||||
**Kein Re-Baseline, kein Rückbau, keine Zeile aufs Gerät** — nur die SoT nachgezogen.
|
||||
🆕 **28. ComplianceRule `interface-veth`** (vorher gab es für `/interface veth` keine ⇒ ein
|
||||
gelöschtes veth hätte **nichts** gemeldet). 🔴 **Zwei Funde dabei:** (a) der veth-Export trägt
|
||||
**zwei gerätevergebene MACs** — eine nackte Regel hätte Dauer-Drift auf allen drei APs erzeugt;
|
||||
gelöst mit zwei eng auf die veth-Zeile verankerten `ConfigReplace`-Regeln (`60-`/`61-veth-*`,
|
||||
`nautobot/ingest-veth-rule.py`), bewusst mit der vorhandenen Maske `<<REDACTED>>`, weil die im
|
||||
Repo zugleich die **Push-Sperre** ist. (b) **Der erste Compliance-Lauf meldete `SUCCESS` und war
|
||||
trotzdem unvollständig** (139 statt 140 Einträge, `crs326-core`/`interface-veth` fehlte;
|
||||
Job-Log: `RENDER COMPLIANCE TASK GROUP failed: Broken pipe`). Zweiter Lauf sauber.
|
||||
⚠️ **Merkregel: nach einem Refresh nicht nur die Konformitätsquote lesen, sondern die ANZAHL der
|
||||
Einträge** — sie muss `Regeln × Geräte` sein. Eine fehlende Kombination sieht aus wie „die neue
|
||||
Regel greift nicht" und ist in Wahrheit ein halb gelaufener Job.
|
||||
*(Übrig bleibt genau `crs326-core`/`wifi-security` = offene Transaktion `TP25-fund-e-ft-over-ds`.)*
|
||||
- 🆕 **MCP-Bestand 2026-08-28 korrigiert:** **9 MCPs identisch** in `~/.claude.json` und `~/.config/opencode/opencode.jsonc` (vorher Asymmetrie 7 vs. 11 — `portainer-mcp`/`shelly-mcp` raus, `gitea-mcp`/`n8n-mcp` rein). **Mac mini = n8n-Host, NICHT zentraler MCP-Host** (Performance-Restriktion); zentraler MCP-Host = **DS923** (`nas-bf`, Portainer Endpoint 14). Inventur-Stand `mcp/INVENTORY.md` + Policy `docs/mcp-host-policy.md`.
|
||||
- 🆕 **MCP-Migration FQDN→IP (2026-08-29, TP35 Schicht 1):** `gitea-mcp` und `n8n-mcp` in `~/.config/opencode/opencode.jsonc` von CF-FQDN auf LAN-IP umgestellt — `gitea-mcp` → `http://10.40.20.167:3000/mcp` (macmini, **ohne** Bearer, intern), `n8n-mcp` → `http://10.40.20.167:3001/mcp` (mit `Bearer {env:N8N_MCP_BEARER}`). **Befund dabei:** der Handoff 1.2 nannte für gitea-mcp die falsche IP `.157:3000` (das ist die Gitea-Web-UI, `400 Invalid CSRF`); der echte gitea-mcp läuft auf `.167:3000` (`serverInfo: gitea-mcp 0.0.10`). `cloudflare`-MCP bleibt auf dem offiziellen FQDN (User-Direktive).
|
||||
- 🆕 **TP16.3 §2/§3 durchgezogen (2026-08-31, Vor-Ort):** je ein `cloudflared`-Container auf
|
||||
@@ -319,7 +336,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 — offen: Flip §5, Abbau §6) | — |
|
||||
> | 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) | — |
|
||||
> | TP17.1 | ❌ | Shelly Gen4 → Zigbee | 2026-08-23 |
|
||||
> | TP17.3 | ✅ | Shelly-Regression behoben | 2026-08-23 |
|
||||
> | TP18 | 🔜 | Garage-Objektspeicher | — |
|
||||
@@ -636,7 +653,21 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
- 🟡 **MikroMCPs `export_config` liefert einen unvollständigen Export** (301 B gegen 6,2 KiB bei
|
||||
direktem `/export`) — ein Rollback-Artefakt, das existiert und trotzdem leer ist. Für die Backups
|
||||
dieser Session wurden die MCP-Exporte verworfen und `/export file=…` verwendet.
|
||||
- 🔴 **Offen und entscheidungsbedürftig: Compliance steht auf 128/135, nicht 134/135.** §3.4 schreibt
|
||||
- ✅ **ERLEDIGT 2026-08-31: die sechs Drifts sind ins Soll gehoben, Compliance 139/140.**
|
||||
Entscheid Christoph: ins Template heben (nicht als Transaktion führen), und `/interface veth`
|
||||
bekommt eine **eigene ComplianceRule** — vorher war es das tragende Stück ohne jede Überwachung.
|
||||
Umgesetzt in `nautobot/mikrotik_routeros.j2` (Block `[7]`), `nautobot/ingest-ap-configcontext.py`
|
||||
(`ap.container`) und neu `nautobot/ingest-veth-rule.py`. **Kein Geräte-Write.**
|
||||
🔴 **Der veth-Export trägt zwei gerätevergebene MACs** (`mac-address`, `container-mac-address`,
|
||||
je AP verschieden). Ohne Vorbehandlung hätte die neue Regel auf **allen drei APs Dauer-Drift**
|
||||
erzeugt — also genau die immer-rote Zahl, die niemand mehr liest. Zwei `ConfigReplace`-Regeln
|
||||
normalisieren sie im Backup, eng auf die veth-Zeile verankert (`[^\n]*?` plus Lookbehind, damit
|
||||
VAP-/Bridge-/Ethernet-MACs nicht mitgefangen werden; Selbsttest im Skript).
|
||||
⚠️ **Ehrlich dazugesagt:** das kostet Backup-Treue — die veth-MACs stehen in `bf-golden-config`
|
||||
nicht mehr im Klartext. Vertretbar, weil RouterOS sie beim Neuanlegen ohnehin neu vergibt; was die
|
||||
Regel beweist, ist die **Existenz** des veth mit der richtigen Adressierung.
|
||||
*(Der ursprüngliche Befund, zur Nachvollziehbarkeit:)*
|
||||
- 🟢 **War: Compliance stand auf 128/135, nicht 134/135.** §3.4 schreibt
|
||||
Direkt-Writes für `veth` / `ip address` / `nat` vor, während `/ip address` und `/ip firewall` unter
|
||||
GC-Drift-Kontrolle stehen — **Runbook und Governance widersprechen sich.** Folge: je AP zwei neue
|
||||
`extra`-Drifts (`ip-address` mit `172.17.0.1/24 interface=veth-cf`, `ip-firewall-nat` mit dem
|
||||
|
||||
@@ -398,6 +398,10 @@ wie es war. Dann einfach neu absetzen.
|
||||
Das `masquerade` ist **Pflicht**, nicht Kosmetik — siehe §1.2: ohne es kommen die Pakete mit
|
||||
`172.17.0.2` am Core an, wo weder Route noch Firewall-Regel sie kennt.
|
||||
|
||||
✅ **Seit 2026-08-31 stehen diese drei Zeilen im SOLL** (AP-Template Block `[7]`, Werte aus dem
|
||||
ConfigContext `ap-common` → `ap.container`). Wer sie hier direkt setzt, erzeugt daher **keine
|
||||
Drift mehr** — aber auch keinen Bedarf: bei einem neuen AP rendert Golden Config sie mit.
|
||||
|
||||
### 3.5 Image importieren und Container bauen
|
||||
|
||||
```bash
|
||||
@@ -503,7 +507,20 @@ curl -s -X POST -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: appli
|
||||
```
|
||||
Dazu **eine Ingress-Regel** für `test-tp163.emsenhuber.net` → `https://10.40.20.40:443` mit
|
||||
`originServerName: vw.emsenhuber.net` in `bf-public` ergänzen. Dann **von außerhalb des LAN, ohne
|
||||
WARP** aufrufen. Erwartet: Access-Login, **keine Redirect-Schleife**.
|
||||
WARP** aufrufen.
|
||||
|
||||
🔑 **Das Erfolgskriterium ist praeziser, als es hier bis 2026-08-31 stand — und die frühere Fassung
|
||||
war zweideutig.** Gemessen am 2026-08-31 gegen `10.40.20.40`:
|
||||
|
||||
| Antwort | Bedeutung |
|
||||
|---|---|
|
||||
| Access-Login, danach **`200` mit LEEREM Body** und Header **`server: Caddy`** | ✅ **Strecke bewiesen.** Caddy hat geantwortet; es gibt für `test-tp163` nur kein Site-Block, und genau so antwortet Caddy auf einen unbekannten Host. |
|
||||
| **`404`** | ❌ Die Ingress-Regel greift nicht — das ist der **Catch-all** von `bf-public` (`http_status:404`). |
|
||||
| **`ERR_TOO_MANY_REDIRECTS`** | ❌ Blocker A ist zurück (Ingress auf `:80` oder `originServerName` fehlt). Sofort abbrechen. |
|
||||
|
||||
⚠️ **Ohne diese Tabelle liest man das leere 200 als „kaputt" und das 404 als „Caddy sagt nichts" —
|
||||
beide Male falsch herum.** Der zweite, unabhängige Beweis ist immer das Caddy-Log (§5.3).
|
||||
|
||||
⇒ Erst wenn das steht, wird ein Produktivname angefasst. Danach Testname + Testregel wieder entfernen.
|
||||
|
||||
### 5.2 Flip je Name
|
||||
@@ -639,12 +656,23 @@ physischem Gang. Es schadet nicht — ohne laufenden Container ist es ein gesetz
|
||||
12. 🔴 **`docker save` liefert seit Docker 25 OCI statt docker-v1** → `no config found in manifest`.
|
||||
13. 🔴 **`/container/envs` nimmt `list=`, nicht `name=`.**
|
||||
14. 🔴 **Der `device-mode`-Bestätigungs-Boot installiert keine Pakete** — Reihenfolge s. §3.3.
|
||||
15. 🔴 **§3.4 kollidiert mit der GC-Governance:** `ip address` und `ip firewall nat` stehen unter
|
||||
Drift-Kontrolle. Direkt gesetzt ⇒ **zwei `extra`-Drifts je AP**. Entweder vorher ins Soll heben
|
||||
(AP-Template/ConfigContext) oder die Drift bewusst als offene Transaktion führen.
|
||||
16. 🟡 **`A - AVAILABLE` in `/system package print` ist ein Download-Katalog**, kein Paket auf dem
|
||||
15. ✅ **ERLEDIGT 2026-08-31 — §3.4 kollidierte mit der GC-Governance:** `ip address` und
|
||||
`ip firewall nat` stehen unter Drift-Kontrolle, direkt gesetzt ergab das **zwei `extra`-Drifts
|
||||
je AP**. Sie sind jetzt **ins Soll gehoben** (AP-Template Block `[7]` + ConfigContext
|
||||
`ap.container`), **nicht** als Transaktion geführt: ein Dauerzustand gehört ins Template.
|
||||
Dazu kam die **28. ComplianceRule `interface-veth`** — vorher war das veth das tragende Stück
|
||||
**ohne jede Überwachung**. 🔴 **Falle darin:** der veth-Export trägt zwei gerätevergebene MACs;
|
||||
ohne Normalisierung (`ConfigReplace` `60-`/`61-veth-*`) erzeugt die Regel Dauer-Drift auf allen
|
||||
drei APs. Stand danach: **139/140**, übrig nur die offene TP25-Transaktion.
|
||||
16. 🔴 **Ein Golden-Config-Job meldet `SUCCESS` und kann trotzdem halb durchgelaufen sein.**
|
||||
Am 2026-08-31 fehlte nach dem ersten Compliance-Lauf genau **ein** Eintrag
|
||||
(`crs326-core`/`interface-veth`), Job-Status `SUCCESS`, im Job-Log dagegen
|
||||
`RENDER COMPLIANCE TASK GROUP failed: Broken pipe`. **Abnahme ist deshalb nicht die
|
||||
Konformitätsquote, sondern die ANZAHL der Einträge = Regeln × Geräte.** 139 statt 140 sieht
|
||||
aus wie „die neue Regel greift nicht" und ist ein halb gelaufener Job. Zweiter Lauf reichte.
|
||||
17. 🟡 **`A - AVAILABLE` in `/system package print` ist ein Download-Katalog**, kein Paket auf dem
|
||||
Gerät — `enable` würde einen Internet-Fetch auslösen (auf ap1/ap2 gesperrt). `.npk` bleibt der Weg.
|
||||
17. 🟡 **MikroMCPs `export_config` exportiert unvollständig** (301 B statt 6,2 KiB). Für Backups
|
||||
18. 🟡 **MikroMCPs `export_config` exportiert unvollständig** (301 B statt 6,2 KiB). Für Backups
|
||||
`/export file=…` per SSH verwenden. Nach zwei
|
||||
Reboots je AP lohnt der Blick — die Tabelle zeigte beim CAPsMAN-Ausfall 14 h lang zufriedene
|
||||
Clients ohne Adresse.
|
||||
|
||||
Reference in New Issue
Block a user