TP28 wieder geoeffnet: ap3 (cAP ax) vorbereitet, core ether21 Trunk, MikroMCP-Registry auf bf-infra

Dritter Access-Point ap3 (MikroTik cAP ax, cAPGi-5HaxD2HaxD) kommt dazu und loest
mittelfristig ap1 in Technik UG ab. Statt eines neuen TP wandert TP28 aus dem Archiv
zurueck -- neue Regel: ein archiviertes TP ist ein geschlossenes, kein versiegeltes
Ticket (Christoph-Direktive 2026-08-30).

Live am Core:
- ether21 ist AP-Trunk (10/20/30/40/50/90/99 tagged, Muster ether15). ⚠️ Erratum: erst
  war ether22 angenommen und getaggt; der Port hat keinen Link. Gegenprobe ueber die
  Bridge-Host-Tabelle: auf ether21 sitzt D0:EA:11:FF:16:9D = E01 vom ap3-Label.
  ether22 wieder leer.
- Backups vorher: pre-ap3-20260830.backup/.rsc auf core und ap1.
- Compliance vor und nach jeder Aenderung 104/104, 0 Drifts.

Golden Config (2 Pushes: e25d654b, 20472cdb):
- Core-L2-Block traegt ether21.
- AP-Zweig rendert die Bridge-Ports jetzt aus ap.extra_ports statt hartkodiert
  ether3/4/5. Das war die stille Annahme "AP == hAP ax2 mit 5 Ports"; der cAP ax hat
  zwei. Default in ap-common = hAP-ax2-Bestand, ap3 ueberschreibt mit [].
  Dass ap1/ap2 danach zeichengleich rendern, beweist die 0-Drift-Messung.

Kanalplan NICHT neu erfunden: TP25 hat ihn am 2026-08-24 fuer genau dieses Geraet
gerechnet (DFS vom User genehmigt). ap3 = 5180/Ce + 2437 (ch6, nicht ch1 -- ch1 bleibt
fuer ap1, damit 1/6/11 erstmals lueckenlos aufgeht). ap1/ap2 gehen beim Umzug auf
5260/Ce bzw. 5300/Ce, 5220/Ce bleibt Ausweichspur.

MikroMCP-Registry (MCP-Lifecycle, User-Freigabe 2026-08-30) -- zwei Drifts:
- MIKROMCP_CONFIG_PATH zeigte auf ~/dev/bf-network-r6 (Archiv-Repo); die identische
  Datei in bf-infra war wirkungslos. Jetzt bf-infra = SSoT.
- In opencode.jsonc fehlte MIKROMCP_CONFIG_PATH ganz, hinterlegt waren nur ap1/ap2 --
  opencode kannte core/branch gar nicht. Beide Clients zeigen jetzt auf dieselbe
  Registry; ap3 aufgenommen, rosVersion von stale 7.23/7.19.5 auf 7.24 korrigiert.
  Neustart des MCP noetig, Registry wird nur beim Start gelesen.

Noch offen: physischer Bring-up (Datei liegt bereit), ap1-Radios aus, CAPsMAN-Objekte
fuer ap3, Nautobot-Adoption, Messrunde -- und die Passwort-Rotation: das gemeinsame
MikroTik-Admin-PW ist in dieser Session durch eine ungefilterte Ausgabe des
mikromcp-env-Blocks ins Transkript geraten und gilt als verbrannt (Posten fuer TP30).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 12:14:21 +02:00
parent dd12ab505b
commit fd05286e4b
11 changed files with 403 additions and 139 deletions

View File

@@ -60,7 +60,7 @@ teuerste Eigenschaft der Datei zerstört, um ihr billigstes Problem zu lösen. B
| [TP22](#tp22) | Device-Adoption + Golden-Config Compliance-Push (RouterOS-Fleet) | ✅ DURCH (2026-08-13) — Compliance heute **104/104, 0 Drifts** (live 2026-08-23) |
| [TP26](#tp26) | `/ip firewall filter` unter Drift-Kontrolle | ✅ DURCH (2026-08-17) |
| [TP27](#tp27) | RouterBOOT-Firmware auf 7.24 nachziehen | ✅ DURCH (2026-08-17/18) |
| [TP28](#tp28) | WLAN über CAPsMAN auf `crs326-core` | ✅ KOMPLETT (2026-08-18) |
| [TP28](#tp28) | WLAN über CAPsMAN auf `crs326-core` | ↩️ **wieder geöffnet 2026-08-30** (ap3) — Volltext in [teilprojekte.md](teilprojekte.md#tp28) |
| [TP-R](#tp-r) | Router-Capabilities-Sweep | FERTIG (docs/research/routeros-capabilities.md) |
Dazu am Ende: **[TP25 (Langfassung)](#tp25-lang)** — die Messchronik und die Funde A–E im Volltext.
@@ -1261,126 +1261,13 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
<a id="tp28"></a>
### TP28 — WLAN über CAPsMAN auf `crs326-core` ▸ ✅ **KOMPLETT (2026-08-18)** — mit Nachtrag: **`slaves-datapath` fehlte, IOT+MEDIA lagen ~14 h**
### TP28 — WLAN über CAPsMAN auf `crs326-core` ▸ ↩️ **WIEDER GEÖFFNET 2026-08-30**
- 🔴🔴 **POST-MORTEM 2026-08-18 (gemeldet von Christoph: „die -iot-geräte sind offline … connect möglich, aber kein dhcp"):**
Seit dem Cutover hingen **alle Slave-VAPs in gar keiner Bridge**. `/interface wifi cap slaves-datapath`
war auf beiden APs leer — und genau dieses Feld ist das Einzige, was die vom Manager erzeugten
Slave-VAPs lokal in die Bridge haengt. Der Manager schickt `datapath.bridge=bridge` zwar mit,
**der CAP uebernimmt davon nur die `vlan-id`.** Betroffen: `dirtyvader-iot`, `-media`, `-untrusted`,
`-guest`. Nicht betroffen: `dirtyvader-main` — dessen Master-Radios `wifi1`/`wifi2` sind
**statische** Bridge-Ports und liefen deshalb weiter. Genau das machte den Ausfall unsichtbar.
- **Fix (live 2026-08-18 auf ap1 + ap2, seither Soll im Template):**
`/interface wifi datapath add name=dp-caps-slaves bridge=bridge` +
`/interface wifi cap set slaves-datapath=dp-caps-slaves`. Das Objekt traegt **bewusst keine
`vlan-id`** — die liefert der Manager pro VAP. Danach erscheinen die VAPs als **dynamische
Bridge-Ports mit `pvid`=30/40/50/90**, und DHCP laeuft sofort wieder.
- 🔴 **Die Diagnose-Lehre: „Client assoziiert" beweist gar nichts.** Am Manager standen 25 IOT-
Registrations — das WLAN sah perfekt aus. Erst zwei Reads trennten die Faelle:
`torch` auf `vlan30` am Core (**leer**) und der TP5-Drop-Log (**kein einziger DHCP-Eintrag**).
Beides leer heisst: es wird nichts verworfen, es **kommt** nichts. Damit war die Firewall
— der naheliegende Verdaechtige nach der Haertung derselben Nacht — in zwei Minuten entlastet.
- ⚠️ **Die Abnahme „✅ Ohne jeden Aussetzer" weiter unten war falsch.** Sie zaehlte Registrations
(30 Clients, beide CAPs `Ok`, 7 VAPs je AP) — also genau die Metrik, die hier luegt. Keiner
dieser Werte beruehrt die Bridge. Ein Abnahmekriterium fuer WLAN-Umbauten ist ab jetzt eine
**frische DHCP-Lease pro SSID**, nicht die Registration-Table.
- **`routeros/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. Der Ein-Zeilen-Fix war damit weg. Nachtrag steht im Skript.
- ✅ **Reboot-Abnahme an ap2 (2026-08-18), drei Fragen auf einmal beantwortet:** `slaves-datapath`
ueberlebt den Neustart (statisches Objekt, steht im `/export`), der CAP **findet seinen Manager
durch die gehaertete input-Kette wieder** (`current-caps-man-identity=crs326-core` — MNDP/CAPWAP
sind also korrekt offen, das war seit TP5 Etappe 4 nie durchgespielt), und die sieben Slave-VAPs
kommen von selbst als dynamische Bridge-Ports mit pvid 30/40/50/90 zurueck. AP nach **40 s**
wieder erreichbar. Abnahme nach neuer Regel = **frische Lease**: IOT-Client `10.40.30.8`
`last-seen=30s`, MAIN-Client `10.40.10.180` `last-seen=1m54s`.
- ⚠️ **Reboot per MikroMCP geht auf 7.24 nicht:** das `reboot`-Tool sendet `delay`, die REST-API
antwortet `unknown parameter delay`; `run_command` ist fuer `/system reboot*` per Deny-Policy
gesperrt. Weg bis das gefixt ist: `sshpass` + `ssh admin@<ap> "/system reboot"`.
- ✅ **Soll nachgezogen, Compliance wieder sauber: 92/92, 0 Drifts** (2026-08-18). Weg: Template in
`nautobot/mikrotik_routeros.j2` → `routeros/push-gc-template.py` (Secret-Guard) → GitRepository-Sync
→ Backup/Intended/Compliance. Ohne den Push meldet der Refresh die zwei neuen Zeilen als `extra`
auf beiden APs — das Jinja lebt im **separaten** Gitea-Repo `bf-golden-config`, ein Commit hier
allein erreicht Nautobot nicht.
- ⚠️ **Beim ersten Sync-Versuch: `redis.exceptions.ConnectionError: broken pipe`** auf dem
Nautobot-Stack. Ein simpler Retry ging durch; NAS-Load war unauffaellig (0,9). Der Job meldet das
als `FAILURE` — nicht mit einem inhaltlichen Fehler verwechseln.
- ✅ **Der offene GC-Rest ist erledigt (2026-08-18).** Die fuenf `wifi-*`-ComplianceFeatures haengen
jetzt am **Core**, der AP-Zweig des Templates ist auf eine einzige Zeile eingedampft
(`/interface wifi cap set discovery-interfaces=vlanXX enabled=yes`).
- 🔴 **Dabei aufgefallen: die APs trugen noch die KOMPLETTE Standalone-WLAN-Config** aus TP3 —
je 2 channel, 6 datapath, 6 security, 7 configuration, 1 steering. Der Cutover vom 08-17 hatte
sie nie abgeraeumt. Wirkungslos (der Manager liefert alles dynamisch), aber sie im Template als
Soll zu rendern hiesse, totes Zeug zur Absicht zu erklaeren — dasselbe Argument wie bei den
defconf-Firewallregeln in TP26. Abgeraeumt mit `routeros/tp28-ap-wifi-reste-abraeumen.rsc`.
- ✅ **Ohne jeden Aussetzer:** vorher/nachher 30 Clients, beide CAPs `Ok`, 7 dynamische VAPs je AP.
Die Sorge vor einem Radio-Re-Apply (TP25/TP3.3: „wirft jeden Client kurz raus") hat sich nicht
bestaetigt — die dynamischen VAPs tragen ihre Werte **inline** (`datapath.vlan-id=…`) und
referenzieren kein lokales Objekt; nur `wifi1`/`wifi2` hielten noch einen toten
`configuration=`-Verweis, der beim Loeschen folgenlos blieb.
- 🔴 **`[find !dynamic]` ist auf diesen Sektionen ein SYNTAXFEHLER**, nicht bloss wirkungslos:
`/interface wifi configuration` & Co. haben gar keine `dynamic`-Eigenschaft (die gibt es nur auf
`/interface wifi` selbst). Der erste Anlauf lief komplett in die `on-error`-Zweige, aenderte
**nichts** und meldete trotzdem „Plan Completed". Wieder: nur die Gegenpruefung am Geraet zaehlt.
- ✅ **Drei neue ComplianceRules schliessen die letzten WLAN-Luecken:** `wifi-capsman`
(der Manager-Schalter), `wifi-provisioning` (die vier Regeln je `radio-mac` — sie entscheiden,
welcher AP welche Kanaele und Slave-VAPs bekommt) und `wifi-cap` (die CAP-Seite; faellt
`discovery-interfaces` weg, findet der AP seinen Manager nach dem naechsten Reboot nicht mehr).
**Ergebnis: 92/92 compliant, 0 Drifts.**
- ⚠️ **`wifi-security` ist gruen, aber NICHT deploybar.** Die Passphrasen stehen als `<<REDACTED>>`
im Template (User-Entscheid 2026-08-18: alle fuenf Features umhaengen, Platzhalter in Kauf nehmen).
Der gruene Haken beweist nur, dass Soll und Ist dieselbe **Maske** tragen — nicht, dass die
Passphrasen stimmen, und schon gar nicht, dass die Sektion ausgerollt werden koennte. Das steht
als Warnung im Template. Wer sie aendert, liest den Ist-Stand per REST zurueck
(`GET http://10.40.99.1/rest/interface/wifi/security`) — **nicht** aus `wlan-psks.env` oder den
drei Bring-up-Dateien, die voneinander abgeschrieben sind.
- ⚠️ **Die frueher hier notierte „bisher fehlende Rule auf `/interface wifi`" ist gegenstandslos** —
wie vorhergesagt: ein CAP hat keine Inline-Overrides mehr, die driften koennten.
> **Methodenwechsel auf Christophs Anstoß:** *„ich möchte die methode in frage stellen … eine sot ist zwar nett,
> aber wenn sie uns das leben zur hölle macht, verzichte ich auf diese governance."* Der Entscheid vom
> 2026-07-22, CAPsMAN abzuschaffen, ist damit **revidiert**.
- ✅ **Warum es diesmal trägt:** 2026-07-22 war **ap1 Manager UND AP** — und ein Manager kann seine eigenen
Radios nicht per CAPsMAN provisionieren (MikroTik-bestätigt). Genau diese Asymmetrie war die Ursache von
TP3.1. Mit dem **Core** als Manager sind beide APs symmetrisch. **Der Core braucht dafür kein `wifi-qcom`:**
das `capsman`-Menü steckt im Basis-`routeros`, die 3,35 MB freier Flash sind irrelevant. Die zweite
Begründung von damals („WLAN instabil") war ohnehin widerlegt — standalone blieb es instabil, die Ursachen
waren die Funkparameter aus TP25.
- ✅ **Ist-Stand:** Manager auf `vlan99`, 4 Kanäle · 6 Datapaths · 6 Security · 2 Steering · 9 Configurations ·
4 Provisioning-Regeln je `radio-mac`. Beide `remote-cap` **`Ok`**, je 7 dynamische VAPs. Kanäle exakt wie in
TP25 gemessen (ap1 `5180/ax/Ce/I`+`2412/ax`, ap2 `5220/ax/Ce/I`+`2462/ax`). **34 Clients** (main 3, iot 27,
media 4), Roaming im Manager-Log belegt. **`ft-over-ds=yes`** ist jetzt aktiv (unter CAPsMAN erstmals
verfügbar), `-guest` hat eigenes `st-guest` mit **`neighbor-group=bf-guest`** — nicht `bf-main` mitbenutzen,
sonst meldet 802.11k Gast-Clients BSSIDs einer SSID, auf die sie nicht assoziieren können.
- 📌 **Local-Forwarding ist keine Einstellung mehr:** im neuen `/interface/wifi` gibt es **kein** zentrales
Forwarding („There is no CAPsMAN-forwarding in WiFi (RouterOS 7.0+)"). Die `datapath`-Property existiert
deshalb nicht — `monitor` bestätigt `traffic processing on CAP`.
- 🔴 **DIE MESSFALLE DIESES TPs — unter CAPsMAN führt der MANAGER die Tabellen, nicht der CAP.**
`/interface/wifi/registration-table` und die `wireless`-Logs sind auf ap1/ap2 **leer**, obwohl das WLAN
einwandfrei läuft. Ich habe daraus zweimal „WLAN ist unten" geschlossen, während Christophs Geräte mit
vollem Ausschlag verbunden waren und ein Speedtest gut lief. **Immer am Manager zählen.**
- 🔴 **DIE ZWEITE FALLE — drei übereinstimmende Dateien sind nicht drei Belege.** `wlan-psks.env` wich für
iot/untrusted/infra von `ap1-prov-base.rsc`, `ap2-prov-base.rsc` und `ap1-standalone.rsc` ab. Ich habe die
drei als Bestätigung gelesen und die env-Datei „korrigiert" — **~20 Shellys waren 20 Minuten aus dem Netz.**
Die drei Dateien stammen alle aus dem Bring-up vom 2026-08-08, sind also **eine Quelle in drei Kopien**.
✅ **Auflösung:** die Passphrasen sind am Gerät per REST **lesbar**
(`GET http://10.40.99.1/rest/interface/wifi/security`) — dort ausgelesen ergab sich exakt der env-Wert.
`wlan-psks.env` ist neu aus dem Live-Stand befüllt und trägt jetzt eine Kopf-Warnung; die drei Baselines
sind seit dem Cutover ohnehin nicht mehr deploybar und wurden entschärft (Passphrasen raus, HISTORISCH).
- ✅ **~~OFFEN — das GC-Modell beschreibt weiter Standalone-APs~~ — ERLEDIGT am 2026-08-18.** Die
`wifi-*`-Features haengen jetzt am Core, das AP-Template ist auf die `cap`-Zeile eingedampft, und die
toten Standalone-Objekte sind von beiden APs abgeraeumt. Details im ersten Block dieses TPs.
Die hier genannte Zahl `76/76` ist damit doppelt ueberholt (aktuell 92/92 bei 23 Rules).
*(Der Absatz stand bis 2026-08-19 unveraendert als „OFFEN" hier, obwohl der Kopf des TPs schon
„KOMPLETT" sagte — ein Selbstwiderspruch im selben Abschnitt, ueber den prompt die naechste Session
gestolpert ist. Merkregel fuer kuenftige Statuswechsel: **nicht nur den Header umschreiben, sondern
die Punkte darunter mitziehen.**)*
- 📌 **Nebenbefund:** HAs `mikrotik`-Integration pollt alle 10 s und schreibt zwei Log-Zeilen pro Poll auf jedes
Gerät. Die AP-Logs sind dadurch für Diagnose praktisch unbrauchbar (`get_log` ohne `topics`-Filter liefert
nur `admin logged in/out via api`).
- **Abh.:** TP25 ✅ (die Funkparameter sind übernommen), TP15/TP21.1 ✅ (Core als L3-Router = Manager-Standort).
Verwandt: **TP3** (dessen CAPsMAN-Ära hier revidiert wird), **TP22** (GC-Scope).
> Der Volltext steht seit dem 2026-08-30 wieder in
> [`teilprojekte.md` → TP28](teilprojekte.md#tp28), weil mit **ap3** (cAP ax) ein dritter
> Access-Point dazukommt. **Ein archiviertes TP ist ein geschlossenes Ticket — es darf wieder
> geöffnet werden** (Christoph-Direktive 2026-08-30); der Abschnitt wandert zurück, nicht nur
> ein Nachtrag. Hier bleibt dieser Zeiger stehen, damit alte Links nicht ins Leere gehen.
<a id="tp-r"></a>