TP5-Session vorbereitet + Statuskorrekturen (TV-Beweis, TP19.1, Ist-Stand)

TP5 (Deny-by-default) ist nach TP22 der kritische Pfad und jetzt einsatzbereit
vorbereitet — auf Live-Erhebung von crs326-core statt aus der Doku.

Neu:
- docs/tp5-deny-by-default-runbook.md: Ist-Stand forward/input/NAT/Interface-
  Listen, Inter-VLAN-Flow-Matrix aus conntrack + Countern, offene Entscheidungen
  D1–D6, 4 Etappen (Etappe 1 = reiner Log-Lauf ohne Blockierung), Rollback.
- docs/doku-cleanup-session.md: Arbeitsliste A–E für die Aufräum-Session
  (Ist-Stand-Block, Reihenfolge-Liste, stale "ap1 = Router"/CAPsMAN-Aussagen).

Statuskorrekturen in teilprojekte.md:
- TP21.1 Punkt 4: TV-End-to-End-Beweis erbracht (Ping 5/5, MAC auf ether4/VID40
  gelernt, RX 1.338 -> 6.909 Pakete). Das Kabel-Follow-up entfaellt — geloest
  wurde am Port, nicht am Kabel.
- TP19.1: WIP -> erledigt (ap2 seit TP3-Rebuild auf .99.12, sw1/sw2 ausgebaut
  und in Nautobot Decommissioned).
- TP5: Holes + WAN-Seal auf crs326-core re-verifiziert — die Verifikation vom
  2026-07-02 galt ap1, das seit 2026-08-08 Werksreset ist. Befund: die 5
  mDNS-Input-Regeln sind hinter TP10-seal-lan wirkungslos (0 Pakete).
- Ist-Stand-Block als Historie markiert, "Naechster Schritt" auf TP5 -> TP6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 16:19:00 +02:00
parent e17e45db91
commit cbef32ca11
3 changed files with 293 additions and 10 deletions

View File

@@ -0,0 +1,102 @@
# Doku-Aufräum-Session — `teilprojekte.md` auf den Stand nach dem Core-Cutover bringen
> **Vorbereitet 2026-08-14.** Reine Doku-Session, **kein** Netz-Eingriff, kein Gerät wird angefasst.
> Auslöser: `docs/teilprojekte.md` beschreibt an mehreren Stellen noch die Topologie **vor** dem
> 2026-08-08 (ap1 = Router, sw1/sw2 lebendig, Omada aktiv, CAPsMAN). Das Dokument sagt über sich
> selbst: *„ganze Liste braucht mal eine Aufräum-Session"* — das hier ist sie.
## Warum das kein Kosmetik-Thema ist
`CLAUDE.md` schickt **jede** frische TP-Session zuerst in `docs/teilprojekte.md` („kein anderer Kontext nötig").
Steht dort ein überholter Ist-Stand, plant die Session Arbeit ein, die es nicht mehr gibt — oder trifft
Entscheidungen auf Basis einer Topologie, die seit einer Woche nicht mehr existiert. Am 2026-08-14 sind
beim Statusbaum vier solcher Stellen aufgefallen und sofort korrigiert worden; die Liste unten ist der Rest.
## Leitplanken (Projektkonvention, gilt für die ganze Session)
- **Fortschreiben, nicht überschreiben.** Historie bleibt lesbar — durchstreichen + datierter Nachtrag,
so wie es TP1/TP2 mit ihrer Geräte-Abkündigung schon machen. Ein Doku-Stand, aus dem man nicht mehr
rekonstruieren kann, *warum* etwas entschieden wurde, ist schlechter als ein veralteter.
- **Quelle ist das Gerät, nicht die Doku.** Wo ein Ist-Stand behauptet wird, vorher per MikroMCP nachsehen
(dieselbe Regel, an der TP22 Schritt 5 hing).
- **Zusammengehörige Marker mitziehen:** Header-Marker, `Abh.:`-Zeile und die Erwähnung in
„Reihenfolge / Abhängigkeiten" driften sonst auseinander.
---
## Arbeitsliste
### A — Der „Ist-Stand (Kurz)"-Block (Zeilen 21–25) 🔴 höchste Wirkung
Vier von fünf Zeilen sind Historie: ALLNET `.11` als lebender Core, Omada-Controller `.175` „🟢 live"
(Container am 2026-07-16 gelöscht), ap1 `.1` als Router + WAN-Edge, der Edge-Cutover-Pfad über `sw1 gi16`.
Am 2026-08-14 wurde ein ⚠️-Vorspann davorgesetzt, der den Block als Historie markiert — **die Neufassung
steht aus.**
**Zu tun:** Block neu schreiben gegen den echten Stand (`crs326-core` = L3 `.99.1` / WAN `vlan100` /
`90.146.33.177`, `crs326-branch` `.99.2`, ap1 `.99.11` + ap2 `.99.12` = reine APs, Nautobot GC als
Config-Weg). Alte Fassung als datiertes Zitat darunter. **Danach den ⚠️-Vorspann entfernen** — er ist
ausdrücklich ein Provisorium.
### B — „Reihenfolge / Abhängigkeiten" (Zeilen ~664 ff.)
Die nummerierte Liste 1–7 ist inhaltlich tot, wird aber noch als Reihenfolge gelesen:
- **Punkt 3** („Jetzt: Omada-PVID-Fix") — obsolet, Omada ist raus (User-Entscheid 2026-07-22, „nie wieder aufgreifen").
- **Punkt 4** — TP5→TP6 stimmt inhaltlich, steht aber unter „Dann:" hinter einem obsoleten Punkt.
- **Punkt 7** — „TP20 hängt an TP18 ①" ist überholt (Abhängigkeit am 2026-07-16 entfernt).
**Zu tun:** Liste auf den tatsächlichen Rest-Pfad eindampfen (**TP5 → TP6**, daneben TP19-Restarbeiten und
die Research-getriebenen TPs), Erledigtes als durchgestrichene Historie behalten.
### C — Stale „ap1 = Router"-Aussagen in noch aktiven TPs
Diese TPs sind **nicht** abgeschlossen, tragen aber die alte Rollenverteilung — hier ist das Risiko am
größten, weil sie noch gelesen und umgesetzt werden:
| Stelle | Was dort steht | Realität |
|---|---|---|
| **TP16.1** (~Z. 431) | „Router bleibt ap1/ap2 rein für L3/WLAN" | ap1/ap2 sind reine APs; L3 = core |
| **TP21** Scope-Grenze (~Z. 548) | „Router (ap1/ap2, dauerhaft) + beide CRS326"; „außerhalb bleibt Omada-WLAN" | Omada existiert nicht mehr; Rollen vertauscht |
| **TP15** (~Z. 384) | „WLAN bleibt hAP ax²/**CAPsMAN**" | CAPsMAN am 2026-08-08 abgeschafft |
| **TP15** Header (~Z. 364) | „Core-Tausch **vorbereitet**, Cutover = nächstes Wartungsfenster" | Cutover am 2026-08-08 vollzogen (TP21.1) |
| **TP15** (~Z. 372) | „🔜 Als Nächstes: Core-Tausch = L3-Umzug" | erledigt |
| **TP4** Header | „hAP#1 = Router + WAN-Edge" | Rolle auf `crs326-core` (Teil-Nachtrag existiert bereits) |
### D — Kleinkram mit eigener Halbwertszeit
- **TP14.3** listet als offen: verwaister `omada-mcp`-Eintrag in `~/.claude.json` (Server connectet nie mehr)
+ ungeprüfte CF-Ingress-Reste `omada`/`omada-mcp`. Beides in 10 Minuten erledigt oder abgehakt.
- **TP19** trägt noch cudy1 als „aktiver VLAN1-Leak" — laut TP22 Schritt 5 hat `core ether11` **keinen Link**,
Nautobot-Status *Offline*. Verifizieren, dann Formulierung angleichen.
- **Zeile 27** (Ziel-Absatz) nennt die ap2-`frame-types`-Härtung und `st-main rrm/wnm` als „Krücken, die mit
VLAN1 rausfliegen". `st-main` ist seit TP3.3 (2026-08-13) **fester Bestandteil der Golden Config** — also
keine Krücke mehr, sondern Zielzustand. Zeile entsprechend korrigieren.
- **`switch/`** (ALLNET-Telnet-Runner) + `switch/ui-guides/02-vlan99-mgmt-cutover.md`: Gerät ausgebaut →
als Archiv kennzeichnen (README-Kopf), nicht löschen.
### E — Gegenprüfen, nicht blind übernehmen
- **`CLAUDE.md`**: Hardware-Tabelle ist aktuell gepflegt, aber die Gotcha-Liste enthält Sätze aus der
ap1-als-Router-Zeit. TP3-Rebuild-Eintrag nennt „breiterer CLAUDE.md-Gotcha-Cleanup" bereits als offen.
- **Memory-Dateien**: `project_wifi_rebuild_crs326_l3`, `project_tp15_core_cutover_blocked_20260805`,
`project_tp20_tp21_fasttrack_20260716` beschreiben Zwischenstände, die überholt sind. Memories sind
Momentaufnahmen — überholte nach der Konsolidierungs-Regel zusammenführen oder löschen, nicht doppeln.
---
## Reihenfolge & Aufwand
**A → B → C → D**, danach E als eigener Durchgang (anderes Substrat: Memory + `CLAUDE.md`).
A und C sind die zwei, die wirklich Fehlentscheidungen verhindern — wenn die Zeit knapp ist, nur die.
Grobschätzung: A+B+C ≈ eine Session, D+E ≈ eine halbe.
## Abnahme
1. Eine frische Session liest **nur** `docs/teilprojekte.md` und beschreibt daraus die Topologie korrekt:
`crs326-core` als L3-Router, kein sw1/sw2, kein Omada, kein CAPsMAN, ap1/ap2 als APs.
2. `grep -n "CAPsMAN\|Omada\|ap1.*Router" docs/teilprojekte.md` — jeder Treffer ist entweder als Historie
markiert oder korrekt.
3. Der ⚠️-Provisorium-Vorspann über Zeile 21 ist **weg** (weil überflüssig geworden).
4. Statusbaum (`/projektstatus`) unverändert plausibel — die Aufräumaktion darf **keinen** TP-Status ändern;
sie ändert nur, wie präzise er begründet ist.

View File

@@ -18,12 +18,15 @@
IP-Blöcke: `.1–10` Router/APs (ap1=.1, ap2=.2) · `.11–20` Switches (ALLNET=.11, Omada=.12). GW je VLAN = `.1`.
## Ist-Stand (Kurz)
> ⚠️ **Die folgenden 5 Zeilen (ALLNET/Omada/ap1-als-Router/Edge-Cutover-Pfad) beschreiben die Topologie VOR dem 2026-08-08 und sind HISTORIE** — sw1/sw2 sind ausgebaut, der Omada-Stack ist gelöscht, ap1 ist reiner AP. **Aktueller Ist-Stand = Hardware-Tabelle in `CLAUDE.md` + TP21.1** (`crs326-core` = L3-Router `.99.1`, WAN auf `vlan100`). Bewusst nicht überschrieben (Historie), aber nicht als Ist lesen. **Neufassung dieses Blocks = Punkt A der vorbereiteten Aufräum-Session, `docs/doku-cleanup-session.md`** (dieser Vorspann fliegt dabei raus).
ALLNET-Core `.11` (FW2.2.1, VLANs 10/20/30/40/50/90/99/100; GE1/GE2/GE8 Trunk; **TP1 ✅ 2026-06-15**). Omada-Switch `.12` (adopted, **TP2 ✅ 2026-06-15**; Trunk-ALL auf P1+P2, Access-Profile auf P3-P8; Profile noch PVID=1 bis Omada-PVID-Fix).
Omada-Controller **`.175`** (DS923/macvlan, mbentley 6.2, 🟢 live). omada-mcp **`.176`** (pve-LXC, StreamableHTTP, 🟢 live, 84 read-Tools; Controller-API v2 intern via christoph@emsenhuber.com).
2× hAP ax² (7.23.1): ap1 `.1` (ALLNET P1) — **TP4 ✅ 2026-07-01: Router + WAN-Edge** (VLAN-Subinterfaces, DHCP, DNS, NAT, Public-Edge). ap2 `.2` (Omada P2 — Trunk).
**Edge-Cutover ✅ 2026-07-01:** FB6660 physisch entfernt (Liwest-Kabelmodemtausch, kein Zurück), Arris-Kabelmodem im Bridge-Mode; WAN = `sw1 gi16 Access VLAN100 → gi15 Trunk → ap1 ether2 → vlan100 auf bridge` (**NICHT** ether1); ap1 hält Public-IP direkt (Liwest, kein CGNAT), Double-NAT weg. Telefonie war auf der FB und wird nicht weitergeführt. Vorarbeit: TP10-Kern durch (2026-06-27, WG-Hub live) → Bridge-Gate vorher gelöst. Runbook: `routeros/wan-cutover-runbook.md`.
Kontrolle: MikroMCP (MikroTik) live · ALLNET = Klickanleitungen · Omada → Controller + omada-mcp 🟢.
**Nächster Schritt (Stand 2026-07-22): TP15 CRS326-Bring-up als neuer L3-Core** (Routing/DNS/DHCP von ap1 → `crs326-core`), danach **WLAN-Neuprovisionierung ohne CAPsMAN** (TP3). Nautobot-Basisdaten sind eingepflegt (TP21). ⚪ **Omada-PVID-Fix ist obsolet** (User-Entscheid 2026-07-22 — Omada spielt seit der TP15-Korrektur keine Rolle mehr im Netz, nie mehr aufgreifen). TP5 Deny-by-default folgt nach TP21/CRS326-Adoption (Sonos-/HA-/mDNS-Holes und WAN-Input-Seal stehen bereits).
**Nächster Schritt (Stand 2026-08-14): 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 (TP15). ⚪ **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, prüfen ob nach Migration noch nötig; (c) **cudy1 = verbleibender aktiver VLAN1-Leak** (Dual-DHCP-Race, Doku Memory `project_vlan1_dhcp_incident`). Bis dahin sind diese Griffe Krücken, kein Zielzustand.
> ⚠️ **HW-Constraint hAP ax²:** 1 GB RAM, aber nur **128 MB Flash + KEIN USB** → **Container auf dem Router NICHT praktikabel**.
> Folge: **native RouterOS-Features bevorzugen** (z.B. Built-in-mDNS statt Container); Container (mDNS-Reflector, BIND9-DNS, Omada-Controller) laufen auf **NAS/pve**, nicht am hAP.
@@ -202,17 +205,21 @@ 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 ▸ ⏳ TEIL-LIVE (Sonos/HA-Holes + WAN-Seal gebaut, Deny-by-default steht aus)
### TP5 — Firewall & Inter-VLAN-Policy ▸ ⏳ TEIL-LIVE auf `crs326-core` (Holes + WAN-Seal re-verifiziert 2026-08-14; Deny-by-default steht aus) — **jetzt das nächste Arbeitspaket, Session vorbereitet** — 📋 `docs/tp5-deny-by-default-runbook.md`
- 📋 **Session-Runbook liegt (2026-08-14): `docs/tp5-deny-by-default-runbook.md`** — Ist-Stand live erhoben, **beobachtete Inter-VLAN-Flow-Matrix** (conntrack + Counter), 6 offene Entscheidungen (D1–D6), 4 Etappen mit Absicherung, Verifikation + Rollback. **Kernansatz: Etappe 1 ist ein reiner Log-Lauf ohne Blockierung** (`action=log` ans Ende von `forward`) — die Whitelist wird aus dem Log abgeleitet, nicht am Schreibtisch geraten. Drei Funde, die vorab eine Entscheidung brauchen: ein **iPhone sitzt in VLAN30**, ein **ICMP-Dauersweep von `.10.82` auf alle Shellys**, und **vlan99 ist Mitglied der `LAN`-Liste** (→ `seal-lan` erlaubt Mgmt-Input aus jedem VLAN). **VLAN50/90 tragen null Inter-VLAN-Verkehr** → Internet-only-Pinning ist dort risikofrei.
- **Deny-by-default + least-privilege** (Ziel). MAIN→INFRA nur Whitelist-Dienste; MAIN↔MEDIA allow (+mDNS); UNTRUSTED/GUEST nur Internet; MGMT isoliert; Router-input gehärtet.
- ✅ **Bereits live** (verifiziert `list_firewall_rules` 2026-07-02):
- ⚠️ **Gerätewechsel beachten (2026-08-14 nachgetragen):** der ✅-Block unten war ursprünglich **auf ap1** verifiziert (2026-07-02) — ap1 ist seit 2026-08-08 Werksreset und reiner AP. Die Regeln sind beim Core-Cutover (TP21.1) mitgewandert, waren am neuen Gerät aber **nie gegengeprüft**. Am **2026-08-14 auf `crs326-core` live nachverifiziert** (`list_firewall_rules`, chains `forward` 13 Regeln / `input` 12 Regeln): **alle unten gelisteten Regeln existieren, sind enabled, tragen ihre `TP5:`/`TP10-seal-`-Kommentare und zählen Traffic.** Merkregel: nach jedem Rollenwechsel eines Geräts gilt eine Verifikation vom Vorgänger nicht weiter.
- ✅ **Bereits live** (ap1 2026-07-02 → **re-verifiziert auf `crs326-core` 2026-08-14**):
- `forward accept vlan10↔vlan40` — TP5: MAIN↔MEDIA (AirPlay/Sonos)
- `forward accept vlan20↔vlan40` — TP5: INFRA↔MEDIA (HA↔Sonos)
- `input accept udp/5353 vlan10/vlan20/vlan30/vlan40` — mDNS-Repeater (TP7-Anschluss)
- `forward accept vlan90↔vlan40` + `input accept udp/5353 vlan90` — **GUEST→MEDIA (Sonos/Cast), permanent** (TP7.2, 2026-07-03)
- **WAN-Input-Seal komplett** (TP10-seal-est/inv/dhcp/icmp/lan/wandrop + WG-Hub UDP/51821 accept)
- ⏳ **Offen:** Deny-by-default am Ende von `forward` (aktuell noch permissiv nach fasttrack); UNTRUSTED/GUEST auf Internet-only pinnen; MGMT isolieren; IoT→INFRA-Whitelist bauen.
- ⏳ **Offen:** Deny-by-default am Ende von `forward` (**live bestätigt 2026-08-14: die `forward`-Kette endet nach `TP5: MEDIA->GUEST` ohne Drop → alles nicht explizit Erlaubte läuft durch**); UNTRUSTED/GUEST auf Internet-only pinnen; MGMT isolieren; IoT→INFRA-Whitelist bauen.
- 🔍 **Befund beim Re-Verify (2026-08-14) — die 5 `TP5: mDNS in vlanXX`-Input-Regeln sind derzeit tot:** sie stehen **hinter** `TP10-seal-lan` (`in-interface-list=LAN`, action=accept), das jeden LAN-Input schon vorher annimmt → Counter aller 5 mDNS-Regeln stehen auf **0 Pakete**, während `seal-lan` 3,5 Mio. zählt. **Kein Fehler und nichts zu tun** — sie sind die Vorbereitung auf genau den Schritt, der noch aussteht: sobald der Router-`input` gehärtet wird (`seal-lan` verengen/entfernen), werden sie scharf. **Falle für die TP5-Session: erst `seal-lan` verengen, DANN testen** — vorher beweist ein grüner mDNS-Test gar nichts, weil er über `seal-lan` läuft.
- 📌 **Ausgangslage für die Umsetzung (Live-Stand `crs326-core`, 2026-08-14):** `forward` = defconf (est/rel/untracked accept · fasttrack · drop invalid · drop WAN !dstnat) → 2× TP10-WG → 6× TP5-Holes (MAIN↔MEDIA, INFRA↔MEDIA, GUEST↔MEDIA), **kein abschließender Drop**. `input` = TP10-seal komplett (est/inv/dhcp/icmp/lan/wandrop) + WG-Listen 51821 + 5× mDNS. Der Deny-by-default-Griff ist damit **eine Regel am Ende von `forward`** plus die Whitelists davor — nicht ein Umbau der Kette. ⚠️ **Governance:** läuft über Nautobot GC (`ip-firewall-*`-Features aus TP22), **nicht** per Direkt-Write; vorher `/system backup` (TP22-Regel 3). ⚠️ **Rettungspfad:** ein zu früh gesetzter Drop killt Mgmt/DHCP/DNS quer durchs Haus — Reihenfolge Whitelists zuerst, Drop zuletzt, und `device-mode` auf core erlaubt scheduler → **Auto-Revert-Scheduler als Sicherung ist hier möglich** (anders als auf den hAPs).
- **IoT→INFRA-Rückmeldung (deine Frage):** IoT darf **aktiv** zu INFRA-Diensten initiieren — Firewall-Allow IoT→INFRA NUR auf **MQTT (1883/8883), HA-API, InfluxDB (8086)** o.ä.; Antworten via established/related; IoT→MAIN bleibt deny. So pusht ein Sensor Daten an HA/MQTT/Influx, ohne dass IoT „frei" ist.
- Abh.: TP4 ✅.
- Abh.: TP4 ✅ (L3-Basis, Rolle inzwischen auf `crs326-core`), **TP14.5 ✅** (Freigabe-Gate), **TP22 ✅** (GC-Deploy-Pipeline = der vorgeschriebene Weg für den Push). **Keine offenen Blocker mehr — TP5 ist der kritische Pfad.** Folge: **TP6 (CAKE)**. Hängt dran: **TP5.1** (DNS-Redirect/Torch für Low-Trust).
### TP5.1 — DNS-Visibility & Flow-Observability für Low-Trust-Geräte (Airfryer-Fall) ▸ vorgemerkt
- **Kontext (2026-07-08/09):** Airfryer „airschreier" (Philips/Versuni, ESP, `10.40.30.180`) bekam per DHCP-Option 6 `dns 1.1.1.1` als Override, weil das OTA-Update über den ap1-DoH-Gateway-Pfad nicht durchging (DoH-Latenz beim primitiven ESP-Stack — **kein** Content-Block, via Gateway-Logs bewiesen, s. `memory/ref_esp_ota_doh_not_block`). Nebenwirkung: public **1.1.1.1 = anonymer Consumer-Resolver ≠ accountgebundener Gateway-DoH** (`px35ynlol3.cloudflare-gateway.com`) → **DNS-Sicht auf das Gerät weg**, Gerät umgeht zudem die Filterung.
@@ -503,14 +510,16 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
- **Teardown-Sequenz (angepasst an den Live-Stand):** VLAN1-Client-Sweep ist **schon fast leer** (nur sw1-Mgmt + pve-Interim reachable) → `defconf`/pool-v1 ist **bereits disabled** → cudy-Abbau **entfällt** (cudy1 umgenutzt statt abgebaut, cudy2 tot) → ✅ **SwitchBot + Twinkly erledigt (2026-07-16)** → **verbleibt:** Media-Check (B1.3), pve-`.41.100` abräumen (B1.5), Interim-Krücken bewerten (ap2 `frame-types=admit-only-vlan-tagged`, `st-main rrm/wnm`), Inventar/`ip-plan`/DNS `.41→Ziel` final.
- Abh.: **TP14 ✅** (Hosts raus aus VLAN1), **TP17 ✅** (Shellys raus). Verwandt: `project_vlan1_dhcp_incident` (cudy-Dual-DHCP-Leak), TP5 (Deny-by-default danach sauberer). SSoT hier + `docs/tp19-vlan1-cudy-teardown-runbook.md`. Folge: **TP19.1**.
#### TP19.1 — VLAN99-MGMT-Cutover (sw1/sw2/ap2-Mgmt VLAN1 → VLAN99) ▸ ⏳ ap1 ✅, sw2 ✅, ap2 auf Nautobot vertagt, sw1 offen (Stand 2026-07-16)
#### TP19.1 — VLAN99-MGMT-Cutover (sw1/sw2/ap2-Mgmt VLAN1 → VLAN99) ▸ ✅ ERLEDIGT (2026-08-14 nachgezogen) — alle lebenden Geräte auf VLAN99, die beiden Rest-Punkte gegenstandslos
- ✅ **Abschluss-Nachtrag 2026-08-14 (Status-Korrektur, kein neuer Change):** der Header stand noch auf „ap2 vertagt, sw1 offen" (Stand 2026-07-16) — beides ist durch spätere TPs eingelöst bzw. gegenstandslos geworden, ohne dass es hier nachgetragen wurde. Ist-Stand: **core `.99.1` · branch `.99.2` · ap1 `.99.11` · ap2 `.99.12`** — jedes lebende Netzgerät hat sein Mgmt auf VLAN99. **sw1/sw2 existieren nicht mehr** (physisch ausgebaut, in Nautobot per TP22 Schritt 5 auf *Decommissioned*). Damit ist TP19.1 vollständig; offen bleibt nur der VLAN1-**Client**-Teil, und der gehört zu TP19 (Hauptteil), nicht hierher.
- **Scope:** die einzigen Dinge, die TP19s Hauptteil bewusst in VLAN1 belässt — sw1 (`.41.11`), sw2, ap2-Mgmt (`.41.2`) — auf VLAN 99 (MGMT, `10.40.99.0/24`) umziehen. Erst danach ist VLAN1 wirklich **komplett** weg, nicht nur als Client-Netz.
- **User-Entscheid (2026-07-16):** kein eigenständiges TP-Nummer — bewusst als **Unterpunkt von TP19** geführt („VLAN1 killen"), nicht als TP22 o.ä.
- ✅ **ap1-Teil erledigt (2026-07-16):** ap1 brauchte keinen funktionalen Umzug (vlan99-Interface/GW `.99.1` läuft schon seit TP4) — nur der kosmetische DNS-Static-Nachtrag `ap1.bf.lan` `10.40.41.1`→`10.40.99.1` war offen, per MikroMCP erledigt (dry-run→apply, `manage_dns_entry`).
- ✅ **sw2-Teil erledigt (2026-07-16, Christoph selbst über die Klickanleitung):** sw2 jetzt auf **`10.40.99.12`** (statisch, planmäßiger Zielwert aus `ip-plan.md`) — per Ping verifiziert. Zwischenzeitlich war das Gerät kurz auf einer *dynamischen* `10.40.99.200`-Lease aufgetaucht (unklare Ursache, s. Memory `project_tp20_tp21_fasttrack_20260716`), jetzt aber sauber auf der geplanten statischen Adresse. `CLAUDE.md`/`ip-plan.md` nachgezogen.
- 🔜 **ap2-Teil bewusst vertagt (User-Entscheid 2026-07-16): erst NACH Nautobot (TP21).** Nautobot übernimmt dann in einem Rutsch ap1 + ap2 + die neuen CRS326-Switches (TP15) als config-as-code-Fleet — der ap2-Mgmt-VLAN-Umzug wird also nicht mehr isoliert von Hand gemacht, sondern Teil der Nautobot-Erstadoption. `ap2.bf.lan`-DNS-Static bleibt bewusst auf `10.40.41.2` bis dahin.
- ✅ **ap2-Teil erledigt (2026-08-08, im TP3-Rebuild) — die Vertagung wurde wie geplant eingelöst.** ap2-Mgmt liegt auf **`10.40.99.12`** (VLAN99), gesetzt bei der Standalone-Neuprovisionierung, nicht isoliert von Hand; `primary_ip4` in Nautobot per TP22 Schritt 5 nachgezogen. Der `ap2.bf.lan`-DNS-Static wurde im TP22-Pilot-Deploy (2026-08-13, GC-ConfigPlan) von `10.40.41.2` auf `.99.12` gezogen. Ursprüngliche Vertagungs-Begründung zur Historie:
- 🔜 **~~ap2-Teil bewusst vertagt~~ (User-Entscheid 2026-07-16): erst NACH Nautobot (TP21).** Nautobot übernimmt dann in einem Rutsch ap1 + ap2 + die neuen CRS326-Switches (TP15) als config-as-code-Fleet — der ap2-Mgmt-VLAN-Umzug wird also nicht mehr isoliert von Hand gemacht, sondern Teil der Nautobot-Erstadoption. `ap2.bf.lan`-DNS-Static bleibt bewusst auf `10.40.41.2` bis dahin.
- 🔒 **TP19.1 war die letzte Ausnahme vom ap1/ap2-Config-Freeze — der jetzt (2026-07-16) zur generellen Regel ausgeweitet wurde** (s. Governance-Entscheid oben): **jede** Gerätekonfiguration künftig ausschließlich über Nautobot, keine direkten Änderungen mehr an einzelnen im Netz verstreuten Geräten. Der ap1-DNS-Fix oben war die letzte direkte MikroMCP-Write-Aktion unter der alten (engeren) Regel.
- ⏳ **sw1-Teil: Klickanleitung fertig, Ausführung on-demand (User-Entscheid 2026-07-16).** `switch/ui-guides/02-vlan99-mgmt-cutover.md` liegt bereit — Christoph entscheidet spontan, ob er noch klickt oder direkt auf CRS326 wartet. Nicht blockierend, kein Diskussionsbedarf mehr.
- ⚪ **sw1-Teil GEGENSTANDSLOS (2026-08-14 festgestellt):** Christoph hat sich für „auf CRS326 warten" entschieden — sw1 wurde am **2026-08-08 durch `crs326-core` ersetzt und physisch ausgebaut** (Nautobot: *Decommissioned*, TP22 Schritt 5). Ein Mgmt-VLAN-Umzug für ein nicht mehr existierendes Gerät entfällt ersatzlos. **`switch/ui-guides/02-vlan99-mgmt-cutover.md` ist damit historisch** (nie ausgeführt, nicht mehr ausführbar — der Telnet-Runner `switch/` insgesamt nur noch Archiv). Ursprünglicher Stand zur Historie: Klickanleitung fertig, Ausführung on-demand (User-Entscheid 2026-07-16), nicht blockierend.
- **Bereits vorbereitet:** `docs/ip-plan.md` Phase 2 hat schon einen Entwurf (ap2→`10.40.99.2`, sw1→`10.40.99.11`, „Lockout-Risiko, sorgsam", sw1 zuletzt).
- **Abh.:** TP19-Hauptteil (VLAN1-Client-Retirement) — logisch danach, da VLAN99 als eigenes Mgmt-Netz erst dann wirklich nötig wird, wenn VLAN1 sonst leer ist. sw1-Teil braucht sw1-Telnet-Zugriff (User macht sw1-Changes direkt, s. Feedback-Memory) — Lockout-Risiko am größten bei sw1 (einziger Netzpfad zu sw2 hängt am Uplink).
@@ -587,7 +596,7 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
- **Herkunft:** `ether4` war als **ap1-Uplink-Trunk vorbereitet** („ap1 wandert #15→#4"); ap1 blieb auf `ether15`, in den übrigen Trunk-Port wanderte das Sideboard-Kabel.
- ✅ **BEHOBEN 2026-08-13 — am Port, nicht am Kabel (User-Vorgabe): „Patchfeld 1–10 ist durchnummeriert und komplett gepatcht, die Nummerierung wird nicht wegen einer Config geändert."** Richtig so — die Portnummer ist physische Infrastruktur. Also `ether4` sauber auf **untagged VLAN40** gezogen statt das Kabel zu verschieben.
- **Ausgeführt via Nautobot-GC-ConfigPlan** (`plan_type=manual`, 6 Zeilen, change_control_id `TP21.1-4 …`), nicht per Direkt-Write — Governance gewahrt. Vorher `/system backup` = `core-pre-ether4-vlan40-20260813.backup` (Regel 3). `ether4` aus den Tagged-Listen von VLAN 10/20/30/40/50/90 entfernt + als untagged-Member zu VLAN40 ergänzt. **`pvid=40` stand bereits** — das war nie das Fehlende. **Verifiziert:** `vlan40 untagged=ether2,ether3,ether4,ether5`, `tagged=ether1,ether8,ether15`; vlan99 (Mgmt) und vlan100 (WAN) unangetastet. Damit ist auch der Flood-Leak aus IoT/INFRA/MAIN zum Wohnzimmer-Switch weg.
- ⏳ **End-to-End-Beweis steht aus:** der TV antwortet nicht (ARP weiter `failed`, letzter Funkkontakt 2,5 h alt) — er ist mit hoher Wahrscheinlichkeit im Standby. **Beim nächsten Einschalten gegenprüfen:** MAC muss auf `ether4`/vid40 gelernt werden und `ping 10.40.40.11` durchgehen.
- ✅ **End-to-End-Beweis ERBRACHT (2026-08-14, live via MikroMCP auf `crs326-core`)** — der TV war am 08-13 tatsächlich nur im Standby. Alle vier Kriterien grün: `ping 10.40.40.11` = **5/5, 0 % Loss** (avg 563 µs); ARP `complete=true`/`status=delay` auf `vlan40` (vorher `failed`); `/interface/bridge/host` lernt `70:AF:24:B8:C9:86` auf **`ether4`, VID 40**; `ether4` `rx-unicast=6.909` / 3,0 MB RX (am 08-13 noch 1.338 Pakete / 452 KB → der Downstream lebt jetzt). DHCP-Lease `tv` weiterhin bound auf `dhcp-v40`. **Damit ist TP21.1 Punkt 4 vollständig abgeschlossen** und die Diagnose „tagged Egress auf einem untagged Port" ist end-to-end bestätigt (SSoT-Merkregel: `ref_tagged_egress_oneway_port`).
- 🔴 **INCIDENT + Lehre (2026-08-13): Der erste Deploy lief gegen das FALSCHE GERÄT (ap1 statt core).** Ich hatte 4 Device-UUIDs mit einer Sammelabfrage geholt und die **Reihenfolge angenommen**; die Nautobot-REST-API sortiert aber **alphabetisch** → `ap1, ap2, crs326-branch, crs326-core`. Der ConfigPlan trug damit ap1.
- **Schaden: keiner.** RouterOS wies jedes `set` ab (`invalid value for argument interface`), weil `ether8/13/15` auf einem 5-Port-hAP nicht existieren; die Ablehnung ist **pro Kommando atomar** → kein Teilzustand. ap1 nachgeprüft: VLAN-Tabelle vollständig, 25 WLAN-Clients, Mgmt `.99.11`. **Das war Glück, kein Können** — bei einem auf beiden Geräten *gültigen* Kommando (z.B. `tagged=ether1`) hätte es ap1s VLAN-Tabelle zerlegt.
- **Regel daraus: Device-UUIDs IMMER einzeln per Name auflösen, nie aus einer Sammelabfrage positional zuordnen** — und vor dem Deploy `plan.device.display` gegen den Zielnamen assert'en (im Skript jetzt so gemacht).
@@ -659,7 +668,7 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
---
## Reihenfolge / Abhängigkeiten
> 🎯 **AKTUELLER KRITISCHER PFAD (Stand 2026-07-16, überschreibt die Reihenfolge unten): TP20 (Platform-Postgres) → TP21 (Nautobot) — Ziel: fertig vor CRS326-Produktivsetzung, spätestens Montag 2026-07-20.** TP18 (Garage-S3) und die Komodo-Abhängigkeit wurden am selben Tag als Blocker entfernt/entkoppelt (s. TP20), um diese Deadline zu halten — beide werden später nachgezogen, nicht mehr vorher abgewartet. **➡️ Stand-Update 2026-08-08:** TP20/TP21-Plattform steht, Core-Cutover (TP21.1) + WLAN-Rebuild (TP3) + VLAN20-Migration (TP14) sind durch. Neuer Rest-Pfad: **TP22 (Device-Adoption + Compliance-Push) → TP5 (Deny-by-default) → TP6 (CAKE, das Ziel).** Kleine Follow-ups davor: DoH-Cloudflare auf core, USV (TP15). **➡️ Stand-Update 2026-08-13 (Abschluss): TP22 ist DURCH** (alle 5 Schritte; Fleet adoptiert, Deploy-Pipeline scharf, Datenmodell as-built, Secret-Handling entschieden) → **kritischer Pfad jetzt: TP5 (Deny-by-default) → TP6 (CAKE)**. Kleine Follow-ups davor: DoH-Cloudflare auf core, Kabel `core ether4`→`ether2` (Sideboard/TV), DC-USV (TP15). Historisch: **TP22 war das nächste Arbeitspaket** — TP17 (Shelly-Migration) ist parallel dazu vollständig abgeschlossen (alle Shellys auf VLAN30, User-bestätigt). Grund für den Nautobot-First-Ansatz: Governance-Entscheid „Config exklusiv über Nautobot" (s. oben) macht Nautobot zur Voraussetzung für praktisch jede weitere Router-/Switch-Änderung. Die Punkte 3-4 unten (Omada-PVID-Fix etc.) sind **obsolet** (User-Entscheid 2026-07-22 — Omada spielt seit TP15-Korrektur keine Rolle mehr, nie wieder aufgreifen) — ganze Liste braucht mal eine Aufräum-Session, hier nur der aktuelle Fokus vorangestellt.
> 🎯 **AKTUELLER KRITISCHER PFAD (Stand 2026-07-16, überschreibt die Reihenfolge unten): TP20 (Platform-Postgres) → TP21 (Nautobot) — Ziel: fertig vor CRS326-Produktivsetzung, spätestens Montag 2026-07-20.** TP18 (Garage-S3) und die Komodo-Abhängigkeit wurden am selben Tag als Blocker entfernt/entkoppelt (s. TP20), um diese Deadline zu halten — beide werden später nachgezogen, nicht mehr vorher abgewartet. **➡️ Stand-Update 2026-08-08:** TP20/TP21-Plattform steht, Core-Cutover (TP21.1) + WLAN-Rebuild (TP3) + VLAN20-Migration (TP14) sind durch. Neuer Rest-Pfad: **TP22 (Device-Adoption + Compliance-Push) → TP5 (Deny-by-default) → TP6 (CAKE, das Ziel).** Kleine Follow-ups davor: DoH-Cloudflare auf core, USV (TP15). **➡️ Stand-Update 2026-08-13 (Abschluss): TP22 ist DURCH** (alle 5 Schritte; Fleet adoptiert, Deploy-Pipeline scharf, Datenmodell as-built, Secret-Handling entschieden) → **kritischer Pfad jetzt: TP5 (Deny-by-default) → TP6 (CAKE)**. Kleine Follow-ups davor: DoH-Cloudflare auf core, DC-USV (TP15), **Doku-Aufräumen (`docs/doku-cleanup-session.md`, vorbereitet 2026-08-14 — dieses Dokument beschreibt an mehreren Stellen noch die Topologie vor dem Core-Cutover)**. ~~Kabel `core ether4`→`ether2` (Sideboard/TV)~~ **entfällt (2026-08-14):** gelöst wurde am **Port**, nicht am Kabel (User-Vorgabe „Patchfeld-Nummerierung wird nicht wegen einer Config geändert") — `ether4` steht seit 08-13 auf untagged VLAN40, End-to-End-Beweis am 08-14 erbracht, s. **TP21.1 Punkt 4**. Historisch: **TP22 war das nächste Arbeitspaket** — TP17 (Shelly-Migration) ist parallel dazu vollständig abgeschlossen (alle Shellys auf VLAN30, User-bestätigt). Grund für den Nautobot-First-Ansatz: Governance-Entscheid „Config exklusiv über Nautobot" (s. oben) macht Nautobot zur Voraussetzung für praktisch jede weitere Router-/Switch-Änderung. Die Punkte 3-4 unten (Omada-PVID-Fix etc.) sind **obsolet** (User-Entscheid 2026-07-22 — Omada spielt seit TP15-Korrektur keine Rolle mehr, nie wieder aufgreifen) — ganze Liste braucht mal eine Aufräum-Session, hier nur der aktuelle Fokus vorangestellt.
> ✅ **TP16 (CF-Tunnel Round-Robin/macvlan-Host-Isolation → reziprokes 3-Tunnel-HA)** KERN UMGESETZT 2026-07-10 (#1033 strukturell weg). Offen nur Access-Strang (WARP/`vw`) = user-gated. As-Built `docs/cf-tunnel-mapping.md §10`.
1. ~~**TP1 (GE8) → TP2 (Omada Controller).**~~ ✅ erledigt 2026-06-15.
2. ~~**TP4 (Router-Cutover L3-Infra + WAN-Edge).**~~ ✅ erledigt 2026-06-15 (L3) + 2026-07-01 (Edge-Cutover, FB physisch weg).

View File

@@ -0,0 +1,172 @@
# TP5 — Deny-by-default auf `crs326-core` · Session-Runbook
> **Stand der Vorbereitung: 2026-08-14** (Live-Erhebung auf `crs326-core` via MikroMCP).
> **Status: vorbereitet, nicht ausgeführt.** Diese Datei ist der Einstieg für die TP5-Session —
> kanonischer Scope bleibt `docs/teilprojekte.md` → TP5.
---
## 0. Worum es geht (in einem Absatz)
Die `forward`-Kette auf dem Core endet heute **ohne Drop**: alles, was nicht von einer der 6 TP5-Hole-Regeln
erfasst wird, läuft trotzdem durch. Die VLAN-Segmentierung ist damit **dokumentiert, aber nicht durchgesetzt**.
TP5 schließt genau diese eine Lücke — plus die Whitelists, die es dafür braucht. Es ist der letzte Schritt
vor TP6 (CAKE), dem eigentlichen Projektziel.
**Das Risiko ist asymmetrisch:** ein zu früh gesetzter Drop nimmt DHCP, DNS, Mgmt und das halbe Smart-Home
gleichzeitig mit — und zwar auch den Pfad, über den man den Fehler zurücknehmen wollte. Deshalb ist unten
**Etappe 1 ein Log-Lauf ohne jede Blockierung.** Wer direkt zum Drop springt, arbeitet blind.
---
## 1. Ist-Stand (live erhoben 2026-08-14, `crs326-core`)
### 1.1 `forward` — 13 Regeln, kein abschließender Drop
| # | Aktion | Bedeutung |
|---|---|---|
| 1 | accept `established,related,untracked` | defconf |
| 2 | fasttrack `established,related` | defconf (`hw-offload=true`) |
| 3 | drop `invalid` | defconf |
| 4 | drop in-list=WAN `!dstnat` | defconf |
| 5–6 | accept in/out `wg-hub` | TP10 (FM/DW-Spokes) |
| 7–8 | accept `vlan10↔vlan40` | TP5: MAIN↔MEDIA |
| 9–10 | accept `vlan20↔vlan40` | TP5: INFRA↔MEDIA |
| 11–12 | accept `vlan90↔vlan40` | TP5: GUEST↔MEDIA |
| — | **(nichts)** | ⬅️ **hier fehlt der Deny-by-default** |
### 1.2 `input` — 12 Regeln, LAN pauschal offen
TP10-Seal komplett (`est` · `inv` · `dhcp` · `icmp` · **`lan`** · `wandrop`) + WG-Listen 51821 + 5× mDNS.
⚠️ **`TP10-seal-lan` (`in-interface-list=LAN`, accept) nimmt jeden LAN-Input an** — inkl. VLAN99-Mgmt,
VLAN90-Guest und VLAN50. Die 5 `TP5: mDNS in vlanXX`-Regeln stehen **dahinter** und zählen daher
**0 Pakete** (seal-lan: 3,5 Mio.). Sie sind nicht kaputt, nur noch nicht dran.
### 1.3 NAT + Interface-Listen
- `srcnat`: `accept dst-address=10.40.0.0/16` (**no-NAT inter-VLAN, steht vor masquerade**) → `masquerade out-list=WAN`.
- `WAN` = `vlan100` · `LAN` = `vlan10,20,30,40,50,90,99` (**vlan99 ist Mitglied von LAN** — relevant für 1.2 und für D4).
---
## 2. Was heute real über VLAN-Grenzen läuft
Erhoben aus `/ip/firewall/connection` (Momentaufnahme) + den kumulativen Regel-Countern.
⚠️ **Beides zusammen lesen:** conntrack zeigt nur, was *gerade* offen ist; die Counter zeigen, was *jemals* lief.
Beispiel: `INFRA→MEDIA` hat 178.142 Pakete auf dem Zähler, stand aber im Snapshot auf 0 Verbindungen.
| Richtung | Snapshot | Was genau |
|---|---|---|
| **v20 → v30** | 24 | **HA (`.20.105`) pollt 22 Shellys auf `tcp/80`** + `.30.137:6638` |
| **v10 → v30** | 224 | **223× ICMP von `.10.82` („Mac") auf alle Shellys** + 1× udp/3722 |
| **v10 → v20** | 10 | `.10.82`/`.10.183` → NAS `.20.10:6690` (Synology Drive), `.20.173:3000` (pve-mcp), `.20.167:49152` |
| **v20 → v10** | 4 | Mac mini `.20.167` ↔ iPad `.10.180` udp/3722; HA → `.10.6:161` (SNMP) |
| **v30 → v20** | 3 | `.30.249` → **HA-API `.20.105:8123`**; udp/5540 (Matter) → HA; `.30.201` → `.20.167:49152` |
| **v30 → v10** | 4 | Rückrichtungen zu `.10.82`/`.10.180`/`.10.183` (ephemere Ports) |
| **v10 → v99** | 1 | `.10.82` → `core .99.1` **tcp/22 + tcp/80** (= Mgmt-Zugriff) |
| **v40 → \*** | 0 | MEDIA initiiert nichts nach außerhalb |
| **v50 / v90** | 0 | **komplett leer — Internet-only-Pinning ist hier risikofrei** |
### 2.1 Drei Funde, die vor dem Drop eine Entscheidung brauchen
1. 📱 **Ein iPhone sitzt in VLAN30 (IOT):** `10.40.30.201`, Hostname `iPhone`, und es spricht mit dem
Mac mini (`udp/3722`, Apple-Continuity-Muster). Entweder hat sich jemand bewusst ins `dirtyvader-iot`-SSID
gehängt, oder das ist ein Ausrutscher. **Ein IOT-Deny trennt dieses Gerät** — vorher klären, nicht danach.
2. 🔍 **`.10.82` („Mac") pingt im Dauerlauf alle ~30 Shellys** (223 offene ICMP-Conntrack-Einträge).
Sieht nach einem Monitoring-/Scan-Tool aus. Wenn das gewollt ist, braucht MAIN→IOT eine ICMP-Ausnahme;
wenn nicht, ist es der erste Kandidat zum Abdrehen.
3. 🔑 **VLAN99 ist Mitglied der `LAN`-Liste** → `TP10-seal-lan` erlaubt Mgmt-Input aus *jedem* VLAN.
„MGMT isolieren" (TP5-Ziel) heißt also: `seal-lan` verengen — das ist derselbe Griff, der die
5 mDNS-Regeln scharf schaltet. **Beides passiert zusammen oder gar nicht.**
---
## 3. Offene Entscheidungen (vor der Session klären)
| # | Frage | Vorschlag |
|---|---|---|
| **D1** | MAIN→INFRA: welche Dienste? | Beobachtet: NAS `6690`, pve-mcp `3000`, macmini `49152`, `3722`. Vorschlag: **erst mit dem Log-Lauf (Etappe 1) vervollständigen**, dann Whitelist — nicht jetzt raten. |
| **D2** | iPhone `.30.201` in IOT | Ins MAIN-SSID holen (sauber) **oder** bewusst als Ausnahme dulden. Empfehlung: umhängen. |
| **D3** | ICMP-Sweep `.10.82`→IOT | Zweck klären. Falls Monitoring: schmale Regel `vlan10 → vlan30 protocol=icmp`. |
| **D4** | Wer darf auf VLAN99-Mgmt? | Vorschlag: nur MAIN (`vlan10`), Rest drop. `seal-lan` entsprechend verengen. |
| **D5** | IOT→INFRA-Whitelist | Doku nennt MQTT 1883/8883, HA-API, Influx 8086. Beobachtet real: **`8123` (HA), `5540/udp` (Matter)**. Vorschlag: die beobachteten + MQTT. |
| **D6** | UNTRUSTED/GUEST | Beide tragen **null** Inter-VLAN-Verkehr → Internet-only sofort und gefahrlos pinnbar. |
---
## 4. Umsetzung in 4 Etappen
> **Governance (TP22):** alles über **Nautobot Golden Config**, `plan_type=manual`, feature-scoped —
> **kein** Direkt-Write, **kein** „full intended" (Regel 1: `<<REDACTED>>`-Sektionen nie pushen).
> Vor **jedem** Push `/system backup` auf dem Core (Regel 3). Und: **nur die Gegenprüfung am Gerät zählt**,
> Job- und Plan-Status sind kein Wirksamkeitsnachweis (zweimal belegt, TP21.1/TP22).
### Etappe 1 — Log-Lauf (blockiert nichts, Dauer: einige Tage)
Eine einzige Regel **ans Ende von `forward`**, `action=log` statt `drop`:
```
/ip firewall filter add chain=forward action=log log-prefix="TP5-WOULD-DROP" comment="TP5: log-only, Vorstufe zum deny-by-default"
```
Das protokolliert exakt die Pakete, die der spätere Drop treffen würde — inklusive der Dinge, an die
niemand denkt (Drucker-Discovery, Backup-Jobs, ein Gerät, das nur einmal pro Woche funkt). **Diese Liste
ist die Whitelist**, nicht eine am Schreibtisch ausgedachte. Danach D1/D3/D5 final beantworten.
⚠️ Log-Ziel vorher setzen (`/system logging`), sonst läuft nur der Speicher-Ringpuffer mit.
### Etappe 2 — Whitelists bauen (noch immer ohne Drop)
Die aus Etappe 1 abgeleiteten Regeln **vor** der Log-Regel einfügen: MAIN→INFRA (D1), IOT→INFRA (D5),
ggf. MAIN→IOT-ICMP (D3). Danach muss die Log-Regel **verstummen** — solange sie noch Nutzverkehr sieht,
ist die Whitelist unvollständig. **Das ist das Abbruchkriterium für Etappe 3.**
### Etappe 3 — Drop scharf schalten
`action=log` → `action=drop` (bzw. Log behalten und Drop dahinter). **Erst wenn Etappe 2 still ist.**
🛟 **Sicherung — auf dem Core möglich, anders als auf den hAPs:** `crs326-core` läuft **nicht** in
`device-mode=home`, also stehen `scheduler` und `fetch` zur Verfügung. Vor dem Drop einen Auto-Revert
scharfstellen, der die Regel nach n Minuten selbst wieder abschaltet, wenn niemand ihn abbestellt:
```
/system scheduler add name=tp5-autorevert interval=10m on-event="/ip firewall filter set [find comment~\"TP5: deny-by-default\"] disabled=yes; /system scheduler remove tp5-autorevert"
```
Läuft alles sauber → Scheduler manuell entfernen. Läuft es nicht → das Netz heilt sich in ≤10 Minuten selbst.
**Diese Absicherung gibt es auf ap1/ap2 nicht** — dort ist sie durch `device-mode=home` blockiert (TP22-Regel 2).
### Etappe 4 — UNTRUSTED/GUEST + MGMT (D4/D6)
`vlan50`/`vlan90` auf Internet-only pinnen (risikofrei, s. §2), `seal-lan` auf MAIN verengen → MGMT isoliert,
und als Nebeneffekt werden die 5 mDNS-`input`-Regeln endlich wirksam.
---
## 5. Verifikation (nach jeder Etappe, immer am Gerät)
1. `list_firewall_rules` chain=forward/input → Regel existiert, `disabled=false`, Kommentar korrekt.
2. **Funktionstest quer durchs Haus:** Sonos aus MAIN steuern · HA erreicht die Shellys (`v20→v30:80`) ·
Shelly meldet an HA (`v30→v20:8123`) · NAS-Zugriff aus MAIN (`6690`) · Drucker · AirPlay/Cast ·
Gast-WLAN kommt ins Internet und **sonst nirgendwohin**.
3. Counter der neuen Regeln lesen — eine Drop-Regel, die *gar nichts* zählt, ist genauso verdächtig wie
eine, die zu viel zählt.
4. Nach der Geräteänderung: **Backup → Intended → Compliance** in dieser Reihenfolge
(GC vergleicht gegen das letzte Backup, nicht gegen das Live-Gerät — TP22-Falle).
## 6. Rollback
- Sofort: `disabled=yes` auf der Drop-Regel (bzw. Auto-Revert greift von selbst).
- Ganz zurück: `/system backup` von vor der Session einspielen.
- 🚨 Wenn der Mgmt-Pfad weg ist: Rettung ist der **Kabelweg**, nicht WLAN. `crs326-core` steht in
Technik UG; VLAN10-Fallback `10.40.10.1` existiert zusätzlich zu `.99.1`.
- ⚠️ **WARP-Falle:** „Ping auf alles tot, TCP geht" ist **kein** Firewall-Befund, sondern ein aktiver
WARP-Client. Vor jeder Firewall-Fehlersuche zuerst WARP trennen (`ref_warp_local_icmp_trap`).
---
## 7. Anschluss
**TP5.1** (DNS-Redirect + Torch für Low-Trust) hängt am UNTRUSTED-Pinning aus Etappe 4.
Danach ist der Weg frei für **TP6 — CAKE**, das Projektziel.