Commit Graph

10 Commits

Author SHA1 Message Date
e9a22c8277 ComplianceRule wifi-access-list: die letzte ungepruefte Sektion schliessen
/interface wifi access-list stand unter KEINER ComplianceRule. Eintraege dort
erzeugten keinen Drift und liessen sich nicht als Config-Transaktion fuehren --
gc-transaktion.py verlangt eine ComplianceRule als --scope. Seit dem 22.8. ist
das nicht mehr theoretisch: docs/tp25-pin-s22.sh schreibt bei jedem Messrundgang
Regeln dorthin, und TP25 Fund E (signal-range-Boden) wuerde dauerhaft genau in
diesem blinden Fleck landen.

  - nautobot/ingest-wifi-access-list-rule.py (idempotent, Dry-Run default)
  - Template-Abschnitt [6c], bewusst NUR Kommentare: der Soll-Zustand ist LEER,
    und das ist die Aussage. Die intended config gewinnt keine wirksame Zeile.
    Nach bf-golden-config gepusht (51c11f0), Repo-Sync SUCCESS.

ZWEI KORREKTUREN AN DER AUFGABENSTELLUNG:

1. Der Zaehler geht auf 96, nicht auf 94. Die Regeln gelten PLATTFORMWEIT, nicht
   geraetespezifisch -- 92 Checks waren exakt 23 Rules x 4 Geraete, jetzt sind es
   24 x 4. Die Annahme "2 geraete-relevante Checks" war falsch.
2. Vor Beginn stand bereits ein Drift in der Anzeige (bridge-vlan auf
   crs326-core, ether3 als Trunk), obwohl der Sideboard-Rollback am 08-22
   gelandet war. Das Geraet war live korrekt -- die Compliance vergleicht gegen
   das letzte BACKUP, und das war aelter als der Rollback. Mit dem Refresh weg.

WIRKSAMKEIT BEWIESEN, nicht behauptet (TP22-Regel "Job-Status ist kein
Wirksamkeitsnachweis"):
  96/96 compliant, 0 Drifts
  -> Test-Eintrag mit nicht existierender MAC (kein echter Client betroffen)
  -> 95/96, extra = exakt diese Zeile bei crs326-core | wifi-access-list
  -> Eintrag entfernt -> 96/96, 0 Drifts
  Zusaetzlich: gc-transaktion.py akzeptiert --scope wifi-access-list.
  Ausserdem geprueft: 4 Compliance-Datensaetze (einer je Geraet), und der
  [6c]-Block steht wirklich in der intended config von crs326-core.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 00:08:12 +02:00
1ba82608f2 CAPsMAN: slaves-datapath fehlte, IOT+MEDIA lagen 14h
Seit dem CAPsMAN-Cutover (2026-08-17) war `/interface wifi cap
slaves-datapath` auf ap1 und ap2 leer. Das ist das einzige Feld, das die
vom Manager erzeugten Slave-VAPs lokal in die Bridge haengt: der Core
schickt `datapath.bridge=bridge` zwar mit, der CAP uebernimmt davon aber
nur die vlan-id. Ergebnis: -iot, -media, -untrusted und -guest hingen in
gar keiner Bridge — Clients assoziierten sauber und bekamen nie DHCP.
`dirtyvader-main` lief weiter, weil wifi1/wifi2 statische Bridge-Ports
sind; genau das hat den Ausfall getarnt.

Fix live auf beiden APs: dp-caps-slaves (bridge=bridge, bewusst ohne
vlan-id) + slaves-datapath darauf. Die VAPs stehen seither als dynamische
Bridge-Ports mit pvid 30/40/50/90 in der Bridge.

Nicht die TP5-Haertung: torch auf vlan30 am Core leer UND kein einziger
DHCP-Eintrag im Drop-Log — es wurde nichts verworfen, es kam nichts an.

tp28-ap-wifi-reste-abraeumen.rsc hat den Ausfall nicht ausgeloest, aber
zementiert: mit den geloeschten datapath-Objekten gab es lokal nichts
mehr, worauf slaves-datapath haette zeigen koennen.

Die TP28-Abnahme "ohne jeden Aussetzer" ist korrigiert — sie zaehlte
Registrations, also genau die Metrik, die hier luegt. Abnahmekriterium
fuer WLAN-Umbauten ist ab jetzt eine frische DHCP-Lease pro SSID.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:13:26 +02:00
c709c9da6b NTP-Governance, SSDP-Relay live, WLAN-Config zurueck unter Drift-Kontrolle
92/92 compliant, 0 Drifts (vorher 71/76 bei 19 Rules -- jetzt 23 Rules).

NTP: die Wurzel war doppelt. Der Core hatte keinen eigenen Client, UND sein
Server hielt Stratum 16 fest, weil er eingeschaltet wurde, bevor der Client
synchron war. Der Test, der es aufgeklaert hat: branch einmal auf
at.pool.ntp.org zeigen lassen -- 20 Sekunden bis synchronized, also war der
Client heil und der Server schwieg. Jetzt im Template, per DHCP-Option 42 an
alle Clients ausgeliefert und mit der Rule system-ntp ueberwacht.

TP7.1: SSDP-Relay laeuft als LXC 108 auf pve, zweibeinig in VLAN10+40.
User-bestaetigt: "sonos ist da!". core ether13 traegt dafuer jetzt beide VLANs.

TP28: die APs trugen noch die komplette Standalone-WLAN-Config aus TP3 --
wirkungslos, aber sie haette als Soll totes Zeug zur Absicht erklaert.
Abgeraeumt, ohne einen einzigen Client zu verlieren (30 vorher, 30 nachher).
Die fuenf wifi-*-Features haengen jetzt am Core, dazu drei neue Rules
(wifi-capsman, wifi-provisioning, wifi-cap).

Gelernt: [find !dynamic] ist auf /interface wifi configuration ein
SYNTAXFEHLER, kein Filter -- der erste Anlauf aenderte nichts und meldete
trotzdem "Plan Completed".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 06:04:28 +02:00
b93514a045 RouterBOOT-Klickanleitung + TP5 E3/E4 abgenommen, NTP-Zeitquelle, Template-Fixes
docs/routerboot-firmware-klickanleitung.md: Schritt-fuer-Schritt fuer WinBox.
RouterOS ist auf allen vier bereits 7.24, nur der Bootloader haengt zurueck
(core/branch 7.19.5, ap1/ap2 7.23.2 -- live erhoben). Der Weg geht per Hand,
weil `/system routerboard upgrade` interaktiv nachfragt: MikroMCP blockt ihn per
Deny-Policy, und Netmiko bekommt den Prompt statt einer Antwort und quittiert mit
E3001 bei LEERER Fehlermeldung. Auf core/branch waere ein Scheduler-Umweg
moeglich, auf den APs nicht (device-mode=home sperrt ihn).
Reihenfolge ap1 -> ap2 -> core -> branch mit Ausfall je Geraet; branch zuletzt,
weil der Arbeitsplatz per Kabel daran haengt. Dazu Gegenprobe-Einzeiler fuer alle
vier und die Falle, dass ohne Schritt 7 (Reboot) `Current Firmware` alt bleibt.

Aus der Parallelsession dazugekommen:
- TP5 Etappe 3 UND 4 sind abgenommen, beide Auto-Reverts abbestellt. Die
  Abnahmen stehen in den Skriptkoepfen: forward-Drop hat in der Testphase 11
  Pakete gefressen, ausschliesslich die eigene pve->branch:22-Sonde; beim
  input-Drop war es reines Broadcast-Rauschen (NetBIOS, SSDP). Der GC-Deploy-Pfad
  wurde als Pfadbeweis mitgetestet (nautobot-worker -> ap2:22 = SUCCESS).
- E4-Nachtrag: MNDP und CAPWAP muessen in den input. Die CAPs finden ihren
  Manager per Layer-2-Discovery (`current-caps-man-address` ist eine MAC, keine
  IP) -- bestehende Sitzungen laufen ueber seal-est weiter, der Bruch schluege
  also erst beim naechsten AP- oder Manager-Neustart zu.
- TP19 NTP: alle drei Nicht-Core-Geraete fragten einen Zeitserver, den es nicht
  gab (`status=waiting`, branch hatte gar keinen). ap2 war 17 Stunden nach und
  hat einen Logeintrag von 04:57 als 12:19 gestempelt -- geraeteuebergreifende
  Korrelation war damit wertlos. Core wird Zeitquelle, die drei werden Clients.
- Template: `/ip service` exportiert `available-from=`, nicht `address=`. Das
  Soll war falsch und das Geraet hatte recht -- vier Dauer-Drifts. Und
  `hw-offload` fliegt aus dem Firewall-Renderer, weil REST es meldet und
  /export es weglaesst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 05:15:28 +02:00
2103774d1a 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>
2026-08-17 15:55:57 +02:00
d68e82d9ae TP16.1 Nachlauf: Mgmt-ACL via GC auf alle 4 Geraete (72/72), CF-Schalter entschieden
Neue Compliance-Feature ip-service (17->18 Regeln, 68->72 Checks). Sollzustand
einheitlich im Template: ssh/www/winbox/api = 10.40.0.0/16,100.96.0.0/12;
ftp/telnet/api-ssl disabled. Deploy gestaffelt (ap2 zuerst, am Geraet
gegengeprueft), Job liegt als 'mgmt-acl' in gc-configplan.py.

Befund war invertiert: branch/ap1/ap2 hatten GAR KEINE Address-Beschraenkung
und waren laengst per Mesh erreichbar; winbox war auf allen vier offen. Aus dem
Erreichbarkeits-Fix wurde eine Haertung. ftp/telnet/api-ssl dabei abgeschaltet.

CF-Schalter 'Allow all Cloudflare One traffic to reach enrolled devices':
recherchiert, bleibt AUS - er oeffnet die Client<->Client-Richtung, unsere laeuft
ohne ihn. Kein API-Feld, CF-Docs widersprechen sich (Profil- vs. globale
Einstellung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 12:55:03 +02:00
63851ad0ad TP16.1 ABGESCHLOSSEN: privater Zugang via natives WireGuard, ICMP repariert
4.5 Abnahme bestanden: 0% Ping-Loss auf alle BF-VLANs (vorher 100%), TCP mit
echtem Datenfluss ok, FQDN-Smoke beweist cloudflared-Public-Teil unberuehrt.
4.6 Auflage #4 erfuellt: Ist-Stand als intended config nach Nautobot,
65/68 -> Template ergaenzt -> 68/68 keine Drifts.

Zentrale Falle dokumentiert: /ip service address=10.40.0.0/16 sperrt das
Router-Mgmt aus der Mesh-Range 100.96.0.0/12 aus - Ping geht, SSH/REST/MikroMCP
sterben. Fuer branch/ap1/ap2 noch offen. Und: nc -z ueber WARP ist kein
Reachability-Beweis, der CF-Proxy terminiert den Handshake.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 12:28:03 +02:00
e17e45db91 TP22 abgeschlossen + WLAN-Roaming repariert (802.11k/v)
TP22 Schritt 5 — Datenmodell as-built aus dem Geraet erhoben (bridge/port,
bridge/vlan, bridge/host + ARP/Leases), nicht aus der Doku:
- crs326-core von 5 auf 26 Ports; 3 waren "GEPLANT (tentativ)", ether1 zeigte
  noch auf das tote sw1 #12
- Standort-Fehler: crs326-branch + ap2 standen auf Technik UG, real Technik OG
- sw1/sw2/cudy2 -> Decommissioned (Endzustand), cudy1 -> Offline;
  sw1-Duplikat-Ports (gi*) entfernt
- Schritt 4 entschieden: keine Secret-Injection (Governance-Regel 1 deckt es ab)

TP21.1/4 — core ether4 geklaert und behoben: dort haengt das Wohnzimmer-
Sideboard. Der Port war als ap1-Trunk vorkonfiguriert, pvid=40 nahm untagged an
(Upstream ok), Egress war tagged -> TV bekam nichts. Diagnose ueber TX/RX-
Asymmetrie + ARP failed bei frischem bound-Lease (ein bound-Lease beweist nur
den Upstream: INIT-REBOOT-REQUEST braucht kein ACK). Auf untagged VLAN40
gezogen, Kabel bleibt auf Port 4 (Patchfeld-Nummerierung ist Infrastruktur).

TP3.3 — Steering-Regression aus dem TP3-Rebuild behoben: /interface wifi
steering war auf BEIDEN APs leer. 802.11r/FT macht die Uebergabe nur schnell,
ausgeloest wird sie von 802.11k/v -> sticky client bis zum Abriss. st-main
(rrm/wnm, neighbor-group bf-main) wiederhergestellt und ins GC-Template
aufgenommen, damit eine Neuprovisionierung es nicht wieder still verliert.

Compliance 20/20 -> 63/68 (dieselben 5 bekannten Altlasten):
- neue Features wifi-steering, bridge-port, bridge-vlan
- der L2-Layer war bisher komplett unueberwacht (core-Zweig hatte gar keine
  Bridge-Sektion, AP-Zweig nur VLAN ohne Ports)
- Bridge-Sektionen bewusst als Literal-Block statt aus DCIM abgeleitet: pvid aus
  untagged_vlan zu generieren haette die akzeptierten Schiefstaende (core ether3,
  core ether2, branch ether9-23) zu Dauerdrift gemacht

Alle Geraete-Aenderungen liefen ueber Nautobot-GC-ConfigPlans mit /system backup
davor, keine Direkt-Writes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 02:51:38 +02:00
3666e1e7fe TP22: RouterOS-Fleet unter Nautobot Golden Config, Deploy scharf
Nimmt die 4 Live-Geräte (crs326-core/-branch, ap1, ap2) real unter Golden
Config: Backup -> Compliance -> intended -> kontrollierter Push. Damit greift
der Governance-Entscheid "Config exklusiv über Nautobot" operativ.

Secret-Leak geschlossen (Anlass, ungeplant gefunden)
  Es gab keine ConfigReplace-Regeln, deshalb hatte der Backup-Job den
  ap1-/export ungefiltert nach Gitea geschrieben: der live genutzte
  WG-Hub-private-key und 6 WLAN-PSKs lagen dort im Klartext.
  - nautobot/ingest-gc-scrubbing.py: 5 ConfigReplace-Regeln, Maske
    "<<REDACTED>>". RouterOS quotet nur bei Bedarf (4 von 6 PSKs standen
    unquotiert), daher Alternation mit der quotierten Variante zuerst --
    \S+ ist greedy und würde bei einem PSK mit Leerzeichen den Rest
    exponieren. Regex-Selbsttest läuft bei jedem Aufruf.
  - Gitea-Repo neu angelegt (History-Rewrite verworfen: Gitea hält
    unerreichbare Blobs bis zum server-seitigen gc). Verifiziert: 0
    unmaskierte Secrets über alle 4 Geräte. User-Entscheid: nicht rotieren.
  - push-gc-template.py: Pre-Push-Secret-Guard, --dry-run, -m, sha optional.

Template
  - AP-Zweig (role == "Wireless AP"), datengetrieben aus ConfigContext
    ap-common + local_config_context_data; ap1/ap2 differieren nur in 4
    Werten. RadioProfile verworfen (hängt an einem Controller, den es seit
    der CAPsMAN-Abschaffung nicht gibt).
  - crs326-core-Zweig von Slash- auf /export-Form (Space-Form, Attribute
    alphabetisch), stale disabled=yes aus der Cutover-Ära entfernt.
  - Switch-Zweig für crs326-branch.
  - Mgmt-Nummernplan korrigiert: ap2 und branch waren in den DNS-Statics
    vertauscht, ap1 zeigte auf ein nicht existierendes .99.3.
    Verbindlich: core .99.1 | branch .99.2 | ap1 .99.11 | ap2 .99.12.
  Ergebnis: ap1 intended == Geräte-Ist (0 Drift), core 68/69 Zeilen
  byte-identisch. 14 ComplianceRules, 51/56 compliant -- die 5 Restdrifts
  sind echte Altlasten (Rettungspfade, Aufräumen gehört zu TP19).

Deploy (nautobot_config.py, Image gc9)
  enable_plan/enable_deploy an. napalm-ros ist READ-ONLY: der Default-
  Dispatcher wählt NAPALM (Platform trägt napalm: ros), Backup geht,
  merge_config scheitert grundsätzlich mit leerer Fehlermeldung. Fix =
  custom_dispatcher auf NetmikoMikrotikRouteros, in den Golden-Config-
  Settings (nicht den Nornir-Settings). Pilot-Deploy: DNS-Statics auf dem
  Core korrigiert, per Purge-vor-Add, weil plan_type=missing nur add
  erzeugt und sonst Duplikate entstanden wären.
  Governance-Regeln in docs/teilprojekte.md festgeschrieben: Pläne nur
  feature-scoped (ein Voll-Push schriebe die Maske als PSK auf die APs),
  AP-Template nie zeilenweise auf ein laufendes Gerät (vlan-filtering=no
  reisst den Mgmt-Pfad ab).

CLAUDE.md: Power-Save-Fehldiagnose korrigiert
  Der P750W war nicht im Power-Save, sondern schlicht ausgeschaltet; das
  Ping-Symptom kam vom lokal mitlaufenden WARP-Client (cloudflared =
  QUIC-Proxy, kein ICMP). Die Merkregel "DHCP-geht-aber-Ping-nicht =
  ARP/Power-Save" ist damit widerlegt und entfernt; strukturell schliesst
  TP16.1 diese ICMP-Lücke.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 18:16:21 +02:00
d281a0f36f TP15: CRS326-Core als L3-Router aktiviert
- crs326-core nimmt Routing/DHCP/DNS/NAT/WAN/WireGuard von ap1 ueber.
- L2-Portplan korrigiert (ap1 #15, Arris WAN #16, branch #8, Sonos #2/3/5/6,
  IoT #14, VLAN10-Access #11, VLAN1-Hybrid #3/7/9/10/12/17-24).
- Backup-RSC gefixt (ether3-24 disabled) und via fixed-RSC eingespielt.
- Gestagede L3-Config enabled in einem Rutsch.
- Falsche statische Default-Route 0.0.0.0/0 -> 10.40.41.1 entfernt,
  WAN-DHCP via 90.146.33.177/24 aktiv.
- SFP-Ports bleiben disabled (Stromersparnis).
- ap1 ist L3-stillgelegt und wird in naechster Session reiner AP.

Backup-Dateien (*.backup) und leases-export.json bleiben lokal.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 22:39:29 +02:00