TP26: /ip firewall filter ist drift-ueberwacht — 76/76, TP5 Etappe 3 entblockt

Bis heute gab es nur ip-firewall-nat. "72/72 compliant" sagte ueber die
Firewall gar nichts — und TP5 Etappe 3 wollte dort einen Deny-by-default
setzen, der dann als einzige Regel im Netz unbeobachtet gewesen waere.

Umsetzung datengetrieben statt als Templatezeilen: die 36 Regeln liegen in
local_config_context_data.firewall_filter, das Template rendert sie nur.
36 Regeln fest ins Jinja zu schreiben hiesse, dass jede TP5-Etappe einen
Template-Edit braucht — genau die Reibung, wegen der die Governance in
Verruf geraten ist. Neue Regel = ein Listeneintrag.

ingest-core-firewall.py ist ein RE-BASELINE-Werkzeug, kein Sync: es erklaert
den Ist-Stand zum Soll und macht blind ausgefuehrt die Drift-Erkennung
wertlos. Darum nur nach einer bewusst verifizierten Aenderung laufen lassen.

Drei Formatfallen beim Nachbau des /export-Formats, alle durch Vergleich mit
dem echten Geraete-Export bzw. durch die neue Rule selbst gefunden:
- REST liefert Booleans als STRINGS. `if rule.get("dynamic")` ist fuer
  "false" wahr und filterte erst alle 36 Regeln weg (0 statt 36).
- REST sagt hw-offload=true, /export schreibt yes. Und "!" bzw. Kommas
  werden NICHT gequotet (connection-nat-state=!dstnat, dst-port=8123,1883).
  Quoting nur bei Leerzeichen.
- /export laesst Default-Werte weg: `disabled=no` steht nie drin,
  `disabled=yes` dagegen schon. Das schlug beim ersten Lauf der neuen Rule
  als 75/76 auf — die Rule hat ihren Zweck damit sofort erfuellt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 15:55:57 +02:00
parent b1ddd3574d
commit 2103774d1a
3 changed files with 153 additions and 9 deletions

View File

@@ -1125,11 +1125,10 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
(sie tun nichts — ein reiner AP hat keine `forward`-Kette zu schützen). Empfehlung: **abräumen**, sonst
schreibt man Werksmüll als Absicht in die SoT — dasselbe Argument wie bei `telnet` in TP16.1.
(b) **branch:** 0 Regeln ist der korrekte Sollzustand und muss im Template auch als *leer* gerendert werden.
- 🔴 **Folge 2 (und die ist gewichtiger): `/ip firewall filter` ist NICHT abgedeckt.** Die TP5-Zeile
„läuft über Nautobot GC (`ip-firewall-*`-Features aus TP22)" ist damit **irreführend — es existiert nur
NAT.** Die 11 Etappe-2-Regeln und der kommende Deny-by-default sind **nicht drift-überwacht**:
„72/72 compliant" sagt über die Firewall **gar nichts**. ➡️ **Das gehört VOR TP5 Etappe 3**, denn eine
Drop-Regel, die niemand überwacht, ist genau die, die still verschwindet.
- ✅ **Folge 2 — GESCHLOSSEN (2026-08-17, TP26): `/ip firewall filter` hat jetzt eine Compliance-Rule.**
Vorher gab es nur `ip-firewall-nat`; „72/72" sagte über die Firewall gar nichts. Jetzt **76/76**
(eine neue Rule × 4 Geräte). `config_ordered=true` — bei Firewallregeln ist die Reihenfolge semantisch.
**Damit ist TP5 Etappe 3 entblockt.**
- ⚠️ **`steering=`/Channel-Änderungen re-applien alle VAPs und werfen jeden Client kurz raus** (TP3.3 am
2026-08-13 gemessen: ap1 25→2, ap2 7→14). **Nicht während eines Calls deployen.** `/system backup` je AP vorher.
- **Abh.:** TP22 ✅ (GC-Deploy-Pipeline). Übernimmt den offenen Rest von **TP3.3**, verwandt **TP3.2** (Coverage-Doku
@@ -1210,10 +1209,11 @@ TP5 E1 ✅ ──► TP5 E2 ✅ ──► [mehrtägiges stilles Fenster] ──
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) · **und neu: eine Compliance-Rule auf `/ip firewall filter`.**
🔴 **Am 2026-08-17 festgestellt: die Filter-Kette ist NICHT drift-überwacht** — es gibt nur
`ip-firewall-nat`. Eine Deny-by-default-Regel ohne Drift-Erkennung ist genau die, die still verschwindet
und niemandem auffällt, bis etwas nicht mehr geht. **Siehe TP25 Schritt 6.**
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