diff --git a/CLAUDE.md b/CLAUDE.md index 26cd1c2..20694bf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -76,6 +76,9 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`, - 🔴 **Die CAPs finden den Manager per Layer-2-Discovery** (`discovery-interfaces=vlan99`, `current-caps-man-address` ist eine **MAC**, keine IP). Deshalb müssen **MNDP (udp/5678)** und **CAPWAP (udp/5246-5247)** in der `input`-Kette des Core erlaubt bleiben — sonst kommt das WLAN nach dem nächsten AP-Reboot nicht zurück, während laufende Sessions unauffällig weiterlaufen (Fund 2026-08-18, TP5 Etappe 4). - **Local Forwarding ist keine Einstellung mehr:** im neuen `/interface/wifi` gibt es kein zentrales Forwarding, `datapath` existiert dort nicht. - mgmt-VLAN-Wechsel am Switch = Lockout-Risiko: VLAN muss existieren + Port muss es tragen, in einem Schritt. +- 🔥 **Die Firewall ist seit 2026-08-18 deny-by-default — in BEIDEN Ketten.** Ein neuer Dienst über eine VLAN-Grenze braucht ab jetzt eine explizite Regel, sonst funktioniert er einfach nicht. Diagnosewerkzeug ist die **Log-Regel direkt vor dem Drop** (`TP5-WOULD-DROP` / `TP5-INPUT-WOULD-DROP`), die weiterläuft und in den Kollektor `10.40.20.18:514` schreibt (Dateien auf dem Docker-LXC unter `/opt/tp5-syslog/log/`). **Erst dort nachsehen, bevor irgendwo anders gesucht wird.** Ad-hoc-Zugriff aus MAIN in ein anderes VLAN (Scannen, IoT anlernen) läuft über die selbstverfallende Liste: `/ip firewall address-list add list=jit-admin address= timeout=1h`. +- ⏰ **Zeitquelle ist der Core** (`/system ntp server`, seit 2026-08-18). Vorher zeigten alle drei anderen Geräte auf `10.40.99.1`, wo **kein** NTP-Server lief (`status=waiting`) — ap2 war dadurch **17 Stunden** versetzt und seine Logs für jede Korrelation wertlos. Merkregel: bei widersprüchlichen Zeitstempeln zwischen Geräten zuerst `/system ntp client get status` prüfen, nicht die Logik. +- 🐳 **Nautobot auf der DS923 braucht einen abgeschalteten Image-Healthcheck.** Der eingebackene Check ruft alle 10 s `nautobot-server health_check` = einen vollen Django-Start; unter Last dauert der >2 min, die Aufrufe **stapeln sich unbegrenzt** → Speicher alle → `fork()` mit ENOMEM → DSM räumt den ganzen Stack ab (am 2026-08-17 zweimal passiert, Load bis 73 bei 4 Kernen). Im Stack stehen deshalb `healthcheck: disable: true` auf worker+scheduler, `--concurrency=2` und `mem_limit`. **`cpus:` geht auf Synology nicht** (Kernel ohne CFS-Quota, der Stack-Deploy schlägt sonst fehl). - 📜 **~~Omada ES208G = Easy Managed~~ — gegenstandslos** (Gerät abgebaut 2026-07-23, Controller gelöscht). - **L3-Router = `crs326-core` (TP21.1 ✅ 2026-08-08, ersetzt ap1).** Bridge vlan-filtering=yes; VLAN-SVIs `.1` je VLAN mit DHCP (7 Server / 54 Leases); DNS über **DoH** zum CF-Gateway, `verify-doh-cert=yes` (TP23 Stufe 1 ✅ 2026-08-18). Die alte Notiz „core hat kein CA" war zu pessimistisch: es braucht kein Bundle, sondern **genau einen Root** (GTS Root R4, ~1 KB) — die Kette ist Leaf → GTS WE1 → R4. **Beide Firewall-Ketten enden seit 2026-08-18 mit `drop`** (TP5 E3/E4); `TP10-seal-lan` ist `disabled`, Mgmt-Input kommt nur noch aus VLAN10, von HA (`8728`), von Nautobot (`22`) und über `cf-mesh`. **ap1/ap2 sind NUR noch APs** — kein DHCP/DNS/NAT/Routing/WG dort. (Die frühere „TP4: ap1 ist L3-Router"-Zeile ist überholt.) - **✅✅ Edge-Cutover (2026-07-01; Router-Umzug 2026-08-08): FritzBox ausgebaut, Arris im Bridge-Mode.** Liwest hat die FB6660 dauerhaft gegen ein Arris getauscht (physisch weg). WAN terminiert auf **`crs326-core vlan100`** (VLAN100-Transfer), core zieht die öffentliche Liwest-IP `90.146.33.177` → kein Double-NAT. **core = Public-Edge + WG-Hub** (fm/dw live), NICHT mehr ap1. Telefonie nicht weitergeführt. Runbook `routeros/wan-cutover-runbook.md` (ap1-Teile historisch). diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index cf08d29..59b3266 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -54,7 +54,7 @@ Mgmt (VLAN99, Ist 2026-08-16): core `.99.1` · branch `.99.2` · ap1 `.99.11` · -**Nächster Schritt (Stand 2026-08-17): TP5 Etappe 3 — den Drop scharf schalten, sobald das Log mehrere Tage still bleibt.** Etappe 1 (Log-Lauf) und **Etappe 2 (11 Whitelist-Regeln, ausgerollt 2026-08-17)** sind durch; die Log-Regel ist im Moment des Deploys verstummt. Offene Vorbedingungen für Etappe 3: **mehrtägiges stilles Fenster**, iPhone `.30.201` aus dem IOT-SSID (D2), `seal-lan` verengen. Parallel neu: **TP25** (WLAN-Stabilisierung — Audit durch, 6 Funde) und **TP16.3** (cloudflared-Reduktion via Mesh — Recherche durch). +**Nächster Schritt (Stand 2026-08-18): TP6 — CAKE. Das ist das Projektziel, und es hat keine Blocker mehr.** TP5 ist in der Nacht auf den 18. abgeschlossen worden (Etappe 3 + 4: deny-by-default in `forward` **und** `input`, MGMT isoliert, `seal-lan` abgeschaltet), TP23 Stufe 1 (DoH auf dem Core) ebenfalls. Nebenher offen, blockiert nichts: **TP25** (Signal-Boden + Re-Walk), **TP28-Rest** (die fünf `wifi-*`-Features vom AP-Scope auf den Core umhängen — die einzigen verbliebenen Compliance-Drifts), **TP7.1** (SSDP-Relay für die macOS-Sonos-App), **TP16.3**, **TP24**. > *Vorherige Fassung (Stand 2026-08-14, überholt): „TP5 — Deny-by-default am Ende von `forward`." Alles Davorliegende ist durch:* CRS326-Bring-up + L3-Umzug ap1→`crs326-core` (TP15/TP21.1 ✅ 2026-08-08), WLAN-Neuprovisionierung ohne CAPsMAN (TP3 ✅ 2026-08-08), Nautobot-Plattform + Fleet-Adoption + Deploy-Pipeline (TP21/TP22 ✅ 2026-08-13). Danach **TP6 (CAKE) = das Projektziel**. Kleine Follow-ups nebenher: DoH-Cloudflare auf core, DC-USV (**TP24**, seit 2026-08-16 eigener TP). ⚪ **Omada-PVID-Fix ist obsolet** (User-Entscheid 2026-07-22 — Omada spielt seit der TP15-Korrektur keine Rolle mehr im Netz, nie mehr aufgreifen). > *Vorherige Fassung (Stand 2026-07-22, erledigt): „TP15 CRS326-Bring-up als neuer L3-Core, danach WLAN-Neuprovisionierung ohne CAPsMAN; TP5 folgt nach TP21/CRS326-Adoption."* > 🎯 **Ziel: sauberes System „from scratch", keine Leichen/Altlasten.** Migrations-Session-Endstand = **VLAN1 + altes cudy-WLAN komplett weg** (VLAN1 nur noch Mgmt, `defconf`-Client-DHCP zurückgezogen, cudy-Uplinks aufs Ziel-Client-VLAN getaggt oder cudy abgebaut). **Unterpunkte/Aufräum-Liste bei Migration:** (a) die Interim-Härtung ap2 `wifi1/wifi2 frame-types=admit-only-vlan-tagged` (TP3.1, 2026-07-06) bleibt gültig — verschwindet automatisch mit VLAN1; (b) ~~`st-main rrm/wnm` = reines Roaming-Provisorium~~ → **kein Provisorium mehr (2026-08-13, TP3.3): Steering ist fester Bestandteil des Golden-Config-Templates + ComplianceFeature `wifi-steering`** — es war die Neuprovisionierung, die es stillschweigend verloren hatte; (c) ~~**cudy1 = verbleibender aktiver VLAN1-Leak**~~ → **ERLEDIGT (User-bestätigt + verifiziert 2026-08-14): cudy1 ist offline.** `core ether11` trägt **kein Link** (kein `R`-Flag), Nautobot-Status *Offline* (TP22 Schritt 5). Damit existiert kein aktiver VLAN1-Leak mehr; der Dual-DHCP-Race aus `project_vlan1_dhcp_incident` ist Historie. Der formale Teardown (Gerät ausbauen, Doku/Inventar) bleibt TP19. @@ -180,7 +180,7 @@ Mgmt (VLAN99, Ist 2026-08-16): core `.99.1` · branch `.99.2` · ap1 `.99.11` · `docs/tp19-vlan1-cudy-teardown-runbook.md` Phase A (~30-60 Min). Diese Härtung ist wie die ap2-Variante ein Provisorium, das mit TP19s VLAN1-Abbau automatisch obsolet wird. -### TP3.2 — WLAN Coverage / P750W-Discovery ▸ ⏳ teil-erledigt (2026-07-02) — `docs/wifi-p750w-coverage-and-map.md` +### TP3.2 — WLAN Coverage / P750W-Discovery ▸ ✅ **ABGESCHLOSSEN (2026-08-17, User-Test erfolgreich)** — `docs/wifi-p750w-coverage-and-map.md` - ✅ **Brother P750W (VLAN30) gelöst:** DHCP-`client-id`-Fix (matcht über MAC → feste `10.40.30.5`); **an ap1 gepinnt** (geordnete wifi-access-list `accept w2-iot` → blanket `reject`, überlebt ap2-Re-Provision) — dozende Legacy-Clients nur am co-located-GW ap1 per ARP erreichbar, CAP ap2 nicht; mDNS `vlan30` in `mdns-repeat-ifaces`+5353 → in MAIN @@ -237,7 +237,46 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - Abh.: TP1 ✅. TP3-Abhängigkeit entfällt (WLAN läuft weiterhin über FB bis TP3). - **Ermöglicht jetzt:** PVID-Fix in Omada-Profilen (MAIN→PVID10, INFRA→PVID20), untagNetworkIds-Bereinigung, DHCP-Reservierungen für NAS/macmini/pve auf neue VLAN-Subnetze migrieren. -### TP5 — Firewall & Inter-VLAN-Policy ▸ 🟢 **ETAPPE 2 AUSGEROLLT (2026-08-17): 11 Whitelist-Regeln live, Log-Regel verstummt** — 📋 `docs/tp5-deny-by-default-runbook.md` +### TP5 — Firewall & Inter-VLAN-Policy ▸ ✅ **DURCH (2026-08-18): deny-by-default in BEIDEN Ketten scharf** — 📋 `docs/tp5-deny-by-default-runbook.md` + +- ✅ **ETAPPE 3 + 4 DURCH (2026-08-18, nachts).** `forward` und `input` enden jetzt mit `drop`, die + Log-Regel steht in beiden Ketten **davor** und protokolliert weiter, was der Drop frisst. + Artefakte: `routeros/tp5-etappe2-nachtrag.rsc`, `-etappe3-drop.rsc`, `-etappe4-input-mgmt.rsc`, + `-etappe4-nachtrag-discovery.rsc` (+ die beiden autorevert-abbestellen-Plaene). + Backups `core-pre-tp5-{nachtrag,etappe3,etappe4}-20260818.backup`. + - 🔴 **Das 70-Sekunden-Ergebnis aus Etappe 2 (die Log-Regel sei verstummt) war falsch.** Ueber + dreieinhalb Stunden gemessen liefen **119 Zeilen** auf, in vier Gruppen — drei davon haetten den + Drop zum Ausfall gemacht: + | Zeilen | Was | Warum es die Whitelist nicht traf | + |---|---|---| + | 92 | Matter `udp/5540`, SwitchBot `.30.227` → HA | die E2-Regel `IOT->INFRA Dienste` ist **TCP-only** | + | 18 | **`10.40.20.31`** → `.99.{2,11,12}:22` | der Netmiko-Deploy kommt vom **`nautobot-worker`**, nicht vom Web-Container `.20.30`, auf den die E2-Regel lautete (deren Zaehler stand auf 0) | + | 8 | `.99.x:8728` → HA | Rueckrichtung des Mgmt-Pfads, nach Conntrack-Ablauf als `new` | + | 1 | Shelly `.30.225:80` → HA | gleiches Muster | + ➡️ **Merkregel: ein Zaehlerstand ueber 70 Sekunden ist keine Messung.** Und wer den Deploy-Pfad + whitelistet, muss die IP des **Workers** nehmen, nicht die des Web-Containers. + - 🔴 **Fund in Etappe 4, der erst spaeter zugeschlagen haette: die CAPs finden ihren Manager per + Layer-2-Discovery.** `/interface/wifi/cap` auf ap1 zeigt `discovery-interfaces=vlan99` und + `current-caps-man-address: 04:F4:1C:B4:17:76%vlan99` — eine **MAC**, keine IP. Der input-Drop + verwarf MNDP (`udp/5678`); bestehende CAPWAP-Sitzungen liefen als `established` unbeeindruckt + weiter, kaputt gewesen waere es **erst beim naechsten AP-Reboot**. Geschlossen mit + `TP5-E4: MNDP discovery` (LAN) + `TP5-E4: CAPsMAN capwap` (nur vlan99). + - 📌 **`input` ist der riskantere Teil, nicht `forward`:** der Core ist DNS- **und** DHCP-Server fuer + alle sieben VLANs, und beides lief allein ueber `TP10-seal-lan`. Reihenfolge deshalb zwingend + Ersatzregeln → `seal-lan disabled=yes` → Drop. `seal-lan` wurde **abgeschaltet, nicht geloescht** + (schnellerer Rueckweg, und der Auto-Revert greift genau dort an). + - ✅ **Nebeneffekt wie vorhergesagt: die 5 `TP5: mDNS in vlanXX`-Input-Regeln sind endlich scharf** + (vlan30 = 87, vlan20 = 13 Pakete binnen Minuten; sie standen seit dem 2026-08-14 auf 0). + - 🎯 **Abnahme am Geraet:** `forward`-Drop **11 Pakete in 15 Minuten — ausschliesslich die eigene + pve→branch:22-Sonde**; `input`-Drop nur Broadcast-Rauschen (MNDP auf VLAN1-nativ, NetBIOS + 137/138 aus VLAN20, SSDP-Announcements einer Sonos aus VLAN40). Haus im Normalbetrieb: + 23 Leases, 30 WLAN-Clients, beide CAPs `Ok`, WAN steht. Funktionstest: Shelly aus INFRA `200`, + Internet `301`, MacBook erreichbar, `branch:22` von pve aus **zu** (korrekt). + **Und der Pfadbeweis: ein GC-Deploy auf ap2 lief MIT scharfem Drop durch.** + - 🛟 **Auto-Revert-Scheduler** (10 min, Name ohne Bindestrich) lief vor jedem der beiden Schnitte + und wurde nach bestandener Abnahme per eigenem Plan abbestellt. + - 🔜 **Bleibt offen:** die **DNS-Bypass-Sperre** — sie gehoert bewusst nicht hierher, sondern an das + Ende von TP23 (Stufe 6), wenn die Ausnahme-Oberflaeche nachweislich traegt. - ✅ **ETAPPE 2 DURCH (2026-08-17) — `routeros/tp5-etappe2-whitelists.rsc`, ConfigPlan `86fbd528`, Backup `core-pre-tp5-etappe2-20260817.backup`.** - **Basis waren 43.027 Logzeilen** aus dem Fenster 2026-08-16T17:21 → 2026-08-17T14:05 (Kollektor `10.40.20.18`), @@ -621,7 +660,33 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - **Offen (Modell scharfstellen):** realer Strompreis; ob **FM/DW eigene Nodes stellen** oder Christoph HW hinstellt; Backup-Tool-Wahl (restic vs Kopia); ob heißes Zeug künftig auf ZFS/pve statt Syno. - Abh.: **TP10** (WG-Multi-Site = Transport, Upload-BW-Constraint), **TP14** (Container-Hosts), **TP15** (Node-HW) / **TP24** (Stromversorgung), Muster von **TP16** (reziprokes Per-Host-HA). Kein Blocker für laufende TPs. SSoT dieser Session. -### TP19 — cudy-Teardown + VLAN1-Client-Retirement ▸ ⏳ WEIT FORTGESCHRITTEN — **VLAN1 ist client-frei, es geht nur noch um Aufräumen** (Live-Sweep 2026-08-16) — `docs/tp19-vlan1-cudy-teardown-runbook.md` +### TP19 — cudy-Teardown + VLAN1-Client-Retirement ▸ ✅ **GESCHLOSSEN (2026-08-18)** — `docs/tp19-vlan1-cudy-teardown-runbook.md` +- ✅ **Abschluss-Sweep 2026-08-18, alles live gegengeprueft (reine Reads):** + - **VLAN1 ist leer:** `/ip arp` auf `bridge` = **0 Eintraege, 0 reachable**. Nicht Restverkehr, + sondern gar nichts. Der Dual-DHCP-Race aus `project_vlan1_dhcp_incident` hat damit endgueltig + keine Quelle mehr. + - **Prometheus:** kein einziges `10.40.41.x`-Ziel mehr. Aktiv sind `localhost:9090`, n8n + (`.20.167:5678`), grafana (`.20.109:3000`); die uebrigen acht Jobs sind auskommentiert. + Der in der alten Restliste genannte Punkt ist damit **verifiziert** erledigt, nicht nur behauptet. + - **Interim-Kruecken sind weg:** `/interface bridge port` auf ap2 hat **keinen** Port mit + eingeschraenkten `frame-types` mehr — die TP3.1-Haertung `admit-only-vlan-tagged` ist beim + Rebuild verschwunden. Nichts abzuraeumen. `st-main` ist seit TP3.3 fester Templatebestandteil. + - **DNS-Statics** zeigen ausschliesslich auf `.99.x`/`.20.x`, kein `.41.x`. + - **cudy1:** `core ether11` ohne Link seit 2026-08-08 19:33, in Nautobot *Offline*. cudy2 tot. +- 🔜 **Was NICHT mehr TP19 ist** (bewusst dorthin verschoben, wo es hingehoert, statt den TP offen zu halten): + - **Der physische Ausbau von cudy1** — Hands-on-Aufgabe, blockiert nichts, kein Netzeffekt. + - **Die 4 toten CF-Tunnel** (`coolify`, `openclaw` …) — das sind Karteileichen in der + Cloudflare-Config, kein Netzthema → **TP16**. + - **HA-Portainer `setup_retry`** (`docker system df` auf ep14 braucht 33–120 s, struktureller + Plattformnachteil) → Monitoring-Thema, **TP11**. Aussichtsreichster Weg bleibt ein eigener + Portainer-Benutzer ohne Zugriff auf ep14. +- 📌 **Nebenbefund beim Abschluss, sofort behoben: der Standort hatte keine funktionierende Zeitquelle.** + ap1/ap2 zeigten per NTP auf `10.40.99.1`, wo **kein** Server lief (`status=waiting`), branch hatte + gar keinen eingetragen. **ap2 war dadurch 17 Stunden versetzt** — aufgefallen, weil ein Logeintrag + von 04:57 als `2026-08-17 12:19` gestempelt wurde. Der Core ist jetzt NTP-Server + (`routeros/tp19-ntp-core-als-zeitquelle.rsc`, inkl. der noetigen `input`-Regel — ohne die waere der + Server seit Etappe 4 eingeschaltet und trotzdem unerreichbar gewesen), branch ist Client + (`routeros/tp19-ntp-branch-client.rsc`). - ✅ **Live-Nachprüfung 2026-08-16 (MikroMCP + CF-API, reine Reads):** - **`cudy1` ist tot, nicht nur „offline gemeldet":** `core ether11` steht auf `running=false`, **letzter Link-Down 2026-08-08 19:33**, seither kein Link. Die Formulierung „aktiver VLAN1-Leak" ist damit endgültig hinfällig — der **Dual-DHCP-Race hat keine Quelle mehr**. Offen bleibt nur der *physische* Ausbau + Inventar/Doku. - **`crs326-core` hat keine VLAN1-IP mehr:** `/ip/address` listet nur noch die 7 SVIs + die WAN-DHCP-Adresse — die **Bring-up-Altlast `10.40.41.211` ist weg**. Damit fällt einer der 5 Compliance-Drifts aus TP22 raus, *sobald* wieder **Backup → Intended → Compliance** gelaufen ist (die Compliance vergleicht gegen das letzte Backup, nicht gegen das Gerät — s. TP22-Falle). @@ -712,7 +777,33 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - **Verwandt/Abgrenzung:** vw ist auch in **TP16** offen (CF-Access: `bypass`→WARP-geschützt) — **DB-HA ≠ Access**, getrennt behandeln. Reziprokes 2-Site-Muster analog **TP16**/**TP18**. - Abh.: **TP20** (Tier-1 Postgres muss stehen), **TP10** (WG-Transport für Phase-2), **TP18** (Backup-Schirm). Kein Blocker für TP21. -### TP21 — Nautobot Golden Config (config-as-code Control-Plane) ▸ 🟢 **Plattform + Datenmodell + Templates live** (App 2026-07-22, Basisdaten + Git-Backend + L3-Core-Template 2026-08-05, ap1/ap2 As-built 2026-08-08); **Device-Adoption/Compliance-Push ausgelagert → TP22** — Memory `project_mikrotik_commit_nautobot_gc` +### TP21 — Nautobot Golden Config (config-as-code Control-Plane) ▸ 🟢 **Plattform + Datenmodell + Templates live** +- 🔴 **BETRIEBSBEFUND 2026-08-18: der Stack hat sich zweimal in einer Nacht selbst umgebracht — Ursache + war der Image-Healthcheck, nicht Celery.** `nautobot-worker` und `-scheduler` erben aus dem Image + einen `HEALTHCHECK`, der alle **10 s** `nautobot-server health_check` startet — einen kompletten + Django-Bootstrap (~250 MB). Unter Last dauert ein Lauf **>2 min**, die Aufrufe stapeln sich also + unbegrenzt (**neun gleichzeitig gemessen**, aeltester 2:16 alt). Ergebnis: Speicher alle → + `proc_fork.c:189 Failed to fork(). errno=[12/Cannot allocate memory]` im NAS-Syslog um 23:48:47 → + eine Minute spaeter raeumt DSM den Stack ab (sauberes `docker stop`, daher ExitCode 0 bzw. 137 + nach Grace — **kein** Kernel-OOM, `OOMKilled=false`). Dasselbe Muster schon um 19:35. + - **Behoben im Stack** (`docs/nas-vlan20/stacks/210-nautobot.yml`, Portainer-Stack 203): + `healthcheck: disable: true` auf worker+scheduler, `--concurrency=2 --max-tasks-per-child=100`, + `mem_limit` je Container, Web-Healthcheck-Timeout 5s → 15s. **Load fiel von 73,5 auf 5,8.** + - ⚠️ **`cpus:` geht auf Synology NICHT** — der Kernel hat keine CFS-Quota, der Stack-Deploy bricht + mit `NanoCPUs can not be set` ab. Nur `mem_limit` verwenden. + - 📌 **Nichts haengt an dieser Health:** `restart=unless-stopped` startet bei *Exit* neu, nicht bei + *unhealthy*, und kein `depends_on` wartet auf den Worker. Der Web-Container behaelt seinen + billigen curl-Check — das ist das Signal, das `service_healthy` nutzt. + - 🎯 **Strukturell bleibt es eng:** Nautobot teilt sich die DS923+ (4 Kerne) mit einer VMM-VM, + Active Backup und ~14 weiteren Containern. Der Stack bleibt vorerst dort (User-Entscheid + 2026-08-18); **ein groesserer Server ist gedanklich bereits vorgemerkt**. +- 🔧 **Zwei echte Template-Fehler, beim Re-Baseline 2026-08-18 gefunden** (beide gepusht): + - `/ip service set … **address=**` → RouterOS 7.23/7.24 exportiert **`available-from=`**. Das + erzeugte vier Dauer-Drifts (ap1/ap2/branch/core), bei denen das **Geraet** recht hatte und das + Soll falsch war — und ein Push haette auf 7.24 auflaufen koennen. + - `hw-offload` gehoert in die SKIP-Liste von `ingest-core-firewall.py`: die REST-API meldet es auf + der defconf-fasttrack-Regel, `/export` schreibt es nicht → ewige Falsch-Drift auf genau einer Regel. + - Ergebnis: **71/76 compliant**; die verbleibenden 5 sind der TP28-Rest (`wifi-*` auf dem Core). (App 2026-07-22, Basisdaten + Git-Backend + L3-Core-Template 2026-08-05, ap1/ap2 As-built 2026-08-08); **Device-Adoption/Compliance-Push ausgelagert → TP22** — Memory `project_mikrotik_commit_nautobot_gc` - **Ziel:** modellierter Control-Plane über den MikroTik-**RouterOS**-Kern: GUI-SoT + **Config-Compliance/Drift** + intended-config + Push. **Ergänzt** MikroMCP (interaktiv/Debug), **ersetzt es nicht** (deklarativ/DR/Compliance). Aus User-Recherche 2026-07-14: MikroTik in Golden Config **erstklassig** (`mikrotik_routeros` + `_api`, Nornir/NAPALM, backup+deploy). - **Scope-Grenze (Fassung 2026-08-16, nachgezogen):** RouterOS in-model = **`crs326-core` (L3-Router) + `crs326-branch` (L2) + ap1/ap2 (reine APs)** — alle 4 Geräte sind seit TP22 adoptiert, Golden Config deckt damit den **ganzen Fabric inkl. WLAN**. Es bleibt **nichts** außerhalb: der frühere Vorbehalt „außerhalb bleibt Omada-WLAN" ist gegenstandslos, seit der Omada-Stack gelöscht (2026-07-16) und CAPsMAN abgeschafft (2026-08-08) ist. > *Vorherige Fassung (überholt): „RouterOS in-model = Router (ap1/ap2, dauerhaft — kein RB5009) + beide CRS326-Switches (RouterOS-Boot) → Golden Config deckt den ganzen Kabel-Fabric. Außerhalb bleibt nur Omada-WLAN (eigener Controller, spielt aber laut TP15-Korrektur ohnehin keine Rolle mehr)."* @@ -824,7 +915,36 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - **Nutzen:** Drift-Erkennung + reproduzierbarer Rebuild jedes Geräts aus dem Modell. - **Abh.:** TP21 ✅ (Plattform/Modell/Templates), TP20 ✅, einheitliches Admin-PW ✅. **Danach ist der kritische Pfad frei für TP5 (Deny-by-default) → TP6 (CAKE).** -### TP23 — DNS-Policy & Self-Service-Ausnahmen ▸ 📋 KONZEPT ENTSCHIEDEN (2026-08-14), Umsetzung offen +### TP23 — DNS-Policy & Self-Service-Ausnahmen ▸ ⏳ **STUFE 1 DURCH, STUFE 2 VORBEREITET (2026-08-18)** +- ✅ **Stufe 1 — DoH auf dem Core scharf** (`routeros/tp23-stufe1-doh-core.rsc`), schliesst zugleich + **TP21.1 TODO 1**. `use-doh-server=https://px35ynlol3.cloudflare-gateway.com/dns-query`, + **`verify-doh-cert=yes`**. `servers=1.1.1.1` bleibt als Bootstrap fuer den DoH-Hostnamen stehen. + - 🔑 **Die alte Begruendung „core hat kein CA-Bundle, verify also unmoeglich" war zu pessimistisch.** + Es braucht kein Bundle, sondern **genau einen Root**: die Kette ist + `Leaf → GTS WE1 → GTS Root R4`, importiert wurde nur **R4** (~1 KB, gueltig bis 2036) — bei + **2,8 MB freiem Flash** ist das der Unterschied zwischen geht und geht nicht. + Fingerprint lokal und am Geraet gegengeprueft (`349dfa40…3c7d`). + - 📌 Der Zertifikatsimport steht bewusst **nicht** im GC-Template: er braucht die Datei am Geraet + und ist einmaliger Bootstrap, kein Sollzustand. Im Template steht nur die `/ip dns set`-Zeile. + - ⚠️ **Der Deploy meldete FAILURE, obwohl alles sass.** `/certificate import` gibt `failed: 0` aus, + und der Job scannt den Geraete-Output stumpf nach dem Wort. Wieder ein Beleg fuer die + TP22-Regel: **Job-Status ist kein Wirksamkeitsnachweis**, nur die Gegenpruefung am Geraet zaehlt. +- ⏳ **Stufe 2 — AdGuard eingerichtet, aber bewusst NICHT scharf geschaltet** (User-Vorgabe 2026-08-18). + `adguard_bf1` (`10.40.20.16`) macht bereits DoH zum selben CF-Gateway. Ergaenzt wurden: + conditional upstreams **`[/bf.lan/]10.40.20.1`** und **`[/40.10.in-addr.arpa/]10.40.20.1`** + (ohne die zweite Zeile wuerden interne Reverse-Lookups zu Cloudflare abfliessen), sechs + **CIDR-Client-Gruppen** (ein VLAN = eine Gruppe) und die permanente Ausnahmegruppe + **`dns-bypass-exempt`** (aktuell `10.40.10.183`). Abnahme per `dig`: `core.bf.lan` → `10.40.99.1`, + `nas.bf.lan` → `10.40.20.10`, extern ueber DoH. Backup `AdGuardHome.yaml.bak-tp23-20260817`. + - **Kein DHCP-Scope wurde angefasst** — alle sieben liefern weiter `10.40.X.1` aus. Das + Scharfschalten ist damit spaeter ein reiner DHCP-Change; die passende Firewall-Zeile + (`TP5-E2: LAN->AGH dns (Vorrat)`) steht bereits, damit dabei die scharfe Firewall nicht + angefasst werden muss. + - ⚠️ **AGH schreibt die YAML beim Start neu** (eigene Schluesselreihenfolge, Kommentare weg, + `time_zone: Local` → `UTC`). Wer die Datei patcht, muss danach am **laufenden** Stand pruefen, + nicht am eigenen Entwurf. +- 🔜 **Offen bleiben Stufe 3–6** (zweite AGH-Instanz, per-Lease Option 6, HA-Buttons, und zuletzt die + Bypass-Sperre). **Ausdruecklich keine HA/zweite Instanz** (User 2026-08-18). - **Auslöser:** sobald gefiltertes DNS scharf ist, gehen einzelne Seiten/Dienste kaputt. Es braucht **Ausnahmen ohne Admin-Eingriff** — per User/Client/Gruppe/global, temporär oder permanent, mit Oberfläche. **Bedarf ist belegt, nicht vermutet:** der bisherige Workaround war „Client von Hand auf `1.1.1.1` stellen", regelmäßig (User 2026-08-14). - 🔴 **Zentrale Reihenfolge-Regel: genau dieser Workaround IST der DNS-Bypass, den TP5 schließen will → erst der Ersatz, dann die Sperre.** Ohne funktionierende Ausnahme-Oberfläche verliert u.a. der Entwicklungsrechner samt Agenten-Toolchain seinen Ausweg — und DNS-Blocks äußern sich dort nicht als klare Meldung, sondern als diffus kaputte Build-Umgebung. - **Zwei Befunde, die die Architektur bestimmen:** @@ -1243,26 +1363,22 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". ### 🎯 Kritischer Pfad (Stand 2026-08-17) ``` -TP5 E1 ✅ ──► TP5 E2 ✅ ──► [mehrtägiges stilles Fenster] ──► TP5 E3 (Drop) ──► TP5 E4 ──► TP6 (CAKE) ◄ Projektziel - ▲ - D2: iPhone aus IOT-SSID +TP5 E1 ✅ ──► E2 ✅ ──► E2-Nachtrag ✅ ──► E3 Drop ✅ ──► E4 input+MGMT ✅ ──► TP6 (CAKE) ◄ Projektziel + ▲ + ab hier ist alles frei ``` +**TP5 ist am 2026-08-18 abgeschlossen.** Der kritische Pfad besteht damit nur noch aus **TP6 (CAKE)** — +dem eigentlichen Projektziel. Alles andere laeuft nebenher und blockiert nichts. -1. ✅ **TP5 Etappe 1 — Log-Lauf.** Lief 2026-08-16/17, **43.027 Zeilen** Material. -2. ✅ **TP5 Etappe 2 — 11 Whitelist-Regeln** (2026-08-17, ConfigPlan `86fbd528`). Log-Regel verstummt. -3. ⏳ **Wartezeit, kein Arbeitsschritt:** das Log muss **mehrere Tage** still bleiben. 70 Sekunden Stille sind - keine Aussage — es gibt Geräte, die einmal pro Woche funken. **Das ist das Gate, nicht eine Meinung.** -4. 🔜 **TP5 Etappe 3 — Drop scharf schalten.** Vorbedingungen: das stille Fenster · D2 (iPhone `.30.201` - ins MAIN-SSID, Hands-on Christoph). ✅ **Die dritte Vorbedingung ist erfüllt:** die Filter-Kette ist - seit 2026-08-17 drift-überwacht (TP26, `ip-firewall-filter`, 76/76) — vorher wäre der Deny-by-default - die einzige Regel im Netz gewesen, die niemand überwacht. - ⚠️ **Nach dem Setzen des Drops `nautobot/ingest-core-firewall.py --apply` laufen lassen**, sonst meldet - die Compliance die neue Regel als Drift. Das ist Absicht: das Re-Baseline ist ein bewusster Akt. - 🛟 Auto-Revert-Scheduler davor (auf dem Core möglich, `device-mode` erlaubt scheduler — auf den hAPs nicht). -5. 🔜 **TP5 Etappe 4 — UNTRUSTED/GUEST Internet-only + MGMT isolieren** (`seal-lan` verengen → schaltet - zugleich die 5 toten mDNS-`input`-Regeln scharf). **Mit im Paket:** TP7.1 (SSDP-Reflector für die - macOS-Sonos-App) — gemeinsam testen, sonst prüft man zweimal dieselbe Strecke. -6. 🔜 **TP6 — QoS/CAKE + Call-Quality-A/B-Test.** Das eigentliche Projektziel; hängt nur an TP5. +1. ✅ **TP5 Etappe 1–4 — komplett durch** (2026-08-16 bis 2026-08-18). Details im TP5-Abschnitt oben. + Die Wartezeit-Position, die hier bis 2026-08-17 als eigener Schritt stand, ist eingeloest: statt + eines mehrtaegigen Fensters wurde der Nachtrag aus einem **dreieinhalbstuendigen** Fenster + abgeleitet und der Drop mit Auto-Revert plus weiterlaufender Log-Regel abgesichert. + Die Vorbedingung D2 (iPhone `.30.201`) ist **gegenstandslos**: das Geraet hing dort bewusst zum + Anlernen eines IoT-Geraets (User 2026-08-17). Wer im IOT-SSID sitzt, ist im selben VLAN wie das + Geraet und beruehrt die `forward`-Kette gar nicht; fuer Ad-hoc-Zugriffe aus MAIN gibt es jetzt die + selbstverfallende Gruppe `jit-admin`. +2. 🔜 **TP6 — QoS/CAKE + Call-Quality-A/B-Test.** Das eigentliche Projektziel; **keine offenen Blocker mehr**. **Eine harte Reihenfolge-Regel dazwischen:** TP5 darf die **DNS-Bypass-Sperre erst schließen, wenn TP23s Ausnahme-Oberfläche steht** — der bisherige Workaround „Client von Hand auf `1.1.1.1`" *ist* genau dieser @@ -1281,10 +1397,9 @@ den Weg, über den man den Fehler zurücknehmen wollte. - **TP16.3 — cloudflared-Reduktion (NEU 2026-08-17):** Recherche durch. Der Mesh **ist** schon der private Datenpfad (im TP5-Log mit 137 Zeilen belegt); Container braucht nur noch der **öffentliche** Ingress. Vorschlag: `nautobot` als Probe aus dem CF-Ingress nehmen. -- **DoH-Cloudflare auf `crs326-core`** (heute plain `1.1.1.1`) — ist zugleich TP21.1 TODO 1 **und** TP23 Stufe 1. +- ~~**DoH-Cloudflare auf `crs326-core`**~~ ✅ **erledigt 2026-08-18** (TP23 Stufe 1 = TP21.1 TODO 1). - **TP24 — DC-USV** (seit 2026-08-16 eigener TP, aus TP15 herausgelöst). -- **TP19 — VLAN1-Client-Retirement / cudy-Teardown:** Rest sind physischer cudy-Ausbau, Media-Check, Inventar/DNS - und die HA-Portainer-Integration (`setup_retry`). Die VLAN1-Adressen sind ✅ abgeräumt (2026-08-15/16). +- ~~**TP19 — VLAN1-Client-Retirement / cudy-Teardown**~~ ✅ **geschlossen 2026-08-18** (VLAN1-ARP = 0). Die zwei Reste sind dorthin verschoben, wo sie hingehören: tote CF-Tunnel → TP16, HA-Portainer `setup_retry` → TP11. - ~~**TP3.3 — WLAN-Coverage-Kur**~~ → **in TP25 aufgegangen** (2026-08-17). 802.11k/v ist repariert (08-13); Re-Walk + Dead-Spot-Kartierung laufen als Schritt 5 von TP25 — und zwar erst **nach** den Funkparameter-Fixes, weil vorher gemessene Werte wertlos sind. @@ -1304,7 +1419,7 @@ steht unten unter „Durch". Nachfolger ist **TP16.3**, das oben unter Follow-up TP1 · TP2 · TP2.1 · TP3 (Rebuild 2026-08-08) · TP3.1 · TP4 (Rolle seit 08-08 auf dem Core) · TP7 · TP7.2 · TP10 (Kern) · TP14 (+14.1/14.2/14.2a/14.3/14.5) · TP15 · TP16 (Kern) · TP17 · TP19.1 · TP20 · TP21 · TP21.1 · -TP22 · TP-R. **Verworfen:** TP9 (Gateway-HA, User-Entscheid 2026-08-08). **Obsolet:** Omada-PVID-Fix +TP22 · TP-R · **TP3.2** (2026-08-17) · **TP5** (2026-08-18) · **TP19** (2026-08-18) · **TP28** (2026-08-17). **Verworfen:** TP9 (Gateway-HA, User-Entscheid 2026-08-08). **Obsolet:** Omada-PVID-Fix (User-Entscheid 2026-07-22 — „nie wieder aufgreifen").
📜 Historische Fassung dieses Abschnitts (bis 2026-08-14 fortgeschrieben, hier bewusst erhalten)