Ein Hebel, sonst nichts. 2026-08-31 08:09 am Manager crs326-core: /interface wifi security set [find name="sec-main"] ft-over-ds=no /interface wifi capsman remote-cap provision [find] ft=yes bleibt -- FT laeuft weiter over-the-air, nur nicht mehr over-the-DS. Nimmt exakt die Aenderung vom 2026-08-17 zurueck. Abnahme (Lease, nicht Registration-Table): - Manager, alle vier aktiven Master-VAPs cap-wifi3/4/5/6: ft=true ft-over-ds=false - alle 3 CAPs state=Ok, alle VAPs running=yes AM CAP gelesen - iPhone nach 71 s zurueck auf dirtyvader-main, frische Lease 10.40.10.196, auth-type=ft-wpa3-psk, -54 dBm; 30 Clients gesamt zurueck - Log 08:13:20 zeigt sauberes "roamed to" zwischen zwei APs -> Roaming intakt - Geraete-Backup vorher: pre-tp25-funde-ftoverds.backup Governance: Transaktion TP25-fund-e-ft-over-ds OFFEN (Scope wifi-security, Ablauf 2026-09-03). Compliance steht deshalb ABSICHTLICH auf 134/135; der Diff ist exakt ft-over-ds=yes->no, kein Kollateral-Drift durch die Re-Provisionierung. Das GC-Template wird erst beim COMMIT nachgezogen -- vorher gruen machen wuerde den laufenden Versuch unsichtbar machen, und gc-transaktion.py verweigert den Commit ohnehin, solange der Scope driftet. 135/135 kommt nach der Messung zurueck. Messstand nach 25 min: weiter 93, letzter reauthenticating 07:34:43 (vor dem Eingriff). Logging nachweislich lebendig (593 wireless-Zeilen heute, beide SSIDs). Noch kein Ergebnis, nur ein sauberer Schnitt. Drei Funde: - cap-wifiN-Karte hat sich beim Re-Provisionieren VERSCHOBEN: ap2 war 1/2 -> jetzt 3/5, ap3 war 5/6 -> jetzt 4/6, ap1 hat 1/2 bekommen. Wer die 07:xx-Zeilen gegen die neuen liest, ordnet dem falschen AP zu. - Korrektur am Vormittagsbefund: main unterscheidet sich in ZWEI Attributen, nicht einem -- es ist auch die einzige SSID ohne wpa2-psk. Die Kontrollgruppe trennt FT und WPA3-only nicht. Wenn Hebel 1 und 2 beide nichts bewegen, ist authentication-types der naechste Kandidat, NICHT signal-range. - gc-transaktion.py rief sshpass -p auf (Passwort in argv, Klasse vom 2026-08-22). Auf SSHPASS-Env + -e umgestellt, weil das Skript laufen musste. Fuenf weitere Dateien unter routeros/ haben dasselbe Muster und sind bewusst NICHT angefasst (Stop-Bedingung; gehoert zu TP30). Entwarnung: /export auf 7.24 gibt Passphrasen gar nicht aus (live geprueft), die Transaktionsakte im Git ist sauber. Nebenbei: .gitignore hatte docs/nas-vlan20/stacks/ MIT Schraegstrich -- im Worktree liegt dort ein Symlink auf den Haupt-Checkout, der war damit nicht ignoriert. Doku an allen drei Stellen nachgezogen (Quick-Index, TP25-Abschnitt, Ist-Stand-Block) plus CLAUDE.md-Pflichtlektuere und neuer Handoff mit Entscheidungstabelle fuer 09-01. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nautobot-Tooling
ingest-baseline.py
Idempotenter Basisdaten-Ingest (Locations, Rollen, Device-Types, Devices, VLANs/Prefixes, ap1-Interfaces + IPs, WLAN-Modelle). Bildet den Ist-Zustand ab, nicht den Zielzustand.
export NAUTOBOT_TOKEN=... # aus docs/nas-vlan20/stacks/210-nautobot.yml (gitignored)
python3 nautobot/ingest-baseline.py # Dry-Run
python3 nautobot/ingest-baseline.py --apply # schreiben
API-Fallen (teuer gelernt)
tagged_vlansliest sich per REST alsnull, obwohl korrekt gespeichert. Verifikation nur über GraphQL:POST /api/graphql/mit{interfaces(device:"ap1"){name mode untagged_vlan{vid} tagged_vlans{vid}}}.- Relationen kommen ohne
?depth=1ohnedisplay→ ein voll gepflegtes Device sieht leer aus. LocationType.content_typesmussipam.vlangroup/ipam.vlan/ipam.prefix/dcim.controllerenthalten, sonst 400 beim Anlegen.parent_interfacenur für virtuelle Interfaces — WLAN-VAPs können ihren Master nicht als Parent tragen.WirelessNetworkhat kein VLAN-Feld; die VLAN-Bindung hängt anwireless/controller-managed-device-group-wireless-network-assignmentsund braucht zwingend einenController(bei uns logisch,controller_deviceleer — kein CAPsMAN).RadioProfile.channel_widthwill Integer ([20,40,80]), nicht"20mhz".- IP↔Interface läuft über
/ipam/ip-address-to-interface/.
ingest-wifi-access-list-rule.py
Legt ComplianceFeature + ComplianceRule wifi-access-list an (Plattform RouterOS,
match_config=/interface wifi access-list). Idempotent, Dry-Run ist Standard.
export NAUTOBOT_TOKEN=...
python3 nautobot/ingest-wifi-access-list-rule.py --apply
Warum es die Rule braucht: ohne sie erzeugen Eintraege in der access-list keinen Drift
und lassen sich nicht als Config-Transaktion fuehren -- gc-transaktion.py verlangt eine
ComplianceRule als --scope. docs/tp25-pin-s22.sh schreibt dort bei jedem Messrundgang, und
TP25 Fund E (signal-range-Boden) landet dauerhaft dort.
Der Soll-Zustand ist leer und steht als Kommentarblock [6c] im Template. Waehrend eines
Messlaufs ist der Drift erwartet und gehoert als offene Transaktion gefuehrt.