Die `### TPnn`-Header trugen weiterhin Status-Anspruche (▸ ✅ FERTIG …, ▸ ⏳ CUTOVER …),
obwohl Index/Status seit dem TP36-Cutover in Gitea liegt. Das war eine dritte Statusquelle,
die den Labels nachlief — Header-Marker datierten teils Wochen vor dem Issue-Update.
- 75 Header (32 aktiv + 43 Archiv) auf `### TPnn · Gitea #N — <Titel> — <Caveat>` umgestellt.
Caveats, Warnungen, Querverweise und Archiv-Links bleiben erhalten, nur der Status faellt weg.
Status-Marker im Fliesstext (Messchronik, Unterpunkte) bleiben — sie beschreiben Historie.
- TP47 fehlte als Gitea-Issue komplett (nur in der Datei seit 808d3a1) -> als #74 angelegt.
- bin/gitea-tp-sync.py schrieb in die falsche Richtung: der Abgleich leitete den Zielzustand
aus dem Datei-Marker ab (fest ✅) und haette #24 (TP34, bewusst status:dropped) auf status:done
gezogen. Jetzt werden nur noch FEHLENDE Archiv-Issues angelegt, bestehende nie angefasst.
- CLAUDE.md: Header-Form + Werkzeug-Richtung festgehalten.
- Announcement 2026-10-03 für die naechste Session.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
312 KiB
BF-Netzwerk — Teilprojekte-Archiv (abgeschlossene TPs)
Was hier steht: jedes Teilprojekt, an dem keine offene Arbeit mehr hängt — im Volltext und unverändert, so wie es in
teilprojekte.mdstand. Nichts ist gekürzt oder umgeschrieben worden; der Split am 2026-08-23 hat Text nur verschoben.Was hier NICHT steht: der aktuelle Stand. Der lebt in
teilprojekte.md— Ist-Stand, kritischer Pfad und alle offenen TPs. Eine frische Session braucht nur jene Datei; diese hier liest man, wenn man wissen will, warum etwas so entschieden wurde.⚠️ Nicht als Ist-Stand lesen. Jeder Abschnitt beschreibt den Stand zum Zeitpunkt seines Abschlusses. Wo ein Gerät seither ausgebaut oder eine Rolle umgezogen ist, steht das als datierter Nachtrag drin (Projektkonvention: fortschreiben, nicht überschreiben) — aber die Wahrheit über das heutige Netz ist das Gerät, dann
CLAUDE.md, dannteilprojekte.md.
Warum überhaupt getrennt (User-Anstoß 2026-08-23: „die teilprojekte.md beginnt zu explodieren"):
die Datei war auf 2217 Zeilen gewachsen, 49 % davon abgeschlossene TPs. Das Wachstum kam nicht
aus der Zahl der TPs, sondern aus der Historie erledigter — und die wird gelesen, wenn jemand
gezielt danach sucht, nicht beim Einstieg. Bewusst nicht getrennt wurde nach TP (das wären ~35
Dateien): die Querbezüge, die das Dokument wertvoll machen — Reihenfolge, Abhängigkeiten, „TP23 hängt
an TP5 in beide Richtungen" — leben von der Nähe im selben Text. Ein Schnitt pro TP hätte die
teuerste Eigenschaft der Datei zerstört, um ihr billigstes Problem zu lösen. Begründung im Detail:
doku-cleanup-session.md Punkt F.
Inhalt
| TP | Thema | Status bei Abschluss |
|---|---|---|
| TP1 | ALLNET Core-Switch finalisieren | ✅ FERTIG (2026-06-15) → ❌ Gerät AUSSER BETRIEB (2026-08-08, durch crs326-core ersetzt) |
| TP2 | Omada Access-Switch + Controller | ✅ FERTIG (2026-06-15) |
| TP2.1 | Omada-Switch (sw2/ES208G) → Standalone-Recovery (kein Controller) | ✅ FERTIG (2026-07-16, User solo) |
| TP3 | WLAN | 📜 VOLLSTÄNDIG HISTORISCH |
| TP3.1 | ap2 VLAN-Trunk-Fix | ✅ Config live (2026-07-01) |
| TP3.2 | WLAN Coverage / P750W-Discovery | ✅ ABGESCHLOSSEN (2026-08-17, User-Test erfolgreich) |
| TP3.3 | WLAN Coverage-Kur | 📜 IN TP25 AUFGEGANGEN (2026-08-17) |
| TP4 | Router-Cutover (hAP#1 = Router + WAN-Edge) | ✅ FERTIG (2026-07-01) |
| TP5 | Firewall & Inter-VLAN-Policy | ✅ DURCH (2026-08-18): deny-by-default in BEIDEN Ketten scharf · + E5 (2026-08-19) |
| TP6 | QoS/CAKE + Call-Quality-A/B-Test | ✅ GESCHLOSSEN 2026-08-23 — ⚠️ Begründung darin von TP6.1 überholt |
| TP6.1 | Saettigung vermeiden statt Bufferbloat bekaempfen | ✅ LIVE UND GEMESSEN (2026-08-23): 40,8 → 11,0 ms unter Last |
| TP7 | Media-Discovery (mDNS) für VLAN 40 | ✅ FERTIG (2026-07-02) |
| TP7.1 | SSDP-Relay (macOS-Sonos-App über VLAN-Grenze) | ✅ LÄUFT (2026-08-18) |
| TP7.2 | HA↔Sonos static-host binding + VLAN1/GUEST-Discovery | ✅ FERTIG (2026-07-03) |
| TP9 | Gateway-/Router-HA | ❌ OBSOLET (User-Entscheid 2026-08-08) |
| TP10 | Multi-Site VPN | ✅ KERN DURCH (2026-06-27) |
| TP14 | Host/Container-IP-Migration VLAN1→VLAN20 (Docker-Cutover NAS+pve) | ✅ DURCH (2026-07-13; live re-verifiziert 2026-08-08) |
| TP14.1 | Session A: NAS fertigstellen | ✅ DURCH (2026-07-10); Omada-Inform/sw2 VERTAGT |
| TP14.2 | Session B: pve-Docker-LXC (.126) → VLAN20 | ✅ DURCH (2026-07-10) (ipvlan) |
| TP14.2a | pve-mcp Single-Session-Fix + VLAN20-Host-DNS | ✅ (2026-07-10) |
| TP14.3 | Session C: Dormante Stacks vlan20-tauglich + Referenz-Sweep | ✅ Referenz-Sweep durch (2026-07-16); dormante Stacks weiter bewusst nicht deployt |
| TP14.5 | Session E: Freigabe-Gate → TP5-Firewall | ✅ ERFÜLLT (2026-08-08) |
| TP15 | HW-Refresh: Switching + Router | ✅ ABGESCHLOSSEN (2026-08-08) |
| TP16.1 | Private Access via native Cloudflare Mesh (WireGuard) auf crs326-core |
✅ ABGESCHLOSSEN (2026-08-17) — privater Zugang via nativem WireGuard cf-mesh |
| TP17 | Shelly-Übersiedelung VLAN1 → VLAN30 (IOT) + shelly-mcp |
✅ KOMPLETT (User-Bestätigt 2026-08-13): alle Shellys auf VLAN30 |
| TP19 | cudy-Teardown + VLAN1-Client-Retirement | ✅ GESCHLOSSEN (2026-08-18) |
| TP20 | Platform-Datenbank (Postgres Precious-Tier + MariaDB Tier-2) | ✅ Plattform live (2026-07-16) |
| TP21 | Nautobot Golden Config (config-as-code Control-Plane) | 🟢 Plattform + Datenmodell + Templates live |
| TP21.1 | Core-Cutover-Recovery (ap1 → crs326-core als L3-Router) | ✅ NETZ WIEDER LIVE (2026-08-08) — Aufräum-Todos alle erledigt (Stand 2026-08-23) |
| TP22 | Device-Adoption + Golden-Config Compliance-Push (RouterOS-Fleet) | ✅ DURCH (2026-08-13) — Compliance heute 104/104, 0 Drifts (live 2026-08-23) |
| TP25 | WLAN-Stabilisierung | ✅ FERTIG (2026-09-15) — Platzierung final (ap1 Sideboard · ap2 UG · ap3 OG), Fund E geschlossen |
| TP26 | /ip firewall filter unter Drift-Kontrolle |
✅ DURCH (2026-08-17) |
| TP27 | RouterBOOT-Firmware auf 7.24 nachziehen | ✅ DURCH (2026-08-17/18) |
| TP28 | WLAN über CAPsMAN auf crs326-core |
↩️ wieder geöffnet 2026-08-30 (ap3) — Volltext in teilprojekte.md |
| TP-R | Router-Capabilities-Sweep | FERTIG (docs/research/routeros-capabilities.md) |
| TP39 | LXC-Hygiene pve: Resolver-Altlasten, networking.service, DB-Reverse-Lookup |
✅ ABGESCHLOSSEN (2026-09-01) — pve+NAS-Sweep grün |
| TP34 | Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) | ❌ VERWORFEN (2026-09-08) — Caddyfile bleibt manuell · Fortsetzung: TP34.2 (2026-09-22) |
| TP44 | Cloudflare-Estate als Dokumentations-SSoT in Nautobot | ✅ DURCH (2026-09-10) |
| TP41 | CF-Access-Reparatur + Zero-Trust-Konsolidierung | ✅ ABGESCHLOSSEN (2026-09-10) — Gelis WARP via Android eingerichtet, letzter Blocker weg |
| TP43 | dw-Standort-DNS-Uplink (site-spezifische Overrides) | ♻️ REOPENED (2026-09-11) — Volltext zurück in teilprojekte.md; interne BF-Namen über WG am dw offen |
| TP42 | Namens-Vereinheitlichung: ein interner Suffix bf.emsenhuber.net | ✅ DURCH (2026-09-02) — .bf.lan raus, .16 abgebaut, Compliance 140/140 |
Dazu am Ende: TP25 (Kondensat) + TP25 (Langfassung) — TP25 ist ✅ abgeschlossen (2026-09-15); der aktive Stand (Kondensat) und die 394-Zeilen-Herleitung (Messchronik A–G) liegen beide hier.
TP1 · Gitea #34 — ALLNET Core-Switch finalisieren — → ❌ Gerät AUSSER BETRIEB (2026-08-08, durch crs326-core ersetzt)
- ✅ GE8 Trunk (native vlan1, tagged 10/20/30/40/50/90/99/100) — war bereits aktiv.
- ✅ VLAN 40 umbenannt: UNTRUSTED → MEDIA (
switch/cli/04-vlan50-media-untrusted.cli). - ✅ VLAN 50 angelegt + benannt: UNTRUSTED.
- ✅ GE1/GE2 (AP-Trunks) um VLAN 50 ergänzt; GE8 auto-includiert (Trunk).
- Ergebnis: Core trägt alle VLANs (10/20/30/40/50/90/99/100) an P1/P2/P8.
TP2 · Gitea #35 — Omada Access-Switch + Controller
- ✅ Omada Controller 6.2.10.17 auf DS923 (macvlan
.175):omada/docker-compose.yml, Stack via Portainer endpointId=14. Wizard abgeschlossen (configured=true), Creds inmcp/omada/.env. - ✅ pve-mcp (samik081) in Claude Code eingetragen (
~/.claude/settings.json, SSE.173:3000). - ✅ omada-mcp live auf pve-LXC (
.126, endpointId=2), ipvlan-IP.176, Stack Id=200, URL in~/.claude/settings.json.- Transport: StreamableHTTP
http://10.40.41.176:3000/mcp(Health/health→ 200). Settings-Bug (doppelter Eintrag) behoben 2026-06-15. - Auth: Omada Open API Client-Credentials. Creds in
mcp/omada/.env. Token-Format:Authorization: AccessToken=<token>(nicht Bearer). OMADA_TOOL_CATEGORIES=all (alle 84 read-Tools aktiv; write für VLANs/Ports nicht im MCP implementiert → direkte Open API oder Controller-UI). - omadac_id=
adbef8fa…, site_id=6a2fe68e….
- Transport: StreamableHTTP
- ✅ VLANs im Controller: 1/10/20/30/40/50/90/99/100 — alle angelegt, Switch adopted (switchConsistent=true).
- ✅ Port-Plan (ES208G, alle 8 Ports konfiguriert):
Port Name Profil Gerät Status 1 uplink Trunk-ALL → ALLNET GE8 ✅ korrekt 2 ap2 Trunk-ALL hAP ax² #2 ✅ korrekt 3 Port3 Access-MAIN — (frei) ⚠️ PVID=1 4 dock/monitor Access-MAIN Docking-Station ⚠️ PVID=1 · Lifeline-Port, nicht anfassen 5 drucker Access-MAIN Drucker ⚠️ PVID=1 6 Port6 Access-MAIN — (frei) ⚠️ PVID=1 7 macmini Access-INFRA Mac mini ⚠️ PVID=1 · fixe IP 10.40.41.x, nicht anfassen 8 ds923+ Access-MAIN NAS (2. Port) ⚠️ PVID=1 · nicht anfassen - ⚠️ Profile-PVID-Constraint (bis TP4 offen): NAS, Mac mini und andere Geräte haben fixe IPs im
Bereich
10.40.41.x(VLAN-1-Subnetz der FritzBox). Solange diese nicht auf VLAN-10/20-Subnetze migriert sind, mussnativeNetworkId=Default(VLAN 1)in allen Access-Profilen bleiben — sonst kein DHCP, kein Internet für diese Geräte. Fix nach TP4. - ⚠️ Bekannter Fehler
untagNetworkIds(Analyse 2026-06-15 via Controller-API v2): Access-MAIN hatuntagNetworkIds=[VLAN1, VLAN20, VLAN10](3 untagged!) statt[VLAN10]. Access-INFRA hatuntagNetworkIds=[VLAN20, VLAN1]statt[VLAN20]. Geräte erhalten Frames aus mehreren VLANs ungetaggt → Inter-VLAN-Tests verfälscht. Fix erst sinnvoll nach TP4 zusammen mit PVID-Korrektur. - Sichere Testports (kein kritisches Gerät): P3, P5, P6.
- ✅ Portainer-Ablösung: Komodo empfohlen (einzige Option mit nativem MCP
mcp-server-komodo). Eigener Task. - Abh. erfüllt: TP1 (GE8 Trunk ✅).
- → TP4 wird vorgezogen: Alle VLANs im Controller definiert (status=false = kein Management-IP, normal). Traffic läuft noch auf VLAN 1 bis TP4 die L3-Interfaces + DHCP-Server je VLAN aktiviert.
TP2.1 · Gitea #36 — Omada-Switch (sw2/ES208G) → Standalone-Recovery (kein Controller) — User solo)
- Root Cause: beim VLAN20-Umzug des Omada-Controllers (TP14.1, 2026-07-10) ist die Controller↔sw2-Verbindung zerbrochen (sw2 seither „Disconnected", ursprünglich als reiner Mgmt-Loss vertagt). Beim Rettungsversuch hat der User versehentlich einen Werks-Reset am Switch ausgelöst. Ein anschließender Wiederherstellungsversuch (durch Claude) hat Teile der Config unbemerkt halluziniert — der damalige „wiederhergestellte" Stand war nicht vertrauenswürdig.
- Entscheidung (User 2026-07-15): Controller-Zustand als invalid betrachtet, sw2 komplett neu — diesmal OHNE Managementsoftware. Kein Omada-Controller-Re-Adopt, kein Omada-Ecosystem-Anschluss (s. TP15-Korrektur — Omada bekommt generell keine Rolle mehr, auch nicht WLAN). sw2 direkt über eigenes Web-UI konfiguriert, wie ein eigenständiger Switch.
- ✅ 2026-07-16 (User-Aussage): „voll durch, Funktionsweise erfolgreich getestet." Nach dem gescheiterten Claude-Versuch hat der User sw2 komplett allein neu aufgesetzt (Runbook
docs/tp2.1-omada-switch-standalone-runbook.mdals Playbook-Referenz, nicht Schritt-für-Schritt-Log). Keine formale Einzelschritt-Verifikation dieser Session (kein Port-für-Port-Protokoll, keine Live-Prüfung durch Claude) — Status beruht auf User-Bestätigung „es geht einfach", nicht auf eigener Nachkontrolle. - sw2 bleibt Solo: „bekommt nie Geschwister" — keine weiteren Omada-Geräte geplant. Interimslösung bis zur Ablösung durch CRS326 (TP15).
- Offen/nachzuziehen (nicht blockierend): finale Portbelegung + IP von sw2 in
docs/ip-plan.md/CLAUDE.md-Hardware-Tabelle nachtragen (aktuell dort noch „Adoption pending" — stale, aber Wert unbekannt, nicht geraten);omada/.secretsauf neue Standalone-Creds prüfen; ob Omada-Controller-Container jetzt komplett überflüssig ist. - Abh.: TP1 ✅ (VLAN-Trunk am Uplink). Verwandt: TP15 (löst sw2 mittelfristig durch CRS326 ab), TP14.1 (Auslöser).
TP3 · Gitea #37 — WLAN
🔴 Lesehinweis (überarbeitet 2026-08-19): dieser gesamte TP ist Geschichte, von der ersten bis zur letzten Zeile. Er beschreibt zwei überholte Zustände nacheinander — die CAPsMAN-Ära (Juni/Juli 2026) und danach den Standalone-Rebuild vom 2026-08-08. Beides gilt nicht mehr: seit TP28 (2026-08-17) läuft das WLAN wieder über CAPsMAN, mit
crs326-coreals Manager; ap1/ap2 sind reine CAPs ohne eigene WLAN-Konfiguration.⚠️ Bis 2026-08-19 trug dieser TP im Header „beide hAP ax² sind reine Standalone-APs, CAPsMAN abgeschafft" und der Lesehinweis verwies als „Ist-Stand" auf den 08-08-Eintrag. Wer die WLAN-Frage hatte, landete zuerst hier — und bekam die falsche Antwort. Genau daran ist eine frische Session am 2026-08-19 hängengeblieben. Für den aktuellen WLAN-Stand: TP28 lesen, für Funkparameter TP25. Der Wert dieses TPs sind die Gotchas (VLAN-Leck ohne
datapath, Bring-up-Fallen), nicht der Status.
- ✅ 5 sichtbare SSIDs live, beide APs, beide Bänder, je SSID→VLAN (wifi datapath vlan-id):
dirtyvader-main(10, WPA3-only, FT),-iot(30, nur 2,4 GHz, WPA2+3),-media(40, WPA2+3, FT=no wg. Sonos),-untrusted(50, WPA2+3),-guest(90, WPA2+3). Alt-SSIDsinstall*/BF-Main/wv*entfernt. Temp-PSK (User setzt echte). - ✅ CAPsMAN-Architektur: ap1=Manager+AP (lokale Radios), ap2=CAP (dynamisch via Provisioning,
remote-cap=Ok). Kernlektion: Der Manager kann seine eigenen Radios NICHT über CAPsMAN provisionieren → ap1 lokal zuweisen (Master viaset+ statische Slave-VAPs), ap2 zieht Master+Slaves dynamisch. Ein CAP hält keine Eigen-Config. - ✅ Kanal-Plan (non-DFS, überlappungsfrei): ap1 ch36/5180 + ch1/2412 · ap2 ch149/5745 + ch11/2462.
(Auto-Channel hatte beide APs auf 5500-DFS/2437 gelegt = Co-Channel → fix gepinnt. ap2-Kanaländerung braucht
remote-cap provision-Push.)bound-Problem damit obsolet/sauber gelöst. - ✅ Sonos-Migration abgeschlossen (2026-07-02): alle 10 Sonos auf
dirtyvader-media/VLAN 40 mit MAC-fest reservierten DHCP-Leases indhcp-v40. Household geschlossen, iOS-App findet alle Geräte (mDNS via Repeater). Inventar/IPs = SSoTdocs/sonos-inventar.md(IPs haben sich verschoben — Arc jetzt.199, Arbeitszimmer-Paar auf.191/.192). - Vertagt: hidden
dirtyvader-infra(20)+-mgmt(99) (Mgmt verkabelt). TP8: eine 802.1X-SSID (dirtyvader-secure) mit FreeRADIUS-Dynamic-VLAN → dann PSK-main/infraeinstampfen (Konsolidierung). - SSID-Strategie-Entscheid (Begründung): unterschiedl. WPA-Typ/Band erzwingen separate SSIDs; „alles in 1 SSID per Auth" nur via 802.1X (Geräte ohne EAP wie Sonos/TV/IoT brauchen ohnehin PSK) → Hybrid in TP8.
- Mesh = NEIN (beide APs wired-trunk → Loop-Risiko). DoH-Upstream = Cloudflare Gateway (seit TP4 aktiv).
- Abh. erfüllt: TP4 ✅ (L3/VLAN-Interfaces). Folge: TP8 (802.1X), Sonos-Migration.
- 🔄 CAPsMAN wird abgeschafft (User-Entscheid 2026-07-22) — WLAN-Neuaufbau from scratch. Anlass: WLAN dauerhaft instabil, besonders wenn beide APs laufen. Beide APs bekommen künftig eigenständige, von Nautobot Golden Config identisch generierte RouterOS-Configs statt Manager/CAP.
- Begründung (kein Widerspruch zu Nautobot, aber ein echter Reibungspunkt): CAPsMAN erzeugt auf dem CAP dynamische Objekte (
wifi13–22), die nie in dessen eigener Config stehen → Golden-Config-Compliance sieht auf ap2 faktisch nichts. Genau diese Halbheit war die Ursache von TP3.1 (CAPsMAN schriebdatapath.vlan-idnicht auf die Leitung und legte die tagged-Member am CAP nicht an). - Was NICHT verloren geht: 802.11r/k/v braucht kein CAPsMAN, sondern nur gleiche SSID/PSK/Mobility-Domain → Fast-Roaming bleibt. Preis: Radio-/Kanaländerungen sind zwei Deployments statt eines Provision-Pushes — mit Nautobot ohnehin ein Job-Run.
- Reihenfolge: WLAN-Neuprovisionierung erst nach dem CRS326-Bring-up (TP15), da Routing/DHCP/DNS vorher umziehen.
- ✅ DURCH (2026-08-08): beide APs als reine Standalone-APs neu provisioniert, CAPsMAN weg. ap1
10.40.99.11(an coreether15), ap210.40.99.12(an branchether24); Uplink geräteseitig aufether1(PoE-Port,poe-out=off) umgestellt, ether2 aus dem Trunk entfernt. 6 SSIDs (main WPA3+FT / infra/iot/media/untrusted/guest WPA2+3, iot nur 2,4 GHz, media FT=no); jede SSID mit eigenemdatapathbridge+vlan-id → das TP3.1-„cfg-main-2g ohne datapath"-Leck ist strukturell weg. Kanäle non-DFS ap1 ch36/ch1, ap2 ch149/ch11. Client-Test grün (VLAN10/30-Leases korrekt). Configsrouteros/.secrets/ap{1,2}-prov-base.rsc, PSKsrouteros/.secrets/wlan-psks.env, As-built → Nautobot vianautobot/ingest-ap-rebuild.py. Einheitliches Admin-PW auf allen 4 MikroTik (User-Vorgabe). Henne-Ei beim Bring-up: Werks-192.168.88.1über Core-Temp-Pfad (192.168.88.2+ masq, wieder entfernt) via scp+/import; Werks-Inline-Overrides auf wifi1/wifi2 mussten geleert werden (!configuration.ssid !security.*), sonst funkt die Main-VAP die Werks-SSID. Offen: DoH auf core (nur plain 1.1.1.1), breiterer CLAUDE.md-Gotcha-Cleanup (ap1-als-L3-Router-Referenzen sind überholt).
- Begründung (kein Widerspruch zu Nautobot, aber ein echter Reibungspunkt): CAPsMAN erzeugt auf dem CAP dynamische Objekte (
TP3.1 · Gitea #38 — ap2 VLAN-Trunk-Fix — routeros/tp3.1-ap2-vlan.rsc
- Root Cause: ap2 (CAP, local forwarding) hatte
bridge vlan-filtering=no→datapath.vlan-idwurde nie auf die Leitung geschrieben → ALLE WLAN-Clients auf ap2 (main/media/iot/…) egressten ungetaggt in VLAN1 (defconf/10.40.41.x) statt ins Ziel-VLAN. Symptom: iPhone (VLAN10) im OG „verbunden, aber sporadisch kein WLAN-Symbol" — beim Roaming ap1↔ap2 sprang es VLAN10↔VLAN1 (Subnetz-Flip → Abbruch). Sonos-Terrasse landete auf ap2 fälschlich auf10.40.41.183. TP3 „ein CAP hält keine Config" gilt nur für Manager-Forwarding — hier local forwarding, daher braucht ap2 doch VLAN-Config. - ✅ Fix (wie ap1): ap2-Bridge
vlan-filtering=yes; VLAN1 untagged=bridge,ether2 (Mgmt), VLANs 10/30/40/50/90 tagged auf ether2. Da nur die Master-Radios wifi1(5G)/wifi2(2.4G) Bridge-Ports sind (Slave-VAPs forwarden über den Master), zusätzlich wifi1/wifi2 als tagged-Member je Client-VLAN (wifi1: 10/40/50/90, wifi2: 10/30/40/50/90). CAPsMAN legt diese auf dem CAP nicht automatisch an → manuell gesetzt. Danachremote-cap provision. - Lockout-Risiko gehandhabt: ap2-Mgmt (10.40.41.2) untagged VLAN1 blieb erhalten; kein Scheduler (device-mode=home) → Recovery = Power-Cycle OG. Ausgeführt im leeren-registration-table-Fenster.
- ⏳ Offen — funktionaler OG-Test durch User: Handy auf
dirtyvader-mainim OG → Lease mussdhcp-v10/10.40.10.xsein (nichtdefconf/10.40.41.x). Falls kein DHCP: Omada-Port-2-Trunk (tagged 10/30/40/50/90) prüfen. - Abh.: TP3 ✅, TP4 ✅ (Bridge-VLAN-Muster gespiegelt). Config ap2-lokal (nicht CAPsMAN-verwaltet).
- 🔁 Interim-Härtung 2026-07-06 (Migrations-Provisorium, fliegt mit VLAN1 raus): Symptom „kein DHCP auf
dirtyvader-main, Altnetz ebenso, nichts geändert". Diagnose via MikroMCP (ap1+ap2): Dual-DHCP-Race — dieselben Main-MACs (56:71:6C:22:E6:A9,F2:62:4C:E1:AF:09,C0:C7:DB:DE:71:BE) hielten gleichzeitig eine korrekte VLAN10-Lease (dhcp-v10/10.40.10.x) und eine VLAN1-Lease (defconf/10.40.41.18x);defconfunddhcp-v10boten parallel →offering ... without success+ Minutentakt-Flapping.bridge-ARP auf ap1 = 333 Einträge (flache VLAN1 lebt voll weiter; IoT/Shelly untagged auf10.40.41.2xx). Griff: auf ap2 die Master-Radio-Bridge-Portswifi1/wifi2vonframe-types=admit-allaufadmit-only-vlan-tagged— untagged Main/Slave-Frames werden verworfen statt in VLAN1 gedumpt (im Zielbild ohnehin korrekt, daher kein Rückbau nötig, verschwindet mit VLAN1).ether2bleibtadmit-all(VLAN1-Mgmt/Trunk, kein Lockout). Rollback:frame-types=admit-allauf beiden Ports. ⚠️ Rest-Leak bleibt: cudy1 (altes WLAN) bridged Clients weiter untagged in VLAN1 — nur per Switch-Port-Tag bzw. Alt-WLAN-Abbau (Migration) zu schließen, NICHT auf der MikroTik-Seite. Zusätzlichst-main rrm=yes wnm=yes(802.11k/v, behandelt nur das Roaming-Symptom). SSoT-Detail: Memoryproject_vlan1_dhcp_incident. - 🎯 ROOT CAUSE des ap1-Lecks gefunden (2026-07-22, live aus
/interface/wifi/configuration print) — es ist KEINframe-types-Problem:cfg-main-2g(SSIDdirtyvader-mainauf 2,4 GHz, gebunden an Master-Radiowifi2) hat überhaupt keinendatapath-Block — wederbridgenochvlan-id. Das 5-GHz-Pendantcfg-main-5g/wifi1taggt sauber nach VLAN 10, 2,4 GHz taggt gar nicht → egress ungetaggt in VLAN 1. Ein Client, der zwischen den Bändern derselben SSID wechselt, springt damit10.40.10.x↔10.40.41.x— Subnetzwechsel mitten in der Verbindung. Erklärt das Dual-DHCP-Race und das „verbunden, aber sporadisch kein WLAN" ohne jede Zusatzannahme. Fix nicht mehr direkt anwenden — geht mit der WLAN-Neuprovisionierung (CAPsMAN-Abschaffung, TP3) über Nautobot ein. Nebenbefund:cfg-infraexistiert auf ap1, wird von keinem Interface benutzt (deckt sich mit TP3.3), und ap1 funkt real auf ch36/ch1 — die Interfaces überschreiben das Channel-Profilch-5g(5745/ch149). - 🔴 Update 2026-07-15: gleiches Leck jetzt auf ap1 vermutet.
dirtyvader-main-Clients bekommen zeitweise10.40.41.x-IPs statt10.40.10.x— identisches Dual-DHCP-Race-Muster wie oben, aber die 2026-07-06-Härtung wurde nur auf ap2 gemacht. Nächster Schritt: gleicheadmit-only-vlan-tagged-Umstellung auf ap1s lokalen Main-Radio-Bridge-Ports (⚠️ NICHTether2anfassen — das ist ap1s Mgmt-/WAN-Trunk-Pfad). Diagnose+Fix-Schritte:docs/tp19-vlan1-cudy-teardown-runbook.mdPhase A (~30-60 Min). Diese Härtung ist wie die ap2-Variante ein Provisorium, das mit TP19s VLAN1-Abbau automatisch obsolet wird.
TP3.2 · Gitea #39 — WLAN Coverage / P750W-Discovery — docs/wifi-p750w-coverage-and-map.md
- ✅ Brother P750W (VLAN30) gelöst: DHCP-
client-id-Fix (matcht über MAC → feste10.40.30.5); an ap1 gepinnt (geordnete wifi-access-listaccept w2-iot→ blanketreject, überlebt ap2-Re-Provision) — dozende Legacy-Clients nur am co-located-GW ap1 per ARP erreichbar, CAP ap2 nicht; mDNSvlan30inmdns-repeat-ifaces+5353 → in MAIN auffindbar. Druck+Selbsttest OK. Web-UIhttp://10.40.30.5/general/information.html. - ✅ Nebenbei:
multicast-enhance=enabled(iot+media), Guestft=yes, INFRA-SSID(20) angelegt (nur ap2), Steering-Profilst-main/neighbor-group=bf-mainauf beide Main-Configs. - Nomenklatur: dynamische ap2-CAP-Slaves (
wifi13–22) nicht praktikabel umbenennbar (name-formatunzuverlässig) → Map dokumentiert statt umbenannt. Backupsbf-ap{1,2}-pre-nomen-20260702.backup/.rscauf den Geräten. - ⏳ Offene Coverage-Arbeit → ausgelagert nach TP3.3 (Fortsetzung in neuer Session).
TP3.3 · Gitea #40 — WLAN Coverage-Kur — offene Arbeit steht dort, nicht hier
⚠️ Der Header sagte bis 2026-08-19 „🔜 TODO (Fortsetzung, neue Session)" — dieselbe Falle wie bei TP3: ein Status, der nicht mitgezogen wurde. Der Re-Walk und die Dead-Spot-Kartierung sind Schritt 5 von TP25 und zwar bewusst nach den Funkparameter-Fixes; die 802.11k/v-Reparatur ist am 2026-08-13 erledigt worden. Was hier steht, ist Begruendung und Messhistorie.
- ✅ BEHOBEN 2026-08-13, noch am selben Abend (User: „aus Zeitgründen zuerst 11k/v, der nächste Call steht an").
st-main(rrm=yes wnm=yes neighbor-group=bf-main) auf beiden APs wiederhergestellt und ancfg-main-5g/cfg-main-2ggehängt — via GC-ConfigPlan, bewusst nicht per Direkt-Write: der Push läuft so NAS→Kabel→AP und nicht über die WLAN-Verbindung, die man gerade umkonfiguriert./system backupje AP davor (ap{1,2}-pre-steering-20260813.backup). Gegengeprüft am Gerät (nicht am Plan-Status):st-main rrm=true wnm=true ng=bf-main, beide Main-Configs verweisen darauf.- ⚠️ Erwartete Nebenwirkung: alle Clients haben kurz reassoziiert (ap1 25→2, ap2 7→14 unmittelbar danach) —
steering=auf einerwifi configurationzu setzen re-applied die VAPs, auch die nicht angefassten. Nach ~2 Min eingependelt (ap1 15 / ap2 13, VLAN30 = 28 Hosts auf der Core-Bridge). Nicht während eines Calls machen. - ✅ In GC verankert: Steering steht jetzt im AP-Zweig des Templates (
st-main/bf-mainals Konstante — es gibt genau eine Roaming-Domain pro Standort) + neues ComplianceFeaturewifi-steering. Eine künftige Neuprovisionierung kann es damit nicht mehr stillschweigend verlieren — genau das war der Fehler vom 2026-08-08. - ⏳ Offen: der Praxistest. Dieselbe Route noch einmal gehen. Reißt es weiterhin ab, ist es echte Coverage → Dead-Spot-Kartierung.
- ⚠️ Erwartete Nebenwirkung: alle Clients haben kurz reassoziiert (ap1 25→2, ap2 7→14 unmittelbar danach) —
- 🔴 Der Befund (2026-08-13): Steering war auf BEIDEN APs weg.
/interface/wifi/steering= 0 Einträge auf ap1 und ap2 (live geprüft). Vor dem Rebuild warst-mainmitrrm=yes wnm=yes+neighbor-group=bf-mainauf beiden Main-Configs gesetzt (s. TP3.2 + TP3.1-Interim). Die Neuprovisionierung am 2026-08-08 ausrouteros/.secrets/ap{1,2}-prov-base.rschat es nicht wieder angelegt.- Wirkung: kein 802.11k (Neighbor Reports → der Client kennt die Nachbar-APs gar nicht) und kein 802.11v (BSS Transition → der AP kann den Client nicht wegschicken). Der Client bleibt am sterbenden AP kleben, bis die Verbindung zusammenbricht, und muss dann komplett neu scannen + assoziieren = harter Abriss statt Übergabe. Genau das Symptom „einmal durch die Wohnung, WLAN weg" (User-Erlebnis 2026-08-13 während eines Telegram-Videocalls, musste auf 5G ausweichen).
- ⚠️
ft=yesist KEIN Gegenbeweis (auf beiden APs gesetzt,ft-mobility-domainbeidseitig leer = gleicher Default, FT selbst also intakt). 802.11r macht die Übergabe schnell, sobald der Client sie beschließt — es bringt ihn nicht dazu, sie zu beschließen. Ohne 11k/v fällt die Entscheidung viel zu spät. „FT ist an" ≠ „Roaming funktioniert". - Reihenfolge-Konsequenz: Diese Regression vor der Dead-Spot-Kartierung beheben und dieselbe Route nachlaufen — sonst kartiert man Löcher, die in Wahrheit Roaming-Verhalten sind, und zieht daraus womöglich Hardware-/Platzierungs-Entscheidungen (s. „ap1 ins Sideboard"-Idee unten).
- Weg (Governance): Steering gehört ins GC-Template (
/interface/wifi/steering+steering=an der Main-Configuration) → feature-scoped Deploy. Kein Direkt-Write. Betrifftwifi-configuration(bereits Compliance-Feature) + ein neues Featurewifi-steering.
- 💡 Idee „ap1 ersetzt den Sideboard-Switch" (User 2026-08-13): ap1 hat 4 freie Ports (
ether2–5;ether3/4/5sind bereits Bridge-Ports mitpvid=1,ether2ist seit der ether1-Umstellung kein Bridge-Port mehr und müsste wieder aufgenommen werden) → die Wohnzimmer-Multimediageräte könnten direkt an ap1, der Smart-Managed-Switch entfiele. Technisch machbar (untagged VLAN40 wiecore ether2), aber platzierungsgebunden: ein Media-Sideboard ist RF-mäßig einer der schlechtesten AP-Standorte (geschlossen, Metallgehäuse der AV-Geräte, niedrig). User-Vorgabe: Platzierung hat Vorrang vor dem eingesparten Gerät. Entscheidung daher erst nach der Steering-Reparatur + Re-Walk. Problem: Kanten/Terrasse grenzwertig — Clients (iPhone/iPad) landen bei −76..−89 dBm und springen zwischen allen 4 Main-Radios (ap1-5G/2,4G ↔ ap2-5G/2,4G) → „0–1 Striche + häufiger Abriss"; Terrasse auch mittags schlecht. FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
Bereits geklärt/erledigt (nicht nochmal aufrollen):
- NICHT config-verursacht (ap1 kein Reboot, RF-Konfig unverändert). TX schon am AT-Max (18/15 dBm, EIRP-Deckel — kein Hebel).
- Kanalplan intern überlappungsfrei (ap1 ch1/ch36, ap2 ch11/ch149). Steering
st-main/neighbor-group=bf-mainauf beiden Main-Configs gesetzt (hilft Client-Entscheidung, macht Signal aber nicht stärker). - ap1-only ist vom Tisch (echte Funklöcher) → beide APs nötig, aber besser platziert.
Offene Arbeit:
- Dead-Spot-Kartierung (Tageslicht): User stellt sich in jeden Problempunkt (Terrasse zuerst, entfernte Räume,
dicke Wand) → je Punkt
registration-table+monitor(Signal je Radio/Band/AP). Zusätzlich Nachbar-WLAN-Scan/interface/wifi/scanje AP (störend — wirft Clients kurz ab) gegen Abend-Congestion. Output → SSoT-Doku. - Remediation nach Befund: Platzierung (ap2 Richtung Schwachseite umstellen / 3. AP / Outdoor-Unit / Kabelweg);
Roaming-Feintuning (802.11v
transition-Schwellen ab 7.21, Band-Overlap reduzieren); Kanalplan aus Scan nachziehen. - INFRA(20) auf ap1 ergänzen (fehlt — sendet nur auf ap2): lokaler
w2-/w5-infra-Slave analog w2-/w5-media. - Danach Re-Walk-Test (wie 2026-07-02, aber mit Kartierung als Baseline).
Sicherheitsnetz: Backups bf-ap{1,2}-pre-nomen-20260702.backup/.rsc auf den Geräten. Kontext-Memory project_wifi_coverage
ref_wifi_powersave_multicast. Abh.: TP3 ✅, TP3.1 ✅, TP3.2 ✅.
TP4 · Gitea #41 — Router-Cutover (hAP#1 = Router + WAN-Edge) — ⚠️ Rolle seit 2026-08-08 auf crs326-core (TP21.1); alles unten beschreibt den damaligen ap1-Aufbau und gilt als Historie/Referenz, nicht als Ist
- ✅ Bridge VLAN-Filtering aktiviert (
vlan-filtering=yes); VLAN-Tabelle: VLAN1 untagged bridge+ether2, VLANs 10/20/30/40/50/90/99/100 tagged bridge+ether2. - ✅ VLAN-Subinterfaces: vlan10/20/30/40/50/90/99 auf bridge; je GW
.1(10.40.10.1 … 10.40.99.1). - ✅ DHCP: dhcp-v10…dhcp-v99 je auf eigenem VLAN-Interface, pools .100-.200, GW+DNS = VLAN-GW.
- ✅ DNS: RouterOS-nativ, allow-remote-requests=yes. Upstream seit 2026-06-16: DoH Cloudflare Gateway (
use-doh-server=https://px35ynlol3.cloudflare-gateway.com/dns-query, verify-doh-cert,servers=1.1.1.1als Bootstrap; FB-Upstream abgelöst). Statische Einträge für alle Infra-Hosts unterbf.lan(13 Einträge, Transition-IPs bis PVID-Fix).- ⚠️ Auto-Suffix
.lan(RouterOS-Einschränkung, kann nicht auf leer gesetzt werden) — TP5-Cleanup.
- ⚠️ Auto-Suffix
- ✅ NAT: srcnat masquerade out-interface=vlan100 (ap1 = Public-Edge; kein Double-NAT mehr). Fallback-Konfig für ether1 bleibt reversibel dokumentiert (
routeros/wan-cutover-runbook.md). - ✅ Routing-Tabelle: 0.0.0.0/0 via Liwest-Gateway auf vlan100; alle 7 VLAN-Subnetze als Connected-Routes aktiv.
- ✅ Edge-Cutover vollzogen (2026-07-01): FritzBox 6660 physisch weg (Liwest hat gegen ein Arris-Kabelmodem im Bridge-Mode getauscht — kein Zurück). WAN =
Arris → sw1 gi16 Access VLAN100 → gi15 Trunk → ap1 ether2 → vlan100 auf bridge(NICHT ether1). ap1 hält Public-IP direkt (Liwest, kein CGNAT). WAN-Input-Seal live (TP10-seal-Regeln: est/inv/dhcp/icmp/lan/wandrop iminput-Chain,list_firewall_rules2026-07-02 verifiziert). Telefonie war auf der FB und wird nicht weitergeführt (User-Bestätigung 2026-07-02). - DNS-Entscheidung (Technitium und externer BIND verworfen): RouterOS-DNS als Resolver, keine DHCP→DNS-Auto-Registrierung (soweit möglich). Infra-Hosts als statische
/ip dns static-Einträge unterbf.lan; dynamische Clients bewusst ohne Namen. Filtering/DNSSEC via DoH-Upstream (TP3). HA: 2. Resolver auf ap2, statische Einträge beidseitig pflegen. - 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 · Gitea #42 — Firewall & Inter-VLAN-Policy — + E5 (2026-08-19)** — 📋 docs/tp5-deny-by-default-runbook.md
📌 „DURCH" heißt nicht „abgeschlossen". E5 (MAIN→IOT) kam einen Tag nach dem Drop — unter deny-by-default braucht jeder neue Dienst über eine VLAN-Grenze seine Regel. Weitere Etappen sind normaler Betrieb, kein Rückschritt. Der Weg dahin ist immer derselbe: erst den Drop-Log lesen, dann die Regel schreiben.
-
✅ ETAPPE 5 (2026-08-19):
MAIN → IOTaufgemacht —routeros/tp5-e5-main-iot.rsc, Backupcore-pre-tp5-e5-main-iot-20260819.backup, Compliance danach 92/92, 0 Drifts.- Auslöser (User): Brother P750W und die Shellys aus VLAN10 nicht erreichbar. Der Drop arbeitete
korrekt — es gab schlicht nie eine
vlan10→vlan30-Zeile. Offen waren nurMAIN→MEDIA,MAIN→INFRA,MAIN→MGMT; IOT fehlte als einziges Paar in der Liste. - 🔴 Merkregel: der Drucker fällt mit
udp/161auf, NICHT mit631. Im Drop-Log stehen 40 Zeilen SNMP nach10.40.30.5und kein einziges IPP — macOS fragt zuerst den SNMP-Status ab und bricht ab, bevor es überhaupt zu IPP kommt. Wer nur 631 whitelistet, repariert nichts. - Log-Matrix
in:vlan10 out:vlan30: 497 ICMP · 489udp/5353· 489udp/137· 237udp/3722(Apple-Continuity →.30.201) · 40udp/161. Quellen:.10.183(1596 Zeilen, Sweep über alle 254 Adressen),.10.180(118),.10.82(38). - Entscheid (User): voll einbahnig, kein Portfilter. MAIN steht zu INFRA/MEDIA/MGMT ohnehin
ungefiltert offen — und INFRA hält NAS, Proxmox und Nautobot, also deutlich mehr Wert als die
Shellys. MAIN→IOT eng zu filtern wäre Symbolik, kostet aber bei jedem neuen IoT-Gerät eine Runde
Fehlersuche. Der Sicherheitswert sitzt in der Gegenrichtung:
IOT→MAINbekommt bewusst keinacceptund bleibt gedroppt; Antworten laufen überdefconf: accept est,rel,untracked. - Abnahme am Gerät (von
10.40.10.82, also der Quelle aus dem Log):.30.5ICMP 0 % Loss,snmpget sysName.0→P750W, tcp/631+9100+80 offen;.30.202/.203/.221HTTP 200..30.201bleibt still — kein Firewall-Thema mehr (die Regel ist ungefiltert), Gerät aus. - ⚠️ Bewusste Nebenwirkung: der Subnetz-Sweep von
.10.183läuft ab jetzt durch statt im Drop-Log aufzulaufen. Betriebsneutral, aber der Log wird an dieser Stelle leiser — nicht mit „Problem gelöst" verwechseln, wenn später jemand die Log-Rate als Metrik liest. - 🔧 Werkzeug-Fix nebenbei:
gc-manual-plan.py --assertURL-encodet die Query jetzt. Ein Kommentar mit Leerzeichen (TP5-E5: MAIN->IOT) warfhttp.client InvalidURL— nach dem erfolgreichen Deploy, d.h. der Change war durch und nur die Gegenprüfung crashte. Das ist die schlechtere Reihenfolge: man steht mit einem Traceback da und weiß nicht, ob es gewirkt hat.
- Auslöser (User): Brother P750W und die Shellys aus VLAN10 nicht erreichbar. Der Drop arbeitete
korrekt — es gab schlicht nie eine
-
✅ ETAPPE 3 + 4 DURCH (2026-08-18, nachts).
forwardundinputenden jetzt mitdrop, die Log-Regel steht in beiden Ketten davor und protokolliert weiter, was der Drop frisst. Artefakte:routeros/tp5-etappe2-nachtrag.rsc,-etappe3-drop.rsc,-etappe4-input-mgmt.rsc,-etappe4-nachtrag-discovery.rsc(+ die beiden autorevert-abbestellen-Plaene). Backupscore-pre-tp5-{nachtrag,etappe3,etappe4}-20260818.backup.- 🔴 Das 70-Sekunden-Ergebnis aus Etappe 2 (die Log-Regel sei verstummt) war falsch. Ueber
dreieinhalb Stunden gemessen liefen 119 Zeilen auf, in vier Gruppen — drei davon haetten den
Drop zum Ausfall gemacht:
Zeilen Was Warum es die Whitelist nicht traf 92 Matter udp/5540, SwitchBot.30.227→ HAdie E2-Regel IOT->INFRA Diensteist TCP-only18 10.40.20.31→.99.{2,11,12}:22der Netmiko-Deploy kommt vom nautobot-worker, nicht vom Web-Container.20.30, auf den die E2-Regel lautete (deren Zaehler stand auf 0)8 .99.x:8728→ HARueckrichtung des Mgmt-Pfads, nach Conntrack-Ablauf als new1 Shelly .30.225:80→ HAgleiches Muster ➡️ Merkregel: ein Zaehlerstand ueber 70 Sekunden ist keine Messung. Und wer den Deploy-Pfad whitelistet, muss die IP des Workers nehmen, nicht die des Web-Containers. - 🔴 Fund in Etappe 4, der erst spaeter zugeschlagen haette: die CAPs finden ihren Manager per
Layer-2-Discovery.
/interface/wifi/capauf ap1 zeigtdiscovery-interfaces=vlan99undcurrent-caps-man-address: 04:F4:1C:B4:17:76%vlan99— eine MAC, keine IP. Der input-Drop verwarf MNDP (udp/5678); bestehende CAPWAP-Sitzungen liefen alsestablishedunbeeindruckt weiter, kaputt gewesen waere es erst beim naechsten AP-Reboot. Geschlossen mitTP5-E4: MNDP discovery(LAN) +TP5-E4: CAPsMAN capwap(nur vlan99). - 📌
inputist der riskantere Teil, nichtforward: der Core ist DNS- und DHCP-Server fuer alle sieben VLANs, und beides lief allein ueberTP10-seal-lan. Reihenfolge deshalb zwingend Ersatzregeln →seal-lan disabled=yes→ Drop.seal-lanwurde abgeschaltet, nicht geloescht (schnellerer Rueckweg, und der Auto-Revert greift genau dort an). - ✅ Nebeneffekt wie vorhergesagt: die 5
TP5: mDNS in vlanXX-Input-Regeln sind endlich scharf (vlan30 = 87, vlan20 = 13 Pakete binnen Minuten; sie standen seit dem 2026-08-14 auf 0). - 🎯 Abnahme am Geraet:
forward-Drop 11 Pakete in 15 Minuten — ausschliesslich die eigene pve→branch:22-Sonde;input-Drop nur Broadcast-Rauschen (MNDP auf VLAN1-nativ, NetBIOS 137/138 aus VLAN20, SSDP-Announcements einer Sonos aus VLAN40). Haus im Normalbetrieb: 23 Leases, 30 WLAN-Clients, beide CAPsOk, WAN steht. Funktionstest: Shelly aus INFRA200, Internet301, MacBook erreichbar,branch:22von pve aus zu (korrekt). Und der Pfadbeweis: ein GC-Deploy auf ap2 lief MIT scharfem Drop durch. - 🛟 Auto-Revert-Scheduler (10 min, Name ohne Bindestrich) lief vor jedem der beiden Schnitte und wurde nach bestandener Abnahme per eigenem Plan abbestellt.
- 🔜 Bleibt offen: die DNS-Bypass-Sperre — sie gehoert bewusst nicht hierher, sondern an das Ende von TP23 (Stufe 6), wenn die Ausnahme-Oberflaeche nachweislich traegt.
- 🔴 Das 70-Sekunden-Ergebnis aus Etappe 2 (die Log-Regel sei verstummt) war falsch. Ueber
dreieinhalb Stunden gemessen liefen 119 Zeilen auf, in vier Gruppen — drei davon haetten den
Drop zum Ausfall gemacht:
-
✅ ETAPPE 2 DURCH (2026-08-17) —
routeros/tp5-etappe2-whitelists.rsc, ConfigPlan86fbd528, Backupcore-pre-tp5-etappe2-20260817.backup.- Basis waren 43.027 Logzeilen aus dem Fenster 2026-08-16T17:21 → 2026-08-17T14:05 (Kollektor
10.40.20.18), also ~21 Stunden echter Nutzverkehr statt der 10-Minuten-Stichprobe von Etappe 1. Die vollständige Matrix:Paar Zeilen Dienste (Ziel:Port, absteigend) vlan20 → vlan9920.682 8728auf branch (7468) / ap1 (7468) / ap2 (5731) = HA-mikrotik-Integration ·:22je 8 = Nautobot-Netmikovlan10 → vlan208.082 macmini udp/37226234 (Continuity) · NAS66901578 · Nautobot8080137 · AirPlay700069 · pve-mcp300022 · HA958316 · pve:2212 · macmini49152/udp 59107je 8 · NAS:224 · Ollama114342vlan20 → vlan107.123 Rückrichtung Continuity (eigene Flows je Richtung) vlan20 → vlan306.238 HA pollt ~22 Shellys auf tcp/80vlan30 → vlan20306 .30.249→ HA8123(203) · macmini49152(1)vlan10 → vlan30237 nur udp/3722→.30.201= das iPhone im IOT-SSID (D2)vlan10 → vlan99214 Arbeitsplatz .10.82→ branch/ap1/ap2:22/:80/:443cf-mesh → *137 100.96.0.1→ Nautobot8080(62) · NAS6690(46) · macmini/NAS/branch/ap1/ap2:22· pve8006· pve-mcp3000vlan10 → vlan1017 same-VLAN mDNS 5353(vom Repeater auf dem Core)vlan40/vlan50/vlan900 ➡️ D6 bestätigt: Internet-only-Pinning ist risikofrei. out:bridgekommt nicht mehr vor (VLAN1-Rückbau hält). - Entscheidungen (User 2026-08-17): D1 = MAIN→INFRA pauschal (MAIN ist das Trusted-VLAN; 13 Einzelports
wären eine Wartungsfalle, die bei jedem neuen Dienst still bricht). D4 = MGMT named sources — MAIN komplett
- HA
.20.105:8728+ Nautobot.20.30:22+cf-mesh, Rest drop. D5 = beobachtetes8123+ MQTT als Absicht; Influx8086NICHT (nie beobachtet, der Weg läuft über HA).
- HA
- 🎯 ABNAHME am Gerät bestanden: 11 Regeln (
*1B–*25) existieren,disabled=false, alle vor der Log-Regel (place-before, sonst wäre das Gate unten nicht messbar), Selbstprotokolltp5e2: ENDE whitelist-regeln=11. Und der Zähler der Log-Regel steht: 54.129 bei 14:17:06 und unverändert bei 14:18:13; die letzte Zeile im Kollektor ist14:17:16— genau der Deploy-Zeitpunkt. Die Regel ist also verstummt. - ⚠️ Aber das ist noch KEIN Freibrief für Etappe 3. 70 Sekunden Stille sind keine Aussage — das Runbook verlangt bewusst „einige Tage", weil Geräte existieren, die einmal pro Woche funken (Backup-Jobs, Drucker-Discovery). Gate für Etappe 3: mehrtägiges Fenster ohne neue Zeilen.
- 📌 Zwei Dinge müssen VOR dem Drop passieren: (a) D2 — iPhone
.30.201ins MAIN-SSID umhängen (Hands-on Christoph); solange es im IOT-SSID hängt, killt der Drop die 237udp/3722-Flows. Eine Whitelist darauf wäre instabil, weil iOS pro SSID eine eigene Private Address vergibt. (b)seal-lanverengen (D4input-Teil), was zugleich die 5 toten mDNS-input-Regeln scharf schaltet.
- Basis waren 43.027 Logzeilen aus dem Fenster 2026-08-16T17:21 → 2026-08-17T14:05 (Kollektor
-
✅ ABNAHME DES VLAN1-RÜCKBAUS BESTANDEN (2026-08-16):
out:bridge= 0. 10-Minuten-Messfenster nach dem Wiederanschalten, Logdatei vorher geleert. Vorher warenvlan20 → bridge76 % des gesamten Inter-VLAN-Verkehrs. Die Rate fiel von ~166 auf ~34 Zeilen/min — der Rückbau hat das Log auf echten Nutzverkehr eingedampft. Wiederaufnahme überrouteros/tp5-etappe1-resume.rsc(GC, Backupcore-pre-tp5-resume-20260815.backup). -
📊 Beobachtete Matrix, 339 Zeilen / 10 min — das Arbeitsmaterial für Etappe 2:
Paar Zeilen was genau vlan20 → vlan99126 HA 10.40.20.105→10.40.99.2:8728+10.40.99.11:8728(je 67) = der Management-Pfadvlan20 → vlan3085 HA → IoT: .30.211:80(44),.30.8:10081(22),.30.244:8080Nuki (22),.30.5:631Drucker (4)vlan10 → vlan2065 Arbeitsplatz → INFRA vlan20 → vlan1061 INFRA → MAIN vlan10 → vlan102 mDNS 10.40.10.183:5353 → 10.40.10.82:5353— s.u. -
🔑 D4 ist damit belegt, nicht mehr geschätzt: der Management-Pfad ist HA (
10.40.20.105), das über seine viermikrotik-Integrationen8728auf branch/ap1/ap2 pollt (core.99.1erscheint nicht, weil dasinputist, nichtforward). Dazu MikroMCP vom Arbeitsplatz. Ohne Whitelist sperrt der spätere Drop die Verwaltung des eigenen Netzes aus. -
⚠️ Neuer Merkposten für Etappe 3 — same-VLAN-Verkehr erreicht die
forward-Kette:vlan10 → vlan10, unicast mDNS zwischen zwei MAIN-Clients, erzeugt vom mDNS-Repeater auf dem Core. Zwei Pakete in 10 Minuten, harmlos — aber ein blanker Drop am Kettenende würde sie treffen und damit Discovery innerhalb von MAIN beschädigen. Zusammen mitaccept out-interface-list=WANdie zweite Regel, die bekannt ist und nicht aus dem Log wiederentdeckt werden muss. -
✅ D2 vollzogen: iPhone ist im MAIN-SSID,
10.40.30.201steht im ARP auffailed. -
✅ Etappe 1 ausgerollt 2026-08-14 (über Nautobot GC, manual Config Plans; Backups
core-pre-/post-tp5-etappe1-20260814.backup). Auf dem Gerät:forward-Regelaction=log log-prefix="TP5-WOULD-DROP"am Kettenende, Syslog-Actiontp5syslog→ Kollektor10.40.20.18:514(syslog-ng-Containertp5-syslogauf dem Docker-LXC, Logs/opt/tp5-syslog/log/, 10-Minuten-Cron kappt bei 500 MB — der LXC hat nur ~2,5 GB frei).firewallist aus dem Memory-Ring genommen (topics=info,!firewall), sonst wäre der On-Box-Log tagelang unbrauchbar. Blockiert nichts. Artefakte:routeros/tp5-etappe1-log-lauf.rsc, Push-Werkzeugnautobot/gc-manual-plan.py. Compliance danach 16/17 (der eine Rotpunktip-address= bekannte VLAN1-Bring-up-IP10.40.41.211aus dem TP22-Backlog, keine neue Drift). -
🔴 Fund aus dem Log-Lauf, der Etappe 3 bestimmt: die Regel fing anfangs auch allen Internet-Verkehr (
out:vlan100, ~¼ der Zeilen in einer ruhigen Minute, unter Last mehr). Die Log-Regel steht deshalb jetzt aufout-interface-list="!WAN". Konsequenz für den späteren Drop: er darf NICHT bare ans Kettenende — davor gehörtaccept out-interface-list=WAN, sonst ist das ganze Haus offline. Diese Whitelist-Zeile ist damit bekannt und muss nicht aus dem Log wiederentdeckt werden. -
🔍 Erste Befunde nach 60 s (Rate nach Einengung ~166 Zeilen/min): 76 % des Inter-VLAN-Verkehrs ist
vlan20 → bridge, also INFRA nach VLAN1 — ein Monitoring-Host10.40.20.151scrapet ~10 tote/alte10.40.41.x-Ziele, HA.20.105zieht auf10.40.41.100:8006(pve unter seiner alten VLAN1-Adresse, real.20.100),.20.107auf10.40.41.10:8080. Das ist TP19-Material, das TP5 gerade sichtbar macht. Weiter:vlan20 → vlan99:8728(MikroTik-API auf branch/ap1/ap2 = der Management-Pfad selbst, muss in die Whitelist, betrifft D4),vlan20 → vlan30(HA → Drucker.30.5:631, Shelly, Nuki.30.244:8080),vlan10 ↔ vlan20(Synology Drive6690, Apple-Continuityudp/3722). -
✅ D2 entschieden (User 2026-08-14): iPhone wird ins MAIN-SSID umgehängt. Faktenlage war:
10.40.30.201, dynamische Lease, HostnameiPhone, MAC12:99:A6:AC:B0:CB= iOS Private Wi-Fi Address, aktiv aufdirtyvader-iotmit 748 MB rx. Die statische Reservierung10.40.10.196„iPhone" (andere private MAC — iOS vergibt pro SSID eine eigene) belegt, dass es dasselbe Telefon ist. Umhängen ist die Hands-on-Aufgabe von Christoph (SSID am Gerät wechseln +dirtyvader-iotvergessen lassen); technisches Argument: eine Whitelist auf eine rotierende Private MAC wäre ohnehin instabil. -
📋 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=logans Ende vonforward) — 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.82auf alle Shellys, und vlan99 ist Mitglied derLAN-Liste (→seal-lanerlaubt 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.
-
⚠️ 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-corelive nachverifiziert (list_firewall_rules, chainsforward13 Regeln /input12 Regeln): alle unten gelisteten Regeln existieren, sind enabled, tragen ihreTP5:/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-core2026-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(live bestätigt 2026-08-14: dieforward-Kette endet nachTP5: MEDIA->GUESTohne 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 hinterTP10-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ährendseal-lan3,5 Mio. zählt. Kein Fehler und nichts zu tun — sie sind die Vorbereitung auf genau den Schritt, der noch aussteht: sobald der Router-inputgehärtet wird (seal-lanverengen/entfernen), werden sie scharf. Falle für die TP5-Session: erstseal-lanverengen, DANN testen — vorher beweist ein grüner mDNS-Test gar nichts, weil er überseal-lanlä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 vonforwardplus 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, unddevice-modeauf core erlaubt scheduler → Auto-Revert-Scheduler als Sicherung ist hier möglich (anders als auf den hAPs). -
🔊 Im Paket enthalten (User-Vorgabe 2026-08-14): der macOS-Sonos-Client-Fix. Ist-Stand: iOS-App findet alles (mDNS via Repeater ✅), HA steuert/gruppiert sauber (Sonos-Panel, via static hosts +
advertise_addr, TP7.2 ✅) — nur die macOS-Desktop-App findet die Sonos-Umgebung nicht. Ursache ist bekannt und keine Firewall-Frage: die Desktop-App entdeckt per SSDP (UDP 1900), und RouterOS reflektiert nur mDNS, kein SSDP → die Discovery quert die VLAN-Grenze MAIN(10)→MEDIA(40) nicht. Dieforward accept vlan10↔vlan40-Regel ist bereits offen und hilft hier nicht, weil das Problem vor dem Verbindungsaufbau liegt. Fix = SSDP-Reflector (TP7.1) auf NAS/pve (nicht am Router — kein Flash) mit Bein in vlan10 + vlan40, plusinput accept udp/1900auf den bedienten VLANs. TP7.1 wird damit aus „vorgemerkt" in dieses Arbeitspaket gezogen und ist mit der Deny-by-default-Arbeit gemeinsam zu testen (sonst prüft man zweimal dieselbe Strecke). -
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 ✅ (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).
TP6 · Gitea #43 — QoS/CAKE + Call-Quality-A/B-Test — ⚠️ Die Erklaerung darin ist von TP6.1 ueberholt: nicht DOCSIS, sondern fehlende Klassentrennung.
🔴 ZUERST LESEN — diese Analyse ist teilweise widerlegt (2026-08-23, durch TP6.1). Unten steht, die ~30 ms entstuenden im DOCSIS-Uplink und seien unabaenderlich. Sie sind es nicht. TP6.1 holt dieselbe Strecke unter derselben Saettigung auf 11,0 ms — allein durch Klassentrennung mit Prioritaet. Der Fehler lag in der Methode hier: Bulk und Messverkehr kamen vom selben Host, damit gab es fuer CAKEs
triple-isolatenichts zu trennen, und blosses Shapen aendert keine Reihenfolge. Weiter gueltig bleibt: dass CAKE als eine Queue ueber allem nichts brachte (dreimal gemessen), und der Befund zur Queue-Platzierung (Interface-HTB tot, Global-HTB wirkt). Der Rest dieses Abschnitts ist als Messprotokoll zu lesen, nicht als Ursachenanalyse. 🔴 A/B gemessen, gleicher Client, gleiche Methode, Minuten auseinander:
Konfiguration avg Latenz unter Upload-Last ohne CAKE 42,4 ms CAKE 8,5 Mbit (88 % der Linerate) 43,3 ms CAKE 7 Mbit (73 %) 44,0 ms CAKE 5 Mbit (52 %) 44,6 ms idle 12,9 ms. Selbst bei halber Linerate aendert sich nichts — und dort muss die Warteschlange zwingend im Router liegen, der Modem-Puffer also leer bleiben. Die ~30 ms Zusatzlatenz entstehen damit stromabwaerts: im Arris/DOCSIS-Uplink, wo das Request/Grant-Scheduling auf MAC-Layer sitzt und gar keine Warteschlange ist. Das kann keine Queue im Router beheben. Nebenbefund: die max-Werte steigen mit haerterer Drosselung (53 → 94 → 148 ms) — die eigene Queue wird laenger, die DOCSIS-Latenz bleibt. ⚖️ Empfehlung: TP6 schliessen — nicht mangels Nutzen, sondern weil das Werkzeug nicht an die Ursache reicht. Das ist ein staerkeres Ergebnis als „marginal“ von 2026-06-16.
✅ Dass CAKE technisch funktioniert, ist dabei bewiesen, nicht angenommen: Global-HTB zaehlte 6.040.563 Bytes, und bei
cake-bandwidth=7000000fiel der Durchsatz von 9,3 auf 7,78 Mbit. Sie zaehlt und drosselt. Es scheitert nicht am Bau.🔴 KORREKTUR der ersten Fassung dieses Abschnitts (ebenfalls 2026-08-23): dort stand „der CRS326 fuehrt keine Software-Queue“ — das war falsch und stuetzte sich auf zwei eigene Testfehler. Richtig ist praeziser:
/queue tree parent=<interface>ist bei hw-offloadetem out-interface wirkungslos. MikroTik dokumentiert das: „Interface HTB will not work correctly when the out-interface is hardware offloaded and the bridge Fast Path is not active.“ Das war die echte Ursache der ersten, wirkungslosen Queue aufparent=vlan100./queue tree parent=global+packet-markwirkt sehr wohl — die HTB Global sitzt im IP-Stack, nicht an der Interface-Queue. Rezept:mangle chain=postrouting out-interface=vlan100 action=mark-packet(postrouting laeuft vor src-nat, die LAN-Quelle ist dort noch sichtbar), dann Tree aufparent=global.- Die Simple-Queue-„Gegenprobe“ auf
10.40.0.0/16war untauglich: die Reihenfolge ist mangle postrouting → src-nat → HTB Global → simple queues. Zum Zeitpunkt der Simple Queue ist die Quelle laengst die WAN-IP; das Target konnte nie matchen.ipv4-fast-path-active: noundipv4-fasttrack-packets: 0belegen zudem: die CPU sieht jedes Paket im Slow Path. Die Hardware war nie die Grenze. Details und die restlichen Sackgassen: Memoryref_queue_htb_platzierung_docsis.✅ Was aus beiden Anlaeufen bleibt: die ComplianceRule
queue(Feature + Rule,match_config=/queue type+/queue tree) schliesst die blinde Stelle aus §4.1 — dieselbe, die TP26 fuer/ip firewall filtergeschlossen hat. Wirksamkeit bewiesen: erst 99/100 mit der fehlenden Queue alsmissing, nach dem Deploy 100/100. Zaehler jetzt 25 Rules x 4 Geraeten = 100 Checks. ⚠️ Am Geraet steht weiterhin die wirkungslose Interface-Queue (qos-wan-upaufparent=vlan100) — in der SoT, compliant, aber ohne jede Funktion. Sie gehoert entfernt, sobald der Abschluss entschieden ist; bis dahin NICHT fuer aktives QoS halten.💡 Falls QoS hier je wieder Thema wird: weder
hw-offloadopfern noch Chip-QoS ist noetig — der Global-HTB-Weg funktioniert ohne beides. Es lohnt nur nicht.
(Vorheriger Kopf, als Messbefund weiter gueltig:) 🟡 GEMESSEN 2026-08-20/21 — Fall B, aber „messbar, nicht hörbar"
✅ Die Prämisse ist geprüft. Ergebnis + Rohdaten:
tp6-praemisse-messrunbook.md§5.
idle / C0 Upload-Last Download-Last Durchlauf 1 (ohne Call) 12,9 ms 60,4 ms 41,3 ms Ort 1 Küche (mit Call) 13,2 ms 42,8 ms 37,1 ms Ort 2 Terrasse (mit Call) 12,8 ms 40,4 ms 36,3 ms Referenz 2026-06-16 12 ms 17,5 ms nie gemessen Linerate erstmals dokumentiert: Upload 9,6 Mbit · Download 54,6 Mbit. Der Anstieg liegt in der Senderichtung bei +28 bis +47 ms und damit über der §3-Schwelle von ≲30 ms → formal Fall B, CAKE ist begründet. 🔴 Aber: durch alle sechs Lastphasen lief ein Telegram-Videocall, und es wurde kein einziger Problem-Button gedrückt. Messbar ja, wahrnehmbar nein. waveform gibt zeitgleich Grade A — kein Widerspruch, sondern ein kürzerer Test (Erklärung in §5.3). Empfehlung: TP6 bleibt offen und begründet, hat aber niedrigere Priorität als TP25 — was die Calls tatsächlich zerreißt, sind die WLAN-Übergaben, und die repariert keine Queue. Wenn gebaut wird: erst
/queueins GC-Template + ComplianceRule (§4.1), dann die Queue, dann dieselbe Messung als A/B-Nachweis. 📋 Eigene Session, Einstieg:docs/handoff-tp6-session.md(Übergabe 2026-08-19), Arbeitsplan:docs/tp6-praemisse-messrunbook.md. Abbruchkriterium steht vor der Messung fest.
- 🔴 Der Widerspruch, der zuerst aufzulösen ist: dieser TP wird seit Monaten als „DAS Ziel" geführt —
aber
docs/call-quality-diagnosis.mdhat den Bufferbloat bereits gemessen und kommt zum gegenteiligen Schluss. Wörtlich in dessen Ergebnistabelle:CAKE / QoS | kein Bufferbloat-Spielraum | ❌ nicht deployt (wäre marginal), und im Kopf: TP6 „hat sich als Nicht-QoS-Problem entpuppt". Messwerte (2026-06-16): 3 Flows = 10,3 Mbit Upload gesättigt · idle 12 ms · Vollast avg 17,5 ms / max 26 ms → A/A+. Bei solchen Zahlen holt CAKE nichts mehr. - ⚖️ Was das relativiert: die Messung stammt aus der FritzBox-Ära. Seither ist der Edge komplett
getauscht (Arris im Bridge-Mode, NAT und Queuing liegen auf
crs326-core). Die Leitung ist dieselbe, das Pufferverhalten des neuen Edge ist ungemessen. - ✅ ERLEDIGT 2026-08-20/21 — gemessen statt vermutet (die frühere Fassung dieser Zeile verlangte genau das): der Bufferbloat-Test gegen den heutigen Edge ist gefahren, dreimal, davon zweimal mit laufendem Videocall an verschiedenen Orten. Es ist schlechter geworden als 2026-06-16 (60,4 statt 17,5 ms avg unter derselben Sättigung), die Ursache ist damit neu und liegt nicht an der Core-CPU (~10 % unter Upload-Last). Zahlen und Einordnung: Runbook §5.
- 🔎 Fasttrack ist auf dem Core faktisch tot — und das ist kein Entwurf, sondern ein Unfall
(Befund 2026-08-18): die Regel
defconf: accept est,rel,untrackedsteht vordefconf: fasttrack, also wird Fasttrack nie erreicht. Live: 32.979.171 Pakete auf der accept-Regel, 0 auf der Fasttrack-Regel, 0 von 445 Verbindungen fasttracked.- Herkunft:
ap1hatte die Reihenfolge vor dem Cutover richtig (Fasttrack zuerst, wie im MikroTik-defconf). Umgedreht wurde sie beim handgebauten Core-Aufbau (TP21.1). - Für TP6 ist das günstig: Fasttrack umgeht die Queues, CAKE braucht sie — ein Konflikt, den man sonst erst auflösen müsste, existiert hier gar nicht.
- ✅ ENTSCHIEDEN (Christoph, 2026-08-19): der Zustand bleibt — und gilt ab jetzt als Absicht, nicht
als Unfall. Begründung: bei ~10 Mbit WAN kostet der Verzicht nichts (die Core-CPU trägt den
Forward-Pfad ohnehin, 32,9 Mio Pakete sind der Beleg), und für CAKE ist er die bequemere Ausgangslage.
Damit ist auch die TP21-Warnung „das Re-Baseline hat den Fehler zum Soll erklärt" aufgelöst: die
Reihenfolge in der SoT ist jetzt gewollt. Sie war es bei der Aufnahme nur nicht.
- ⚠️ Gegenbedingung, unter der neu bewertet wird: wenn Inter-VLAN je auf Gigabit soll (NAS ↔ MAIN läuft geroutet über dieselbe 800-MHz-CPU), ist der Verzicht teuer. Die Messung dafür steht aus — und sie, nicht die WAN-Zahl, ist die Vorbedingung jeder Neubewertung.
- ⚠️ Ungemessen ist der Preis: ohne Fasttrack läuft jedes geroutete Paket durch die volle Kette samt Conntrack, auf der Core-CPU. Für 10 Mbit WAN irrelevant, für Inter-VLAN-Transfers (NAS ↔ MAIN, Synology Drive) möglicherweise nicht. Das ist messbar und sollte gemessen werden, bevor jemand die Reihenfolge „repariert".
- 🔴 Und es steht seit 2026-08-18 als ABSICHT in der SoT: das Re-Baseline
(
ingest-core-firewall.py --apply) hat die Reihenfolge unverändert nach Nautobot geschrieben, Ruleip-firewall-filtermitconfig_ordered=true.Entscheidung nötig: Reihenfolge korrigieren (Fasttrack lebt wieder) · Fasttrack-Regel entfernen (ehrlich: wir nutzen sie nicht) · so lassen und hier begründet stehen lassen.→ entschieden am 2026-08-19, s. oben: so lassen. Damit stimmen SoT und Absicht wieder überein — bisher stimmten sie nur zufällig überein.
- Herkunft:
- 📋 Runbook liegt bereit:
docs/tp6-praemisse-messrunbook.md(2026-08-19). Es reproduziert die Methode von 2026-06-16 (3 Flows + 24 Pings idle/Last), misst erstmals auch die Download-Richtung (die 2026-06-16 nie gemessen wurde — beim asymmetrischen Kabelanschluss die wahrscheinlichere Problemseite), und trägt das Abbruchkriterium vor der Messung: A/A+ → TP6 wird geschlossen statt gebaut. Enthält außerdem den Bau-Kontext für den Fall B, damit er nicht neu recherchiert wird — vor allem:/queuefehlt im GC-Template und hat keine ComplianceRule (dieselbe blinde Stelle, die TP26 für/ip firewall filtergeschlossen hat), eine handgesetzte Queue wäre also driftend und ungeschützt. - 📌 Nicht im Repo dokumentiert und deshalb Teil der Messung: die tatsächliche Liwest-Linerate. Die „~10 Mbit" stammen aus der Sättigungsmessung von 2026-06-16, nicht aus einem Tarifdatenblatt. Ohne diese Zahl ist die übliche CAKE-Vorgabe „85–95 % Linerate" geraten.
- Abh.: TP5 ✅ (keine Blocker mehr). Vorgelagert: die Messung oben.
TP6.1 · Gitea #44 — Saettigung vermeiden statt Bufferbloat bekaempfen
Der Gedanke kam von Christoph beim TP6-Abschluss („dann koennten wir zumindest den Sync von der NAS zurueckhalten“) — und er hat mein TP6-Urteil zu Recht angezweifelt.
🟢 Abnahme, echte Saettigung, Kontrollmessung inklusive:
gleiche NAS-Last, gleicher Messclient avg max Priorisierung aus 40,8 ms 53,4 ms Priorisierung an 11,0 ms 14,6 ms −73 %. Und die Last war echt, nicht behauptet:
wan-up-totalfuhr 9,0 Mbit (das max-limit greift exakt),wan-up-bulk8,87 Mbit mit 1581 Drops — der Sync wurde aktiv gebremst, waehrendwan-up-restfrei durchlief.vlan100 tx = 9,0 Mbps. Die Kontrolle mit abgeschalteter Markierung war noetig, um auszuschliessen, dass die Verbesserung bloss daher kommt, dass Bulk und Ping jetzt von verschiedenen Hosts stammen.🔴 Damit ist die DOCSIS-Erklaerung aus TP6 widerlegt. Dort stand, die ~30 ms entstuenden stromabwaerts im Uplink und seien unabaenderlich. Sie sind es nicht — sie loesen sich auf, sobald der Verkehr in getrennte Klassen faellt. Der Fehler steckte in der TP6-Methode: Bulk und Messverkehr kamen vom selben Host, also gab es fuer CAKEs Host-Fairness (
triple-isolate) nichts zu trennen — alles lag in derselben Klasse, und Shapen allein aendert an einer Reihenfolge nichts. Was CAKE nicht schaffte, schafft explizite Klassentrennung mit Prioritaet. Merkregel: nicht die Bandbreite ist das Problem, sondern wer vor wem drankommt.Was gebaut ist (Template [11a], via GC, 104/104 compliant):
- zwei
mangle-Regeln inpostrouting(vor src-nat — nur dort ist die LAN-Quelle noch sichtbar): NAS →bulkup, alles andere →restupwan-up-total(parent=global,max-limit=9M) mit zwei Klassen darunter:wan-up-restpriority=1 limit-at=6Mundwan-up-bulkpriority=8 limit-at=1MDrei Entscheidungen, die begruendet bleiben sollen:
- Prioritaet statt hartem Cap — ein Limit haette die NAS auch nachts gebremst und Bandbreite verschenkt (DSM drosselt von sich aus nicht, User-bestaetigt 2026-08-23).
limit-at=1Msorgt dafuer, dass der Sync nie ganz verhungert.src-address=10.40.20.10, nicht VLAN20 — in INFRA haengen auch HA, Nautobot und pve. Wer das je auf10.40.20.0/24erweitert, verlangsamt seine eigenen Werkzeuge.parent=global, nichtparent=vlan100— Interface-HTB ist auf diesem Geraet tot (hw-offloadetes out-interface, s. TP6).✅ Governance-Vorbedingung erfuellt: ComplianceRule
ip-firewall-mangleangelegt (nautobot/ingest-mangle-rule.py),config_ordered=True— die NAS-Regel muss vor dem Catch-all stehen, sonst waere die Priorisierung still wirkungslos. Zaehler jetzt 26 Rules x 4 Geraeten = 104 Checks.💡 Offen, klein: ob weitere Bulk-Quellen dazugehoeren (pve-Backups? Time Machine?). Erst messen, ob sie ueberhaupt saettigen — die Regel dafuer ist eine Zeile.
TP7 · Gitea #45 — Media-Discovery (mDNS) für VLAN 40 — docs/tp7-mdns.md
- ✅ Built-in mDNS-Repeater aktiv — Live-Stand
crs326-core(verifiziert 2026-08-14):mdns-repeat-ifaces=vlan10,vlan20,vlan30,vlan40,vlan90→ MAIN/INFRA/IOT/GUEST ↔ MEDIA. Reversibel (Feld leeren). 📌bridge(=VLAN1) ist nicht mehr dabei — mit dem VLAN1-Retirement erwartbar und korrekt, war aber nie nachgezogen. Historische Fassung (ap1, bis 2026-08-08):…,vlan90,bridge—bridge=VLAN-1 seit TP7.2 2026-07-03. Realbestand: MAIN=iOS-Client + MacBook, INFRA=Home Assistant, MEDIA=10× Sonos (siehedocs/sonos-inventar.md). - ✅ Funktional durchgetestet (2026-07-02): iOS-Sonos-App (vlan10) und Home Assistant (vlan20) finden die
9 online-Sonos per
_sonos._tcp.local.(Bonjour) automatisch. Household nicht mehr gesplittet. - ✅ TP5-Anschluss live:
forward accept vlan10↔vlan40+forward accept vlan20↔vlan40+input accept udp/5353auf vlan10/20/30/40 sind gebaut (mit „TP5:"-Kommentar), damit Discovery + Steuerung + Streaming ohne Umwege gehen. - ⚠️ SSDP/Cast (UDP 1900) bewusst NICHT gebaut (bräuchte Reflector-Container auf NAS/pve; hAP hat kein USB/Flash). Konsequenz: macOS-Desktop-Sonos-App nutzt SSDP → quert die VLAN-Grenze NICHT und findet die Sonos nicht. iOS-App (mDNS) und HA-Integration decken den Nutzungsbedarf ab; Spotify Connect läuft über Cloud.
- Abh.: TP4 ✅, TP5 (Sonos-Holes) ✅ live.
TP7.1 · Gitea #46 — SSDP-Relay (macOS-Sonos-App über VLAN-Grenze) — User-bestätigt: „sonos ist da!"
- ✅ Umsetzung: eigener LXC 108
mcast-relayauf pve (Ubuntu 24.04, 1 Kern, 256 MB,onboot), zweibeinig:eth0= 10.40.10.21 (VLAN10),eth1= 10.40.40.21 (VLAN40), Default-Route nur über VLAN10, kein IP-Forwarding. Dazucore ether13(pve-Port) umtagged vlan10, vlan40erweitert (routeros/tp7.1-core-ether13-trunk.rsc). Software:alsmith/multicast-relayals systemd-Unitmulticast-relay.service.--noMDNSist Pflicht: mDNS reflektiert bereits der Core (TP7). Zweimal zu reflektieren erzeugt Duplikate.🔴 WIDERRUFEN 2026-08-25: die Flagge war der Fehler — sie schreibt in--ssdpUnicastAddr 10.40.10.21ist ebenfalls noetig — die Sonos antworten auf einen M-SEARCH per Unicast, und diese Antworten muessen zurueckgereicht werden.multicast-relay.pyZ. 630 die Quelle jedes SSDP-Pakets um, worauf Z. 691 die M-SEARCH beim Senden aufeth1selbst verwirft (10.40.10.21ist nicht im VLAN40-Netz). Der Hinweg lief damit nie; ausgebaut, Rückweg wird geroutet (TP5: MEDIA->MAIN). Stand + Merkregeln: Ist-Stand inteilprojekte.mdund Gotcha inCLAUDE.md.
- 🔑 Warum zwei Beine zwingend sind (Christophs Frage „vlan40 sollte keinen relay benoetigen?!?"):
SSDP ist link-lokales Multicast mit TTL 1. Der M-SEARCH des MacBooks verlaesst VLAN10 nie, die
ssdp:alive-NOTIFYs der Sonos verlassen VLAN40 nie. Ein Relay kann nur kopieren, was es selbst hoert — es muss Mitglied beider Broadcast-Domaenen sein. Routing hilft wegen TTL 1 nicht, undforward accept vlan10<->vlan40ist laengst offen: es scheitert vor dem Verbindungsaufbau, an der Entdeckung. Dass AirPlay funktionierte, passt genau ins Bild — das ist mDNS. - 🎯 Beweis im Log:
[Sonos Discovery] Relayed 268 bytes from 10.40.10.183:49358 on eth0 [ttl 64] to 255.255.255.255:1900 via eth1/10.40.40.21— echte Suchrufe beider Macs (.10.183,.10.82). - ⚠️ Falle beim Selbsttest: ein M-SEARCH vom Relay-Host selbst wird nicht weitergereicht (Loop-Schutz: das Werkzeug ignoriert eigene Quelladressen). Mein synthetischer Test meldete deshalb 0 Antworten, waehrend die App bereits funktionierte. Aus dem Relay heraus laesst sich der Relay nicht pruefen — entweder am echten Client testen oder am Log mitlesen.
- Keine Firewall-Arbeit noetig: der Relay spricht in beiden VLANs jeweils lokal; das trifft die
forward-Kette nicht. - 📌 Status-Update 2026-08-14: Symptom vom User erneut bestätigt — iOS-App ✅, HA-Sonos-Panel ✅ (steuern/gruppieren), macOS-Desktop-App findet die Umgebung nicht. Damit ist das Bild vollständig: alles, was mDNS spricht, funktioniert; nur der SSDP-Weg fehlt. Der Fix wird Bestandteil des TP5-Pakets (gemeinsamer Test mit Deny-by-default statt zweimal dieselbe Strecke prüfen). ⚠️ Nicht als Firewall-Problem fehldiagnostizieren:
forward accept vlan10↔vlan40ist längst offen — es scheitert an der Discovery, nicht am Datenpfad. - Bedarf: macOS-Desktop-Sonos-App auf VLAN 10 findet die Sonos in VLAN 40 nicht (Discovery per SSDP UDP 1900, RouterOS reflektiert kein SSDP). iOS-App + HA decken den Alltag ab, aber User will die Desktop-App nutzen.
- Lösung: kleiner SSDP-Reflector-Container mit Bein je Ziel-VLAN. Auf NAS oder pve (nicht am hAP, 128 MB
Flash + kein USB). Kandidaten:
bkupreck/ssdp-repeater,scyto/multicast-relay, oder eigenes Python-Skript. - Scope: vlan10 ↔ vlan40 (MacBook → Sonos). Optional vlan20 ↔ vlan40 falls HA je SSDP-Discovery brauchen sollte (aktuell nicht — HA nutzt zeroconf/mDNS).
- Anschluss TP5:
input accept udp/1900auf den bedienten VLANs (falls Router-lokal reflektiert wird) bzw. Container-Port-Freigaben je Bein. - Alternative (verworfen): macOS-Client temporär in VLAN 40 hängen (unpraktikabel für Alltagsnutzung).
- Abh.: TP7 ✅. Kein Blocker für TP5-Deny-by-default.
TP7.2 · Gitea #47 — HA↔Sonos static-host binding + VLAN1/GUEST-Discovery — docs/sonos-inventar.md
- Root Cause (widerlegt frühere Doku): HA-
media_player.*-Sonos alleunavailable. HA sitzt nicht auf VLAN 20, sondern noch auf10.40.41.105(VLAN-1-Transfernetz, IP-Migration steht aus). Der mDNS-Repeater deckte VLAN 1 nicht ab, und die HA-Sonos-Integration ist SSDP-abhängig (manifest dependencies:[ssdp], soco 0.31.1) → quert die VLAN-Grenze nicht. Die alten „HA nutzt mDNS/zeroconf, fixed 2026-07-02"-Notizen waren falsch. - ✅ HA-Fix (discovery-unabhängig):
sonos: media_player: hosts:mit allen 11 Sonos-IPs +advertise_addr: 10.40.41.105inconfiguration.yaml(Backup.bak-sonos-20260703).advertise_addrfixt die UPnP-Event-Callbacks trotz HA-Multi-Homing (.105/172.16.0.18/docker). Core-Restart → alle 6 Online-Zonenidle/playing(Wohnzimmer-Push verifiziert = Callbacks OK). Terrasse.198offline = kein Entity (kommt beim Einschalten). Kurzes Flapping direkt nach Restart = Settling, danach stabil. - ✅ Nebeneffekt: mit
bridgeim Repeater (s.u.) meldet HA jetzt „Automatic discovery is working, hosts not needed" — die statischen Hosts sind also Redundanz (Gürtel+Hosenträger), bleiben aber als Absicherung. - ✅ VLAN 1 (temp) + GUEST (perm) Discovery/Reach (User-Wunsch 2026-07-03):
- mDNS-Repeater erweitert →
mdns-repeat-ifaces=vlan10,vlan20,vlan40,vlan30,vlan90,bridge(VLAN-1-untagged=bridge). - Firewall:
input accept udp/5353 vlan90+forward accept vlan90↔vlan40(ganzes MEDIA, beide Richtungen; User-Wahl). VLAN 1/bridgebrauchte nichts (schon viaTP10-seal-lan+ permissiver Forward). - Bewusst in Kauf: flacher Repeater → Guests sehen auch MAIN/INFRA/IOT-mDNS-Announcements (Discovery-Leak; echte Verbindungen regelt TP5-Deny-by-default).
- mDNS-Repeater erweitert →
- Offen/später: HA→VLAN 20 (IP-Migration nach Omada-PVID-Fix) → dann nur
advertise_addrauf neue IP; macOS-Desktop-App weiter via SSDP-Reflector TP7.1. Abh.: TP7 ✅, TP5-Holes ✅.
TP9 · Gitea #48 — Gateway-/Router-HA
- ❌ Verworfen (User-Begründung 2026-08-08, „ganz klar nein"): am
crs326-coreführt ohnehin nie ein Weg vorbei — er ist der unumgängliche L3-Durchleitungspunkt. Ein zweites Gerät / VRRP beseitigt diesen SPOF nicht, sondern baut nur zusätzliche Sollbruchstellen ein (2× Config-Sync für DHCP/DNS/Firewall/NAT, Split-Brain-Risiko, VRRP-Eigenfehler) → netto ein Zuverlässigkeits-Verlust, kein -Gewinn. Die Frage ist nicht „Aufwand vs. Nutzen", sondern „mehr Fehlerquellen einbauen?" → nein. DR-Weg = Config-Backup-Restore (+ ggf. AP-Reprovisionierung). VRRP-Skizze unten = nur noch historische Recherche. - „Was, wenn ap1 ausfällt?" → VRRP löst Gateway-Failover je VLAN ~gratis (kreuzweise Master/Backup). ⚠️ Haken (nicht Last): DHCP/Firewall/NAT/DNS müssen auf BEIDEN APs identisch gepflegt sein, sonst „Gateway up, Internet tot". Empfehlung: VRRP nur für MAIN/INFRA, sonst ap2 als Kalt-Ersatz + Backup. DHCP/DNS schon redundant (Split + 2 Resolver).
- Abh.: TP4. (Research erledigt, s. TP-R + Config-Skizze im Report.)
TP10 · Gitea #49 — Multi-Site VPN — beide WG live auf ap1-Hub (docs/tp10-vpn-migration.md)
Details/Cutover/Gotchas/Eckdaten →
docs/tp10-vpn-migration.md(Single Source of Truth). Research:docs/research/vpn-comparison.md.
- ✅ KERN DURCH (2026-06-27) + EDGE-CUTOVER (2026-07-01): beide AVM-Tunnel → 2× WireGuard mit Hub auf ap1 migriert. Live:
peer fm(10.101.0.0/24, bidirektional, myfritz-Endpoint) undpeer dw(10.95.10.0/24, CGNAT-Dial-in) mit frischem Handshake + Traffic. Public-Edge direkt — ap1 hört UDP/51821 aufvlan100(Edge-Cutover 2026-07-01), keine FB-Portfreigabe mehr, kein Double-NAT. FM-IPsec gekillt, Gelis alter FB↔FB-WG sauber geswappt. - ✅ DW/Geli on-site verifiziert (2026-06-27): Geli auf
10.95.10.0/24renumbert, FB-WG single10.95.10.1/24, Keepalive 25, Endpointbf4…:51821. End-to-End von macmini/Linz → Gelis 24/7-APs10.95.10.246/.247sauber (echte LAN-IPs, kein10.255.255.x-NAT-Leak). - 💡 Root Cause (FM-PoC bewiesen): FB masqueradet WG, wenn die Interface-
Addresseine Transfernetz-IP ist → muss die FB-LAN-IP sein (AVM Proxy-ARP). War der Schlüssel zum sauberen LAN-LAN. - Hub:
wg-hub(UDP 51821, KeyP/bzt…, MTU 1412, keine IF-IP). Endpoint = DDNSbf4.emsenhuber.net:51821(Cloudflare, DNS-only → Public-IP). Apply gebündelt inrouteros/tp10-cutover-apply.rsc. - ✅ Permanenter Edge-Cutover durch (2026-07-01) — Details in TP4 (WAN via sw1 vlan100, ap1 = Public-Edge, WAN-Input-Seal live). BF-FB-eigenen WG-Server 51820 entfällt (FB physisch weg).
- Offen: DDNS-Auto-Updater für
bf4.emsenhuber.netauf NAS/pve, damit der A-Record der Public-IP folgt (falls Liwest sie tauscht). Aktuell manuell in Cloudflare gepflegt.
TP14 · Gitea #50 — Host/Container-IP-Migration VLAN1→VLAN20 (Docker-Cutover NAS+pve) — live re-verifiziert 2026-08-08) — docs/nas-vlan20/RUNBOOK.md, Handoff docs/nas-vlan20/handoff/
- ✅ ABGESCHLOSSEN — Migration komplett (Live-Check 2026-08-08 vom core: NAS
.20.10, pve.20.100, Docker-LXC.20.126, platform-pg.20.20, Nautobot.20.30alle 0% Loss). Alle Hosts + Container auf VLAN20. TP14.4 (CF-Access-Token-Rotation) = kleiner, nicht-blockierender Standalone-Follow-up (CF/TP11-Umfeld); TP14.5 war nie ein eigener Change (nur ein Reihenfolge-Gate) → erfüllt, TP5 damit entblockt. - ✅ NAS (DS923, ep14) migriert (2026-07-09/10): Docker von
default_external(macvlan .41) auf einvlan20-Macvlan (10.40.20.0/24, gw .1, parentovs_eth0); DSM-Cutover.20.10; Portainer-Endpoint.20.10:9001. Root-Cause der Dauerfehler = Portainer Config-Only-Macvlan-Falle (Driver:null, kein Container-Attach) + Macvlan-Parent-Exklusivität (default_externalmuss weg fürvlan20) +default_internal(172.18) weg. Container laufen auf.20.x. - ✅ CF-Ingress v116 (2026-07-10): 6 NAS-Origins .41→.20 (SSoT
docs/cf-tunnel-mapping.md§8);vw200 via Tunnel = pve→VLAN20-Routing steht (502 direkt nach Ingress-PUT = transient). - ⚠️ Abh./Reihenfolge: verzahnt mit Omada-PVID-Fix/IP-Migration (Reihenfolge #3); Sessions = Sub-TPs TP14.1–14.5, sequenziell A→B→C→(D jederzeit)→E, keine parallelen Branches (geteilte Live-Infra). Anschlussstatements:
docs/nas-vlan20/handoff/README.md. - ✅ TP14.1 (Session A) durch 2026-07-10: alle ep14-Container auf vlan20 + pve-mcp neu; nur Omada-Inform-Adresse offen (Controller-UI-Task, s.u.).
- ✅ TP14.2 (Session B) durch 2026-07-10: pve-LXC (400/
docker) auf VLAN20 (.20.126, ipvlanparent=veth20); omada-mcp/adguard→.20.x; CF-Connector jetzt VLAN20 = #1033 gelöst. Nächste Session = TP14.3 (Session C, dormante Stacks + Referenz-Sweep ap1-DNS). - ✅ Netz-Abgleich 2026-07-11 (live via MikroMCP/pve-mcp): NAS
.20.10, Mac mini.20.167, pve-LXC.20.126alle reachable auf VLAN20 (+ Container.20.xpopuliert;iobroker .107/ccu .232/z2m .106/vw .127jetzt auch VLAN20). Sonst in VLAN1 (bridge) nur noch: sw1.11/sw2.12/ap2-Mgmt.2(Switch-/AP-Mgmt, interim bis MGMT-VLAN99) + Streu-Clients übers cudy-Alt-WLAN (MacBook.182, iPhone.186, SwitchBot.184, Sonoff) + die 16 VLAN1-Shellys (TP17).defconf/pool-v1-DHCP aufbridgeläuft noch (VLAN1 aktiv). - ✅ pve-Host-Mgmt → VLAN20 (2026-07-13): letzter verbliebener Host-Umzug.
vmbr0bleibt VLAN1.41.100(ohne Default-Route, interim), neuesvmbr0.20(bereits vorbereitet, aber mit kaputteraddress 10.40.20.0/24vorgefunden) korrigiert auf10.40.20.100/24→ifreload -alive (ifupdown2, kein Reboot, LXC 400 durchgehend unbeeinflusst) → Default-GW auf10.40.20.1geflippt. SSH-Key-Auth bestätigt auf.20.100. Nachgezogen: ap1-DNS (pve.bf.lan→.20.100; dabei Fund+Fix eines Alt-Bugs:pve-mcp.bf.lanzeigte noch auf.41.173statt.20.173), CF-Tunnelbf-pveIngress (pve+j44d6tua-SSH-Hostname .41.100→.20.100, PUT viaCF_API_TOKEN, Smoke 200/200), CLAUDE.md,docs/ip-plan.md.~/.claude.jsonwar schon sauber.
TP14.1 · Gitea #51 — Session A: NAS fertigstellen — Omada-Inform/sw2 VERTAGT
- ✅ Alle ep14-Container auf vlan20 redeployed + verifiziert running/.20.x (via Portainer-Stack-Redeploy, Env preserved, Volumes intakt): oc-stack(112 → prometheus
.151/node-exporter.154/grafana.109), default(72 → hms-mqtt.124), nginx(101 → dashboard-web.148), oc-central(160 → qdrant.159), oc-charlie(158 →.162+cf), oc-johnny2(150 →.161+cf), gitea(111 →.157, DB.20.23:3306erreichbar ✓), drawio(107 →.139, intern; CF-CNAME war eh gelöscht). - ✅ pve-mcp NEU als Stack (id 202, vlan20-only
.20.173), verbunden mit Proxmox.41.100(v9.0.11) — ⚠️ StreamableHTTP am Root-Pfad/, NICHT/sse(mcp-pve v0.4.8,MCP_TRANSPORT=http).~/.claude.jsonmcpServers.pve-mcpNEU angelegt{type:http, url:http://10.40.20.173:3000/}(war vorher gar nicht drin) → wirkt nach Claude-Code-Restart. - ✅ Tunnel-Smoke (CF-Ingress v116 zeigte schon auf
.20): gitea 200, grafana 302, vw 200 — Origins existieren jetzt real. - ⚠️ alertmanager
.153: korrekt an vlan20, aber crash-loop wegen PRE-EXISTING Config-Bug (${TELEGRAM_CHAT_ID}-Literal in/etc/alertmanager/alertmanager.yml→ int64-Parse-Fehler; Alertmanager macht kein Env-Substitution). NICHT migrationsbedingt, braucht echte chat_id. Out-of-scope. - ⚠️ openclaw-DB
10.40.41.122:3306down (shared MariaDB, pre-existing; Bots kamen trotzdem hoch).DB_HOST-Env unverändert gelassen.OLLAMA_BASE_URL=.41.167=Mac-mini bleibt korrekt.41(migriert nicht → kein Blanket-Env-.41→.20!). - ⚪ OBSOLET (2026-07-16) —
omada-controller Inform-Adresse + sw2 re-adopt: ursprünglich vertagt (2026-07-10, Controller-Login schlug fehl). Gegenstandslos seit TP2.1: der Controller-Login-Ausfall eskalierte zum Werks-Reset von sw2, User hat daraufhin entschieden, sw2 dauerhaft standalone ohne Controller zu betreiben — und den Omada-Controller-Container samt omada-mcp am 2026-07-16 komplett gelöscht (overkill für 1 Switch auf der Abschussliste, s. TP15/CRS326). Kein Re-Adopt mehr vorgesehen. - 🐞 Gotcha gefunden: Portainer-Stack 111 (gitea) hatte den
vlan20-Networks-Block auskommentiert (Vorsession-Artefakt) → Container landete aufgitea_default/172.18. Fix = Redeploy mit Disk-Filedocs/nas-vlan20/stacks/111-gitea.ymlals Override.
TP14.2 · Gitea #52 — Session B: pve-Docker-LXC (.126) → VLAN20
- ✅ ep2-Container auf
vlan20: omada-mcp.20.176(OMADA_BASE_URL→.20.175), adguard_bf1.20.16, adguard_fm2.20.17— alle running/reachable (health 200, adguard 302). Transf. Filesdocs/nas-vlan20/stacks/{195-adguard,200-omada-mcp}.yml. - ✅ LXC 400 (
docker) net0 →tag=20, ip=10.40.20.126/24, gw=10.40.20.1(⚠️ Retag brauchte Christoph — Tokenclaude@pam!claudehat keinVM.Config.Network; UI-Edit, dann Reboot via API mitVM.PowerMgmt). Portainer wandert aufhttps://10.40.20.126:9443. - 🐞 Gotcha: in-Container-Iface heißt jetzt
veth20, NICHTeth0(UI setzte Name analog net1=veth16) → Dockervlan20=ipvlanparent=veth20(nicht eth0 wie im Runbook). cloudflared(host)/portainer(bridge) unberührt. - ✅ CF-Connector
db713b30jetzt in VLAN20 (Tunnelbf.emsenhuber.nethealthy/8 conns) = löst TP11-Track-B/C (#1033-Zielbild). Ingressportainer.41.126→.20.126. Smoke: portainer/gitea/vw 200, grafana 302. - ✅ Refs nachgezogen:
mcp/portainer/.env(PORTAINER_URL),~/.claude.json(omada-mcp.20.176), CLAUDE.md,docs/ip-plan.md,docs/cf-tunnel-mapping.md. Next = TP14.3 (Session C, dormante Stacks + Referenz-Sweep ap1-DNS). - ✅ Live-Smoke re-verifiziert 2026-07-10: alle 6 VLAN20-IPs ping OK + dienstseitig grün — Portainer
.20.126:9443HTTP 200 (LXC 400 running, net0veth20 tag=20 gw/ns=.20.1), omada-mcp.20.176→Controller.20.175v6.2.10.17 (HTTPS :8043 200), pve-mcp.20.173liefert Proxmox-Config, adguard.20.16/.20.17HTTP :80 302→login (nicht HTTPS/:3000).
TP14.2a · Gitea #53 — pve-mcp Single-Session-Fix + VLAN20-Host-DNS
- pve-mcp „Failed to connect": Ursache = mcp-pve v0.4.8 kann im HTTP-Transport nur eine MCP-Session (ein globaler
StreamableHTTPServerTransport,sessionIdGeneratorgesetzt) → erster Client nach Boot belegt den Slot, jeder weitere Init (neue Claude-Code-Session,claude mcp list-Healthcheck, Reconnect) =400 "Server already initialized". omada-mcp NICHT betroffen (frische Session-ID pro Init → Per-Session-Transport). Fix = Upgrade auf 0.6.1 (Per-Session-Map,serverFactory()je Session, gleiche Env-Vars = Drop-in); Stack 202 neu deployed, Container.20.173= 0.6.1,Connected to Proxmox VE 9.0.11,tools/listliefertpve_*, Claude Code ✔ Connected. 3× init hintereinander = 3× 200 mit verschiedenen session-ids (verifiziert). - Kollateral-Fund — VLAN20-Host-DNS kaputt (beide Docker-Hosts): nach dem VLAN20-Umzug zeigten NAS und pve-LXC
/etc/resolv.confnoch auf totes.41.254→docker pullghcr.io scheitert (EAI_AGAIN/ 5s-Resolver-Timeout; Egress zu ghcr-IP140.82.x:443= OK 31 ms, also nur Resolver tot, nicht Egress). Fixes: LXC.20.126→pct set 400 --nameserver 10.40.20.1(Christoph). NAS → DSM-„Allgemein"-DNS war.20.1, ABER die Netzwerkschnittstelle zog DNS per DHCP und überschriebresolv.conf; Fix = Schnittstelle „DNS manuell"10.40.20.1(Christoph) → NAS pullt wieder direkt. Merkregel Synology: GUI-DNS ≠ wasdockerdliest (Quelle/etc/resolv.conf, per DHCP überschreibbar). Workaround solange NAS-DNS tot:docker save(LXC, hat DNS) → gzip (191-MB-tar reißt am Portainer-Agent-Socket-Proxy „context canceled"; ~70 MB gz geht) → PortainerPOST /endpoints/14/docker/images/load→ Stack-RedeploypullImage:false. Gotcha: laufende Container frieren den127.0.0.11-Upstream zum Erstellzeitpunkt ein (Recreate nötig; für pve-mcp egal — Proxmox per IP.41.100). Memoryref_pve_mcp_singlesession_and_vlan20_dns.
TP14.3 · Gitea #54 — Session C: Dormante Stacks vlan20-tauglich + Referenz-Sweep — dormante Stacks weiter bewusst nicht deployt
- ✅ Dormante Stacks bereitgestellt (2026-07-11):
transform.pyauf core(43)/openclaw(92)/openclaw2(97)/oc20260307(119)/openspeedtest(74)/speedtest_tracker(80)/technikscheiss(42) →.new.yml+.orig.ymlindocs/nas-vlan20/stacks/(gitignored). Nicht deployt (User: „im Bedarfsfall später", Container-Zukunft ungewiss). 42/43 warendefault_internal→ jetzt vlan20-only (DHCP-.20.x). ⚠️ Deploy-Caveats: externe Refs bewusst NICHT umgeschrieben (DB_HOST=.41.122[pre-existing tote openclaw-DB, in 80+119],OLLAMA_BASE_URL=.41.129,REDIS_URL=.41.111in 119); Kollision43-corewill.20.23= gitea-DB-IP (nicht gleichzeitig deploybar). - ✅ Referenz-Sweep
.41→.20(2026-07-16, im Rahmen der TP19-Backup-Vorbereitung live gefunden + gefixt): ap1/ip dns statichatte nochnas.bf.lan→.41.10unddocker.bf.lan→.41.126stale — korrigiert auf.20.10/.20.126(MikroMCPmanage_dns_entry, dry-run+apply). Zusätzlich per User-Entscheid Omada-Controller + omada-mcp komplett gelöscht (overkill für 1 Switch auf der Abschussliste) → DNS-Einträgeomada.bf.lan/omada-mcp.bf.lanentfernt statt migriert.fritzbox.bf.lan(totes Gerät, physisch weg seit 2026-07-01) ebenfalls entfernt.docs/ip-plan.md+ CLAUDE.md nachgezogen. - ✅ ERLEDIGT/GEGENSTANDSLOS (live geprüft 2026-08-16):
~/.claude.json(omada-mcp-Eintrag verwaist), CF-Ingress-Rest (omada/omada-mcp-Hostnames, ungeprüft)~/.claude.json:omada-mcpist nicht mehr als MCP-Server registriert (mcpServersenthält ihn nicht). Er steht nur noch indisabledMcpServerseiniger Projekt-Scopes — ein reiner Merkposten „bewusst aus", keine Verbindungsversuche, kein Handlungsbedarf.- CF-Ingress: alle 9 Tunnel durchgesehen (
cfd_tunnel+/configurations) — kein einzigeromada-Hostname mehr. Sauber.
- ↪️ Shelly-Geräte-Übersiedelung ausgegliedert → TP17 (die ~26 IoT-Shellys sind eine eigenständige WLAN-Migration, nicht Teil des Docker-Ref-Sweeps).
TP14.5 · Gitea #55 — Session E: Freigabe-Gate → TP5-Firewall — kein eigener Change
- Gate „TP14.1–14.3 durch (alle Origins/Connectoren in VLAN20)" ist erfüllt → TP5 (Deny-by-default) ist entblockt. Reines Reihenfolge-Gate, kein eigener Change.
📦 Nachtrag 2026-08-31: die vier Skripte, die den Cutover begleitet haben (
apply-core-cutover-l3,backup-core,restore-core,backup-ap1), liegen jetzt unterrouteros/archiv-tp15-cutover/. Sie zeigten alle auf tote Adressen —backup-ap1.pyallerdings auf eine lebende falsche (10.40.10.1ist die VLAN10-SVI des Core, nicht ap1) und hätte still das falsche Gerät gesichert.
TP15 · Gitea #56 — HW-Refresh: Switching + Router — Bring-up beider CRS326 + Branch-Tausch (2026-07-23) und Core-Tausch/L3-Umzug (2026-08-08, Durchführung s. TP21.1) sind durch — docs/hw-refresh-requirements.md, Memory project_mikrotik_commit_nautobot_gc
🔌 Scope-Änderung 2026-08-16 (User-Entscheid): die DC-USV ist aus diesem TP herausgelöst und heißt jetzt TP24. Sie war der letzte offene Rest hier, hat mit Switching/Routing sachlich nichts zu tun und trägt eigene Entscheidungen (Elektrik, Batterie, Standort). TP15 ist damit inhaltlich zu. Vorherige Header-Fassung (Stand 2026-08-05, überholt): „🟢 CRS326-Bring-up + Branch-Tausch DURCH (2026-07-23); Core-Tausch/L3-Umzug vorbereitet, Cutover-Config materialisiert (2026-08-05), Cutover = nächstes Wartungsfenster."
- ✅ BRING-UP BEIDER CRS326 + BRANCH-TAUSCH gegen sw2 — DURCH (2026-07-23, Claude via REST unter Governance-Ausnahme #2). Ablauf/As-built:
- Zugriffsweg (Henne-Ei gelöst): Erst-Reihenfolge war core zuerst (User-Korrektur — core hängt an sw1 und ist der L2-Pfad, über den branch überhaupt erreichbar wird; branch war isoliert). Zugriff auf die Werks-
192.168.88.1über temporäre ap1-Zweit-IP192.168.88.2/24+ srcnat-Masquerade192.168.88.0/24(beideTP15-temp, nach Bring-up wieder entfernt — Rückweg nötig, weil die Werks-Box keine Route zu VLAN10 hat). Config dann komplett per REST (/system/scriptPUT+run), kein Winbox-Paste. Winbox-MAC-Connect scheiterte reproduzierbar („macconnection sync timeout" über WLAN/quer durch den Fabric — braucht selben Draht). - Identitäten am Gerät verifiziert (nicht nur Doku):
core= sw-id 4W04-URHT, MAC04:F4:1C:B4:17:76, SerialHKA0AREXJFM, PWX9…;branch= sw-id RGZJ-UK0T, MAC04:F4:1C:B4:15:58, SerialHKA0AJJA52F, PWPHR…(ap2 hängt an branch ether24 — bridge-host bestätigt = definitiv branch). PWs in~/.secrets/credentials.env. - branch = produktiv, volle SOLL-Portbelegung (User-manuell erhoben, maßgeblich): ether1 Uplink-Trunk→sw1 #8 (native VLAN1 + tagged 10/20/30/40/50/90/99, kein 100), ether2+ether8 = NAS 2×tagged-VLAN20 (zwei unabhängige Links), ether3 Drucker/VLAN10, ether4 Dock/VLAN10, ether5+ether6 Sonos/VLAN40, ether7 Mac mini/VLAN20, ether24 ap2-Trunk; ether9–23+sfp disabled. vlan-filtering=yes. Mgmt
10.40.99.13(VLAN99) erreichbar über sw1 #8 (+ VLAN1-Temp.41.213während Bring-up). Post-Swap-Abnahme grün: NAS.20.10, Mac mini.20.167(VLAN20), Dock.10.194(VLAN10), Sonos.40.191/.40.192(VLAN40). - core = grundkonfiguriert, NICHT produktiv (bleibt an sw1 #12): identity/vlan-filtering/volle VLAN-Tabelle, ether1 Uplink, ether2 Temp-Downlink (war Config-Pfad für branch), Mgmt
10.40.99.11(VLAN99, erreichbar erst wenn sw1 #12 99T trägt) + VLAN1-Temp.41.211. Port-Layout ab ether3 tentativ (final in Core-Swap-Session). - Beide in MikroMCP
routers.yaml(crs326-core/-branch, ENVROUTER_CRS326_*in~/.claude.json— live erst nach MCP-Neustart, diese Session lief alles per REST-curl). Nautobot modelliert + GraphQL-verifiziert (nautobot/ingest-crs326-ports.py): branch Active + volle Ports + primary_ip4.99.13; core Planned + tentatives Layout; sw1 verifizierte 16-Port-Belegung (löst „UNVERIFIZIERT"); sw2 → Decommissioning. - 🐞 Gotchas festgehalten: (1) Kabel ether3↔ether5 waren beim Umstecken vertauscht → ein AZ-Sonos landete als Access-VLAN10 in
10.40.10.190und blutete via SonosNet nach VLAN40 (= Dual-Homing-Muster,project_dual_homing_slowness_incident) → Kabeltausch gefixt, beide AZ-Sonos jetzt sauber VLAN40 (.191/.192bound). (2) RouterOS-Script-policy-Feld per REST wählerisch → weglassen (admin-Default = volle Policy). (3) Disable-Regex mit^…$-Ankern griff nicht →[find name!="ether1" and …]nutzen. (4) REST-PUT-Antwort mit mehrzeiligemsourceist kein sauberes JSON → ID separat via?.proplist=.idholen. (5) Claude-Code-Auto-Mode-Classifier blockt Device-Config-Writes per Bash (Reads ok) →autoMode.allow-Regel in.claude/settings.local.jsonnötig (kann Claude sich nicht selbst setzen).
- Zugriffsweg (Henne-Ei gelöst): Erst-Reihenfolge war core zuerst (User-Korrektur — core hängt an sw1 und ist der L2-Pfad, über den branch überhaupt erreichbar wird; branch war isoliert). Zugriff auf die Werks-
- ✅ ERLEDIGT 2026-08-08 (Durchführung + Recovery s. TP21.1).
🔜 Als Nächstes (eigene Session, Übergabe): Core-Tausch = L3-Umzug(Routing/DHCP/DNS/CF-Mesh von ap1 → crs326-core) — Vollausfall-Fenster, s.docs/tp15-core-swap-session-handoff-prompt.md. Danach WLAN-Neuprovisionierung (TP3, CAPsMAN-Abbau).Finaler Mgmt-Renumber dann: branch⚠️ Anders gekommen (Ist seit 2026-08-08, live bestätigt): core.99.13→.99.12, core bleibt.99.11..99.1· branch.99.2· ap1.99.11· ap2.99.12. - ✅ Core-Swap VORBEREITET (2026-07-23, reine Prep-Session, kein Netz-Eingriff): ap1s Live-L3-Config vollständig gelesen (MikroMCP) und als staged Config materialisiert →
routeros/tp15-core-l3-staged.rsc(alles Betriebsumlenkendedisabled=yes, im Cutover in einem Rutschenable; ~50 Reservierungen + WG-Privkey bewusst erst im Fenster maschinell von ap1 geholt statt abgetippt). Runbook/Rollback/Verifikation im Plan. 3 Fenster-Start-Entscheide festgelegt: (1) WG-Hub (TP10 FM/DW-VPN) migriert MIT — war im Handoff-Prompt übersehen, hängt an ap1s Public-Edge und kann dort nicht bleiben; (2) Governance = frische Direkt-Ausnahme #3 (REST/MikroMCP), danach intended→Nautobot; (3) Rettungspfad = iPhone-Hotspot. - ✅ Nautobot-Modell + Golden-Config-Template für L3-Cutover vervollständigt (2026-08-05):
crs326-corejetzt Rolle Router, alle VLAN-SVIs (vlan10/20/30/40/50/90/99/100) + Gateway-IPs (.1) modelliert;nautobot/mikrotik_routeros.j2(Giteabf-golden-config) erzeugt fürcrs326-coredie vollständige staged L3-Konfig (Interface-Lists, GW-IPs, WAN-DHCP, DHCP-Server/Pools, DNS, NAT, Firewall, WG-Hub) und für alle anderen MikroTik-Geräte nur die Identität. Git-Sync + Generate Intended Config erfolgreich getestet; intended config fürcrs326-coreliegt in Nautobot vor.- ✅ ap1-Cutover-Daten exportiert + in Cutover-Config eingebaut (2026-08-05): 54 statische DHCP-Leases aus ap1 (
dhcp-v10/v20/v30/v40) nachrouteros/ap1-leases-to-core.rscüberführt; WG-Hub-Privkey von ap1 geholt und in die lokale Cutover-Configrouteros/tp15-core-cutover-intended.rsceingesetzt (der WG-Privkey landet NICHT im Git-Template — Secret). - 🐞 Prep-Gotchas: (a) MikroMCP kann core noch nicht schreiben —
ROUTER_CRS326_CORE_*im MCP-Prozess nicht geladen (jeder Zugriff „Missing environment variable") → vor dem Fenster MCP neu starten oder REST-curl gegenhttp://10.40.41.211/rest. (b) Mgmt-.99.11tot (sw1 #12 trägt kein 99T), nur VLAN1-Temp.41.211erreichbar. (c) WG-Hub: Privkey von ap1 mitnehmen (sonst FM/DW-Reconfig nötig). (d) core-vlan99 wird GW.1; Bring-up-.11dadurch redundant (Fenster-Reconcile). (e) VLAN1 raus: Hybrid-VLAN1-Drops sw1 GE3/7/10 beim Umstecken einem echten VLAN zuordnen oder stilllegen. - ✅ WG-Endpoint-Frage geklärt (2026-07-23): Spokes adressieren den Hub über
bf4.emsenhuber.net:51821= CF-A-Record (proxied=false, TTL 120, aktuell90.146.35.38). Kein Updater auf ap1 → nichts zu migrieren;bf4folgt der IP manuell (offener TP10-Follow-up). Zieht core am WAN eine neue IP (Lease sticky, eher nicht), viaCF_API_TOKENnachziehen:bf4-Record + Access-Policybf4-home-ip(90.146.35.38/32). Chance: core ist nichtdevice-mode=home→ scheduler/fetch gehen →bf4-DDNS-Auto-Updater dort bauen (schließt TP10-Follow-up). - 📋 Session-Handover für die Cutover-Session:
docs/tp15-core-swap-session-handover.md(Einstieg + Pre-Window-Checkliste + Kurz-Runbook; Original-Auftrag bleibtdocs/tp15-core-swap-session-handoff-prompt.md).
- ✅ ap1-Cutover-Daten exportiert + in Cutover-Config eingebaut (2026-08-05): 54 statische DHCP-Leases aus ap1 (
- 📦 2× CRS326-24G-2S+RM werden morgen (2026-07-17) geliefert, Produktivsetzung spätestens Montag 2026-07-20 (User-Entscheid 2026-07-16). Sequenzierung ggü. Nautobot geklärt: TP20+TP21 werden bis dahin fast-getrackt (TP18/Komodo als Blocker entfernt, s. TP20) — Ziel ist, dass Nautobot vor der CRS326-Produktivsetzung steht und die Switches direkt als Nautobot-verwaltete Geräte adoptiert werden, statt erst von Hand konfiguriert und später importiert. sw1/sw2-VLAN99-Umzug (TP19.1) läuft parallel dazu on-demand, unabhängig davon.
- 🧭 Grundsatzentscheid (2026-07-14, korrigiert 2026-07-15): reines MikroTik-Ecosystem — Routing + Switching + WLAN. Omada bekommt KEINE Rolle (weder Switching noch WLAN — der ursprüngliche „Omada=WLAN"-Satz war ein Fehlschluss beim Dokumentieren, User-Korrektur 2026-07-15: „WLAN war NIE von Omada die Rede"). Begründung Switching: Projektziel #1 CAKE nur RouterOS/OpenWrt/OPNsense (Omada-Gateway kann kein CAKE) → Switching = MikroTik CRS. WLAN bleibt auf hAP ax² (
/CAPsMAN— CAPsMAN am 2026-08-08 abgeschafft, Standalone aus der Golden Config; die Hardware-Aussage gilt), kein EAP-Kauf, Coverage-Fix bleibt Platzierungsfrage (TP3.3). Verworfene Vollvarianten (Omada-only, MikroTik-only) samt Begründung + Ansible/Nautobot-Recherche → Memory. Anlass der Korrektur: Omada-Controller↔sw2-Link beim VLAN20-Umzug (TP14.1) zerbrochen, versehentlicher Werks-Reset bei Rettungsversuch, fehlerhafter Wiederherstellungsversuch → sw2 wird standalone neu eingerichtet, s. TP2.1. - 🛒 Switches: 2× CRS326-24G-2S+RM bestellt (2026-07-14 — CSS326-Fehlbestellung storniert → CRS). 24×1G + 2×SFP+, lüfterlos, DC-input (USV-tauglich). Lösen ALLNET-Core (sw1) + Omada-ES208G (sw2, s. TP2.1 — Solo/Interim bis CRS-Tausch) + Cudy ab.
- ✅ CRS = RouterOS-fähig → in-model: MikroMCP-Write + Nautobot Golden Config (TP21) managen auch die Switches, nicht nur den Router → config-as-code deckt den ganzen Kabel-Fabric. (SwOS-Boot bliebe als Fallback möglich, aber nicht genutzt.)
- ⚠️ kein PoE (Sonoff/PoE-Verbraucher via Injektor, falls nötig).
- 📶 WLAN bleibt hAP ax² — kein Hardware-/Ecosystem-Wechsel; die Hardware-Aussage gilt unverändert.
⚠️ Die Betriebsart hat zweimal gewechselt, letzter Stand ist CAPsMAN: CAPsMAN abgeschafft
(2026-07-22/08-08, TP3-Rebuild → Standalone-APs) → wieder eingeführt am 2026-08-17 (TP28), Manager
ist
crs326-core, ap1/ap2 sind reine CAPs. Wer hier nur bis zum ersten Pfeil liest, baut auf einem überholten Stand auf. Coverage-Schwachstellen (P750W-Fall, Terrasse/Kanten) bleiben Platzierungs-/Roaming-Thema von TP3.3, nicht durch neue Hardware gelöst. - 🧭 Router-HW final (User-Entscheid 2026-07-22): kein RB5009. Kein Zukauf einer dedizierten Router-HW.
- 🔄 KORREKTUR (User-Entscheid 2026-07-22, später am selben Tag): der CRS326-Core WIRD der neue L3-Router. Die frühere Fassung dieser Zeile („Router bleibt dauerhaft ap1/ap2, L3/CAKE/Firewall bleiben auf ap1") ist damit überholt. Routing, DNS und DHCP wandern vollständig von ap1 auf
crs326-core; ap1/ap2 werden zu reinen Access Points. Auch der CF-Mesh-Endpoint terminiert dort (s. TP16.1, war schon vorher auf CRS326 retargetet — passt jetzt konsistent zusammen). Damit entfallen diedevice-mode=home-Einschränkungen des hAP (kein scheduler/fetch) für die Router-Rolle. Reihenfolge (User): erst Switches aufsetzen und in Betrieb nehmen, danach WLAN-Neuprovisionierung der APs. Betroffen/nachzuziehen: TP4 (Router-Rolle), TP5/TP6 (Firewall + CAKE landen auf dem CRS326), TP21 (Scope-Grenze). - 📍 CRS326 Live-Stand (2026-07-22, via MNDP von ap1): beide Geräte sind bereits am Netz und laufen — RouterOS 7.19.5, Werkszustand.
crs326-core= MAC04:F4:1C:B4:17:76(software-id4W04-URHT),crs326-branch= MAC04:F4:1C:B4:15:58(RGZJ-UK0T). ⚠️ Beide auf Werks-IP192.168.88.1im selben L2-Segment = IP-Konflikt → beim Bring-up nur eines nach dem anderen adressieren, Unterscheidung ausschließlich per MAC. Die frühere Notiz „Uplink-Port bislang ungenutzt/down" ist überholt. Standorte:crs326-core= „Technik UG" (virtueller Technikbereich im UG/Diele, KEIN Keller),crs326-branch= „Technik OG". - 🔌 PoE-Anschluss der APs (User-Vorgabe 2026-07-22): Verkabelung/Portbelegung bleibt sonst unverändert; ap1/ap2 sollen künftig aber am PoE-Port hängen. PoE selbst ist noch kein Thema, die Config soll es aber schon vorsehen.
- ✅ Port =
ether1. RouterOS nummeriert Interfaces ab 1 (ether1…ether5), nieether0— die Unix-Konventioneth0gilt hier nicht. Auf dem hAP ax² istether1der PoE-Port (live bestätigt:/interface/ethernet/poelistet ausschließlichether1). - ⚠️ Aber: passives PoE 18–28 V, NICHT 802.3af/at. Ein normaler 802.3af/at-Switch oder -Injektor speist den hAP ax² nicht. Es braucht einen passiven PoE-Injektor (MikroTik-Standard). Dazu passend: der CRS326 hat gar kein PoE (bereits dokumentiert) → Strom kommt ohnehin aus einem Inline-Injektor zwischen Switchport und AP, nicht aus dem Switch.
- ⚠️ Config-Konsequenz: ap1s Trunk liegt heute auf
ether2→ wandert bei der Neuprovisionierung aufether1. Undether1steht aktuell aufpoe-out=auto-on(der hAP kann über denselben Port auch Strom abgeben) — beim Umbau auf „ether1 = versorgter Uplink" musspoe-outauf diesem Portoffgesetzt werden, sonst speisen Injektor und AP gegeneinander.
- ✅ Port =
- 🔋 DC-USV → ausgelagert nach TP24 (2026-08-16). Inhalt unverändert gültig (MeanWell LRS-150-48 + DDR-120-48 + LiFePO4 20 Ah, ~€190, 48-V-Bus; die CRS326 haben passenden DC-Input) — steht ab jetzt dort, samt der offenen Entscheidungen (Mac mini/Inverter, Bus-Standort nach dem Core-Umzug, Batteriegröße, Shutdown-Signalisierung).
- ✅ Standort-/Ablösungs-Mapping final (User 2026-07-22) — sauberes 1:1:
Bereich heute wird abgelöst durch Technik UG (virtueller Bereich in der Diele, kein Keller) sw1 (ALLNET, 16 Ports) crs326-core (= neuer L3-Router) Technik OG sw2 (ES208G, 8 Ports) + ap2 + cudy2 crs326-branch Wohnzimmer Sideboard ap1 — (bleibt, wird reiner AP) Kapazität unkritisch: 16+8 belegte Ports heute gegen 2× 24 GbE + 2× SFP+ künftig. Vollständig in Nautobot gepflegt (alle 8 Devices haben einen Bereich). - 📻 cudy-Hardware (User 2026-07-22): beide sind Cudy WR3600E V1.0, Firmware
2.3.15-20250905-191956.cudy1= Technik UG, am Core#11, aktiv als Übergangs-WLAN (elektrosmog.c,10.40.10.246) — und Christophs aktueller WLAN-Pfad.cudy2= Technik OG, außer Betrieb (Nautobot-StatusDecommissioning), wird nicht reaktiviert. - ⚠️ Etappe 1 (Erstzugriff auf die CRS326) ist NICHT kritisch (User 2026-07-22): Werkszustand, Gerät steht griffbereit neben ihm → der IP-Konflikt auf
192.168.88.1wird physisch/seriell aufgelöst, kein Lockout-Szenario. - ✅ Portplan-Widerspruch AUFGELÖST (User 2026-07-22): am Core ist
#15 = ap1und#11 = cudy1. Damit gilt die TP4-Variante (gi16Arris/VLAN100 →gi15Trunk → ap1ether2);switch/cli/03-trunk-ap-ports.cli(gi1 = ap1 / gi2 = ap2) ist STALE — die Datei bezeichnet sich selbst als „provisorisch, 2026-06-09" und wurde vom Edge-Cutover am 2026-07-01 überholt. Nicht mehr als Quelle verwenden.- Zielport nach dem Tausch: ap1 wandert auf
crs326-corePort 4 (User-Vorgabe). Gleichzeitig wandert ap1s Uplink geräteseitig vonether2aufether1(PoE-Port, s.o.). - ⚠️ Nach wie vor NICHT vom Gerät gelesen: die restliche sw1-Belegung.
switch/state-backups/sw1-running-config-20260716-*.txtsind 214-Byte-Fehlschläge (Incorrect User Name!!, toterclaudecode-Login),switch/cli/running-PRE.txtist Pre-TP1.gi16(Arris) undgi8(Trunk → sw2) stehen in Nautobot daher explizit als „UNVERIFIZIERT" markiert.
- Zielport nach dem Tausch: ap1 wandert auf
- 🔴 Betriebliches Kernrisiko (Analyse 2026-07-22): der Core-Tausch ist KEIN Switch-Tausch, sondern ein Vollausfall.
crs326-coreersetzt sw1 und wird gleichzeitig L3-Router — und an sw1 hängt auf#15ap1, also Gateway, DHCP, DNS und der WAN-Trunk fürs gesamte Netz. Core-Tausch und L3-Umzug sind damit faktisch dasselbe Ereignis und brauchen ein geplantes Ausfallfenster. → Reihenfolge-Entscheid (User 2026-07-22):crs326-branchzuerst (gegen sw2, Technik OG),crs326-corein einer eigenen, späteren Session. - 🛟 Rettungspfade liegen günstig auf verschiedenen Switches: Christophs Notebook hängt per WLAN über cudy1 → Core
#11; der kabelgebundene Plan B (Dock/Monitor Arbeitszimmer) hängt am sw2/Branch (P4). Beim Branch-Tausch stirbt also der Kabelweg, das WLAN überlebt. (Beim Core-Tausch stirbt beides — s. Kernrisiko oben.) - Hinweis: die A/B/C/D-Switch-Varianten in
hw-refresh-requirements.mdsind durch die CRS326-Beschaffung überholt (Doc = Recherche-Archiv + USV/Energie-Referenz). - Abh.: TP14 ✅ (IP-Migration). Verzahnt: TP20 (Platform-DB), TP21 (Nautobot GC), TP2.1 (sw2-Standalone-Recovery).
TP16.1 · Gitea #57 — Private Access via native Cloudflare Mesh (WireGuard) auf crs326-core — docs/tp16.1-warp-mesh-native-crs326.md
- ✅ Kernergebnis: ICMP ist repariert. Privater Zugang unterwegs läuft über natives WireGuard auf
crs326-corestatt cloudflared-QUIC — 0 % Ping-Loss auf alle BF-VLANs, vorher 100 %. Genau das Symptom aus dem Incident 2026-07-16, das dieses TP ausgelöst hat. Öffentliche FQDNs unberührt auf dem 3-Tunnel-HA (TP16). Compliance 68/68. - ✅ §4.0 erledigt 2026-08-17: Mesh-Node angelegt.
bf-core-mesh=d1da7c8a-2736-4cbb-8af1-32db5393fb9c, Register-Token inmcp/cloudflare/.env(CF_MESH_REGISTER_TOKEN, gitignored). ➡️ Die seit 2026-07-17 offene Free-Plan-Frage ist beantwortet: der Free-ZT-Plan erlaubt Cloudflare Mesh — der LXC-Fallback ist vom Tisch. - 🔑 Der Weg dahin war ein Token-Problem, kein Plan-Problem (kostete 2 Anläufe). Der alte User-Token hatte zwei fehlende Permissions (§4.0 und §4.1 —
devices/settingswar schon lesend403). Ersetzt durch einen account-owned Token (9984078812bc…, ⏰ gültig bis 2027-01-09). Zwei Fallen, beide sehen aus wie „Token kaputt": (1) Account-Tokens verifizieren an/accounts/{id}/tokens/verify— am alten/user/tokens/verifymelden sie1000 "Invalid API Token", während alle echten Endpoints 200 liefern; (2) Dashboard-Fehler"Account tag in access policy must match tag in request uri"= eine Zone-Permission (DNS) steckt in der Policy-Zeile mit Account-Ressourcen → braucht eine eigene Zeile. Verifiziertes Soll-Set + Permission-IDs indocs/tp16.1-…md§4.0. Merke: Dashboard sagt „Edit", API sagt „Write". - ✅ §4.1–§4.4 durchgezogen 2026-08-17 (User-Freigabe „jetzt durchziehen"). Prereqs:
use_zt_virtual_ip=true, Device-Profil „Cloudflare Mesh" (4d3c0f57…), Split-Tunnel auf beiden Profilen korrigiert (100.64.0.0/10→/11+100.112.0.0/12). Gerät:cf-meshaufcrs326-core, Mesh-IP100.96.0.6/32, Peer162.159.193.2:2408, Handshake steht, Route100.96.0.0/12 → cf-meshaktiv; Backuppre-tp16.1-mesh-20260817.backupvorher (Auflage #4 ✅). CF meldet Node healthy. §4.4: Weg A hat funktioniert — der befürchtete vnet-Gotcha trat NICHT ein,10.40.0.0/16zeigt jetzt aufbf-core-meshstattbf-pve(Rollback = 1 PATCH zurück,bf-pveunangetastet). - ⚠️ Zwei Werkzeug-Fallen, real getroffen (gehören in jede künftige WG-Arbeit): (1) MikroMCPs
manage_wireguard_interfacekann grundsätzlich keinen privaten Schlüssel annehmen — RouterOS erzeugt ihn selbst; bei CF Mesh kommt er aber von CF → Key per SSH mit Interpolation aus der gitignoreten.envsetzen, nicht über das Tool. (2)manage_wireguard_peerschreibtendpoint: "IP:Port"komplett inendpoint-addressund lässtendpoint-port=0→ kein Handshake, sieht aus wie ein Firewall-Problem, ist ein Parameter-Bug. Nach jedem Peer-Addprint detailgegenlesen. Auchpersistent-keepalivefehlt dem Tool. - ✅ §4.5 ABNAHME BESTANDEN 2026-08-17 (MacBook am Hotspot, WARP connected): Ping 0 % Loss auf
10.40.10.1/10.40.20.105/10.40.99.12/10.40.20.10/10.40.99.1(47–63 ms) — vorher 100 %. TCP mit echtem Datenfluss (pve 8006 → 200, Nautobot → 302,ssh macmini→ ok). FQDN-Smoke gitea/hass/pve/nautobot/vw → 200/200/302/302/200 ⇒ cloudflared-Public-Teil unberührt. - ✅ Auflage Ausnahme #4 erfüllt: Ist-Stand als intended config zurück nach Nautobot → zuerst 65/68 (drei
extra-Drifts = die Mesh-Zeilen), Zeilen byte-genau aus dem Backup ins Jinja-Template, Push nachbf-golden-config, Repo-Sync → 68/68, keine Drifts. Privkey bleibt draußen (<<REDACTED>>-Maske wie beiwg-hub). ⚠️ Push-Gotcha: Nautobot schreibt Backups+intended in dasselbe Repo →git pull --rebasevor jedem Push, sonstrejected (fetch first). - ✅ Mgmt-ACL via GC ausgerollt 2026-08-17 (Nachlauf, alle 4 Geräte) —
72/72 compliant. Neue Compliance-Featureip-service(match_config=/ip service,config_ordered=false) → 17→18 Regeln, 68→72 Checks. Sollzustand einheitlich im Template:ssh/www/winbox/api=address=10.40.0.0/16,100.96.0.0/12,ftp/telnet/api-ssl=disabled=yes. Ablauf regelkonform: Backups auf allen Zielen →--job mgmt-acl --apply --no-deploy→ gestaffelter Deploy (ap2 zuerst, am Gerät gegengeprüft, dann ap1/branch/core) → Geräte-Gegenprobe → Compliance.- 🔎 Der Befund war das Gegenteil der Erwartung: ich hatte „branch/ap1/ap2 sperren den Mesh aus" befürchtet — tatsächlich hatten sie gar keine Address-Beschränkung (ssh/www/winbox/api/ftp/telnet komplett offen), und die dynamischen Einträge zeigten
REMOTE 100.96.0.1, waren also längst per Mesh erreichbar.winboxwar auf ALLEN vier unbeschränkt, auch am Core. Aus dem Erreichbarkeits-Fix wurde damit eine Härtung. - ⚠️ Scope-Erweiterung, bewusst und meldepflichtig:
ftp/telnet/api-sslwurden auf branch/ap1/ap2 abgeschaltet (Klartext bzw. ungenutzt; der Core hatte das bereits). Begründung: die Alternative wäre gewesen, „telnet aktiv" als Sollzustand in die SoT zu schreiben. Nichts hier nutzt telnet/ftp — der ALLNET-Telnet-Runner ist Archiv, das Gerät ausgebaut. - 📌 Schreibweise (Falle):
/ip service set ssh …mit dem Dienstnamen, NICHT[find name=ssh]— letzteres trifft auch den dynamischen Verbindungs-Eintrag und quittiert mitfailure: this is configured elsewhere.
- 🔎 Der Befund war das Gegenteil der Erwartung: ich hatte „branch/ap1/ap2 sperren den Mesh aus" befürchtet — tatsächlich hatten sie gar keine Address-Beschränkung (ssh/www/winbox/api/ftp/telnet komplett offen), und die dynamischen Einträge zeigten
- 🔴🔴 DIE FALLE DIESES TPs —
/ip servicesperrte das Router-Mgmt aus dem Mesh aus (Core, vor dem Rollout oben): Direkt nach dem WARP-Connect warcrs326-coremgmt-tot: MikroMCPConnection lost before handshake, SSHkex_exchange_identification: Connection reset, REST 502 — bei gleichzeitig verlustfreiem Ping auf dieselbe IP, und alle Hosts hinter dem Core normal. Ursache:/ip service ssh,www address=10.40.0.0/16, der Mesh-Client kommt aus100.96.0.0/12. ICMP kennt keine Service-ACL. Undnc -zmeldet „offen", weil der CF-Gateway-Proxy den TCP-Handshake terminiert — ein TCP-Connect ist über WARP KEIN Reachability-Beweis. Fix:address=10.40.0.0/16,100.96.0.0/12. Merkregel: wer per Mesh ans Netz kommt, ist noch lange nicht am Router. ⚠️ Fürcrs326-branch/ap1/ap2noch OFFEN — deren eigene/ip service-ACLs sind ungeprüft. Entscheidender Diagnose-Schritt war der Banner-Grab vom macmini (nc 10.40.99.1 22→SSH-2.0-ROSSSH): von innen gesund ⇒ Pfad/ACL, nicht Gerät. Fehlspuren, die man sich sparen kann: MTU (die großen Pings scheitern am WARP-Client-utunMTU 1380, nicht ancf-mesh) und SSH-Session-Erschöpfung. - ✅ Schalter „Allow all Cloudflare One traffic to reach enrolled devices" — recherchiert 2026-08-17, ENTSCHIEDEN: bleibt AUS. Laut CF-Settings-Referenz ist es ein globales Device-Client-Setting („Global device client settings"), alle Pläne, alle OS, Client-Mode „Traffic and DNS". Funktion: es lässt Traffic aus Mesh/WAN zu den eingebuchten Geräten hin — also Zugriff auf Device-IPs. Das ist die Client↔Client-Richtung und für unseren Fall (Gerät → Mesh-Node →
10.40.0.0/16) nicht nötig; der Mesh läuft bewiesenermaßen ohne. Kein API-Feld (in Spec,devices/settings-PATCH und Profil-GET gegengeprüft), und die CF-Docs nennen keinen Menüpfad. ⚠️ Die Docs widersprechen sich: die Mesh-Get-Started-Seite nennt es eine Profil-Einstellung, die Settings-Referenz eine globale. Nach User-Vorgabe („im Zweifel ohne Schalter") nicht gesetzt — nichts gebaut, nichts geklickt. Erst relevant, wenn ein Zugriff auf ein Endgerät (statt auf das Netz) gebraucht wird. - 📌 Bleibt gültig: die HA-Degradierung der öffentlichen Tunnel (TP16,
bf-pvefährt nur einen Connector) wird davon nicht geheilt — eigener offener Punkt. Und für TP5 vormerken: bei deny-by-default braucht der Mesh explizitforward accept 100.96.0.0/12 ↔ 10.40.0.0/16. - ✅ Gate erfüllt (2026-08-16): die Bedingung „gated bis TP21 den CRS326 abdeckt" ist eingelöst —
crs326-coreist seit 2026-08-08 der produktive L3-Router und seit 2026-08-13 in Nautobot adoptiert (68/68 compliant). Runbook §3 neu gemessen, §4.3 von Platzhalter auf echte Werte gezogen. - 🧭 Erwartung geraderücken (wichtig, weil leicht zu verwechseln): das Mesh ersetzt die CF-Tunnel NICHT. TP16.1 löst ausschließlich den privaten Zugang (unterwegs →
10.40.0.0/16per IP, inklusive ICMP) und tauscht dort den cloudflared-QUIC-Proxy gegen natives WireGuard auf dem Core. Die öffentlichen FQDNs bleiben auf dem 3-Tunnel-HA aus TP16. Beide Stränge laufen nebeneinander — die HA-Degradierung aus TP16 (2026-08-16) wird davon nicht geheilt und bleibt ein eigener offener Punkt. - 📌 Live-Befunde 2026-08-16 (read-only erhoben, kein Eingriff):
warp_connector=[], aber der GET antwortet (kein 403) → die Free-Plan-Frage entscheidet sich erst amPOST(§4.0).CF_API_TOKENistactive; ob er die separate Permission „Cloudflare One Connector: WARP" trägt, zeigt genau dieser POST — dort schlug es am 2026-07-17 mit10000fehl.use_zt_virtual_ip: false→ Unique-Device-IP muss weiterhin eingeschaltet werden. Gateway-Proxy TCP+UDP sind an.- Nur EIN Device-Profil (Default). Der „auf beiden Profilen"-Hinweis im Runbook meint also: Default jetzt, Mesh-Profil sobald es existiert — es gibt kein zweites, auf dem man etwas übersehen könnte.
- Split-Tunnel-Exclude enthält unverändert
100.64.0.0/10(verschluckt die Mesh-Overlay-Range) → der §4.1.4-Schritt bleibt nötig. - Die vnet-Route
10.40.0.0/16(5546dcb6…) zeigt weiter aufbf-pve— der Fallback steht. ⚠️ Aberbf-pvefährt derzeit nur einen Connector, der private Pfad hängt also an einem einzelnen cloudflared-Prozess. - ✅ Die letzte inhaltliche Unbekannte ist weg: „Rückweg-Routing TBD" hat sich erledigt, weil der Core L3-Gateway aller VLANs ist — es braucht keine Zusatzroute. Und
wg-hub(TP10) liegt auf demselben Gerät, ist also direktes Vorbild statt fernes Muster.
- ✅ GOVERNANCE-AUSNAHME #4 (User, 2026-08-16): die WG-Zeilen für den Mesh-Bring-up auf
crs326-coredürfen DIREKT gesetzt werden (MikroMCPplan_changesdryRun →apply_plan). Begründung — es ist kein Bequemlichkeits-, sondern ein struktureller Grund: TP22-Regel 1 schließt jede Sektion, die<<REDACTED>>enthält, generell vom GC-Push aus, und/interface wireguardist genau so eine Sektion. Ein privater Schlüssel ist über Golden Config also gar nicht deploybar — die frühere Zeile „CRS326-Zeilen laufen regulär über Nautobot GC" trägt nicht mehr. Auflage (wie Ausnahme #2): Ist-Stand danach als intended config zurück nach Nautobot; vorher/system backup(Regel 3). Scope-Grenze: nur der Mesh-Bring-up aufcrs326-core— nicht spätere WG-Änderungen, nicht andere Geräte. - 🔑 Damit die Ausnahme ein einmaliger Bootstrap bleibt — Secret-Handling-Design (Runbook §4.3): ein privater Schlüssel ist Geräte-Identität, keine Konfiguration (wie ein SSH-Hostkey). Regel: der private Teil entsteht am Gerät und verlässt es nie; nur der öffentliche geht in die SoT und wird in die Peer-Configs gerendert. RouterOS kann das nativ (
/interface wireguard adderzeugt den Privkey selbst). Compliance bleibt grün, weil dieConfigReplace-Maske aus TP22 Schritt 0 byte-identisch zu der im Template ist. ⚠️ Vorbehalt: bei CF Mesh erzeugt CF das Schlüsselpaar — dann fällt die On-Device-Erzeugung weg, das Prinzip („nie in Git, nie in der intended config") hält trotzdem. Stufe 2 (nautobot-secrets-providers+ Vault, Wert erst bei der Plan-Erzeugung einsetzen) lohnt bei 4 Geräten und einem Key nicht — eigener TP nach TP18/TP20.1. - 🧹 Sofort fälliger Modellierungs-Nachzug, unabhängig vom Mesh: die WG-Peers
fm/dwstehen mit hartkodiertenpublic-key="…"im Jinja-Template. Public Keys sind Daten, keine Templatezeilen — gehören nach Nautobot und von dort gerendert. - ⚠️ Für TP5 vormerken: sobald deny-by-default greift, braucht der Mesh-Verkehr explizit
forward accept 100.96.0.0/12 ↔ 10.40.0.0/16— heute passiert er nur, weil dieforward-Kette ohne Drop endet. - ⏭️ Was die Scharfschalt-Session macht:
POST warp_connector(Plan-Gate) → account-weite Prereqs (Unique Device IP, Split-Tunnel auf beiden Profilen) →wgcf-connector-Token → 4 WG-Zeilen auf dem Core → Route5546dcb6…umhängen (vnet-Gotcha, Weg A/B) → Ping-Abnahme. Trifft alle Live-WARP-Geräte mit einem kurzen Reconnect → Zeitpunkt user-gated. - ✅ Update (User-Entscheid 2026-07-22): Ziel-Device für den WG-Mesh-Node ist jetzt der CRS326 Core-Switch statt ap1 — konsistent mit dem TP15-Endstand (kein RB5009) — ⚠️ die damalige Klammer „Router bleibt ap1/ap2 rein für L3/WLAN" ist seit dem Core-Cutover 2026-08-08 überholt: L3 liegt auf
crs326-core, ap1/ap2 sind reine APs. Der Retarget auf den Core war damit im Ergebnis richtig, nur anders begründet als hier notiert und TP21s "ganzer Kabel-Fabric via RouterOS"-Modell (CRS326 ist ohnehin RouterOS-fähig und wird Nautobot-verwaltet). Reine Ziel-Doku-Änderung — das Scharfschalten bleibt weiterhin eine eigene, spätere Session und bleibt gated, bis TP21 den CRS326 als Device abdeckt. Keine neue Governance-Ausnahme: die bestehende ap1-Ausnahme (s. Ist-Stand-Zeile 31) gilt explizit nicht automatisch für den CRS326 — CRS326-Konfiguration soll regulär über Nautobot GC laufen, sobald TP21 so weit ist. Die CRS326 selbst sind aktuell noch Werkszustand (physisch bereits mit dem aktuellen Core verkabelt, aber die betreffende Uplink-Port bislang ungenutzt/down) — konkrete Management-IP/Interface-Zuordnung für den CRS326 als L3/WG-Endpoint ist noch nicht getroffen (TBD nach TP15-Bring-up). - Trennung: Public FQDNs bleiben auf cloudflared-3-Tunnel-HA (TP16); Private Access (unterwegs →
10.40.0.0/16per IP inkl. ICMP) wandert vom cloudflared-QUIC-Proxy auf einen nativen WireGuard-Mesh-Node auf dem CRS326 Core-Switch. - Warum CRS326-nativ: Cloudflare Mesh spricht WireGuard, RouterOS kann natives WireGuard (TP10-Hub auf ap1 ist einer, Muster überträgt sich) → Mesh-Node = WG-Peer zu CF-PoP, kein Container/TUN/LXC/neue HW. Verlagert die Rolle vom Router (ap1, der weiterhin Public-Edge + WLAN-Anker bleibt) auf den Core-Switch, der als zentraler Kabel-Fabric-Knoten ohnehin alle VLANs sieht. RouterOS-Container-Weg bleibt tot (kein
/dev/net/tun-Passthrough auf JEDER Router/Switch-HW) — daher weiterhin natives WireGuard, kein Container-Ansatz. - Verworfen: WG-Roadwarrior (User will keine Extra-App/Profil je Gerät), alle Helper-Host-ZT-Anbieter (SPOF-Verletzung).
- Warum heute nur Konzept: TCP-Pfad funktioniert (nur ICMP-Komfort fehlt), und die CF-Prerequisites sind account-weit (Unique-Device-IP, Split-Tunnel-Exclude, Device-Profile) → treffen Live-WARP-Geräte (1× kurzer Reconnect) → nicht unter Zeitdruck. Zusätzlich jetzt gated durch den Retarget: CRS326-Bring-up (Management-IP, VLAN-Filtering) muss erst stehen.
- Nächste Session (nach CRS326-Bring-up): Plan-Probe
POST warp_connector(Free-Plan-Gate; sonst LXC-Fallback) → account-weite Prereqs →wgcf-connector-Token→WG-Config → 4 WG-Zeilen auf dem CRS326 → Subnetz-Route + vnet-Route5546dcb6…von bf-pve umhängen (Rollback trivial) → Verifikation (Ping verlustfrei). Team-Domainemsenhuber.cloudflareaccess.com. Governance „Config nur via Nautobot" → CRS326-Zeilen regulär via TP21/GC, sobald das Device dort adoptiert ist. - ✅ Recherche-Härtung 2026-07-17 (Primärquellen animmouse + offizielle CF-Docs + OpenAPI-Spec, alles verifiziert, gilt unabhängig vom Zielgerät): (1) Produkt heißt seit 2026-04-14 offiziell Cloudflare Mesh (API-Pfade bleiben
warp_connector, im Spec bestätigt inkl. Token- und sogar HA-Endpoints); (2) ICMP-Proxy ist bereits AN (User-Korrektur: fm-Ping10.101.0.0/24beweist es — kein To-Do; mein „fehlt" war ein Fehlschluss aus dem API-Spec, das Flag ist Dashboard-only); (3) Split-Tunnel-Exclude auf beiden Device-Profilen (Default + Mesh); (4) vnet-Gotcha beim Route-Umzug („virtual networks only for cloudflared") → Weg A PATCH, Weg B DELETE+POST dokumentiert; (5) v4-only-Entscheid (Mesh-IPv6-site-to-site laut Guide broken, NAT66-Gefrickel nicht nötig); (6) keepalive 1m statt 25s ok. Alles indocs/tp16.1-warp-mesh-native-crs326.md§2/§4 eingearbeitet (Config-Block dort als Platzhalter markiert, IP/Interface TBD). - Abh.: TP16 ✅ (Public-Teil), TP10 ✅ (WG-Grundmuster, jetzt als Vorbild statt Direktziel), TP15 (CRS326-Bring-up), TP21 (Nautobot-Adoption des CRS326, Voraussetzung fürs Scharfschalten). SSoT:
docs/tp16.1-warp-mesh-native-crs326.md,docs/cf-tunnel-mapping.md §14.
TP17 · Gitea #58 — Shelly-Übersiedelung VLAN1 → VLAN30 (IOT) + shelly-mcp — Geräte-PW (war TP17.2, seit 2026-08-24 TP30 Posten #3) — mcp/shelly/, Runbook docs/tp17-shelly-go-runbook.md
-
✅ Abschluss 2026-08-13 (User-Bestätigt): auch die zuletzt offenen saisonalen Shellys (s1/s2/s3/s12) sind inzwischen umgeklemmt — alle Shellys auf
dirtyvader-iot/VLAN30, kein VLAN1-Shelly-Rest mehr. Migration-Teil von TP17 damit vollständig abgeschlossen. -
✅ GO durchgezogen 2026-07-13 (16 Shellys VLAN1→VLAN30, 0 Fehler): Pilot s26 + Welle A (s4–s9) + Welle B (s10/11/13/15/17/19/20/21/25) → alle auf
dirtyvader-iot/10.40.30.<octet>verifiziert (SSID+IP+rssi). Mit den 6 Vorab-Migrierten (s14/16/18/22/23/24) = 22/26 auf VLAN30; VLAN1-Sweep.180-250= 0 Shellys. Restliche 4 saisonal ausgesteckte (s1/s2/s3/s12) inzwischen ebenfalls migriert (s.o.). -
🔧 Anker-Verfahren (User-Idee, statt sta1-Backup): je Gerät vor dem sta-Write die geräteeigene AP-Funktion aktiviert (
WiFi.SetConfig ap.enable— Firmware verlangt WPA2, kein offenes AP → PSK=IOT-PSK, live/kein Reboot) = Notanker, falls VLAN30-Join scheitert (Gerät bleibt überShelly*-<mac>-AP erreichbar, kein physischer Reset). Nach Verify alle 22 AP-Anker wiederdeanchort. Runner:mcp/shelly/migrate.py(migrate/deanchor/auth/table, Dry-Run default, stoppt bei erstem Fehler, reuseddiscover.py). -
✅ HA-Cross-Check nach Batch: einzige
unavailableShelly-Entities = s12 (saisonal aus) — alle 22 migrierten reconnecten via mDNS/zeroconf (TP7-Repeater vlan30↔vlan20-HA) auf neuer.30.x-IP, Entity-IDs unverändert (keyt per MAC). Inventarinventory/bf.csv.41→.30 nachgezogen (22 Zeilen, Section→IOT). -
⚠️ Coverage-Flag:
s4 kueche_mikrowelleverbindet mit rssi −93 (Metallgehäuse), hat aber verifiziert — grenzwertig, im Auge behalten. s7 Tiefkühl −85. Rest gut (−26…−81). -
✅ Eco-Mode-Policy (2026-07-13, PROVISORISCH): eco senkt CPU-Takt + WiFi-TX-Leistung → eco AN für RSSI ≥ −80 (Energie-Win, TX irrelevant), eco AUS für < −80 (Uplink-Headroom): s4/−91, s7/−88, s17/−81, s18/−79…−82, s19/−86 → 17× ON / 5× OFF, live via
Sys.SetConfig device.eco_mode(kein Reboot). s4 (Küchen-Sockel/Metall, −91, fix) bewusst eco-OFF = schwächster Link. ⏳ 2. Eval nötig nach TP3.3 (WLAN-Ausrichtung/Aufbau ändert RSSI → Grenzfälle neu bewerten; User 2026-07-13). -
✅ HA-Referenz http vs https geklärt (2026-07-13): HA speichert
configuration_urlfür alle 22 Shellys bereitshttp://10.40.30.x:80(Integration korrekt + neue IPs übernommen). Das „https" ist client-seitig (Mixed-Content-Upgrade, wenn HA selbst über https/Tunnel geöffnet) — kein HA-Fix möglich/nötig, Shelly-SSL bewusst NICHT (CPU/Energie, IoT-Netz). ⚠️ Rand-Fund: 1 HA-Shelly-Device zeigt auf10.95.10.206(Fremd-Subnetz, nicht BF) → separat prüfen. -
⏳ Rest (nicht mehr Migration, s. TP17.2/TP19): (1) einheitliches Geräte-PW → zurückgestellt als #TP17.2 (Kosmetik). (2) Nicht-Shelly-Mover + cudy-Teardown + VLAN1-Client-Retirement → läuft in TP19. (3) DNS/ip-plan Restfeinschliff (mit TP19).
-
Ziel: ~26 Shellys (aktuell untagged VLAN1
10.40.41.2xx, weil auf alt-WLAN cudy, s. TP3.1/project_vlan1_dhcp_incident) auf SSIDdirtyvader-iot(VLAN30,w2-iot, WPA2/WPA3-mixed, PSK74c9L283$669) umklemmen → DHCPdhcp-v30/pool-v30 (live). Kein netzseitiger Move möglich (anderes WLAN) → per-Gerät WiFi-Reconfig. -
User-Entscheide (2026-07-11): (1) volles
shelly-mcpbauen (reusable, nicht nur Skript); (2) Pilot 2–3, dann Rest; (3) DHCP-Reservierungen je MAC in VLAN30 (stabile IPs für HA/ioBroker/DNS). -
✅ Recon durch (
mcp/shelly/discover.py, read-only /shelly-Sweep): 16 live, alle Gen3/Gen4 (uniforme RPC-APIWiFi.SetConfig, auth=off — kein Gen1-Sonderfall). 10 „offline" = weihnachten_* (s1/s2/s3, saisonal ausgesteckt Juli) + s12/s14/s16/s18/s22/s23 (aus/DHCP-drift). ⚠️ Inventar-Fix: s6 (kueche_kuehlschrank,.213) MAC falsch erfasst (0c:72:74:36:90:9e) → reald0:cf:13:d8:18:fc. s24 hat gar keine MAC. -
Mechanismus je Gerät: Gen2+ RPC
WiFi.SetConfig {sta:{ssid,pass,enable}}→ Reboot → landet.30.x. ⚠️ Risiken: falsches PSK → AP-Mode (physischer Reset); Gerät kurz offline; HA/ioBroker-Refs brechen bis re-pointed; WPA3-mixed ggf. zickig auf alter FW; ap1 2,4-GHz-Masterwifi2running:false→ Coverage v.a. via ap2 prüfen. -
✅ Live-Abgleich 2026-07-11 (go-ready): (a)
shelly-mcp(server.py) fertig — discover/get/set_sta/verify/reservation_plan, PSK in.envgesetzt (noch nicht als MCP registriert, optional). (b) Alle VLAN30-DHCP-Reservierungen liegen (.30.2xx, Oktett erhalten, außerhalb Pool.100–.200); s6-Reservierung.30.213MAC gefixt (falsch0C:72…9E→ realD0:CF:13:D8:18:FC). (c) IOT-SSID live verifiziert: ap1w2-iotrunning:true, 8 Clients −26…−68 dBm (ap1-wifi2-„running:false" ist kosmetisch). (d) Migration bereits ~5/26 durch: s14/16/18/22/23 seit ~2,5 d stabil auf reservierten.30.221/.223/.225/.202/.203(+.30.204unbekannt, evtl. s24) → Pilot faktisch bestanden. -
✅ HA-Cross-Check 2026-07-11 (alle IPv4-Geräte in HA): Shellys deckungsgleich;
.30.204= Shelly „Bad/Spiegelschrank" (Plus RGBW PM,14:33:5c:d8:2d:7c) = vmtl. s24 → 6 statt 5 schon migriert. Netzweite Aufstellung + VLAN1-Leerstand-Analyse im Runbook: nach TP17 + pve-Host→VLAN20 + Christophs Endgeräte→VLAN10 ist VLAN1 endgeräte-frei; es bleiben nur Switch-/AP-Mgmt (sw1/sw2/ap2 → VLAN99-Cutover, eigener Schritt) + 1 unidentifiziertes Gerät.41.246(morgen klären). Nicht-Shelly-VLAN30-Mover (User-bestätigt): ✅ SwitchBot floor-lamp.41.184+ ✅ Twinkly-Girlande.30.228(beide 2026-07-16 übersiedelt, s. TP19) + Creality Ender (fehlt noch, off). Withings schon übersiedelt; Tasmota existiert nicht mehr (kein aktives Gerät → stale HA-Eintrag). EOS-Smartwatches/eBook-Reader später + von Christoph selbst (eBook eher VLAN50). -
Scope-Erweiterung (User 2026-07-11): je Gerät 3 Änderungen — WLAN→
dirtyvader-iot+ IP (.41.2xx→.30.2xx) + einheitliches Geräte-Passwort (Shelly.SetAuth, Useradmin, realm-individueller ha1 → Toolset_authinserver.pynachrüsten). PW entschieden: eigenes Shelly-Admin-PW (getrennt vom WLAN-PSK) →SHELLY_DEVICE_PWin.env(Christoph liefert Wert). HA-Entities unverändert (keyt per MAC). HA-Entities bleiben unverändert (HA keyt per MAC). Projektion TP17.1 (experimentell, nachrangig): Gen4 (~11 St.) auf Thread/Matter flashen (Firmware-Verfügbarkeit + Thread-Border-Router offen) — Konflikt mit „Entities unverändert" (Matter = neue Entities) → erst WiFi-Migration stabilisieren. -
✅ Reservierungs-/Pool-Konvention (User 2026-07-11): alle Shellys bekommen statische IP (
10.40.30.<octet>, gw/dns.30.1) + in-pool DHCP-Reservierung als Backup.pool-v30auf.100-.250erweitert (Reservierungen jetzt in-pool);set_staaufstatic=trueumgestellt; s24-Inventar +.30.204-Reservierung angelegt. Vollständiger HA-MAC-Scan: 2 verpasste Media-Geräte Apple TV 4K + Philips TV (aus, → VLAN40) — vor cudy-Abschuss VLAN verifizieren; Apple TV = vmtl. Thread-Border-Router (TP17.1)..41.246/.247 = cudy1/cudy2(Teardown-Ziele). Tasmota bestätigt tot. -
Offene Schritte (morgen, „nur noch go", Runbook
docs/tp17-shelly-go-runbook.md): die 16 verbliebenen VLAN1-Shellys (s4–s11, s13, s15, s17, s19–s21, s25, s26 auf10.40.41.2xx) perWiFi.SetConfig→dirtyvader-iotumklemmen (Batch, je Gerät.30.xverifizieren) → Geräte-PW setzen → HA/ioBroker-Re-Point → SwitchBot/Tasmota/3. Nicht-Shelly → saisonale s1/s2/s3/s12 beim nächsten Einstecken → cudy-Alt-WLAN abbauen → DNS/Inventar/ip-plannachziehen. -
Abh.: SSID/VLAN30 (TP3/TP4 ✅), DHCP-v30 ✅. Verwandt:
project_vlan1_dhcp_incident(cudy-Rest-Leak), TP5 (IOT-Firewall danach). Memoryproject_shelly_migration_tp17. -
➡️ Nachtrag 2026-08-23: die Projektion „TP17.1 — Gen4 auf Thread/Matter" ist keine Projektion mehr. Christoph hat sie aktiviert; sie steht als offenes TP17.1 in
teilprojekte.md, die Umsetzung liegt im HA-Projekt (~/dev/ha-xstate/docs/shelly-gen4-thread-migration.md). Der damals notierte Vorbehalt „Firmware-Verfügbarkeit + Thread-Border-Router offen" hat sich halb aufgelöst: der Border Router läuft (~30 Matter-Knoten), die Firmware gibt es von Shelly aber bis heute nicht — offiziell ist Gen4 nur Matter over WiFi, Thread nur über Dritt-Firmware. Auch der zweite Vorbehalt gilt unverändert: Matter = neue Entities, der Konflikt mit „HA-Entities unverändert" ist real und in der Übergabe ausgeführt. -
📊 Bestandszahl, live 2026-08-23: 22 der 26 Shellys erreichbar — 12 Gen4, 8 Gen3, 2 Gen2. Die „~11 Gen4" aus der Schätzung von 2026-07-11 waren also nah dran.
-
🔑 Nachtrag 2026-08-23 — der IOT-PSK steht in der „Ziel"-Zeile oben im KLARTEXT, und das bleibt vorerst so (User-Entscheid). Der Wert ist am selben Tag gegen den Manager geprüft worden und ist noch der live konfigurierte. Bewusst nicht redigiert und keine History-Rewrite:
- Redigieren allein hilft nicht — die Zeile liegt seit
e76289c(2026-07-11) in der Historie. - Ein
git filter-repowäre hier Aufwand ohne Gegenwert: eine getrackte Fundstelle, drei Commits, Remote nurgitea.emsenhuber.net(kein GitHub), ein lokaler Klon — der Wert hat die eigene Infrastruktur nie verlassen. - Der wirksame Schritt ist die Rotation, und die kostet heute ~26 Geräte. Sie ist deshalb
bewusst hinter TP17.1 eingereiht (Gen4 → Thread), s. Follow-ups in
teilprojekte.md. ⚠️ Wer diesen Abschnitt liest, behandelt den Wert als aktives Geheimnis — nicht zitieren, nicht in Transkripte, nicht in Tickets. Zum Abgleich reicht ein Fingerprint (Länge + Stichproben), genau so ist er am 08-23 verifiziert worden.
- Redigieren allein hilft nicht — die Zeile liegt seit
TP19 · Gitea #59 — cudy-Teardown + VLAN1-Client-Retirement — docs/tp19-vlan1-cudy-teardown-runbook.md
- ✅ Abschluss-Sweep 2026-08-18, alles live gegengeprueft (reine Reads):
- VLAN1 ist leer:
/ip arpaufbridge= 0 Eintraege, 0 reachable. Nicht Restverkehr, sondern gar nichts. Der Dual-DHCP-Race ausproject_vlan1_dhcp_incidenthat damit endgueltig keine Quelle mehr. - Prometheus: kein einziges
10.40.41.x-Ziel mehr. Aktiv sindlocalhost:9090, n8n (.20.167:5678), grafana (.20.109:3000); die uebrigen acht Jobs sind auskommentiert. Der in der alten Restliste genannte Punkt ist damit verifiziert erledigt, nicht nur behauptet. - Interim-Kruecken sind weg:
/interface bridge portauf ap2 hat keinen Port mit eingeschraenktenframe-typesmehr — die TP3.1-Haertungadmit-only-vlan-taggedist beim Rebuild verschwunden. Nichts abzuraeumen.st-mainist seit TP3.3 fester Templatebestandteil. - DNS-Statics zeigen ausschliesslich auf
.99.x/.20.x, kein.41.x. - cudy1:
core ether11ohne Link seit 2026-08-08 19:33, in Nautobot Offline. cudy2 tot.
- VLAN1 ist leer:
- 🔜 Was NICHT mehr TP19 ist (bewusst dorthin verschoben, wo es hingehoert, statt den TP offen zu halten):
- Der physische Ausbau von cudy1 — Hands-on-Aufgabe, blockiert nichts, kein Netzeffekt.
- Die 4 toten CF-Tunnel (
coolify,openclaw…) — das sind Karteileichen in der Cloudflare-Config, kein Netzthema → TP16. - HA-Portainer
setup_retry(docker system dfauf ep14 braucht 33–120 s, struktureller Plattformnachteil) → Monitoring-Thema, TP11. Aussichtsreichster Weg bleibt ein eigener Portainer-Benutzer ohne Zugriff auf ep14.
- 📌 Nebenbefund beim Abschluss, sofort behoben: der Standort hatte keine funktionierende Zeitquelle.
ap1/ap2 zeigten per NTP auf
10.40.99.1, wo kein Server lief (status=waiting), branch hatte gar keinen eingetragen. ap2 war dadurch 17 Stunden versetzt — aufgefallen, weil ein Logeintrag von 04:57 als2026-08-17 12:19gestempelt wurde. Der Core ist jetzt NTP-Server (routeros/tp19-ntp-core-als-zeitquelle.rsc, inkl. der noetigeninput-Regel — ohne die waere der Server seit Etappe 4 eingeschaltet und trotzdem unerreichbar gewesen), branch ist Client (routeros/tp19-ntp-branch-client.rsc).- 🔎 Die Wurzel lag eine Ebene tiefer: auch der Core hatte keinen NTP-Client
(
enabled: no, keine Server) beiuse-local-clock: no. Ein Server ohne eigene Synchronisation liefert Stratum 16, das jeder Client verwirft — die Anfragen kamen also an (die Firewall-Regel zaehlte) und wurden trotzdem nicht brauchbar beantwortet. Der Standort hatte damit an keiner Stelle eine funktionierende Zeitsynchronisation; dass drei von vier Uhren stimmten, war Restglueck vom letzten manuellen Stellen. Behoben mitrouteros/tp19-ntp-core-client.rsc(time.cloudflare.com,at.pool.ntp.org) → Coresynchronized. - 🔴 Und der letzte Schritt war der unauffaelligste: der Server hielt Stratum 16 fest. Er war
eingeschaltet worden, waehrend sein eigener Client noch unsynchronisiert war — RouterOS
bewertet das nicht von selbst neu. Die Anfragen kamen an (die Firewall-Regel zaehlte mit),
wurden aber unbrauchbar beantwortet, und alle drei Clients blieben auf
waiting. Einenabled=no/enabled=yesnach der Synchronisation hat es geloest. Der entscheidende Test dorthin: branch einmal aufat.pool.ntp.orgzeigen lassen — es synchronisierte in 20 Sekunden. Damit war bewiesen, dass der Client heil ist und der Server schweigt, statt weiter im Nebel zu stochern. ✅ Endstand: alle vier Geraetesynchronized. (ap2s Uhr musste einmalig von Hand gestellt werden — 17 h liegen ueber der NTP-Panic-Schwelle, so weit springt kein Client von selbst.) - ✅ Governance nachgezogen (2026-08-18): NTP steht jetzt im GC-Template (Core als Quelle
mit oeffentlichem Upstream, branch/APs als Clients auf
10.40.99.1), wird per DHCP-Option 42 (ntp-server=je Netz, Christophs Vorschlag) an alle Clients ausgeliefert — nicht nur an die MikroTik-Flotte — und ist mit der neuen ComplianceRulesystem-ntpdrift-ueberwacht. Das war exakt der blinde Fleck, den TP26 fuer/ip firewall filtergeschlossen hat.
- 🔎 Die Wurzel lag eine Ebene tiefer: auch der Core hatte keinen NTP-Client
(
- ✅ Live-Nachprüfung 2026-08-16 (MikroMCP + CF-API, reine Reads):
cudy1ist tot, nicht nur „offline gemeldet":core ether11steht aufrunning=false, letzter Link-Down 2026-08-08 19:33, seither kein Link. Die Formulierung „aktiver VLAN1-Leak" ist damit endgültig hinfällig — der Dual-DHCP-Race hat keine Quelle mehr. Offen bleibt nur der physische Ausbau + Inventar/Doku.crs326-corehat keine VLAN1-IP mehr:/ip/addresslistet nur noch die 7 SVIs + die WAN-DHCP-Adresse — die Bring-up-Altlast10.40.41.211ist weg. Damit fällt einer der 5 Compliance-Drifts aus TP22 raus, sobald wieder Backup → Intended → Compliance gelaufen ist (die Compliance vergleicht gegen das letzte Backup, nicht gegen das Gerät — s. TP22-Falle).- ✅
crs326-branch-Interim ERLEDIGT (2026-08-16):10.40.10.2+ SVIvlan10über einen GC-ConfigPlan entfernt (s. TP22). Mgmt läuft über.99.2;/interface bridge vlanblieb byte-identisch, es gibt also weder einen Traffic- noch einen Drift-Effekt. .41.133identifiziert (war TP19 B1.2 „unidentifiziertes VLAN1-Gerät"): es ist das coolify-Origin aus dem gleichnamigen, seit Monaten toten CF-Tunnel. Ebenso.41.147/.148/.139aus dem totenopenclaw-Tunnel. Keine aktiven Geräte — Karteileichen in der Cloudflare-Config, nicht im Netz. Aufräumen = die 4 toten Tunnel löschen (user-gated, s. TP16-Nebenbefund).
- ✅ VLAN1-Adressen abgeräumt (2026-08-15) — der Weg dorthin —
docs/vlan1-rueckbau-howto-manuelle-schritte.md:- pve
10.40.41.100weg (/etc/network/interfaces:vmbr0voninet staticaufinet manual, Adresszeile raus; angewendet perip addr delohneifreload -a, damit die Bridge nicht durchgetreten wird). Nachher nur nochvmbr0.20, keine41.0/24-Route, alle 9 Gäste weiterrunning, Storage aktiv. Backup/root/interfaces.bak-tp19-20260815-183045. - Core
10.40.41.211weg über Nautobot GC (routeros/tp19-core-vlan1-address-remove.rsc). Mgmt.99.1+10.40.10.1intakt. Compliance damals 17/17 grün — der TP22-Backlog-Punkt „crs326-core 10.40.41.211" entfällt. (Zahl inzwischen überholt: nach TP16.1 sind es 72/72 Checks.) - HA zeigt auf
10.40.20.100(User), ioBroker korrigiert (User). - Prometheus bereinigt. Der pauschale
41→20-Ersatz war eine Falle: nurgrafana(.20.109) undn8n(.20.167:5678) liefern echte Metriken.giteahat/metricsgar nicht aktiviert,vaultwardengibt 404,portainer /api/statusliefert JSON statt Prometheus-Format,node/alertmanager/qdrantsind exited,piholeist abgewählt → 8 Jobs +alerting:-Block auskommentiert, 3 aktive Ziele, alleup. - 🔴 NAS-Falle:
prometheus.ymlgehört65534:65534, das Verzeichnisadm.christoph→cat > dateischeitert still („Permission denied"), während eincpdaneben klappt. Schreiben persudo tee+md5sum-Gegenprobe, nie der Shell-Erfolgsmeldung trauen.
- pve
- ⏳ OFFEN: HA-Portainer-Integration bleibt auf
setup_retry—docker system dfauf nas-bf ist zu langsam. Aus dem HA-Debug-Log:PortainerTimeoutError … GET /api/endpoints/14/docker/system/df→ConfigEntryNotReady. Die Integration ruftsystem dffür jede Umgebung bei jedem Update auf.- Container-Manager-Neustart am 2026-08-15 durchgeführt (
/usr/syno/bin/synopkg stop|start ContainerManager— Binary nicht im sudo-PATH; DSM meldet den Status danach weiterhin falsch alsstop). Alle 14 Container aus der Baseline zurück, zusätzlich kamhms-mqtthoch (Restart-Policyalways, lief vorher nicht). - ✅
hms-mqttstillgelegt (2026-08-16, User: „wird bald platt gemacht"). Es war bereits beendet; entscheidend war die Restart-Policyalways→no(docker update --restart=no), sonst wäre es beim nächsten Daemon-Neustart wiedergekommen. Ein bloßesdocker stophätte hier nicht gehalten. - ✅ Der Hänger ist damit weg:
system dfbeendet sich wieder (vorher rc=124 nach Ausgabe der Tabelle). ❌ Aber es bleibt viel zu langsam und schwankt: 33 s → 92 s → 3× >120 s. - 🔑 Wo die Zeit hingeht (gemessen):
images -q84 ms ·ps -aq95 ms ·volume ls -q65 ms ·system df33–92+ s. Also vollständig in der Größenberechnung (du-artiger Durchlauf der overlay2-/Volume-Verzeichnisse auf NAS-Platten) — ein struktureller Plattformnachteil, kein Defekt. Die Mengen sind harmlos (25 Images/13 GB, 10 Volumes/79 MB). - Aussichtsreichster Weg: eigener Portainer-Benutzer für HA ohne Zugriff auf ep14 → die Integration sieht die langsame Umgebung gar nicht. User-gated (Benutzer + Token anlegen). Alternativen: nichts tun (stört nichts) · Images aufräumen (6,98 GB reclaimable, Erfolg offen) · ep14 aus Portainer nehmen (schlechter Tausch).
- ⚠️ Zwei widerlegte Zwischenthesen, nicht wieder aufgreifen: die tote Umgebung
odroid-m1war es nicht (entfernt, Symptom blieb, alle übrigen Endpoints ≤0,16 s); und es ist kein Größenproblem der Images.
- Container-Manager-Neustart am 2026-08-15 durchgeführt (
- ✅ Restliste aus dem TP5-Log-Lauf — ABGEARBEITET (Abnahme 2026-08-16:
out:bridge= 0 über 10 min, Rate von ~166 auf ~34 Zeilen/min gefallen; im 43k-Zeilen-Log vom 08-17 kommtout:bridgenicht mehr vor). Wert dieses Eintrags = die Diagnosemethode, nicht der Stand. Der Log-Lauf hatte gezeigt, dass 76 % allen Inter-VLAN-Verkehrs aus VLAN20 nach VLAN1 (out:bridge) ging, obwohl dort nichts mehr antwortete (alle Ziele im ARPfailed/incomplete). Verursacher waren Konfigurationen, die nie nachgezogen wurden:prometheus(10.40.20.151, NAS) scrapet 10 tote Ziele:10.40.41.109:3000·.126:9443·.127:80·.147:5678·.149:3000·.152:3001·.153:9093·.154:9100·.159:6333·.23:80.10.40.20.105zieht auf10.40.41.100:8006= pve unter seiner alten VLAN1-Adresse (real10.40.20.100).10.40.20.107auf10.40.41.10:8080(NAS alt).- 📌 Umzugsregel: das letzte Oktett bleibt gleich, nur
41→20— belegt für grafana (.109), vaultwarden (.127), Portainer (.126). Für.23/.147/.149/.152/.153/.154/.159existiert kein laufendes VLAN20-Gegenstück (anderswo oder tot;alertmanagerist seit TP14.1 als kaputt notiert) → diese Ziele gehören geprüft und dann aus Prometheus entfernt, nicht umgeschrieben.
- ⚠️ Kein Firewall-/Portproblem (2026-08-14 geprüft, nachdem beim Umstellen ein Timeout auftrat):
pveproxylauscht auf*:8006,pve-firewallist disabled, keine iptables-Regel, kein/etc/default/pveproxy.https://10.40.20.100:8006antwortet aus VLAN10 und VLAN20 mit HTTP 200 in ~0,06 s. Wer hier einen Timeout sieht, sucht an der falschen Stelle — undtimeoutgibt es auf macOS nicht, eintimeout bash -c '… /dev/tcp/…'-Test meldet deshalb falsch-negativ. - ⚠️ Eskaliert 2026-07-15 (historisch — durch den WLAN-Rebuild 2026-08-08 gegenstandslos): der unter TP3.1 dokumentierte VLAN1-Leak trat damals auch auf ap1/
dirtyvader-mainauf — die ap-seitige Interim-Härtung (TP3.1) milderte das Symptom, die endgültige Lösung ist hier, TP19: VLAN1 physisch weg = kein Leck mehr möglich. - 🟢 cudy-Stand (User 2026-07-16): cudy1 (
.41.246) auf10.40.10.246umgehängt — bewusst kein Abbau-Ziel mehr, dient als Standalone-WLAN-Sender während der Umstellungsphase (nicht Teil des Teardowns, extern vom User selbst umkonfiguriert). cudy2 (.41.247) wird nicht mehr reaktiviert — faktisch tot, ARP-Sweep bestätigt keine Präsenz mehr auf VLAN1. B2.2 („cudy1/cudy2 stromlos/Reset/ausbauen") ist damit erledigt/gegenstandslos (cudy2 aus, cudy1 schon migriert statt abgebaut). - 🟢 Live-Sweep 2026-07-16 (ap1, vor geplantem Teardown): VLAN1 ist bereits viel weiter zurückgebaut als dokumentiert:
defconf/pool-v1-DHCP-Server ist bereitsdisabled=yes(Export bestätigt) — B2.4 („defconf zurückziehen") ist de facto schon erledigt, Ursprung/Zeitpunkt dieser Änderung nicht aus dieser Session bekannt (nicht in dieser Doku protokolliert).- ARP auf
bridge(VLAN1): nur noch 2 „reachable"-Hosts —sw1(.41.11, by design, bleibt bis MGMT-VLAN99) undpve-Interim-Fallback (.41.100) (B1.5-Aufräumziel, noch offen — Host-seitige Änderung auf pve, nicht Router). Alle anderen ~20 ARP-Einträge sind stale/„failed" (Cache-Reste längst migrierter Hosts wie macmini/.20.167, NAS/.20.10, grafana/.20.109 etc.), keine aktive Kommunikation mehr. - B1.1 MacBook (Claude-Sandbox-Client) bereits sicher migriert: aktive DHCP-Leases nur noch auf
dhcp-v20(10.40.20.101) unddhcp-v10(10.40.10.187), keinedefconf-Lease mehr. ⚠️ Dual-Homed über 2 VLANs gleichzeitig (project_dual_homing_slowness_incident-Muster) — funktional ok, aber im Auge behalten. - B1.2 unidentifizierte Geräte
.41.133/.41.198: kein ARP-Eintrag mehr vorhanden — entweder migriert oder abgeklungen, gelten für den Teardown als nicht mehr blockierend. - ⚠️ B1.3 (Media→VLAN40) und B1.4 (saisonale Shellys) nicht in diesem Sweep verifiziert — weiterhin offen, kurz vor dem finalen Cutover gegenchecken.
- Backup-Stand vor Cutover (2026-07-16): nur ap1 gesichert (Binary
bf-ap1-pre-vlan1-teardown-20260716.backupauf dem Router + lokaler Exportrouteros/state-backups/ap1-export-20260716-pre-vlan1-teardown.rsc). ap2 nicht gesichert, aber unkritisch: bewusst ausgesteckt (User-bestätigt 2026-07-16, kein Ausfall) — kein Backup nötig, solange es aus bleibt. sw1 nicht per Telnet gesichert (claudecode-Login 2× deterministisch abgelehnt), aber kein Blocker: User macht sw1-Änderungen ohnehin direkt im UI/CLI selbst (effizienter als über den Claude-Runner, gemeinsame Entscheidung) — Telnet-Automation für sw1 ist hier kein Muss. - Ziel (Kapstein der Segmentierung, s. Zeile 27): altes cudy-WLAN weg + VLAN1 als Client-Netz stilllegen (
defconf/pool-v1-Client-DHCP zurückziehen, ✅ bereits disabled). Nicht VLAN1 komplett: Switch-/AP-Mgmt (sw1.11/sw2.12/ap2.2) bleiben by design in VLAN1 (statisch, kein DHCP nötig) bis zum separaten MGMT-VLAN99-Cutover (eigener TP).cudy1/cudy2 =— cudy1 migriert auf.41.246/.247(Teardown-Ziele).10.246(Reuse statt Abbau), cudy2 tot/nicht reaktiviert (s.o.). - 🎯 User-Gate (Update 2026-07-14): Shelly ist wieder da (kein Blocker mehr) — SwitchBot ist KEIN Prereq mehr, funktioniert laut User erst NACH VLAN1-Retirement (Reihenfolge ggü. 2026-07-13 umgedreht) → wandert in die Teardown-Nachlese. TP19 damit direkt startbereit. Twinkly nebenher (saisonal).
- Verlorene Shelly — IDENTIFIZIERT via HA 2026-07-13 (User-Hinweis „du siehst ihn im HA"): HA-Device
shellyplugsg3-e4b063e41ab8, Modell = Shelly Plug S Gen3, MACe4:b0:63:e4:1a:b8, HA-device_id7a21e8f3349e6660f8b35974fc989a7b. NICHT im 26er-Inventar (Spare/Küchen-Steckdose, die Christoph beim Einrichten verbockt hat; er nannte sie „küche s20", aber s20=98:a3:16:7c:5f:ecläuft sauber auf.30.206— Verwechslung). KEIN AP-Mode, nicht tot: assoziiert am Altnetzelektrosmog.c(cudy → untagged VLAN1-L2), aber mit bogus-IP10.95.10.206(Fremd-Subnetz, User-Fehler) → unrouting-bar, daher weder in VLAN1/30-Sweep noch normal per IP erreichbar, aber per MAC in HA/WiFi-Table sichtbar. Der.219/s12-Verdacht war Sackgasse (s12 nur saisonal aus). - Update 2026-07-14: Shelly wieder da (User-Meldung) — Live-Status (noch bogus-IP
10.95.10.206oder inzwischen normal erreichbar?) zu Sessionbeginn per HA/ARP verifizieren; Recovery-Plan unten ggf. obsolet, falls sich das Gerät selbst erholt hat. - Recovery-Plan (falls beim Verify noch nötig): ap1 bekommt temporäre Zweit-IP
10.95.10.1/24auf der Bridge →10.95.10.206per L2 erreichbar → einWiFi.SetConfig {sta: ssid=dirtyvader-iot, pass=IOT-PSK, static, ip=10.40.30.<frei>}+Shelly.Reboot→ Gerät kommt auf VLAN30 hoch → temp-IP entfernen. Danach.30.x-Reservierung + Inventar (MACe4:b0:63:e4:1a:b8) + eco-Policy. Umgeht die „blutige Nase" (IP am Gerät ändern während man drauf hängt = Verbindungsverlust) — vom Router aus in einem Rutsch. Christophs manueller Direkt-Versuch (AP-IP auf 10.40.30 „verdrehen") war genau deshalb gescheitert. - ✅ SwitchBot floor-lamp
.41.184(b8:f8:62:09:f2:04) → erfolgreich auf VLAN30 übersiedelt (2026-07-16, Christoph via App/BLE), Res..30.227.
- Verlorene Shelly — IDENTIFIZIERT via HA 2026-07-13 (User-Hinweis „du siehst ihn im HA"): HA-Device
- Prereqs-Status (live nachgezogen 2026-07-16, s. Live-Sweep oben):
- ✅ Christophs Endgeräte → VLAN10/20 erledigt: MacBook-Air (
c0:c7:db:de:71:be, Claude-Sandbox-Client) hat aktive Leases nur noch aufdhcp-v10/dhcp-v20, keinedefconf-Lease mehr. iPhone.41.186nicht im aktuellen Sweep erneut geprüft (zuletzt off/asleep) — kurz vor Cutover gegenchecken. - ✅ 2 unidentifizierte VLAN1-Geräte (
.41.133/.41.198) aus dem ARP verschwunden — kein aktueller Eintrag mehr, gelten als nicht mehr blockierend (entweder migriert oder abgeklungen). - ⏳ Media → VLAN40 weiterhin offen: Apple TV 4K + Philips TV nicht in diesem Sweep verifiziert.
- ⏳ Saisonale Shellys s1/s2/s3/s12 weiterhin offen — nicht blockierend, kann übersprungen werden (Re-Onboarding-Aufwand akzeptiert).
- ⏳ pve-Interim-IP
.41.100weiterhin aktiv/reachable — Host-seitiger Cleanup auf pve selbst noch offen (nicht Router-Config).
- ✅ Christophs Endgeräte → VLAN10/20 erledigt: MacBook-Air (
- 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.100abräumen (B1.5), Interim-Krücken bewerten (ap2frame-types=admit-only-vlan-tagged,st-main rrm/wnm), Inventar/ip-plan/DNS.41→Zielfinal. - 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 · Gitea #60 — VLAN99-MGMT-Cutover (sw1/sw2/ap2-Mgmt VLAN1 → VLAN99) — 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.1läuft schon seit TP4) — nur der kosmetische DNS-Static-Nachtragap1.bf.lan10.40.41.1→10.40.99.1war 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 ausip-plan.md) — per Ping verifiziert. Zwischenzeitlich war das Gerät kurz auf einer dynamischen10.40.99.200-Lease aufgetaucht (unklare Ursache, s. Memoryproject_tp20_tp21_fasttrack_20260716), jetzt aber sauber auf der geplanten statischen Adresse.CLAUDE.md/ip-plan.mdnachgezogen. - ✅ 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_ip4in Nautobot per TP22 Schritt 5 nachgezogen. Derap2.bf.lan-DNS-Static wurde im TP22-Pilot-Deploy (2026-08-13, GC-ConfigPlan) von10.40.41.2auf.99.12gezogen. 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 auf10.40.41.2bis 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 GEGENSTANDSLOS (2026-08-14 festgestellt): Christoph hat sich für „auf CRS326 warten" entschieden — sw1 wurde am 2026-08-08 durch
crs326-coreersetzt 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.mdist damit historisch (nie ausgeführt, nicht mehr ausführbar — der Telnet-Runnerswitch/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.mdPhase 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).
TP20 · Gitea #61 — Platform-Datenbank (Postgres Precious-Tier + MariaDB Tier-2) — Nautobot-DB angelegt, vw-Migration (TP20.1) offen — Memory project_mikrotik_commit_nautobot_gc
- ✅ Platform-Postgres live (2026-07-16): LXC 105 auf pve,
platform-pg.bf.lan/10.40.20.20, Ubuntu 24.04 (native PG16-Paket, kein PGDG-Repo nötig — bewusste Abweichung von der sonstigen Debian/community-scripts-Konvention der übrigen pve-LXCs, aus PG16-Verfügbarkeitsgründen). Cluster mit--locale en_US.UTF-8 -e UTF8neu initialisiert (Erstinstallation lief inC/SQL_ASCII, für Nautobot ungeeignet, korrigiert).wal_level=replicagesetzt;archive_modebewusst noch NICHT an — ohne pgBackRest/Garage-S3 (TP18) zum Prunen würde archivierte WAL unbegrenzt wachsen und die kleine 8GB-Disk füllen; wird nachgezogen sobald TP18 steht. Rolle+DBnautobotangelegt,pg_hba.conferlaubtscram-sha-256aus10.40.20.0/24. End-to-End-Verbindungstest (Netzwerk, nicht nur localhost) erfolgreich. Creds inpostgres/.secrets(gitignored,chmod 600). - Auslöser: Mehrere Dienste brauchen zentrale DB (Nautobot-SoT [TP21], Vaultwarden, HA-Recorder). Grundsatzentscheid statt Nautobot-Insellösung — „wir skalieren schneller als wir schauen können" (User).
- ⚠️ Abh.-Korrektur (User 2026-07-16): TP18 (Garage-S3) ist KEINE Vorbedingung mehr — „hat mit dem Netz nichts zu tun", transitiv aus der TP21-Kette entfernt. pgBackRest→Garage-S3 (s.u.) wird nachgezogen sobald Garage existiert, blockiert aber nicht mehr den Start.
wal_level=replica/archive_modekönnen mit einem Platzhalter/lokalen Archive-Ziel hochgezogen werden, produktives Off-Site-PITR kommt später. - ⚠️ Komodo-Abh. (s. TP2/Memory
project_komodo_tp_pending) vorerst zurückgestellt: Komodo selbst existiert noch nicht als laufendes System — kann also nicht „darüber" deployt werden. Entscheidung (Claude, 2026-07-16, transparent statt stillschweigend): Postgres-LXC + Nautobot-Stack werden jetzt direkt gebaut (LXC/Docker-Compose), Komodo adoptiert sie später — gleiches Muster wie bei den CRS326 (Hardware/Stack zuerst lauffähig, Management-Layer zieht nach). Sag Bescheid, falls das nicht gewünscht ist. - 🔍 Ressourcen-Check 2026-07-16 (live geprüft, SSH):
- pve (10.40.20.100): 4 vCPU, 15 GB RAM total, ~12 GB belegt, nur ~2-3 GB frei, 3 GB bereits im Swap — eng! Größter Verbraucher: HAOS-VM (
haos, vmid 100) mit ~8,2 GB aktiv von 10 GB Limit. Disk unkritisch (94 GB Root, 85 GB frei). - Mac mini (10.40.20.167): 10 CPU, 24 GB RAM, nur ~1,9 GB "wired" (nicht reklamierbar) — deutlich mehr echter Headroom als pve trotz "23G used"-Anzeige (macOS-Cache-Artefakt). Docker läuft bereits dort (n8n, n8n-redis, cloudflared×2, gitea-mcp, portainer_agent).
- NAS nicht geprüft (kein funktionierender SSH-Zugriff von hier aus mit den vorhandenen Keys/User) — für diese beiden Stacks laut TP20/TP21-Plan ohnehin nicht Zielhost.
- ✅ Entschieden (2026-07-16): Postgres-LXC auf pve, Nautobot-App-Stack auf NAS (nicht Mac mini) — NAS hat mehr Headroom (~12 GB verfügbar) und hostet bereits Gitea (Nautobots Git-Backend für Golden-Config-Templates), kürzere Wege als Mac mini. Deploy-Weg: Portainer-Stack auf ep14, analog dem bestehenden Muster (
docs/nas-vlan20/stacks/*.yml), Basis = offiziellesnautobot-docker-compose(github.com/nautobot/nautobot-docker-compose), nicht von Null gebaut. Wird als separate Session angestoßen (parallel zum Postgres-LXC-Aufbau auf pve). - Nachtrag (2026-07-16, nach Aufräumen): pve hat sich entspannt — nach Abschalten mehrerer mittelfristig eh stillzulegender Services (User) jetzt 6,7 GB frei, 0 Swap (vorher 2-3 GB frei, 3 GB Swap). Postgres-LXC passt entspannt.
- RAM-Upgrade-Idee (32GB-Stick) zurückgestellt (User 2026-07-16): Intel N100 (pve-CPU) ist offiziell auf max. 16 GB spezifiziert + Single-Channel; ein dokumentierter Fall mit demselben Corsair-Modul auf vergleichbarer N100-Hardware endete in Memtest86-Fehlern, stabil erst nach Rückbau auf 8GB. Empfehlung: 16GB als Decke für diese Kiste behandeln statt auf einen Settings-Fix zu hoffen. User rechnet ohnehin mittelfristig mit einem HW-Tausch für pve — gehört ggf. in TP15s HW-Refresh-Scope, noch nicht formal aufgenommen.
- pve (10.40.20.100): 4 vCPU, 15 GB RAM total, ~12 GB belegt, nur ~2-3 GB frei, 3 GB bereits im Swap — eng! Größter Verbraucher: HAOS-VM (
- ✅ 2-Tier (User 2026-07-14):
- Tier-1 „Platform-Postgres" (precious): EIN Postgres-Cluster, getrennte DBs für Nautobot (hier provisioniert) + Vaultwarden (Onboarding = TP20.1). PG 16 (Nautobot-Matrix-safe; Nautobot unterstützt kein MariaDB, nur PG/MySQL-8 → Postgres ist gesetzt, nicht optional).
- Tier-2 (Bestand): HA-Recorder bleibt MariaDB (Write-Churn, andere Zuverlässigkeitsklasse, single-site). (Vaultwarden liegt heute ebenfalls auf MariaDB → wandert per TP20.1 nach Tier-1.) Engine-Split fällt sauber entlang der Tier-Grenze.
- ✅ Single-Site-first (User 2026-07-14): jetzt nur BF-Primary („gehostet wird vorerst auf der bf-site", 2026-07-16 reconfirmed). Nimmt das 2-Site-Quorum/Split-Brain-Problem (bräuchte 3. Witness) vom Tisch. ABER replication-ready ab Tag 1:
wal_level=replica,archive_mode=on(Ziel vorerst lokal/Platzhalter, s.o.) — späterer Standby =pg_basebackup, kein Primary-Umbau/Restart. pgBackRest→Garage-S3 folgt nach TP18, nicht mehr Blocker. - Substrat: Postgres in LXC auf pve (DB-Klasse, nicht Docker).
- Scope TP20 = Plattform: Cluster hoch, Tiering, Backup/PITR, Nautobot-DB anlegen. vw-Migration + Cross-Site-HA = TP20.1 (ausgelagert).
- Offene Sub-Steps: PG-Version final (16 vs 17); Rollen/DB-Anlage Nautobot; pgBackRest-Bucket in Garage folgt nach TP18 (nicht mehr Blocker, s.o.).
- ⚠️ Komodo-Abh. (User 2026-07-16) vorerst zurückgestellt, s.o.: ursprünglich als Blocker gedacht (TP20 + neue Softwarepakete über Komodo statt direkt/Portainer), aber Komodo existiert noch nicht lauffähig und hat keine eigene TP-Nummer (nur unter TP2/TP11 erwähnt) → entkoppelt, um die Montag-Deadline zu halten. Komodo-TP-Nummer weiterhin zu klären, aber nicht mehr auf dem kritischen Pfad für TP20-Start.
- Abh.: keine harten Blocker mehr (TP18 entfernt, Komodo entkoppelt). Blockt weiterhin TP21 + TP20.1.
TP21 · Gitea #62 — Nautobot Golden Config (config-as-code Control-Plane)
- 🔴 BETRIEBSBEFUND 2026-08-18: der Stack hat sich zweimal in einer Nacht selbst umgebracht — Ursache
war der Image-Healthcheck, nicht Celery.
nautobot-workerund-schedulererben aus dem Image einenHEALTHCHECK, der alle 10 snautobot-server health_checkstartet — einen kompletten Django-Bootstrap (~250 MB). Unter Last dauert ein Lauf >2 min, die Aufrufe stapeln sich also unbegrenzt (neun gleichzeitig gemessen, aeltester 2:16 alt). Ergebnis: Speicher alle →proc_fork.c:189 Failed to fork(). errno=[12/Cannot allocate memory]im NAS-Syslog um 23:48:47 → eine Minute spaeter raeumt DSM den Stack ab (sauberesdocker stop, daher ExitCode 0 bzw. 137 nach Grace — kein Kernel-OOM,OOMKilled=false). Dasselbe Muster schon um 19:35.- Behoben im Stack (
docs/nas-vlan20/stacks/210-nautobot.yml, Portainer-Stack 203):healthcheck: disable: trueauf worker+scheduler,--concurrency=2 --max-tasks-per-child=100,mem_limitje Container, Web-Healthcheck-Timeout 5s → 15s. Load fiel von 73,5 auf 5,8. - ⚠️
cpus:geht auf Synology NICHT — der Kernel hat keine CFS-Quota, der Stack-Deploy bricht mitNanoCPUs can not be setab. Nurmem_limitverwenden. - 📌 Nichts haengt an dieser Health:
restart=unless-stoppedstartet bei Exit neu, nicht bei unhealthy, und keindepends_onwartet auf den Worker. Der Web-Container behaelt seinen billigen curl-Check — das ist das Signal, dasservice_healthynutzt. - 🎯 Strukturell bleibt es eng: Nautobot teilt sich die DS923+ (4 Kerne) mit einer VMM-VM, Active Backup und ~14 weiteren Containern. Der Stack bleibt vorerst dort (User-Entscheid 2026-08-18); ein groesserer Server ist gedanklich bereits vorgemerkt.
- Behoben im Stack (
- 🔴 Die Kehrseite des Re-Baselines, am eigenen Leib gelernt (2026-08-18):
ingest-core-firewall.pyerklärt den Ist-Stand zum Soll — es prüft nicht, ob der Ist-Stand sinnvoll ist. Beim Lauf nach TP5 E3/E4 ist damit die kaputte Fasttrack-Reihenfolge des Core als Absicht in den Config-Context gewandert (s. TP6). Der Warnhinweis im Skriptkopf („nur nach einer bewusst durchgeführten, verifizierten Änderung laufen lassen") ist also notwendig, aber nicht hinreichend: die Änderung war bewusst, die Umgebung, die mitgeschrieben wurde, hat aber niemand angesehen. Merkregel: nach dem ersten Re-Baseline einer Sektion deren Diff einmal ganz lesen, nicht nur die Zeilen, die man selbst angefasst hat.- ✅ Nachtrag 2026-08-19: der konkrete Fall ist aufgelöst — Christoph hat entschieden, die Fasttrack-Reihenfolge so zu lassen (Begründung in TP6). Der Eintrag in der SoT ist damit nachträglich korrekt. Die Merkregel bleibt trotzdem gültig: dass ein versehentlich mitgeschriebener Zustand sich hinterher als brauchbar herausstellt, ist Glück, kein Verfahren.
- 🔧 Zwei echte Template-Fehler, beim Re-Baseline 2026-08-18 gefunden (beide gepusht):
/ip service set … **address=**→ RouterOS 7.23/7.24 exportiertavailable-from=. Das erzeugte vier Dauer-Drifts (ap1/ap2/branch/core), bei denen das Geraet recht hatte und das Soll falsch war — und ein Push haette auf 7.24 auflaufen koennen.hw-offloadgehoert in die SKIP-Liste voningest-core-firewall.py: die REST-API meldet es auf der defconf-fasttrack-Regel,/exportschreibt es nicht → ewige Falsch-Drift auf genau einer Regel.- Ergebnis: 71/76 compliant; die verbleibenden 5 sind der TP28-Rest (
wifi-*auf dem Core). (App 2026-07-22, Basisdaten + Git-Backend + L3-Core-Template 2026-08-05, ap1/ap2 As-built 2026-08-08); Device-Adoption/Compliance-Push ausgelagert → TP22 — Memoryproject_mikrotik_commit_nautobot_gc
- Ziel: modellierter Control-Plane über den MikroTik-RouterOS-Kern: GUI-SoT + Config-Compliance/Drift + intended-config + Push. Ergänzt MikroMCP (interaktiv/Debug), ersetzt es nicht (deklarativ/DR/Compliance). Aus User-Recherche 2026-07-14: MikroTik in Golden Config erstklassig (
mikrotik_routeros+_api, Nornir/NAPALM, backup+deploy). - Scope-Grenze (Fassung 2026-08-16, nachgezogen): RouterOS in-model =
crs326-core(L3-Router) +crs326-branch(L2) + ap1/ap2 (reine APs) — alle 4 Geräte sind seit TP22 adoptiert, Golden Config deckt damit den ganzen Fabric inkl. WLAN. Es bleibt nichts außerhalb: der frühere Vorbehalt „außerhalb bleibt Omada-WLAN" ist gegenstandslos, seit der Omada-Stack gelöscht (2026-07-16) und CAPsMAN abgeschafft (2026-08-08) ist.Vorherige Fassung (überholt): „RouterOS in-model = Router (ap1/ap2, dauerhaft — kein RB5009) + beide CRS326-Switches (RouterOS-Boot) → Golden Config deckt den ganzen Kabel-Fabric. Außerhalb bleibt nur Omada-WLAN (eigener Controller, spielt aber laut TP15-Korrektur ohnehin keine Rolle mehr)."
- 🔒 Wird zum alleinigen Config-Weg für Netzgeräte (Governance-Entscheid 2026-07-16, s. oben): ab hier keine ad-hoc MikroMCP-Writes/Switch-UI-Klicks mehr auf Dauer — Nautobot managed den Fleet.
- ✅ Nautobot-Stack live (2026-07-16), auf NAS statt Mac mini (Ressourcen-Check hatte Mac mini vorgeschlagen, dann auf NAS umentschieden — mehr Headroom + Gitea-Co-Location, s. TP20-Log): Portainer-Stack
nautobot(Id 203, ep14), 4 Container —nautobot(App/API,10.40.20.30:8080),nautobot-worker(Celery),nautobot-scheduler(Celery Beat),nautobot-redis. Bildghcr.io/nautobot/nautobot:3.1.7(offizielles Image direkt, nicht dasnautobot-docker-compose-Repo — das ist eininvoke/Poetry-getriebenes Dev-Tooling-Repo ohne eigenständigedocker-compose.yml, für einen Portainer-String-Stack ungeeignet; bewusste Abweichung, dokumentiert statt stillschweigend). DB = Platform-Postgres (10.40.20.20, TP20). Compose-Dateidocs/nas-vlan20/stacks/210-nautobot.yml(gitignored, wie alle NAS-Stack-Files).- 🐛 Gotcha beim ersten Deploy: alle 3 Nautobot-Container liefen initial gleichzeitig
migrate(Standard-Entrypoint-Verhalten) → Race-Condition,IntegrityErroraufpg_type. Fix:nautobot-Service kriegt einenhealthcheck(curl .../health/),nautobot-worker/nautobot-schedulerstarten erst beidepends_on: nautobot: condition: service_healthy— serialisiert die Migration sauber auf einen Container. DB dafür einmalDROP+CREATE(sauberer Neustart, kein Datenverlust — war eh leer). - ✅ End-to-End verifiziert:
/api/status/mit Token 200, Nautobot-Version 3.1.7, alle 4 Container laufen. Superuseradminangelegt, Creds im Stack-File (gitignored) +postgres/.secrets(DB-Seite). - ⚠️ Bekannt offen, nicht blockierend: kein HTTPS/Reverse-Proxy vor Nautobot (Django-Security-Warnings beim Start, erwartet für internen HTTP-only-Betrieb auf VLAN20 — analog anderen internen Diensten); Celery-Worker-Registrierung beim allerersten Start nicht sofort sichtbar (
celery-workers-running:0initial), unkritisch, braucht kurz zum Einpendeln.
- 🐛 Gotcha beim ersten Deploy: alle 3 Nautobot-Container liefen initial gleichzeitig
- PoC-Pfad (angepasst an die Montag-Deadline):
Nautobot-Stack hoch✅ → ap1 + ap2 in einem Rutsch adoptieren (ap2 bekommt dabei gleich seinen VLAN99-Mgmt-Umzug aus TP19.1, s.o. — nicht isoliert vorher) → sobald CRS326 verkabelt sind, direkt als Nautobot-verwaltete Geräte adoptieren statt erst manuell konfigurieren → Compliance/Drift + Templates/intended für VLAN-/Firewall-Standards danach. - ✅ Basisdaten-Ingest durchgeführt (2026-07-22) — Ist-Zustand, nicht Zielzustand (User-Entscheid: „wir gehen vom status quo aus"). Quelle = ap1 live via MikroMCP. Skript-Muster idempotent (get-or-create + Delta-PATCH).
- Locations: neuer LocationType
BereichunterSite;BF → Technik UG(crs326-core, crs326-branch, ap2) undBF → Wohnzimmer Sideboard(ap1). - Devices: ap1 = Rolle Router (Ist am 2026-07-22 — ⚠️ seit der Adoption 2026-08-13 ist ap1 in Nautobot Wireless AP und
crs326-coreder Router, s. TP22), ap2 = neue Rolle Wireless AP + Status Offline, beide CRS326 Platform RouterOS nachgetragen (fehlte → hätte jeden GC-Job auf ihnen verhindert) + Werks-MAC/software-id incomments. Neu als Übergangs-Devices ohne Platform (nie GC-fähig, bewusst):sw1(ALLNET),sw2(ES208G),cudy1. - IPAM: VLAN-Group
BF+ 9 VLANs (1 Deprecated, 10/20/30/40/50/90/99/100 aktiv) + 8 Prefixes, jeweils an ihr VLAN gebunden. VLAN100/WAN bewusst ohne Prefix (öffentliches Liwest-/24, gehört uns nicht). - ap1-Interfaces (26): ether1-5, bridge, lo, wg-hub, vlan10-100, wifi1/wifi2, 7 VAPs — inkl. MACs,
ether2als Trunk (untagged VLAN1 + tagged 10-100), VAPs als Access-Ports auf ihrem VLAN. 9 Gateway-IPs an ihren Interfaces. Platzhalter-Interfacemgmtauf ap1 gelöscht (existiert real nicht). - WLAN: logischer Controller
bf-wlan(kein CAPsMAN —controller_devicebewusst leer, die Control-Plane ist Nautobot GC) + GruppeBF-WLAN-APs(ap1+ap2) + 6 WirelessNetworks mit VLAN-Bindung + 2 RadioProfiles (2,4 GHz ch1 / 5 GHz ch36, Domain AT). - 🐞 API-Gotcha:
tagged_vlanswird vom REST-Serializer in Detail-/List-Views alsnullzurückgegeben, obwohl korrekt gespeichert — Verifikation nur über GraphQL verlässlich. Kostet sonst eine Stunde Fehlersuche an einem Nicht-Problem. Ebenso: Relationen kommen per Default ohnedisplay(?depth=1nötig), undVLANGroup/Prefix/VLANbrauchen passendecontent_typesam LocationType, sonst 400. - ✅ CRS326-Core L3-Device-Modell + Ports angelegt (2026-08-05):
crs326-corejetzt Rolle Router, alle VLAN-SVIs (vlan10/20/30/40/50/90/99/100) + Gateway-IPs.1(außer vlan100) in Nautobot; Portbelegung vianautobot/ingest-crs326-ports.pyaktualisiert.crs326-branchbleibt Switch mit Mgmt-IP.99.13(Zielrenumber.12im Cutover-Fenster). - ⚠️ Offen/nachzutragen: exaktes Modell von sw1 + cudy1 (aktuell
… (Modell TBD)); Standort von sw1/sw2/cudy1 (hängen anBFstatt an einem Bereich);ap2s→ ✅ erledigt (TP22 Schritt 5):primary_ip4zeigt noch auf das tote10.40.41.210.40.99.12.
- Locations: neuer LocationType
- ✅ Git-Backend an Gitea angebunden (2026-08-05): Repository
bf-golden-config(jinja_templates/mikrotik_routeros.j2) sync-t in Nautobot; Generate Intended Config fürcrs326-coreerfolgreich, intended config in GC-Tabelle vorhanden.- ✅ Lokale Cutover-Config materialisiert:
routeros/tp15-core-cutover-intended.rscenthält die aus Nautobot gerenderte Config plus die 54 ap1-Leases und den WG-Hub-Privkey (lokales Fenster-Artefakt, nicht im Golden-Config-Repo).
- ✅ Lokale Cutover-Config materialisiert:
- ↪️ Adoption + Compliance-Push → ausgelagert nach TP22 (eigener TP, User-Entscheid 2026-08-08): ap1/ap2/crs326-Adoption, RouterOS-Nornir-Dispatcher,
enable_deploy, WG-Privkey/PSK-Secret-Handling. TP21 selbst = Plattform + Datenmodell + Templates (steht). Datenmodell-Nachträge (branch/core-Ports final, sw1 außer Betrieb, cudy1) laufen in TP22 mit. - Abh.: TP20 (Postgres muss stehen), Gitea ✅, RouterOS-Fleet (core/branch/ap1/ap2).
TP21.1 · Gitea #63 — Core-Cutover-Recovery (ap1 → crs326-core als L3-Router) — Aufräum-Todos offen → alle fünf erledigt, letzter live gegengeprüft 2026-08-23 (s. Nachtrag am Ende)
Kern-Erkenntnis (wichtig gegen Doku-Verwirrung):
crs326-coreIST jetzt der produktive L3-Router. Der Core-Cutover (TP15) wurde faktisch vollzogen — ap1 wurde plattgemacht/getrennt, core hat Routing/DHCP/DNS/NAT/WG-Hub übernommen. core-Mgmt =10.40.99.1(vlan99-SVI) bzw. same-subnet-Fallback10.40.10.1(RouterOS-Version 7.19.5 identifiziert das Gerät zweifelsfrei als CRS326, nicht als hAP/ap1). Die CLAUDE.md-Zeile „core grundkonfiguriert, NICHT produktiv" ist damit überholt.
- Verlauf: Ausgangssymptom war ein L3-Ausfall-Eindruck (kein DHCP, „kein Routing nach .20.x"). Ursache = unvollständiger Cutover: core hatte L3-SVIs + Firewall, aber es fehlten DHCP-Server, WAN-Egress, WG-Hub und der DNS-Resolver-Upstream. ap1 (bisher alleiniges L3-Gerät) war bereits Werksreset + getrennt.
- ✅ DHCP wiederhergestellt aus letztem ap1-Backup (
routeros/ap1-pre-core-cutover-20260806-073616.rsc): 7 Server (dhcp-v10…v99) + 8 Networks + 54 statische Reservierungen + Optiondns 1.1.1.1. Reproduzierbar inrouteros/tp21-core-dhcp-from-ap1.rsc. Legacy VLAN1 (pool-v1/defconf) + tote omada-inform-Option bewusst weggelassen. - ✅ WAN/Internet: dhcp-client auf
vlan100→ Liwest-Public-IP90.146.33.177gebunden (Arris hängt physisch an core.vlan100), NAT-Masqueradeout-interface-list=WAN, Default-Route korrekt; die self-pointing Blackhole-Route0.0.0.0/0 via 10.40.99.1entfernt. disabled-Falle beachtet: die ap1-Masquerade-Regelnout-interface=bridge/=ether1sinddisabled=yesund wurden NICHT übernommen. - ✅ WG-Hub (TP10) neu aufgebaut:
wg-hub(listen 51821, Privkey ausrouteros/ap1-wg-hub.privkey, Hub-Pubkey unverändert) + Peersfm/dw+ Routen. Beide Tunnel handshaken (dw + fm live). Reproduzierbar (Privkey redacted) inrouteros/tp21-core-wan-wg-restore.rsc. - ✅ DNS gefixt: core hatte
allow-remote-requests=no+ leeren Upstream → Client-DNS tot UND Hub konnte myfritz (FM-Endpoint) nicht auflösen. Fix =allow-remote-requests=yes+servers=1.1.1.1(plain, weil corecerts=0→verify-doh-certunmöglich). Das entsperrte auch FM. - ✅ Identity auf
crs326-coregesetzt (war fälschlich „ap1" — genau diese Altlast stiftete Verwirrung).mcp/mikromcp/config/routers.yamlauf Zielschema: core.99.1, branch.99.2, ap1.99.11, ap2.99.12(wirkt nach MCP-Neustart; danach core via routerIdcrs326-core). - ✅ disabled/invalid-Falle bereinigt (User-Hinweis „keine disabled-Falle?"): (a) die 2 TP10-WG-Forward-Regeln (
allow from/to WG spokes) warenI=invalid, weil aus dem ap1-Backup mit der stale Interface-ID*1Dübernommen → aufin/out-interface=wg-hub(per Name) korrigiert; (b) 2 inaktive WG-Route-Leichen (gateway="", aus einem früheren Cutover-Versuch vor Existenz von wg-hub) entfernt, nur die aktivengateway=wg-hubbleiben. Finaler Sweep sauber: filter-invalid=0, nat-invalid=0, routes-inactive=0, if-disabled=2 (nur ungenutztesfp-sfpplus1/2, gewollt). - ✅ Backups:
core-pre-dhcp-restore-20260808.backup(vor Eingriff) +core-post-tp21-recovery-20260808.backup(nach allen Fixes neu gezogen) auf dem Gerät. - ℹ️ branch ist gesund (L2, forwardet), Mgmt
10.40.99.2(+ temp— die Temp-IP ist am 2026-08-16 entfernt worden) — via core-MNDP bestätigt. Das in Winbox-MAC gesehene „0.0.0.0" ist der bekannte Discovery-Artefakt (Gerät hat auf dem Discovery-VLAN keine IP), kein echtes Problem.10.40.10.2 - 🔜 TODO (Aufräum-Liste, spätere Session — danach WLAN-Neuprovisionierung):
- DoH-Cloudflare-Gateway auf core wiederherstellen (aktuell nur plain 1.1.1.1, keine Filterung/Account-Bindung): CA-Bundle importieren →
use-doh-server=https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes(Referenz-Config liegt auf ap1). - Intended config nach Nautobot zurückschreiben (die Direkt-Writes liefen unter der CRS326-Cutover-Governance-Ausnahme).
- branch
192.168.88.1-Rest verifizieren (Bootstrap Rev 4 entfernt es in Zeile 70; via MCP noch nicht gegengeprüft, weil Registry-Umstellung MCP-Neustart braucht). - ✅ core
ether4GEKLÄRT (2026-08-13) — es ist das Wohnzimmer-Sideboard (Smart-Managed-Switch, nur VLAN40-Multimedia), und der Port ist der falsche. Symptom war „TV meldet, LAN funktioniert nicht".- Ursache = VLAN-Mismatch, kein Kabeldefekt:
ether4hatpvid=40(untagged rein → VLAN40 ✓), ist in VLAN40 aber tagged-Member (untagged sindether2/ether3/ether5) → alles raus ist 802.1Q-getaggt und der untagged Switch/TV verwirft es. Einseitige Kommunikation. - Belege: TX 3,4 GB / 16 M Pakete gegen RX 452 KB / 1.338 Pakete, 0 stabil gelernte MACs; TV-Lease
10.40.40.11(70:AF:24:B8:C9:86) bound, last-seen 1h54m, gleichzeitig ARP-Statusfailed— ein Gerät, das nachweislich sendet, aber nicht antwortet. Der bound-Lease ist kein Gegenbeweis: beim Einschalten macht der TV einen INIT-REBOOT-REQUESTauf seine alte IP, RouterOS quittiert mit ACK und markiert bound — das ACK muss den Client nie erreichen. - Herkunft:
ether4war als ap1-Uplink-Trunk vorbereitet („ap1 wandert #15→#4"); ap1 blieb aufether15, 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
ether4sauber auf untagged VLAN40 gezogen statt das Kabel zu verschieben. - Ausgeführt via Nautobot-GC-ConfigPlan (
plan_type=manual, 6 Zeilen, change_control_idTP21.1-4 …), nicht per Direkt-Write — Governance gewahrt. Vorher/system backup=core-pre-ether4-vlan40-20260813.backup(Regel 3).ether4aus den Tagged-Listen von VLAN 10/20/30/40/50/90 entfernt + als untagged-Member zu VLAN40 ergänzt.pvid=40stand 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 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); ARPcomplete=true/status=delayaufvlan40(vorherfailed);/interface/bridge/hostlernt70:AF:24:B8:C9:86aufether4, VID 40;ether4rx-unicast=6.909/ 3,0 MB RX (am 08-13 noch 1.338 Pakete / 452 KB → der Downstream lebt jetzt). DHCP-Leasetvweiterhin bound aufdhcp-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
setab (invalid value for argument interface), weilether8/13/15auf 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.displaygegen den Zielnamen assert'en (im Skript jetzt so gemacht). - Bestätigt zum zweiten Mal: der Deploy-Job meldete
SUCCESSund der PlanCompleted, obwohl auf dem Gerät nichts ankam. Weder Job- noch Plan-Status sind ein Wirksamkeitsnachweis — nur die Gegenprüfung am Gerät zählt. Der Fehl-Plan wurde gelöscht (irreführender Datensatz).
- Schaden: keiner. RouterOS wies jedes
- ✅ Lücke geschlossen (2026-08-13, User: „compliance rules! die Änderung machen wir"):
/interface bridge port+/interface bridge vlansind jetzt für alle drei Geräteklassen im Template und als ComplianceFeatures scharf — s. TP22.
- Ursache = VLAN-Mismatch, kein Kabeldefekt:
ap1/ap2Neuprovisionierung (WLAN-Rebuild, eigene Session) — ap1 ist Werksreset; danach greifen die.99.11/.99.12-Registry-Einträge.
- DoH-Cloudflare-Gateway auf core wiederherstellen (aktuell nur plain 1.1.1.1, keine Filterung/Account-Bindung): CA-Bundle importieren →
- ✅ Nachtrag 2026-08-23 (Doku-Session): die Aufräum-Liste ist vollständig abgearbeitet — deshalb
steht TP21.1 jetzt im Archiv. Punkt für Punkt:
1 DoH-Gateway ✅ (TP23 Stufe 1, 08-18 — mit
verify-doh-cert=yes; die Sorge „core hat kein CA" war zu pessimistisch, es brauchte einen Root, nicht das Bundle) · 2 intended config zurückgeschrieben ✅ (TP22-Re-Baseline 08-18; belegt durch 104/104 compliant, 0 Drifts, live gegen die Nautobot-API geprüft am 08-23) · 3 branch-192.168.88.1-Rest ✅ live gegengeprüft am 2026-08-23:/ip address print where address~"192.168.88"aufcrs326-branchliefert leer — der Bootstrap-Rest ist weg · 4ether4/Sideboard ✅ (08-13/08-14, s.o.) · 5 AP-Neuprovisionierung ✅ (TP3-Rebuild 08-08, seit TP28 08-17 ohnehin überholt — beide APs sind reine CAPs).
TP22 · Gitea #64 — Device-Adoption + Golden-Config Compliance-Push (RouterOS-Fleet) — Compliance-Backlog abgearbeitet 2026-08-16 → 68/68, 0 Drifts — alle 5 Schritte erledigt (Schritt 4 per Entscheid „keine Secret-Injection"); aus TP21 ausgelagert 2026-08-08
-
Ziel: die 4 Live-Geräte (crs326-core, crs326-branch, ap1, ap2) real unter Nautobot Golden Config nehmen — Backup → Compliance/Drift → intended → Push (
enable_deploy). Damit greift der Governance-Entscheid „Config exklusiv über Nautobot" operativ. Macht die aktuellenrouteros/.secrets/*.rsc-Handoffs mittelfristig überflüssig. -
Stand aus TP21: Plattform + Datenmodell + Git-Template + intended-config für core stehen; ap1/ap2 als reine APs zurückgeschrieben (
nautobot/ingest-ap-rebuild.py, 2026-08-08).enable_plan/enable_deployinnautobot_config.pynoch bewusst aus (pull/read-only). -
✅ Schritt 0 DURCH (2026-08-13) — Backup-Scrubbing + Repo-Neuanlage. Vorgezogen aus Schritt 4, weil ohne Scrubbing jedes weitere Backup Secrets geleakt hätte.
- 🔴 Root-Cause-Fund: Es gab keine ConfigReplace/ConfigRemove-Regeln → der Backup-Job vom 2026-07-22 hatte den ap1-
/exportungefiltert nach Gitea geschrieben.backups/ap1.cfgenthielt im Klartext den damals wie heute live genutzten WG-Hub-private-key (bei der Core-Recovery unverändert aufcrs326-coreübernommen, damit FM/DW-Spokes matchen) und 6 WLAN-PSKs. - ✅ 5 ConfigReplace-Regeln (Platform RouterOS) via
nautobot/ingest-gc-scrubbing.py(Dry-Run-Default, Regex-Selbsttest bei jedem Lauf):10-wifi-passphrase,20-wireguard-private-key,30-preshared-key,40-password,50-secret→ Maske"<<REDACTED>>". Gegen den echten Export kalibriert: RouterOS quotet nur bei Bedarf (4 von 6 PSKs standen unquotiert), deshalb Alternation("(?:[^"\\]|\\.)*"|\S+)mit der quotierten Variante zuerst (\S+ist greedy und würde bei einem PSK mit Leerzeichen den Rest exponieren). Replace normalisiert immer auf die quotierte Form → Maske ist formunabhängig byte-identisch (Voraussetzung für das Template in Schritt 1). Negativtest:public-key=wird nicht maskiert (sonst bräche der WG-Peer-Block). - 🐞 Blocker nebenbei gefunden + gefixt: Nautobot hatte das ALTE Router-Passwort. Der erste Backup-Lauf meldete Job-
SUCCESS, schrieb aber nichts —backup_last_attempt_datesprang,backup_last_success_datenicht (GC meldet Job-Erfolg auch bei Geräte-Fehlern; nur das Success-Datum je Gerät zählt). Ursache:NAUTOBOT_ROUTEROS_PASSWORDim Stack war 12 Zeichen aus der Zeit vor der PW-Vereinheitlichung (2026-08-08, 32 Zeichen, identisch auf allen 4 MikroTik). Fix = Stack-Env nachgezogen + Stack 203 redeployed; Datei zusätzlich aufchmod 600(Backup.bak-20260813). - ✅ Gitea-Repo
admin/bf-golden-configgelöscht + neu angelegt (User-Entscheid: Repo neu, nicht rotieren — History-Rewrite verworfen, weil Gitea unerreichbare Blobs bis zum server-seitigengcbehält). Struktur + Template + README wiederhergestellt. Vollscan aller Blobs der neuen History: 0 unmaskierte Secrets (die 6 Regex-Treffer sind 5× README-Doku der Feldnamen + 1× der Template-Platzhalter). Nautobot-GitRepository re-synct, End-to-End-Backup ins frische Repo verifiziert (112 Z., 6/6 PSKs maskiert). - 📌 Risiko-Akzeptanz (User 2026-08-13): keine Rotation. Faktenlage: Repo
private=true, anonymer Zugriff 404. Aber Gitea hängt auf CF-bypassam Internet undha-xstateist ein Service-Account mit Gitea-Admin (kann jedes private Repo lesen) → Lesbarkeit für 2 Accounts, nicht fürs Internet. Trigger für nachträgliche Rotation: ändert sich die Gitea-Exposition oder derha-xstate-Account → WG-Key rotieren (FM/DW-Klickanleitungrouteros/fritzbox-wg-lanlan-klickanleitung.md). - ⚠️ DR-Konsequenz: ein maskiertes Backup ist kein Wiederherstellungs-Artefakt. Restore hängt weiter an
~/.secrets/,routeros/.secrets/*undrouteros/ap1-wg-hub.privkey(alle gitignored).
- 🔴 Root-Cause-Fund: Es gab keine ConfigReplace/ConfigRemove-Regeln → der Backup-Job vom 2026-07-22 hatte den ap1-
-
✅ Schritt 1 DURCH (2026-08-13) — AP-Zweig im Golden-Config-Template.
- Datenmodell = ConfigContext (
nautobot/ingest-ap-configcontext.py). Verworfen: Wireless-RadioProfile(haengt überControllerManagedDeviceGroupan einem Controller — den gibt es seit der CAPsMAN-Abschaffung bewusst nicht mehr; ein Fake-Controller wäre Modellschuld), CustomFields (skalieren nicht), Ableitung aus VAP-Descriptions (SSID nur als Freitext → stille Brüche). Angelegt: ConfigContextap-common(Scope Role Wireless AP + Platform RouterOS, weight 1000) mitzones/radios/Site-Konstanten +local_config_context_dataje AP mit nur den 2 Kanalnummern. Frequenz wird im Template gerechnet (5000+5*ch/2407+5*ch) statt gespeichert. - Cross-Check im Skript: die
zones-Tabelle wird gegen die 11 real modellierten VAP-Interfaces (Name-Präfix +untagged_vlan) validiert, Divergenz = Abbruch → ConfigContext und DCIM können nicht auseinanderlaufen. - Template: neuer Zweig
{% elif obj.role.name == "Wireless AP" %}(rollen-, nicht namensbasiert). Scope bewusst nur die compliance-verwalteten Sektionen (channel/datapath/security/configuration/bridge-vlan/vlan99/ip-address/route) — nicht die ganze Config: defconf-Boilerplate (ipv4/ipv6-Firewall,/disk,/tool mac-server) und die VAP-Zeilen bleiben draussen, weil deren MACs gerätevergeben und in Nautobot nicht modelliert sind. Die früheren „Ausnahmen" fallen aus den Daten heraus: IOT hatbands:["2g"]→ landet automatisch nur aufwifi2; VLAN1/VLAN99 stehen als literale Zeilen ausserhalb der Schleife (VLAN99 aufbridge, NICHT auf die Radios — sonst Mgmt over-the-air). - 🔑 Formatregel gelernt: gegen den echten
/exportschreiben, nicht gegen die.rsc. RouterOS sortiert Attribute alphabetisch und schreibtft-over-dsnur beift=yes; die handgesetzte.rschat abweichendes Padding/Reihenfolge. Referenz-Export:routeros/state-backups/ap1-gc-backup-scrubbed-20260813.cfg. RouterOS exportiert CRLF, Jinja rendert LF — GC normalisiert das korrekt (die schon vorher grünesystem-identity-Compliance war der Beleg). - ✅ Abnahme: ap1 Intended == Geräte-Ist, 0 Drift (33 Zeilen, zeilenweise identisch); ap2 unterscheidet sich in exakt den 4 erwarteten Werten (identity, 5180↔5745, 2412↔2462,
.99.11↔.99.12). - ✅ Mitgenommen: WG-Privkey-Platzhalter im core-Zweig auf dieselbe Maske
"<<REDACTED>>"vereinheitlicht (sonst Dauer-Diff, sobald eine Feature auf/interface wireguardliegt); DNS-Statics korrigiert (s. Nummernplan unten).routeros/push-gc-template.pygehärtet: Pre-Push-Secret-Guard (verweigert den PUT bei unmaskierten Werten),--dry-runmit Diff,-mstatt hartkodierter Commit-Message,shaoptional (sonst 404 nach Repo-Neuanlage).
- Datenmodell = ConfigContext (
-
✅ Schritt 2 DURCH (2026-08-13) — Adoption + Backup/Compliance grün, 20/20.
- SecretsGroup „RouterOS Nornir" an
crs326-core+crs326-branchgehängt (ap1/ap2 hatten sie schon) — einheitliches Admin-PW seit 2026-08-08 macht eine Gruppe für alle 4 ausreichend. - Datenmodell-Korrekturen vorgezogen (technisch Voraussetzung):
crs326-coreStatus Planned → Active (ist der produktive L3-Router),crs326-branchprimary_ip4.99.13→.99.2(live verifiziert). - ✅ Backup über alle 4 erfolgreich, Sichtprüfung: 0 unmaskierte Secrets (ap1/ap2 je 6 PSKs maskiert, core WG-Privkey maskiert, branch secret-frei).
- ✅ 4 neue ComplianceFeatures (
wifi-channel,wifi-datapath,wifi-security,wifi-configuration, alleconfig_ordered=false) + die bestehendesystem-identity→ 20/20 compliant über alle 4 Geräte. - ⚠️ Bewusst noch KEINE Features für
bridge-vlan/ip-address/ip-route: ComplianceRules gelten pro Platform, nicht pro Rolle — und dercrs326-core-Zweig ist in Slash-Form geschrieben (/ip/address add …), was den Export (Space-Form,/ip address add …) nicht matcht → das gäbe permanenten Falsch-Drift auf dem Core. Follow-up: core-Zweig auf Export-Form umstellen, dann diese Features nachziehen. Die wifi-Features sind unkritisch, weil core/branch keine WLAN-Hardware haben (beide Seiten leer = compliant).
- SecretsGroup „RouterOS Nornir" an
-
✅ Follow-up DURCH (2026-08-13) —
crs326-core-Zweig auf/export-Form. Der Zweig war als staged Cutover-Skript geschrieben (Slash-Form/ip/address, plusdisabled=yes-Flags aus der Vorbereitungszeit) und matchte den Export nicht → er hätte platform-weite ComplianceRules dauerhaft rot gefärbt. Jetzt Space-Form + alphabetische Attribute,disabled=yesentfernt (core ist seit 2026-08-08 produktiv), VLAN-Tabelle als Jinja-Konstante, GW-IPs weiter datengetrieben. Ergebnis: 68 von 69 Zeilen byte-identisch zum Gerät. Zusätzlich Switch-Zweig fürcrs326-branch(Mgmt-Layer) ergänzt — vorher fiel branch auf „nur/system identity" durch und meldete legitime Config als Drift. 9 weitere ComplianceFeatures (interface-list/-vlan/-wireguard, ip-address/-pool/-dhcp-server/-dns/-firewall-nat/-route); beiip-dhcp-serverbewusst drei spezifische Präfixe statt/ip dhcp-server, sonst fingen die 54 dynamischenlease-Zeilen mit. -
✅ Schritt 3 DURCH (2026-08-13) — Deploy-Pipeline scharf, Pilot erfolgreich.
- Image
3.1.7-gc9auf der NAS gebaut (/volume1/docker/nautobot-image), Stack 203 retaggt. ⚠️ Falle: ein bereits vorhandenesgc7trug dieselben Flags; ein Build ohne geänderte Quelldatei zieht den Docker-Cache und liefert eine identische Image-ID — immer gegen die Flags im fertigen Image verifizieren.scpauf die NAS schlug fehl („Connection closed"), Übertragung perssh 'cat > datei'. - Jobs sind in Nautobot zusätzlich einzeln freizuschalten (
enabled=true): die Plugin-Flags machen sie nur verfügbar. - 🔴 Kernbefund:
napalm-rosist ein READ-ONLY-Treiber. Der Default-Dispatcher wählt NAPALM (weilPlatform.network_driver_mappingsnapalm: rosenthält) → Backup (get_config) geht,merge_configscheitert grundsätzlich, mit leerer Fehlermeldung (E1015 … ``). **Fix:** in den Golden-Config-Settings (nicht in den Nornir-Settings!)custom_dispatcher: {"mikrotik_routeros": "nornir_nautobot.plugins.tasks.dispatcher.mikrotik_routeros.NetmikoMikrotikRouteros"}— dieser Dispatcher pusht vianetmiko_send_config`. Danach lief der Deploy sofort. - ⚠️ Gescheiterter Deploy = sauberer Fehlschlag: das Gerät blieb beim NAPALM-Versuch vollständig unverändert (kein Teilzustand). Zusätzlich meldet der Deploy-Job
SUCCESS, obwohl der Plan aufFailedsteht — wie beim Backup gilt: nur der Objekt-Status zählt, nicht der Job-Status. - ✅ Pilot-Deploy: die DNS-Statics auf dem Core. Vorher
/system backup(core-pre-tp22-first-deploy-20260813.backup). ⚠️config_seteines generierten Plans ist schreibgeschützt, undplan_type=missingerzeugt nuradd— das hätte Duplikate ergeben (ap1.bf.langleichzeitig auf.99.3und.99.11). Deshalb manueller Plan mit Purge-vor-Add. Ergebnis verifiziert:ap1→.99.11,ap2→.99.12,branch→.99.2, weiterhin 11 Einträge, keine Duplikate. Compliance 51/56.
- Image
-
✅ Schritt 5 DURCH (2026-08-13) — Datenmodell-Nachträge,
nautobot/ingest-tp22-datamodell.py. Quelle war durchgehend das Gerät, nicht die Doku:bridge/port(pvid),bridge/vlan(tagged/untagged),bridge/host(gelernte MACs je Port+VID) plus ARP/DHCP-Leases zur Identifikation der Gegenstellen.crs326-core: von 5 auf 26 Ports. Vorher waren 3 davon als „GEPLANT (tentativ)" modelliert undether1zeigte auf das totesw1 #12. Belegt (MAC-hart):ether8→crs326-branch,ether13→pve.20.100,ether14→Sonoff.30.250,ether15→ap1,ether16→Arris/WAN,ether5/ether6→Sonos Schlafzimmer.195/.193. Die Trunk-Sets sind exakt wie am Gerät übernommen, inkl. Schiefstände (z.B. trägtether1kein VLAN20/99) — bewusst nicht geradegezogen.crs326-branch:ether1-Zielsw1 #8→crs326-core ether8;ether5/ether6= Sonos Arbeitszimmer (aktuell kein Link, die Schlafzimmer-Paare hängen am Core);ether9–23+sfp waren als „disabled" modelliert, sind live aber enabled (Bootstrap Rev4) → korrigiert.- Standort-Fehler gefunden:
crs326-branchundap2standen in Nautobot auf Technik UG, real Technik OG (die Doku war richtig, das Modell falsch) → korrigiert. - Status-Endzustände: sw1/sw2/cudy2 → Decommissioned (physisch ausgebaut; „Decommissioning" heißt Prozess läuft). Nautobot liefert diesen Status mit, aber nur für
circuits.circuit→content_typesumdcim.deviceerweitert statt einen zweiten gleichnamigen anzulegen.cudy1→ Offline (coreether11hat kein Link; der endgültige Teardown bleibt TP19). sw1s 4 Duplikat-Ports (gi8/gi11/gi15/gi16nebenGE*) entfernt. - ✅ Compliance-neutral verifiziert: Generate-Intended + Compliance über alle 4 Geräte neu gelaufen → weiterhin 51/56 mit exakt denselben 5 bekannten Drifts. Grund: der core-Zweig des Templates iteriert nur Interfaces mit Präfix
vlanund hält die Bridge-VLAN-Tabelle als Jinja-Konstante. Umkehrschluss als Dauerregel: dievlanXX-Descriptions auf dem Core sind NICHT kosmetisch — sie landen alscomment=in der intended config. - 🔍 Nebenbefund, halbkonfigurierte Ports (NICHT angefasst, gehört zu TP19/TP5):
core ether11(cudy1) hatpvid=10ohne VLAN10-Membership → funktionslos;core ether3hatpvid=1bei untagged-VLAN40-Membership;core ether2ist gleichzeitig statisches untagged-Member von VLAN1 und VLAN40;branch ether9–23tragenpvid=20ohne jede Membership. Alles Bring-up-Reste, betriebsneutral (kein Link), aber sie gehören in die VLAN1-Aufräumrunde.
-
✅ Nachtrag 2026-08-13 — Compliance-Abdeckung erweitert auf 68 Checks (63/68 grün; seit 2026-08-16 68/68). Drei neue ComplianceFeatures, alle auf Anhieb grün:
wifi-steering(/interface wifi steering) — sichert die TP3.3-Reparatur ab.bridge-port+bridge-vlan(/interface bridge port//interface bridge vlan) — der L2-Layer war bis dahin komplett unüberwacht: der core-Zweig emittierte gar keine Bridge-Sektion, der AP-Zweig nur die VLAN-Tabelle ohne Ports. Jetzt für alle drei Geräteklassen im Template.- 🔑 Bewusst als Literal-Block, nicht aus DCIM abgeleitet. Der As-built trägt akzeptierte Schiefstände (
core ether3ist untagged-Member von VLAN40, hat aberpvid=1;core ether2hängt zusätzlich in VLAN1;branch ether9–23habenpvid=20ohne Membership). Würde manpvidausuntagged_vlangenerieren, meldete die Compliance genau diese bekannten Altlasten als Dauerdrift. Der Literal-Block liefert das, was hier gebraucht wird: Drift-Erkennung gegen den Ist-Zustand. - ⚠️
/interface bridgeselbst bleibt außen vor — trägt die gerätespezifischeadmin-mac, wäre pro Gerät verschieden und ist kein Fleet-Standard. - 🐞 Falle dabei: Compliance vergleicht gegen das letzte BACKUP, nicht gegen das Live-Gerät. Nach dem Steering-Deploy meldete sie erst Drift auf
wifi-configuration/wifi-steering, weil das Backup vom Nachmittag stammte. Reihenfolge nach jeder Geräteänderung: Backup → Intended → Compliance.
-
✅ Compliance-Backlog ABGEARBEITET (2026-08-16, User-Auftrag „beseitige autonom alle Compliance-Drifts") — Ergebnis: 68/68, 0 Drifts.
- Was entfernt wurde (alle vom Typ
extra, also am Gerät vorhanden und in der intended config bewusst nicht vorgesehen): ap1+ap2/ip dns static 192.168.88.1 router.lan(Werks-defconf, zeigte auf eine IP, die es im Netz nicht gibt — der Core hat sein eigenes, korrektesrouter.lan → 10.40.99.1);crs326-branchvlan10 "TEMP Mgmt VLAN10"+10.40.10.2(Bring-up-Interim). Der fünfte Drift,crs326-core10.40.41.211, war schon vorher über den ConfigPlanTP19-vlan1-core-addressgefallen. - Richtung der Beseitigung bewusst „am Gerät entfernen", nicht „ins Template aufnehmen" — das entspricht der Absicht, die im Switch-Zweig von
mikrotik_routeros.j2seit 2026-08-13 schriftlich steht („Bewusst NICHT emittiert … gehoeren entfernt"). Die frühere Zurückhaltung („potenzielle Rettungspfade") ist mit dem User-Entscheid vom 2026-08-16 aufgehoben; der Mgmt-Fallback aus VLAN10 entfällt damit, Rückweg im Notfall = MAC-Winbox am selben Draht. - Weg: 3 manuelle GC-ConfigPlans (
TP22-drift-aps-defconf-dns,TP22-drift-branch-temp-vlan10), Governance gewahrt — kein Direkt-Write. Vorher/system backupje Gerät ({ap1,ap2,branch}-pre-drift-cleanup-20260816.backup). Deploy gestaffelt: erst die beiden APs, am Gerät gegengeprüft, dann branch. - 🔑 Neue Falle gelernt:
POST /plugins/golden-config/config-plan/ist405 Method Not Allowed— das ViewSet ist read-only. ConfigPlans entstehen ausschließlich über den JobGenerate Config Plans(beiplan_type=manuallandet dercommands-TextVar alsconfig_setauf jedem ausgewählten Gerät). Das erklärt, warum es bis dahin kein Skript gab und alle 17 Vorgänger-Pläne per Hand entstanden sind. - ✅ Verifikation am Gerät, nicht am Job: ap1/ap2
list_dns_entries→total: 0bei unveränderten 28 bzw. 3 WLAN-Clients; branch/interface vlan→ nurvlan99,/ip address→ nur10.40.99.2/24,pingvom Core 4/4 mit 0 % Loss./interface bridge vlan/exportbyte-identisch zu vorher — die Gegenprobe darauf, dass kein neuer Drift entsteht (bridgesteht dort statisch als tagged-Member von VLAN10, unabhängig vom SVI). DanachBackup → Intended → Compliance, alle 4 Geräte mit frischem*_last_success_date. - 🛠️ Tooling neu:
nautobot/gc-configplan.py— legt manuelle Pläne über den Job an, löst Device-UUIDs einzeln per Name auf und assertetplan.device.displayundconfig_setgegen das Ziel (die alphabetische Sortier-Falle aus TP21.1 kann damit nicht wiederkommen), verweigert jedesconfig_setmit<<REDACTED>>(Regel 1) und jedeprint-Zeile, kann gestaffelt deployen (--deploy-ids) und kapselt die ReihenfolgeBackup → Intended → Complianceals--refresh-compliance. Dry-Run ist Default.
- Was entfernt wurde (alle vom Typ
-
🔒 GOVERNANCE — verbindliche Deploy-Regeln (festgeschrieben 2026-08-13, VOR dem Scharfschalten von
enable_deploy):- Config Plans werden ausschliesslich feature-/manual-scoped erzeugt, NIEMALS als „full intended". Ein Voll-Push schriebe wörtlich
passphrase="<<REDACTED>>"auf die APs (= alle WLAN-Clients raus, inkl. ~26 Shellys) bzw.private-key="<<REDACTED>>"auf den Core (= WG-Hub tot, FM/DW-Spokes weg). Jede Sektion, die<<REDACTED>>enthält (/interface wifi security,/interface wireguard), ist vom Push generell ausgeschlossen. - Das AP-Template wird NIE zeilenweise auf ein laufendes Gerät gepusht. Die Provisionierung setzt zwischenzeitlich
vlan-filtering=no→ das reisst den vlan99-Mgmt-Pfad ab, die restlichen Zeilen kämen über dieselbe SSH-Session nie an (halb konfigurierter AP). Voll-Reprovisionierung ausschliesslich per Datei-Upload +/import(routeros/.secrets/ap{1,2}-prov-base.rsc). Verschärfend:device-mode=homeblockt auf den hAPsscheduler/fetch→ die übliche Auto-Revert-Absicherung steht dort nicht zur Verfügung; der VLAN1-untagged-Rettungspfad darf nie wegoptimiert werden. - Vor jedem Push ein
/system backupauf dem Zielgerät. Das GC-Backup ist wegen des Scrubbings kein vollwertiges Restore-Artefakt.
- Config Plans werden ausschliesslich feature-/manual-scoped erzeugt, NIEMALS als „full intended". Ein Voll-Push schriebe wörtlich
-
✅ Schritt 4 ENTSCHIEDEN (User 2026-08-13): Variante (a) — keine Secret-Injection, bleibt wie es ist. Ursprünglich geplant war „WLAN-PSKs + WG-Privkey via Nornir-Secrets injizieren"; die Governance-Regel 1 (unten) hat das überholt: Sektionen mit
<<REDACTED>>sind vom Push generell ausgeschlossen, die Secrets werden also nie gebraucht. Konsequenz, bewusst akzeptiert: Secrets bleiben dauerhaft außerhalb von Modell und Push, DR läuft weiter über~/.secrets/+routeros/.secrets/*+routeros/ap1-wg-hub.privkey; „Gerät vollständig aus dem Modell wiederherstellbar" gilt nur ohne Secrets. Die verworfene Alternative (b) hätte Regel 1 aufweichen müssen — ein Render-Fehler hätte dann WLAN bzw. WG-Hub abgeschossen. Damit ist TP22 inhaltlich abgeschlossen. -
Schritte: (1) AP-GC-Template:
mikrotik_routeros.j2umrole == "Wireless AP"-Zweig erweitern (Bridge/vlan-filtering/ether1-Trunk/vlan99-Mgmt/6 SSIDs ohne PSK/L3) → APs komplett aus GC generierbar; (2) Nornir/NAPALM-Adoption aller 4 (SecretsGroup „RouterOS Nornir"; einheitliches Admin-PW seit 2026-08-08 vereinfacht das), Backup/Compliance-Job grün; (3)enable_plan+enable_deployscharf — erst Dry-Run/Plan, dann kontrollierter Push; (4) Secret-Handling WG-Privkey (core) + WLAN-PSKs (bleiben aus dem Git-Template, via Nornir-Secrets injizieren); (5) Datenmodell-Nachträge: branch/core-Ports final, sw1 (außer Betrieb) + cudy1-Status. -
Nutzen: Drift-Erkennung + reproduzierbarer Rebuild jedes Geräts aus dem Modell.
-
Abh.: TP21 ✅ (Plattform/Modell/Templates), TP20 ✅, einheitliches Admin-PW ✅. Danach ist der kritische Pfad frei für TP5 (Deny-by-default) → TP6 (CAKE).
-
✅ Nachtrag 2026-08-23 — Governance-Lücke geschlossen: ComplianceRule
wifi-access-list./interface wifi access-liststand unter keiner Regel: Einträge dort erzeugten keinen Drift und ließen sich nicht als Transaktion führen (gc-transaktion.pyverlangt eine ComplianceRule als--scope). Seitdocs/tp25-pin-s22.shschreibt jeder Messrundgang dort Regeln, und TP25 Fund E (signal-range-Boden) würde dauerhaft genau dort landen. Angelegt pernautobot/ingest-wifi-access-list-rule.py(idempotent), Template um den dokumentierten Abschnitt [6c] ergänzt (nur Kommentare — der Soll-Zustand ist leer, und das ist die Aussage).- 🔢 Zählerkorrektur: 92 → 96, nicht 94. Die Regeln gelten plattformweit, nicht gerätespezifisch: 24 Rules × 4 Geräte. Die Annahme „nur 2 Geräte betroffen" war falsch.
- ✅ Wirksamkeit bewiesen, nicht behauptet (die TP22-Regel „Job-Status ist kein
Wirksamkeitsnachweis"): Test-Eintrag mit einer nicht existierenden MAC gesetzt →
95/96 mit exakt dieser Zeile als
extra→ Eintrag entfernt → 96/96, 0 Drifts. Zusätzlich geprüft:gc-transaktion.pyakzeptiert--scope wifi-access-listjetzt. - 🔎 Nebenbefund beim Start: ein
bridge-vlan-Drift aufcrs326-corestand noch in der Anzeige (ether3 als Trunk), obwohl der Sideboard-Rollback am 08-22 gelandet war. Das Gerät war live korrekt; die Compliance vergleicht gegen das letzte Backup, und das war älter als der Rollback. Mit dem Refresh verschwunden. Merkregel bleibt: bei einem Drift zuerst fragen, wie alt das Backup ist.
TP26 · Gitea #65 — /ip firewall filter unter Drift-Kontrolle
Nachgetragen 2026-08-18. TP26 existierte bis dahin nur als zwei Commits und eine
.rsc— ohne Abschnitt in dieser Datei. Genau die Lücke, die eine frische Session nicht finden kann.
- Auslöser: vor TP26 gab es eine ComplianceRule auf
/ip firewall nat, aber keine auf/ip firewall filter. Die vielzitierte „72/72 grün" sagte über die Firewall damit gar nichts — und das ausgerechnet, während TP5 den Deny-by-default vorbereitete. Der Drop wäre die einzige Regel im Netz gewesen, die niemand überwacht. - ✅ Rule
ip-firewall-filterangelegt,config_ordered=true— bei Firewallregeln ist die Reihenfolge semantisch, nicht kosmetisch. Ergebnis damals: 76/76. Damit war TP5 Etappe 3 entblockt. - ✅ Zweiter Teil: die defconf-Firewall auf beiden APs abgeräumt (
routeros/tp26-ap-firewall-cleanup.rsc). ap1/ap2 trugen je 12 Werksregeln — input-seal, fasttrack, ipsec-Zeilen, sogar „accept to local loopback (for CAPsMAN)". Inert, weil ein reiner AP nichts routet. Entscheid: abräumen statt ins Template schreiben — sonst erklärt man Werksmüll zur Absicht. Dasselbe Argument hat 2026-08-18 auch die alten WLAN-Objekte auf den APs erledigt (TP28). - 📌
--asserthat dabei zwei Fehlschläge gefangen, die der Job-Status als Erfolg gemeldet hätte. Seitdem ist die Gegenprüfung am Gerät fester Bestandteil vongc-manual-plan.py. - Abh.: TP22 ✅. Direkte Folge: TP5 E3/E4.
TP27 · Gitea #66 — RouterBOOT-Firmware auf 7.24 nachziehen
Nachgetragen 2026-08-18. Auch TP27 hatte keinen Abschnitt — die Arbeit steckt in Christophs Commit
b93514aplusrouteros/tp27-routerboot-firmware-724.rscunddocs/routerboot-firmware-klickanleitung.md.
- Kontext: Christoph hat alle vier MikroTik selbst auf RouterOS 7.24 stable gehoben (core/branch 7.19.5 → 7.24, ap1/ap2 7.23.2 → 7.24). Offen blieb die zweite Hälfte jedes MikroTik-Upgrades: die RouterBOOT-Firmware hängt danach zurück.
- 🔑 Die Falle, wegen der es ein eigener TP ist:
/system routerboard upgradeschreibt die Firmware nur — wirksam wird sie erst beim nächsten Reboot, undcurrent-firmwarezeigt bis dahin weiter den alten Wert. Wer direkt nach dem Befehl prüft, hält den Schritt fälschlich für gescheitert. Reihenfolge also: schreiben → gezielt rebooten →current-firmwaregegenprüfen. - ⚠️
/system routerboard upgrade*steht auf der MikroMCP-Deny-Liste (zu Recht — es schreibt den Bootloader). Der Weg führt über Golden Config; der Reboot dann übersshpass/MikroMCP. - ✅ Abnahme 2026-08-18: auf allen vier Geräten
current-firmware = upgrade-firmware = 7.24. - Abh.: keine. Berührt TP28 insofern, als CAPsMAN erst ab 7.2x das neue
/interface/wifimitbringt.
TP28 · Gitea #18 — WLAN über CAPsMAN auf crs326-core
Der Volltext steht seit dem 2026-08-30 wieder in
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.
TP-R · Gitea #67 — Router-Capabilities-Sweep — docs/research/routeros-capabilities.md)
- Leitsatz: nativ vor Container, NAS vor Router (128MB-Flash-Limit).
- Sofort nativ (~0 RAM): RoMON · Netwatch · Scheduler + Auto-Backup/Mail · SNMP→externes Monitoring · mDNS-Repeater · spectral-scan · 802.11r/k/v (Fast-Roaming statt Mesh) (die Sweep-Fassung nannte hier CAPsMAN — das ist seit 2026-08-08 abgeschafft; 11r/k/v läuft standalone weiter, s. TP3/TP3.3) · Back-to-Home/WireGuard.
- Auf NAS: FreeRADIUS(+LDAP) · NPM · icinga/Grafana · CF-Tunnel.
- Weglassen: LoRa (keine HW) · OpenFlow · CALEA · ZeroTier (CPU-Fresser bis ~60 % → WireGuard) · lokales
dude. - ✏️ Korrektur Reverse-Proxy: RouterOS 7.22+ HAT einen nativen (
/ip/reverse-proxy, ACME/SNI) — aber ersetzt NPM NICHT (kein WebSocket/gRPC/Sticky, nur IPv4-Backends, TLS frisst Router-CPU) → NPM bleibt auf NAS. - Speist TP8/9/11/12.
TP25 — Kondensat (aktiver Stand bis 2026-09-15, abgeschlossen)
✅ TP25 ist ABGESCHLOSSEN (2026-09-15). Platzierung final (ap1 Sideboard · ap2 Technik UG · ap3 Technik OG), Fund E geschlossen (
7.24.1war die Ursache, nichtft-over-ds), alle vier Handoff-Punkte aufgelöst, Gitea #17 closed. Die 394-Zeilen-Herleitung (Messchronik A–G) steht weiter unten unter TP25 — Langfassung.
TP25 · Gitea #17 — WLAN-Stabilisierung — ap2-UNTERPUNKT ✅ WIDERLEGT 2026-09-14 (In-situ, Handoff): ap2 sendet auf 2 m mit −49…−51 dBm, stabil, 0 Roams — Hardware sauber, kein Tausch begründet. Terrasse = 5-GHz-Zellkante (−76…−81 vs. 2,4 GHz −65…−73), Thrash nur in der Band-Überlappungszone −70…−77. Hebel „Access-List-Band-Boden" in der Machbarkeitsprüfung GESCHEITERT (kein band-Property, cap-wifiN-Rejoin-Falle) — s. Block unten** — FUND E ✅ GESCHLOSSEN 2026-09-02: die Abschlussmessung ist ruhig (4 reauth in 8,6 h, 0 Ausfälle, Verlauf 218→40→4) ⇒ 7.24.1 (TP27) war die Ursache, nicht ft-over-ds. Hebel 1 widerlegt+zurückgebaut, Hebel 2–4 entfallen, kein Geräte-Write (Handoff) · Kern erledigt: 🟢 (2026-08-22) Dead Spot Terrasse repariert (43 % → 9 % Verlust, 20,4 s → 1,0 s). Fund F ✅ aufgelöst (08-24, geräteseitig — kein Netzfehler), 5-GHz-Umfeldscan ✅ (08-24), Kanalplan für AP 3 ✅ gerechnet. Nicht mehr kritischer Pfad — Sammel-TP für Christophs Beobachtungen 1–6
📚 Kondensiert am 2026-08-23 (Doku-Session, Punkt F). Dieser Abschnitt war mit 394 Zeilen 18 % der Datei. Die Langfassung steht vollständig und unverändert im Archiv:
teilprojekte-archiv.md→ TP25 (Langfassung) — Messchronik (A)–(G), Funde A–E im Volltext, die beantworteten Fragen (Beobachtung 5, ch149-Herkunft,2ghz-g, Deckenmontage), Umsetzungsreihenfolge mit allen Deploy-Gotchas. Hier steht: Stand, Offenes, Merkregeln. Wer an TP25 weiterarbeitet, kommt mit diesem Abschnitt aus; wer wissen will warum etwas so entschieden wurde, liest die Langfassung.
Stand 2026-09-15 — AP-Zuordnung DEFINITIV geklärt, Tausch-Befund ap2↔ap3 (Handoff). Positionen per IP+MAC+Switch-Port (MNDP/Bridge-Host/Port-Link) live belegt: ap1 = Sideboard/Wohnzimmer (core ether3), ap2 = Technik UG (core ether21), ap3 = Technik OG (branch ether24). Der geplante Tausch (ap1↔ap3, cAP ax → Sideboard) hat faktisch ap2↔ap3 gedreht — ap1 blieb stehen, der cAP ax steht jetzt in OG. MAC-Korrektur: ap2 ether1 ist :39, nicht :3A (:3A = Bridge/Mgmt-MAC). Rundgang (natürlicher Zustand, 1-s-Takt): 0 Disconnects, −45…−77 dBm, Roaming über alle 3 APs; Terrasse −58 stabil (jetzt cAP ax/OG, 2,4G), ap1 nur kurz gestreift. ap1-Aus-Test: Main-Client voll abgedeckt (tiefster Wert −80), alle 27 IOT kehren zurück, aber ~4 Wohnzimmer-IOT marginal −77…−80 ⇒ ap1 technisch redundant, nicht ausfallkritisch. ap1 wieder an (Revert). Aufgelöst 2026-09-15 (Steering-Handoff §6): (1) ap1 bleibt am Sideboard, (2) Tausch-Korrektur verworfen — die Prämisse „Sideboard-AP deckt die Terrasse" war widerlegt (ap1 = Innenraum-König, cAP ax gehört nach OG), (3) Drei-Räume-Schatten verworfen (Signal beim Rundgang gut), (4) Doku-Drift ✅ geschlossen. Platzierung final: ap1 Sideboard · ap2 UG · ap3 OG.
Merke: no cached PMK im Log ≠ FT-Problem — es tritt auch auf ft=no-SSIDs (IOT) auf und ist ein harmloser PMK-Cache-Miss (voller Handshake statt Fast-Reassoc). Der 09-15-Abriss war die Terrassen-Bandkante, nicht PMK/FT.
Stand 2026-09-14, 20:05 — ap2-In-situ: Hardware entlastet, Terrasse = 5-GHz-Zellkante, Band-Boden nicht sauber ausdrückbar (Handoff). Live-Session auf der Terrasse (Christoph kooperierte physisch — der Test, der am 08-31 „nachts nicht möglich" war): das Fund-E-iPhone flappte 18:53–19:18 ~30×, fast ausschließlich ap2-5G ↔ ap2-2,4G (−68…−81), mit 3 Abwürfen (2 Call-Aussetzer). Vor ap2 (1–2 m): **−49…−51 dBm,
2 min stabil, 0 Roams** ⇒ der offene Verdacht „ap2 RF/Antenne/HW" (23:02-Befund, 2 m/−80) ist in situ widerlegt — der 23:02-Wert reproduziert sich seit dem 09-04-Kanalplan (5300/5320, tx-power 18 live) nicht mehr. Am Terrassenplatz ist 2,4 GHz klar besser (−65…−73 vs. 5 GHz −76…−81) und das Telefon dort ruhig (36 s im 1-s-Takt, 0 Roams) — es thrasht nur in der Überlappungszone −70…−77 beider Bänder; zusätzlich client-getrieben (floh 19:44 selbst von −52 auf 2,4/−77; Steering hat keine Schwellen, der AP drängt nichts). Mit
ft=noist jeder Roam ein spürbarer Voll-Reconnect ⇒ so sterben Anrufe. Hebel „Access-List-Boden < −76 auf 5G": Machbarkeitsprüfung negativ —/interface/wifi/access-listhat keinband-Property, Interface-Scoping bricht am cap-wifiN-Rejoin, SSID-/MAC-Scope träfen 2,4 GHz mit (Schlafzimmer −84 ⇒ Lockout). Nicht umgesetzt. Verbleibende Hebel: (1) ✅ DURCH 2026-09-14, 20:30 Uhr —ft=yes ft-over-ds=yesuniform aufsec-main(Ruecknahme der 09-04-Entscheidung; Go per Fragenrunde nach Dry-Run). Weg: Template-Edit +push-gc-template.py(GC-Commit744a17e3) →--refresh-compliance(Driftwifi-securitywie erwartet) →gc-manual-plan.py --deploy(Planb1135f3e, Completed, Asserts gruen; ein Polling-Timeout am Skript war folgenlos — Geraet stand bereits auf ft=yes) → Refresh: 140/140, 0 Drifts. CAP-Abnahme: keine Inline-Overrides auf ap1/ap2/ap3. Commands-File:docs/transaktionen/TP25-ft-yes-secmain.commands.rsc. Abnahme ✅ DURCH (2026-09-14, 20:33–20:34 Uhr, live): Anruf auf der Terrasse ueberstand fuenf Band-Wechsel binnen 60 s (nurroamed to, keinedisconnectedmehr im Fenster — Christoph: „call steht"). (2) Deckungsfix Variante 3 (ap1-5G erreichte die Terrasse mit −64) — beendet das Springen selbst. Nachtrag 20:37: ein Totalverlust anderer Klasse (Roam auf ap1-2,4 bei −89, danach iOS-Aufgeben ohne jeden Reconnect-Versuch; identisch schon 19:01 mit ft=no gesehen) — keine ft=yes-Regression, sondern der strukturelle Rest. Wechselrichter/DTU (Hoymiles HMS-800W-2T, geht mit der Sonne an/ab, 09-14: 07:09–19:35): nachts unbeteiligt; tagsüber ~5:05-Zyklus (connect/connection lost/reconnect + DHCP-Churn) auf ap2-2,4/ch11 bei −53. Messplan „DTU vs. Terrasse" angelegt (Issue #17, Kommentar #225): Referenz-Client auf ch11 pinnen (tp25-Methodik), 30–60 min Ping, Korrelation gegen die 5:05-Taktmarken. ⚠️ Korrektur 09-14 abends (Kommentar #227): Der urspruenglich genannte Hebel „OpenDTU/AhoyDTU-Dongle" existiert fuer DASSES Geraet NICHT — HMS- XXXXW-2T (W = eingebaute DTU „DTUBI", protobuf-Protokoll) wird von AhoyDTU/OpenDTU nicht unterstuetzt (lumapu/ahoy#1189 seit 09-2023 offen; Christophs eigene AhoyDTU nachweislich inkompatibel; nur die Nicht-W-Variante HMS-800-2T ginge per CMT2300-Funk). Die lokale Ebene (hms-mqtt-publisher = „hmsmqtt", dtuGateway, ha-hoymiles-wifi) redet mit der internen DTU uebers Netzwerk — keines davon nimmt die DTU von der Luft, hmsmqtt pollt sogar zusaetzlich. Einziger Airtime-Hebel bleibt DNS-Hoheit ueber die Cloud, von Christoph bewusst zurueckgestellt (Cloud- Aufzeichnungen noch benoetigt, bis hmsmqtt + WLAN stabil); ob eine DTU ohne Cloud ruhiger oder gespraechiger wird, ist selbst eine offene Messfrage. Pin auf anderen AP kontraindiziert (−53 direkt an ap2); 5-Min-Takt ist S-Miles-Telemetrie per Design, kein Ethernet an der DTU-WLite. ✅ Netzwerk-Mechanismus geklaert (09-14, Nacht; Issue #17, Kommentar #228): Der Fund-F-5:05-Zyklus ist das Cloud-Recovery-Verhalten der DTU. Wireshark-Analyse (hms-mqtt-publisher PR #110, HMS-800W-2T): lokaler Poll <30 s resettet den Countdown und setzt Cloud-Updates aus; nach 4–5 min erfolgloser Cloud-Updates startet die DTU eine neue TCP-Session — und dabei (unser Log-Beweis 09-14) eine vollstaendige WiFi-Disassoziation inkl. DHCP-Churn. Die heute gemessenen Zyklus-Abstaende decken sich mit dem Befund aufs Minutenkomma. Ursache war hmsmqtt mit 30 500 ms (Grenzzone); DTU-Firmware aelter, hmsmqtt funktioniert (⇒ #134-Key-Rotation-Falle nicht primaer). Hebel = Poll-Rate, nicht DNS-Hoheit: Christoph hat 30500 → 45000 ms gesetzt (09-14 abends; Community-Wert, 10 Monate stabil). ✅ Verifikation DURCH (09-15, 12:11; Issue #17, Kommentar #230): DTU online seit 06:41:49, uptime 5 h 29 min, 0 Disconnects (Vergleich 09-14 mit 30,5 s: fuenf Zyklen in den ersten 18 min). Die DTU sitzt heute auf ap3-2,4 (cap-wifi4-virtual1, −49; cap-Karte unveraendert, Attribution belastbar) — also aktuell auch vom Terrassen-Band ch11 weg. Fund F ist damit abgeschlossen — Ursache war die DTU-Cloud-Recovery, getriggert durch hmsmqtt-Polling-Kollision. Messplan #225 ist gegenstandslos (der zu messende Effekt existiert nicht mehr); eine ch11-Tagzeitmessung bleibt nur sinnvoll, falls die Terrasse tagsueber weiterhin Call-Probleme zeigt. 📅 terminiert (Issue #17, Kommentar #232): Deckungsfix Variante 3 — Umsetzung 2026-09-15/16 (Christoph: „heute oder morgen"): Deckenstrahler an den guten Platz, verdrängter hAP in den Drei-Raeume-Schatten (Schlafzimmer −84,6/38 %, Bad −82,3/24 %, Kueche −82,0/23 % laut 08-22-Messung). Vorher-Messung Terrasse (Referenz 09-14: 5 GHz −76…−81, 2,4 GHz −65…−73) → Umsetzung → Nachher-Messung + Anruf-Abnahme; Kanalplan (09-04) bleibt unberuehrt, nur Platzierung aendert sich; Config-Aenderungen nur ueber den GC-Weg. Offen vor Ort: Zielraum fuer den verdraengten hAP (PoE/Steckdose) und ap1-Uplink-Thema (Sideboard →core ether3) mitdenken. Randnotizen: ap1 „FUNKSTILL" im CLAUDE.md ist überholt (dient live, Radar-Event 16:51 auf 5280 sauber abgehandelt); Template-Abschnitt [6c] („Fund E WIEDER OFFEN", Stand 08-30) ist inhaltlich überholt — beim nächsten Template-Edit mit aktualisieren, kein separater Edit nur für den Kommentar.
Stand 2026-08-22, 23:30 — die Terrasse ist repariert. Erster Lauf mit beiden Ping-Strecken
(tp25-runde-20260822-2330-auswertung.md): 43 % Verlust /
20,4 s längste Lücke (08-21) → 9 % / 1,0 s bei gleichem Gerät und gleicher Rolle. Wirksam war das
Anheben von ap2 auf 2,5 m; 1,0 s liegt unter der Hörbarkeitsschwelle im Call. Der Dead Spot, der
TP25 seit dem 08-20 getragen hat, ist damit weg.
🔎 Kernbefund, der bleibt: das Netz ist gut, die Redundanz ist es nicht. Die frei roamende Referenz hat in 17 von 21 Raumabschnitten 0 % Verlust; der Gegen-AP liefert Schlafzimmer −84,6/38 %, Bad −82,3/24 %, Küche −82,0/23 %, Terrasse −78,7/19 %. Fällt ein AP aus, ist die halbe Wohnung „verbunden, aber tot". ⇒ Ein dritter AP ist nach Christophs eigener Randbedingung derzeit NICHT begründet — er kaufte Redundanz, keine Abdeckung. Das ist eine andere Frage und Christophs.
Beide vormals offenen Punkte sind am 2026-08-24 abgearbeitet — Fund F ist aufgelöst, der 5-GHz-Umfeldscan gefahren und der Kanalplan für einen dritten AP gerechnet. Was von TP25 bleibt, ist Umsetzung bei Bedarf, keine offene Frage:
-
✅ Fund F — GEMESSEN UND AUFGELÖST (2026-08-24): kein netzseitiges Phänomen. Kollektor am Manager (
/interface wifi registration-table, 15-s-Takt, 29 Samples über 7,7 min, 28 Clients), Rohdatendocs/messdaten/tp25-fundf-20260824.log. Von den drei Kandidaten sind zwei erledigt, einer bleibt — und die zwei fielen ohne Wartezeit:Kandidat Ergebnis woran es hängt (b) DHCP- lease-timegegen die Periode❌ tot dhcp-v30fährtlease-time=1d→ Renew bei 12 h. Kann 5:05 nicht erzeugen. Eine Abfrage, keine Messung.(a) periodischer VAP-Re-Apply ❌ tot Ein Re-Apply wirft alle Clients des VAP gleichzeitig. Auf cap-wifi4-virtual1standen zeitgleich drei Clients bei 16 h 51 min Uptime, 25 von 28 über 6 h. Mit einem 5-Minuten-Takt ist das unvereinbar.(c) das Gerät selbst 🟡 bleibt Der einzige Client, der im Fenster überhaupt neu verband. 🔑 Der entscheidende Punkt an der Beweisführung: dafür braucht es die vier Zyklen nicht. Ein einziges Sample mit 16 h 51 min Uptime auf genau dem VAP, der angeblich alle 5:05 abwirft, widerlegt (a) vollständig. Die Fensterlänge begrenzt nur, was man über abwesende Geräte sagen kann.
🔴 Und genau die sind abwesend: die beiden Fund-F-MACs gibt es gerade nicht.
38:A5:C9:C0:73:1E(10.40.30.178) und38:A5:C9:BC:33:31(10.40.30.179) stehen in/ip arpaufstatus=failed, haben keine DHCP-Lease, stehen nicht in der Registration-Table und sind auch HA unbekannt (keindevice_trackerzu diesen MACs). ⇒ Das Phänomen ist an diesen Geräten derzeit nicht reproduzierbar, weil die Geräte weg sind. 📌 Merkregel — dieselbe wie beim P750W: bevor ein periodisches Trennen als Funk- oder Konfigurationsfehler untersucht wird, erst prüfen, ob die betroffenen Geräte überhaupt da sind. Beim Drucker war die Fehldiagnose „Power-Save", hier wäre sie „VAP-Re-Apply" geworden.⇒ Fund F wird geschlossen: was auch immer der 5:05-Takt war, er lag geräteseitig, und die zwei betroffenen Geräte sind vom Netz. Netzseitig ist nichts zu tun. Nicht erneut aufgreifen, solange
.30.178/.179nicht wieder da sind und das Muster erneut gemessen wird.🟡 Nebenbefund mit Substanz — der DTU ist der einzige Wackelkandidat, den es wirklich gibt.
54:F2:9F:12:51:F0(DTU/Wechselrichter, aufcap-wifi4-virtual1= ap1) war der einzige Client mit einem Uptime-Rücksetzer: 43 min Sitzung, dann weg für ein Sample, dann wieder da — bei −52 dBm, also bei tadellosem Signal. Das ist derselbe Mechanismus, der schon die TransaktionTP17.1-dtu-pin-ap2begründet hat: ein ESP hat EIN Radio, sein eigener AP und die STA-Verbindung teilen sich den Kanal. Periode hier 43 min, nicht 5:05 — es ist nicht Fund F, aber es ist echt. ⇒ Gehört zur ohnehin vorgesehenen Neubewertung des DTU-Pins, sobald der Kanalplan steht (s.o.).📜 Ursprüngliche Fund-F-Formulierung (2026-08-22)
- 🟡 Fund F — IoT-Clients trennen exakt alle ~5:05 bei gutem Signal (−59 dBm, vier Messpaare,
auf 3 s reproduzierbar → ein Timer, kein Funk). Muss am Manager nachgemessen werden, die
AP-Tabellen sind unter CAPsMAN leer. Kandidaten und der Test, der sie trennt:
(a) periodischer VAP-Re-Apply (Fund D war die Ursache → prüfen, ob es nach dem Fix weg ist);
(b) DHCP-
lease-timeder beiden MACs (38:A5:C9:C0:73:1E,38:A5:C9:BC:33:31) gegen die Periode legen; (c) das Gerät selbst mit 5-min-Duty-Cycle → dann bleibt es unverändert. 🚫 Nicht die alte Power-Save-Merkregel wiederbeleben — die ist am 2026-08-13 als Fehldiagnose zurückgezogen (ref_wifi_powersave_multicast).
- 🟡 Fund F — IoT-Clients trennen exakt alle ~5:05 bei gutem Signal (−59 dBm, vier Messpaare,
auf 3 s reproduzierbar → ein Timer, kein Funk). Muss am Manager nachgemessen werden, die
AP-Tabellen sind unter CAPsMAN leer. Kandidaten und der Test, der sie trennt:
(a) periodischer VAP-Re-Apply (Fund D war die Ursache → prüfen, ob es nach dem Fix weg ist);
(b) DHCP-
-
⚖️ Entscheidung 5 GHz auf 20 MHz (statt heute 20/40) — ✅ 5-GHz-Umfeldscan durchgeführt 2026-08-24, Empfehlung: NICHT verschmälern, Entscheidung an einen Auslöser hängen. ⚠️ 2,4 GHz NICHT vorschnell drosseln — dort hängen ~20 IoT-Geräte.
Messung (
/interface wifi scanam Manager, cap-wifi3 = ap1 / cap-wifi1 = ap2, 10–12 s):vom Radio auf fremdes 5-GHz-Netz Kanal Signal Abstand zum eigenen AP ap1 (5180/Ce) Drei_H288A_5G_acHG5745/ac/80 MHz −86 dBm 19 dB darunter ap2 (5220/Ce) LiwestBB93-5G5200/ac/80 MHz (Block 5180–5240) −89 dBm 24 dB darunter ⇒ Das 5-GHz-Band ist an beiden Standorten praktisch leer. Genau ein Fremdnetz je AP, beide rund 20 dB unter dem eigenen Pegel. Der Nachbar
LiwestBB93-5Gliegt mit 80 MHz zwar formal über beiden unserer Blöcke — bei −89 dBm ist das ohne Wirkung.🎯 Warum das gegen 20 MHz spricht — die zwei üblichen Gründe treffen hier nicht zu:
- Fremdinterferenz: existiert nicht (−86/−89). Ein schmalerer Kanal hätte nichts abzuwehren.
- Selbstüberlappung: existiert nicht. ap1
5180/Ce= ch36+40, ap25220/Ce= ch44+48 — überlappungsfrei (Fund C, 08-17). - Bleibt allein das +3 dB Link-Budget — und das ist zum guten Teil schon vorhanden: in einem 40-MHz-BSS sendet die Ratenanpassung an schwache Clients ohnehin auf dem Primärkanal in 20 MHz. Den Ceiling zahlen aber alle Clients dauerhaft. Der Nutzen geht an die, die ihn schon haben.
- Und es löst das gemessene Problem nicht: die offenen Schwachstellen sind die Redundanz-Lücken (Schlafzimmer −84,6 / 38 %, Bad −82,3 / 24 %) am Gegen-AP. +3 dB macht aus 38 % Verlust keine 0 % — das ist eine Platzierungs-/AP-Zahl-Frage, keine Kanalbreiten-Frage.
🔑 Der echte Auslöser ist die AP-Zahl, nicht die Interferenz — und das ist der Grund, die Entscheidung jetzt zu treffen statt sie offenzulassen. Beide Kanäle stehen hart in Band A (
ch-5g-ap1=5180,ch-5g-ap2=5220, keinskip-dfs-channels), und Band A hat unter ETSI genau 4 × 20 MHz = 2 × 40 MHz. Mit zwei APs ist es damit exakt aufgebraucht:Szenario bei 40 MHz bei 20 MHz 2 APs (heute) ✅ passt genau, überlappungsfrei ✅ passt, +3 dB, halber Ceiling 3.–4. AP ❌ Band A voll ⇒ nur mit DFS (Band B ch52–64: Radar-Events, 60 s CAC) ✅ 4 saubere Kanäle, kein DFS ⇒ Empfehlung: 20/40 MHz beibehalten. Die Verschmälerung ist heute ein Preis ohne Gegenwert. Sie wird fällig, sobald ein dritter AP dazukommt — dann lautet die Wahl nicht mehr „20 gegen 40", sondern „20 MHz flottenweit" gegen „DFS akzeptieren", und dafür ist 20 MHz die ruhigere Antwort. Ein Zwischenweg existiert (ap1 behält 40 MHz, AP 2+3 fahren 20 MHz auf 5220/5240) und braucht ebenfalls kein DFS. 📌 Damit ist dieser Punkt entscheidungsreif und an einen Auslöser gebunden statt offen.
📐 Kanalplan für den dritten AP ▸ gerechnet 2026-08-24, DFS vom User genehmigt
User-Vorgaben (2026-08-24): 20/40 MHz bleibt · DFS ist genehmigt, soll aber auf ap1 oder ap2 liegen, nicht auf dem Neuen · der Neue ist ein MikroTik-Deckenstrahler mit ax · möglicherweise kommt er an die Stelle eines der bisherigen APs · der vorhandene Outdoor-AP bleibt konzeptionell außen vor.
Das Kanalbudget unter ETSI (Indoor), als Rechnung statt als Gefühl. Ein 40-MHz-Block darf keine
Bandgrenze überschreiten — [48+52] ist deshalb unmöglich, und daran hängt die ganze Knappheit:
| Band | Frequenzen | Kanäle | 40-MHz-Blöcke | DFS | EIRP |
|---|---|---|---|---|---|
| A | 5150–5250 | 36/40/44/48 | 2 (5180/Ce, 5220/Ce) |
nein | 23 dBm |
| B | 5250–5350 | 52/56/60/64 | 2 (5260/Ce, 5300/Ce) |
ja + TPC | 23 dBm |
| C | 5470–5725 | 100–140 | 5 | ja + TPC | 30 dBm, outdoor erlaubt |
Heute belegen zwei APs mit 40 MHz ganz Band A. Genau das macht den dritten AP zur Bandfrage — und mit genehmigtem DFS ist sie lösbar, ohne irgendwo auf 20 MHz zu gehen.
Empfohlene Zuordnung (3 APs, alle 40 MHz):
| AP | Rolle | Kanal 5 GHz | Band | DFS | 2,4 GHz |
|---|---|---|---|---|---|
| cAP ax (neu) | Primär, beste Position | 5180/Ce (36+40) |
A | nein | 2437 (ch6) |
| ap1 hAP ax² | Sekundär | 5260/Ce (52+56) |
B | ja | 2412 (ch1) |
| ap2 hAP ax² | Sekundär | 5300/Ce (60+64) |
B | ja | 2462 (ch11) |
| — | Ausweichspur, frei halten | 5220/Ce (44+48) |
A | — | — |
- Warum Band B und nicht Band C für die zwei DFS-Radios: gleicher 23-dBm-Deckel wie Band A (kein Leistungssprung zwischen den APs) und CAC 60 s statt 600 s — die 10-Minuten-Prüfung gilt im Wetterradar-Bereich von Band C. Band C bleibt damit frei für den Outdoor-AP, wo seine 30 dBm auch hingehören.
- Warum der Neue das nicht-DFS-Band bekommt: DFS kostet 60 s CAC bei jedem Boot und jeder Provisionierung plus einen erzwungenen Kanalwechsel bei Radar-Erkennung. Diese Kosten gehören auf die Radios, deren Fläche von einem anderen AP mitgetragen wird — nicht auf den bestplatzierten. Christophs Instinkt ist hier richtig.
- 2,4 GHz fällt nebenbei sauber: ch1/6/11 ist mit drei APs erstmals vollständig überlappungsfrei möglich (heute 1/11 mit einer Lücke in der Mitte).
🔴 Zwei Fallen, ohne die der Plan teurer wird als er aussieht:
- Eine hart gepinnte Frequenz macht DFS zum Single Point of Failure.
ch-5g-ap1/-ap2tragen heute je genau einen Wert (frequency=5180bzw.5220). Bei einer Radar-Erkennung muss das Radio den Kanal verlassen — hat es keinen zweiten konfiguriert, bleibt das 5-GHz-Funk dieses APs unten. ⇒ Für DFS gehört in das Channel-Objekt eine Liste (z.B.frequency=5260,5280,5220), damit der AP neu wählen kann. Das ist der Unterschied zwischen „DFS ist unkritisch" und „DFS kostet einen AP". - Vor dem Umzug die erreichte Sendeleistung messen — das ist Fund B, nochmal. Band B/C verlangen
TPC; ohne TPC sinkt der erlaubte EIRP um 3 dB. TP25 Fund B war exakt dieses Muster: 18 dBm gesetzt,
9 dBm gesendet, weil ch149 unter ETSI leistungsbegrenzt ist. ⇒ Diskriminierender Test, bevor
irgendwas gekauft oder umgezogen wird: ap2 testweise auf
5260, dann/interface wifi monitorlesen und die tatsächlichetx-powergegen die heutigen 18 dBm auf5220stellen. Kostet eine Config-Transaktion und zehn Minuten, und entscheidet, ob der Plan trägt.
⚖️ Zur Platzierung — die Messung widerspricht dem Aufstellen an einer bisherigen Stelle. Die Referenzmessung vom 08-22 sagt: 17 von 21 Raumabschnitten haben 0 % Verlust. Zusätzliche Abdeckung ist damit wertlos. Der ganze Wert liegt im Gegen-AP: Schlafzimmer −84,6 / 38 %, Bad −82,3 / 24 %, Küche −82,0 / 23 %.
| Variante | was sie bringt |
|---|---|
| Neuer AP an bisheriger Stelle | besseres Deckenbild an einem Punkt, der schon funktioniert. Die Drei-Zimmer-Lücke bleibt unverändert — gleicher Standort, gleicher Schatten. |
| Neuer AP an neuer Stelle (Richtung Schlafzimmer/Bad/Küche) | schließt die Lücke, also genau die Redundanz, die gekauft werden soll. |
| 🎯 Beides: cAP ax an die bisherige Stelle, der verdrängte hAP ax² wandert in den Schatten | bestes Deckenbild dort, wo die Clients sind, und eine zweite Option in den drei Räumen. Braucht keine vierte Antenne, nur eine Steckdose/PoE im Zielraum. |
⇒ Empfehlung: Variante 3. Sie ist der einzige Weg, bei dem der Deckenstrahler an den guten Platz darf, ohne dass die gemessene Schwäche unangetastet bleibt.
- Voraussetzung Neuer AP: PoE-in am Zielort (die cAP-ax-Reihe hat einen Gigabit-PoE-Port, kein
Netzteil im Lieferumfang üblich) und ein Trunk mit VLAN 10/30/40/50/90/99 wie bei ap1/ap2. Der AP
läuft auf
wifi-qcomund tritt damit als regulärer CAP dem Manager bei — kein neues Modell im GC, nur ein weiteres Gerät plus zweichannel-Objekte. ⚠️ Exaktes Modell vor dem Kauf prüfen (cAP axvs.cAP XL ax) — beide sind ax/wifi-qcom, unterscheiden sich in Abdeckung und Preis. - Wenn später doch der Outdoor-AP dazukommt: er gehört nach Band C (30 dBm, outdoor zulässig);
Band A/B sind dann von den drei Indoor-APs belegt und die Ausweichspur
5220/Ceist aufgebraucht.
🔴 Fund E — WIEDER GEÖFFNET 2026-08-30: die Wiedervorlage-Bedingung ist eingetreten
Fund E war „abgestuft, NICHT umsetzen" mit einer ausdrücklichen Bedingung: „Erst wieder aufgreifen, wenn ein Sticky-Fall erneut gemessen ist." Am 2026-08-30 ist genau das passiert.
Auslöser war eine unabhängige User-Meldung, nicht die Suche danach: „die letzten Tage/Wochen regelmäßig mit dem iPhone den WiFi-Link verloren obwohl bester Kontakt. Ich lande auf 5G und nicht am alten AP oder dem anderen." 🔑 Auf Mobilfunk zu fallen ist kein Roaming-Problem — bei schlechtem Roaming bliebe das Telefon im WLAN und wäre nur langsam. Es heißt: die Assoziation ist gestorben und die Neuanmeldung gescheitert.
Neue Messung (Manager-Log, 2026-08-30): dasselbe iPhone F2:62:4C:E1:AF:09 machte 16
Bandwechsel in 20 Minuten zwischen cap-wifi5 (ap3, 5 GHz) und cap-wifi6 (ap3, 2,4 GHz),
zweimal im Abstand von einer Sekunde, bei −53 … −81 dBm. Kurz darauf dasselbe zwischen
cap-wifi1↔cap-wifi2 — also an ap2. ⇒ Nicht ap3-spezifisch, sondern an jedem AP.
Das deckt sich mit der Ursprungsmessung vom 08-20 (sechs Flaps in 22 Minuten) und mit
…@wifi2 disconnected, not responding, signal strength −47 — Abbruch bei ausgezeichnetem Signal.
⚠️ Zwei Symptome, die NICHT gleichgesetzt werden dürfen: die Band-Oszillation (beide Male gemessen) und der Abbruch „not responding" bei gutem Signal. Christophs Beschreibung passt auf das zweite. Ob dieselbe Ursache dahintersteht, ist offen.
Zeitachse: am 2026-08-17 liefen TP28 (CAPsMAN-Cutover) und TP27 (7.24) gleichzeitig. Vorher
waren ap1/ap2 Standalone ohne Steering und ohne Neighbor-Group, und sec-main fuhr
ft=yes ft-over-ds=no. Beides änderte sich an diesem Tag. Das Beschwerdefenster deckt sich —
Korrelation, kein Beweis.
Was die MikroTik-Doku dazu hergibt (recherchiert 2026-08-30):
transition-thresholdDefault −80 dBm,-time10 s,-request-period30 s,-count3. Unsere Steering-Objekte setzen nichts davon. Bei −53…−74 dBm wird das iPhone also kaum Transition-Kandidat ⇒ unsolicited BTM scheidet als Treiber weitgehend aus.- WPA3 + 802.11r: die Doku nennt nur „802.11r geht nicht über OWE". Eine WPA3-PSK/FT-Inkompatibilität steht dort nicht — sie kursiert in Foren. Hypothese.
2g-probe-delay: dokumentiertes Band-Steering (2,4-GHz-AP ignoriert die ersten 3 Probe-Requests je Client pro 60 s). Bei uns nicht gesetzt.- Bei dynamischen Neighbor-Groups markiert RouterOS 5 GHz als preferable. Wir nutzen die
statische Gruppe
bf-mainüber beide Bänder; ob die Präferenz dort greift, sagt die Doku nicht ⇒ offene Frage.
✅ Erledigt 2026-08-30: die Beweislage ist jetzt dauerhaft. wireless- und caps-Logs gehen in
den Kollektor (10.40.20.18:514, dieselbe Senke wie TP5), und /system logging steht seit heute
unter der 27. ComplianceRule system-logging — vorher war der Block unter keiner Regel und im
Template gar nicht vorhanden. Vorher lief alles nur in einen 75-Zeilen-Ringpuffer.
🔴 NACHTRAG 2026-08-31 — die Daten sind da, und sie kippen die Reihenfolge. Nach einer Nacht
Logging: 559 wireless-Zeilen, 439 davon (79 %) vom iPhone. Entscheidend ist die Trennschärfe —
reauthenticating tritt 93 von 93 Mal bei genau einem Client auf (dem iPhone) und 93 von 93
Mal auf genau einer SSID (dirtyvader-main). Was main von den anderen fünf unterscheidet, ist
ein einziges Attribut: ft=yes ft-over-ds=yes. Dieselben APs, dieselben Radios, derselbe
Zeitraum — die SSIDs mit ft=no zeigen null Ereignisse. Das ist eine saubere Kontrollgruppe;
die WPA3+802.11r-Hypothese ist damit durch eigene Messung gestützt, nicht mehr Forenwissen.
Verlauf am 31.08.: 07:25 (10×) → 07:34 (21×), eskalierend, teils mehrere pro Sekunde, endend mit
der Flucht auf einen 25 dB schlechteren AP (-89 dBm).
⇒ ft-over-ds=no ist jetzt Hebel 1, nicht 2g-probe-delay: Letzteres adressiert
Band-Steering, hier liegt ein Authentifizierungsproblem vor. Details und Messrezept im
Handoff vom 2026-08-31.
🚫 Kein Funk-Parameter wird geändert, solange keine Daten da sind. Vier Hebel, einzeln und je
als Transaktion (gc-transaktion.py). Reihenfolge korrigiert am 2026-08-31 durch den Befund oben —
die alte Liste führte 2g-probe-delay an, das aber Band-Steering adressiert, während hier ein
Authentifizierungsproblem gemessen ist:
| # | Hebel | Begründung der Reihenfolge | Risiko | Stand |
|---|---|---|---|---|
| 1 | ft-over-ds=no auf sec-main |
nimmt die Änderung vom 08-17 zurück; FT bleibt über ft=yes (over-the-air) erhalten. Kleinster Eingriff, der die verdächtige Achse trifft |
gering | ❌ widerlegt — lief 6,4 h allein → 124× (≈19/h) + 2 Ausfälle, zurückgebaut 2026-09-01 |
| 2 | ft=no auf sec-main |
falls (1) nicht reicht: FT komplett aus. Kostet Roaming-Geschwindigkeit, nicht Roaming | mittel | ✅ gezogen 2026-09-04 (User-Entscheid, Dauerzustand — Template + bf-golden-config + Nautobot-Sync) |
| 3 | 2g-probe-delay=yes (2,4-GHz-Configs) |
MikroTiks dafür gebautes Werkzeug; verzögert nur Probe-Antworten und kann keinen Client stranden lassen. Adressiert die Band-Oszillation — ein anderes Symptom | sehr gering | ⏹️ entfällt (Fund E geschlossen) |
| 4 | signal-range-Boden per access-list (Fund E im Original) |
kann Clients aussperren — genau das war 08-22 das Gegenargument; nur mit gemessenem Wert | hoch | ⏹️ entfällt (Fund E geschlossen) |
✅ Ergebnis 2026-09-02 (Abschlussmessung, Handoff): Der Sturm ist mit
ft-over-ds=yesund 7.24.1 verschwunden — 09-02 nur 4 reauth in 8,6 h (alle iPhoneF2:62, isolierte Einzel, 0 Ausfälle), Verlauf 218 → 40 → 4. Vorbedingung geprüft (Core-Uptime 1d18h,caps joined=0). ⇒ 7.24.1 war die Ursache/der Fix, nichtft-over-ds. Hebel 1 widerlegt+zurückgebaut, Hebel 2–4 entfallen, kein Geräte-Write (Soll stand:ft=yes ft-over-ds=yes, Compliance 140/140). Am 2026-09-04 hat Christophft=noaufsec-mainals Dauerzustand entschieden (Hebel 2 doch gezogen). Der folgende Detailblock zu Hebel 1 ist historisch.
🔬 Hebel 1 — gezogen am 2026-08-31 08:09, Messung läuft bis 2026-09-01
Was steht: sec-main am Core auf ft=yes ft-over-ds=no. Abnahme am Manager über alle
Master-VAPs — cap-wifi3/4/5/6 (= ap2 + ap3) melden ft=true ft-over-ds=false; cap-wifi1/2 (= ap1)
sind leer, weil ap1 funkstill ist. Danach remote-cap provision [find]; alle drei CAPs kamen mit
state=Ok zurück, alle VAPs running=yes am CAP gelesen, und das iPhone hing 71 s später wieder
auf dirtyvader-main mit auth-type=ft-wpa3-psk und frischer DHCP-Lease 10.40.10.196 —
also die vorgeschriebene Abnahme (Lease, nicht Registration-Table). 30 Clients insgesamt zurück.
Governance: Transaktion TP25-fund-e-ft-over-ds (Scope wifi-security, Ablauf 2026-09-03),
Geräte-Backup pre-tp25-funde-ftoverds.backup auf dem Core, Snapshot
docs/transaktionen/TP25-fund-e-ft-over-ds.snapshot.rsc.
Compliance danach 134/135, und der Diff ist exakt ft-over-ds=yes → no auf sec-main —
kein Kollateral-Drift durch die Re-Provisionierung. Das GC-Template wird beim Commit nachgezogen,
nicht vorher: sonst wäre der laufende Versuch unsichtbar und status könnte ihn nicht mehr von einem
Versehen unterscheiden.
🔴 Die cap-wifiN-Karte hat sich durch die Re-Provisionierung VERSCHOBEN — wer die Logs vom
31.08. auswertet, muss den Schnitt kennen, sonst ordnet er Ereignisse dem falschen AP zu:
| vor 08:09 (Log 07:xx) | ab 08:09 | |
|---|---|---|
| ap1 (funkstill) | — | cap-wifi1 / cap-wifi2 |
| ap2 | cap-wifi1 / cap-wifi2 |
cap-wifi3 / cap-wifi5 |
| ap3 | cap-wifi5 / cap-wifi6 |
cap-wifi4 / cap-wifi6 |
⚠️ Korrektur am Befund: main unterscheidet sich in ZWEI Attributen, nicht einem. Neben
ft=yes ft-over-ds=yes fährt sec-main als einzige SSID authentication-types=wpa3-psk allein;
die fünf anderen sind wpa2-psk,wpa3-psk. Die Kontrollgruppe trennt also FT und WPA3-only nicht
voneinander. Das ändert nichts an der Hebelreihenfolge (die Foren-Hypothese nennt genau die
Kombination WPA3+FT), aber die Formulierung „genau ein Attribut" ist zu stark — wenn Hebel 1 und 2
beide nichts bewegen, ist wpa2-psk,wpa3-psk auf sec-main der nächste Kandidat, nicht signal-range.
Messung (Erfolgskriterium): reauthenticating für F2:62:4C:E1:AF:09 geht auf ~0, ohne dass die
anderen SSIDs neue Ereignisse zeigen. Die Zahl MUSS sich bewegen.
ssh root@10.40.20.100 "pct exec 400 -- sh -c 'cat /opt/tp5-syslog/log/10.40.20.1/2026-0*-*.log |
grep reauthenticating | grep -oE \"([0-9A-F]{2}:){5}[0-9A-F]{2}\" | sort | uniq -c'"
Baseline 93 (alle iPhone, alle main); davon 79 am 31.08., alle in Stunde 07, der letzte um
07:34:43 — also vor dem Eingriff. Zwischen 08:00 und 08:15 kein einziges. Das ist noch kein
Ergebnis, nur der saubere Schnitt.
(Der Defekt war nie gegenstandslos, nur unbelegt: Fund B/C wurden am 08-20 mit ap1 auf ether15
gemessen — also in genau der Stellung, in der ap1 heute wieder hängt. Er ist platzierungsunabhängig.)
✅ Erledigte Funde — Ergebnis und Merkregel (Volltext im Archiv):
| Fund | Ergebnis | Merkregel, die bleibt |
|---|---|---|
| A 2,4 GHz fuhr 40 MHz statt der profilierten 20 | ✅ 08-17: Inline-channel.* auf wifi1/wifi2 geleert → 2412/2462 @ 20 MHz |
Inline-Overrides gewinnen gegen das verlinkte Profil — die SoT war die ganze Zeit richtig, das Gerät hat sie nicht befolgt |
| B ap2 sendete 5 GHz mit 9 statt 18 dBm | ✅ 08-17: 5220/ax/Ce/I, 18 dBm |
Der Fix ist gemessen, der Mechanismus nicht — beide ersten Erklärungen (ETSI-Band C, „80 MHz kostet generell") sind widerlegt. Resthypothese + diskriminierender Test (ap2 auf 5180/Ceee) stehen im Archiv und gehören vor einen Hardwarekauf |
| C 80 MHz kostete Randabdeckung | ✅ 08-17: ch-5g auf 20/40mhz; ap1 5180/Ce, ap2 5220/Ce, überlappungsfrei |
Unter ETSI gibt es im Indoor-Band nur einen 80-MHz-Block — zwei APs können dort nicht beide 80 MHz fahren. Genau deshalb war ap2 je auf 5745 gelandet |
D w2-iot trug einen Channel-Override auf einem Slave-VAP |
✅ 08-17: Overrides auf beiden APs entfernt, w2-iot seither BR |
band ist eine Eigenschaft des Radios, nicht eines Slave-VAPs. War der Mechanismus hinter „alle SSIDs da, -iot beharrlich nicht" |
| Drift-Lücke — genau diese Overrides lagen außerhalb jeder ComplianceRule | ✅ 08-18 mit dem TP28-GC-Umbau: wifi-*-Features hängen am Core, drei neue Rules; ein CAP hat keine Inline-Overrides mehr |
„Compliant" heißt nur: die abgedeckten Sektionen sind sauber. Fund A und D blieben seit 08-08 unentdeckt, während die Flotte durchgehend compliant meldete |
🔴 Deploy-Gotchas aus derselben Arbeit (kosten sonst zwei Deploys, Volltext im Archiv):
/interface/wifi/set <if> !channel löscht die Inline-Sub-Properties NICHT — es wirft nicht, es tut
nichts; richtig ist einzeln !channel.width !channel.band !channel.skip-dfs-channels. Und bei
Kanalarbeit Breite VOR Frequenz ändern, sonst erzeugt man auf dem Weg eine Co-Channel-Kollision.
⚠️ steering=/Channel-Änderungen re-applien alle VAPs und werfen jeden Client kurz raus — nicht
während eines Calls deployen, /system backup je AP vorher.
🔬 Messwerkzeug — vier Regeln, jede aus einem Fehlbefund geboren:
- 🔴 Für einen Kanal-/Umfeldscan NICHT
list_wifi_interfacesbenutzen (Fund 2026-08-24): das Tool gibtsecurity.passphrasealler Profile im Klartext aus — ein Read für die Kanalbreite hat so fünf WLAN-Passphrasen in ein Transkript geschrieben, den IoT-PSK inklusive. Für Kanäle reicht/interface wifi channel print detail; für diecap-wifiN-Zuordnung… print where master=yesmit Feldauswahl. Der Scan selbst (/interface wifi scan) ist unbedenklich. - 🔴 Die
cap-wifiN-Nummern sind NICHT stabil. Der Manager vergibt sie in der Reihenfolge, in der sich die CAPs anmelden — nach dem ap1-Rückbau sindcap-wifi1/2= ap2 undcap-wifi3/4= ap1, umgekehrt zur früher fest verdrahteten Tabelle. ⇒ Die Zuordnung gehört zum Messlauf, nicht zur Auswertungszeit:tp25-walk-messung.shfriert sie alsap-map.txtein, die Auswertung lässt die Namen sonst roh — unbeschriftet ist ehrlicher als falsch beschriftet. Läufe vor dem 2026-08-22 sind nicht rekonstruierbar; wer ihre AP-Namen zitiert, prüft sie an der Physik (der AP im Raum liefert dort das stärkste Signal). - 🔴 Ein vom Pin abgewiesener Verbindungsversuch ist in Ping-Daten nicht von einem Funkloch zu
unterscheiden — und der Manager protokolliert ihn auf
info-Ebene gar nicht. Android quittiert die Abweisung mit „Verbindung fehlgeschlagen" und wählt das Netz ab; danach misst der Rest des Rundgangs Stille. Die Klick-Konsole schlägt deshalb Alarm, sobald ein gepinnter Client nirgends hängt (sta_iface=absentinsampler-<name>.csv) — denn „der Gegen-AP trägt hier nicht" ist das Messergebnis. - 📐 Eine Runde, N Messpunkte (seit 2026-09-04): die frei roamenden Clients zeigen, was ein normaler
Client wählt — interessant sind die gepinnten. Jeder Client wird band-genau auf einen AP
gezwungen (
tp25-pin-multi.sh,TP25_PINSPEC="name|mac|ap|band;…"), direkt aus der Klick-Konsole. Gute Referenz + schlechte Sonde = die Abdeckung steht, die Rückfallebene nicht. Memoryref_gegen_ap_messung. (Die alte 2-Client-access-list-Automatik übertp25-pin-s22.shist mit dem Multi-Pin-Umbau entfallen;tp25-pin-s22.shliefert nur noch diemap.) - ▶️ Start ohne Werkzeugkette:
bash docs/tp25-runde.sh [name]— legt den Lauf unterdocs/messdaten/tp25-runde-<name>/an, friert die AP-Karte ein, startet Konsole (Port 3031) und Messung, sagt die vom Interface gelesene Adresse fürs Telefon an. In der Konsole: pinnen (N Clients je AP/Band) → gehen (🚶/📍) → Räume antippen → stoppen; beim Beenden löst der Wrapper den Multi-Pin. Auswertung:tp25-gehweg-auswertung.py --dir …. - ℹ️ Und das alles passiert TROTZ aktivem 802.11k/v und FT (
st-mainmitrrm=yes/wnm=yes,ft-over-ds=yes, live geprüft). Die Merkregelref_ft_is_not_roaming(„11k/v fehlen") ist historisch. Bei −48…−55 dBm kostet eine Übergabe 0–2,6 s, meist unter einer halben Sekunde — nicht die Übergabe ist teuer, sondern die schwache Zone.
User-Randbedingung (2026-08-17, wörtlich): „ich weigere mich einen anderen access point zu kaufen solange ich nicht das gefühl habe, wir haben alles aus dem ap rausgeholt." Das ist die Abnahmebedingung dieses TPs — keine Hardware-Empfehlung, bevor die Parameter stimmen. Der Boden ist gelegt (beide APs 18 dBm, überlappungsfrei, 20 MHz auf 2,4 GHz, ap2 auf 2,5 m); was übrig bleibt, ist die Redundanzfrage oben.
- Warum eigener TP: Christoph hat am 2026-08-16/17 sechs konkrete Beobachtungen gemeldet und ausdrücklich einen TP dafür verlangt; sie hängen alle an derselben Ursache-Klasse (Funkparameter, die nicht nach Manual gesetzt sind). TP25 übernimmt den offenen Rest von TP3.3 (Re-Walk, Dead-Spot-Kartierung — mit der Raumkarte vom 08-22 faktisch geleistet). TP3.2/TP3.3 stehen als Historie.
- Stand bei Sitzungsende 2026-08-22: Pin gelöst, Automatik aus,
crs326-coreunverändert und transaktionsfrei — dieaccess-liststeht unter keiner ComplianceRule, es gab nichts zu committen. (Seit 2026-08-23 gibt es die Rulewifi-access-list, s. TP22-Nachtrag — Fund E wäre ab jetzt transaktionsfähig.) - 📋 Übergabe:
handoff-tp25-session-20260821.md· Messungen:tp25-wlan-roaming-messung-20260820.md,tp25-runde-20260822-2330-auswertung.md - Abh.: TP22 ✅ (GC-Deploy-Pipeline). Verwandt TP3.2 (
docs/wifi-p750w-coverage-and-map.md), TP29 (nutzt dieselbe Datenquelle als Sensor). Kein Blocker für irgendetwas.
🔬 Fund E — 2026-09-01: der ap2-Teilbefund (gültig) und eine widerlegte Heilungs-Wertung
Anlass: Christoph meldete 2026-08-31 23:02 eine Störung am Schreibtisch (5G, iPhone, kein
Telefonat). Analyse (alles read-only am Manager crs326-core):
- AP-Karte (stabil seit letztem CAP-Rejoin 15:57, kein Rejoin danach — Attribution belastbar):
cap-wifi5/6 = ap2,cap-wifi3/4 = ap3,cap-wifi1/2 = ap1(funkstill, Radios da, 0 Clients). - 23:02-Ereignis: iPhone
F2:62:4C:E1:AF:09ping-pongt im Sekundentaktcap-wifi5 ↔ cap-wifi6= ap2s 5G (5220) ↔ ap2s 2,4G (ch11/2462) — Band-Steering-Thrash auf demselben AP, plusdisconnected, not respondingum 22:37:40 (−76) und 23:01:00 (−82). Feldstärke der Roams −75…−88 dBm. - 🔴 Christophs Fakt kippt die Coverage-Deutung: iPhone und ap2 nur 2 m entfernt, gleicher
Raum, ap2 auf 2,3 m. Bei 2 m Sicht wären −35…−45 dBm normal. −80 auf 2 m ist kein Coverage-
und kein FT-Problem. Dazu: aktuell 0 Clients auf ap2, alle 29 auf ap3 — die Clients meiden
ap2. ⇒ ap2s Funk selbst unterperformt (RF/Antenne/HW) und/oder die DTU-Störung auf ap2/ch11
(Transaktion
TP17.1-dtu-pin-ap2, Wechselrichter54:F2:9F:12:51:F0mit −59 dBm auf ap2s 2,4-Radio). - In-situ zu messen (nachts nicht möglich — Phone idle auf ap3): Registration-Signal live prüfen,
während ein Client auf ap2 hängt; Kandidaten-Eingriffe — DTU-Pin lösen/verlegen,
dirtyvader-mainauf ap2 temporär deaktivieren (ap3 übernimmt den Schreibtisch), ap2-Antenne/HW prüfen. Keine Änderung ohne diese Messung.
🔴 WIDERRUFEN am 2026-09-01 vormittags — der zweite Teil dieses Abschnitts war ein Messfehler.
Ursprünglich stand hier: „Fund E ist im sauberen Fenster geheilt — 0× reauthenticating seit dem
14:36-Reboot (sinceMinutes=1440, total 0), also hat Hebel 1 sein Ziel erreicht."
Warum das nicht trägt: get_log liest den flüchtigen Ringpuffer des Routers, nicht den
Kollektor. Live nachgemessen fasst er 1000 Zeilen und reicht bis 01.09. 00:38:58 zurück — keine
9 Stunden. Der Core-Reboot um 14:36 hatte ihn geleert; der 31.08. Vormittag war darin gar nicht
enthalten. total 0 hieß „im Puffer nichts", nicht „in 24 h nichts". Das ist exakt die Falle,
wegen der am 30.08. das persistente Logging gebaut wurde.
Was der Kollektor zeigt: im upgrade-freien Fenster 08:09–14:36 (Hebel 1 allein) 124×
reauthenticating — 09h=1 · 11h=2 · 12h=20 · 13h=31 · 14h=70, alle vom iPhone allein, dazu
Christophs zwei erlebte Ausfälle 13:16 und 14:23. Zwischen 09:00 und 14:36 lag kein Reboot.
⇒ Hebel 1 wurde am 2026-09-01 zurückgebaut; der Rückbau ist das entscheidende Experiment
(s. Ist-Stand-Block oben).
✅ Der ap2-Teilbefund oben bleibt davon unberührt und gültig — er ist unabhängig gemessen und
erklärt die 23:02-Störung, die weder FT noch Coverage erklärt.
Commit-Weg (wartet auf Christophs Go — git-push-Kette): Template nautobot/mikrotik_routeros.j2
Z. 220 sec-main von ft-over-ds=yes → ft-over-ds=no; dann Template-Repo nach Nautobot syncen,
gc-configplan.py --refresh-compliance (Backup→Intended→Compliance), dann
gc-transaktion.py commit --change-id TP25-fund-e-ft-over-ds. Danach wifi-security wieder driftfrei.
🔴 Kreuzt git-push (Backup-Guard + Commit-Hinweis-Regel) und Live-Nautobot-Jobs — nicht autonom.
Handoff: handoff-20260901-tp25-ap2-verdacht.md.
TP25 — Langfassung (Messchronik + Funde im Volltext, Stand 2026-08-22)
✅ TP25 ist ABGESCHLOSSEN (2026-09-15). Der aktive Stand (Kondensat) steht oben unter TP25. Hier liegt wortgleich die Fassung, die bis zum 2026-08-23 dort stand — 394 Zeilen Herleitung: die Messchronik (A)–(G) mit allen zwischendurch korrigierten Irrtümern, die Funde A–F im Volltext, die beantworteten Fragen (Beobachtung 5 „CAPsMAN oder Nautobot GC?", Herkunft der ch149-Notiz,
2ghz-gfür IoT, Deckenmontage-APs) und die Umsetzungsreihenfolge mit den Deploy-Gotchas.📌 Warum das nicht gelöscht wurde: ein guter Teil des Werts steckt in den widerlegten Erklärungen — zweimal stand hier eine plausible Ursache, die die nächste Messung gekippt hat (ETSI-Band C bei Fund B; „ap1 ans Sideboard" bei (F)/(G)). Wer TP25 fortsetzt, muss sehen können, welche Wege schon abgelaufen sind.
TP25 · Gitea #17 — WLAN-Stabilisierung — 43 % → 9 % Verlust, 20,4 s → 1,0 s). Offen nur noch Fund F (5:05-Takt IoT) und die Entscheidung 5 GHz auf 20 MHz. Nicht mehr kritischer Pfad — Sammel-TP für Christophs Beobachtungen 1–6
🆕 Messung 2026-08-20/21:
tp25-wlan-roaming-messung-20260820.md(Nebenprodukt der TP6-Messreihen, Core-Sampler im 2-s-Takt über 2,5 h, teils mit laufendem Videocall). Drei Befunde: (A) Der Bandabstand 2,4 ↔ 5 GHz beträgt 8–10 dB — physikalisch normal (6,7 dB allein Freiraumdämpfung), keine Konfigurationsursache. Das Problem ist der Absolutwert: 5 GHz liegt an den Telefonier-Orten bei −75 bis −80 dBm. (B) Sticky Client: ein Weg Küche → Kinderzimmer → Schlafzimmer → Terrasse, dreimal direkt an ap1 vorbei (−43 dBm), eine einzige Übergabe — und die erst oben bei −73 dBm. (C) Band-Ping-Pong: 12 Wechsel in 9 Minuten am selben Ort, immer ap2 5↔2,4 GHz. (D) 2026-08-21 nachgemessen (Gehweg, 5 Pings/s auf das Telefon,docs/tp25-walk-messung.sh): die „~4 s je Wechsel" waren Zählerartefakt — bei −48…−55 dBm kostet eine Übergabe 0 bis 2,6 s, meist unter einer halben Sekunde, Fast Transition funktioniert also. Der wahre Befund ist schlimmer und liegt woanders: bei −69…−77 dBm ist das Telefon 6 bis 45 s nicht erreichbar, zweimal über 20 s am Stück. Nicht die Übergabe ist teuer, sondern die schwache Zone. (E) 2026-08-21, Raumkarte — der Dead Spot hat einen Namen: die TERRASSE. Ping vom Core, Konsole auf dem iPhone, Raumwechsel per Klick markiert. Im ganzen Haus null Verlust (Technik UG/OG, Diele, Kinder-, Schlaf-, Arbeitszimmer, Treppe — alle 0 %, Übergaben ap1↔ap2 kosten 0,2 s). Auf der Terrasse: 43 % Verlust, längste Lücke 20,4 s bei −72 dBm. Erklärung ist die Topologie: ap2 sitzt in Technik OG — das ist aber kein eigener Raum, sondern ein virtueller Bereich im Arbeitszimmer (User-Korrektur 2026-08-21, die frühere „drei Wände"-Erklärung war falsch). Zwischen ap2 und Terrasse liegen zwei Mauern der Diele OG plus teilweise die PV-Anlage an der Mauer — und die ist als leitende Fläche ein Schirm, keine dämpfende Wand. Deshalb wird mehr Leistung oder ein schmalerer Kanal dort wenig ausrichten; gegen einen Schirm hilft nur, ihn zu umgehen. Details:tp25-wlan-roaming-messung-20260820.md§6. ⚠️ Konsequenz für Fund E: einsignal-range-Boden würde die Terrasse verschlechtern, weil es dort keinen besseren AP gibt, auf den gesteuert werden könnte. Stattdessen: (1) 5 GHz auf 20 MHz (+3 dB, Ein-Wort-Change im Template), (2) ap2 von Technik OG in die Diele OG umhängen — die grenzt an Terrasse, Arbeitszimmer und Treppe, kostet keinen neuen AP und erfüllt damit die User-Randbedingung; zu klären ist die Verkabelung (ap2 hängt ancrs326-branch ether24). (3) dritter AP erst, wenn beides nicht reicht. (F) 2026-08-21 abends, Raumkarte 2 — ap1 versetzt ans Sideboard (core ether3). Das OG gewinnt (Diele OG −50 ⌀ über 5,5 min mit 0 % Verlust, Technik OG −44), die Schlafräume verlieren: Schlafzimmer von −61 (ap1/5 GHz) auf −83 (ap2/2,4 GHz), Kinderzimmer von −53 auf −75, Bad −83 mit 31 % Verlust. 🔴 Und genau das ist vermutlich KEIN Abdeckungsproblem: laut User liegen Schlaf- und Kinderzimmer 2 bzw. 4 m Luftlinie von ap1, während ap2 4–6 m entfernt ist und zwei zusätzliche Mauern dazwischen hat. Ein Client, der so am ferneren AP klebt, ist ein Steering-Fall — und damit die erste Stelle im Haus, an der Fund E (signal-range-Boden) wirklich hilft, weil es hier eine bessere Alternative gibt. Test steht aus (Handover §5). Korrektur zur Terrasse: der Platz, an dem das Telefon normalerweise steht, ist mit −46…−66 dBm gut; schlecht ist der Teil dahinter. (G) 2026-08-22 — Sideboard-Test BEENDET, ap1 geht zurück aufcore ether15. Ergebnis nach einem Tag, User-Befund: ap1 am Sideboard richtet das Wohnzimmer nicht — womit die RF-Vorhersage aus der Idee von 2026-08-13 (geschlossenes Media-Möbel, Metallgehäuse, niedrig) bestätigt ist — und der Preis ist ein dunkles Schlafzimmer (Fund F: −61 → −83 dBm). Damit ist die Idee „ap1 ersetzt den Sideboard-Switch" entschieden: nein. Die User-Vorgabe „Platzierung hat Vorrang vor dem eingesparten Gerät" greift — und die bessere Platzierung ist die alte. TransaktionTEST-ether3-trunk-ap1-sideboardwird zurückgerollt (ether3wieder untagged VLAN40 = Sideboard-Access-Port); Compliance geht damit auf 92/92 zurück. 🔴 Reihenfolge beim Rückbau: erst ap1 physisch aufether15umstecken, dann die Config zurückrollen. Umgekehrt hängt ap1 im Moment des Deploys ungetaggt in MEDIA und verliert vlan99/Manager.ether15ist durchgehend in allen VLANs getaggt geblieben, das Umstecken allein genügt also. ↗️ Stattdessen als Nächstes: ap2 wurde auf 2,5 m Höhe gehievt (User 2026-08-22) — der billigste verbliebene Hebel unter der Randbedingung „kein neuer AP, solange nicht alles aus den vorhandenen rausgeholt ist". Wirkung noch ungemessen: Raumkarte mittp25-walk-messung.shneu laufen, sonst steht Höhengewinn gegen Fund F ohne Zahlen im Raum. Erster Eindruck des Users (2026-08-22): die Terrasse ist damit besser ausgeleuchtet — subjektiv, Nachmessung steht aus und ist genau der Punkt, an dem der Dead Spot aus (E)/(F) zu prüfen wäre. ⚠️ Korrektur 2026-08-22 (User): die Formulierung „der Steering-Fall entfällt mit dem Rollback" war falsch. Was entfällt, ist nur die konkrete Ausprägung aus (F) — Schlaf-/Kinderzimmer bei 2 m zu ap1 an ap2 klebend. Der Defekt selbst bleibt, er verlagert sich nur: Übergabe bzw. Abriss passieren dann an anderen Stellen im Haus. Das ist auch belegt: Fund B (Sticky Client, dreimal an ap1 bei −43 dBm vorbei, eine einzige Übergabe) und Fund C (Band-Ping-Pong, 12 Wechsel in 9 min) wurden am 2026-08-20 gemessen — mit ap1 aufether15, also in genau der Stellung, in die wir jetzt zurückgebaut haben. Der Sticky-Client-Defekt ist damit platzierungsunabhängig. ⇒ Fund E (signal-range-Boden am Manager) bleibt unverändert die richtige Maßnahme und ist nach dem Rückbau der oberste offene Punkt in TP25 — nicht erledigt, nicht gegenstandslos. 🔴🔴 2026-08-22, Werkzeug-Fund mit Rückwirkung auf ALLE bisherigen Messungen: diecap-wifiN-Nummern sind NICHT stabil. Der Manager vergibt sie dynamisch in der Reihenfolge, in der sich die CAPs anmelden — nach dem ap1-Rückbau aufether15sind heutecap-wifi1/2= ap2 undcap-wifi3/4= ap1, also genau umgekehrt zu der festen Tabelle, die intp6-marker/server.pyundtp25-gehweg-auswertung.pystand. ⚠️ Daraus folgt NICHT, dass die alten Auswertungen falsch sind — der erste Verdacht in diese Richtung war voreilig. Die Gegenprobe spricht dagegen: wendet man die heutige Karte auf die Raumkarte vom 08-21 an, wird Technik OG von ap1 mit −43 dBm versorgt — in dem Raum, in dem ap2 steht. Die alte Tabelle war zu ihrer Zeit also plausibel richtig und ist erst durch das Umstecken falsch geworden. ⇒ Die Zuordnung gehört zum Messlauf, nicht zur Auswertungszeit.tp25-walk-messung.shfriert sie jetzt alsap-map.txtim Lauf ein; die Auswertung nimmt ausschließlich diese Datei und lässt die Namen sonst roh (cap-wifiN) — unbeschriftet ist ehrlicher als falsch beschriftet. Läufe vor dem 2026-08-22 sind nicht rekonstruierbar; wer ihre AP-Namen zitiert, muss sie an der Physik prüfen (der AP im Raum liefert dort das stärkste Signal).🆕 Messaufbau neu gedacht (Christoph, 2026-08-22) — eine Runde statt zwei. Das frei roamende iPhone zeigt ohnehin, welchen AP ein normaler Client wählt; interessant ist der andere. Das S22 wird deshalb per
access-listautomatisch auf den Gegen-AP des iPhones gezwungen (docs/tp25-pin-s22.sh, Automatik in der Klick-Konsole auf Port 3031). Pro Standort fallen so zwei Messpunkte an. Ein Doppelton meldet „beide angemeldet, verschiedene APs" = weitergehen. 🔴 Die Falle dabei, live erlebt: ein vom Pin abgewiesener Verbindungsversuch ist in den Ping-Daten nicht von einem Funkloch zu unterscheiden, und der Manager protokolliert ihn aufinfo-Ebene gar nicht (Beleg: zwischendisconnected, access-list changedund dem manuellen Reconnect stehen vier Minuten ohne eine einzige Zeile). Android quittiert die Abweisung mit „Verbindung fehlgeschlagen" und wählt das Netz ab — danach misst der Rest des Rundgangs Stille. Die Konsole schlägt deshalb mit Ton, Vibration und Vollbanner Alarm, sobald das gepinnte Gerät nirgends hängt, und schreibt nach 45 s vergeblicher SucheUNERREICHBAR=apX— denn „der Gegen-AP trägt hier nicht" ist das Messergebnis. ✅✅ 2026-08-22, 23:30 — DIE TERRASSE IST REPARIERT. Erster Lauf mit beiden Ping-Strecken (tp25-runde-20260822-2330-auswertung.md): 43 % Verlust / 20,4 s längste Lücke (08-21) → 9 % / 1,0 s — gleiches Gerät, gleiche Rolle. Das Anheben von ap2 auf 2,5 m hat gewirkt; 1,0 s liegt unter der Hörbarkeitsschwelle. Der Dead Spot, der TP25 seit dem 08-20 getragen hat, ist damit weg. 🔎 Neuer Kernbefund: das Netz ist gut, die Redundanz ist es nicht. Die frei roamende Referenz hat in 17 von 21 Raumabschnitten 0 % Verlust; der Gegen-AP dagegen liefert Schlafzimmer −84,6/38 %, Bad −82,3/24 %, Küche −82,0/23 %, Terrasse −78,7/19 %. Fällt ein AP aus, ist die halbe Wohnung im Zustand „verbunden, aber tot". ⇒ Dritter AP nach der eigenen Randbedingung derzeit NICHT begründet — er kaufte Redundanz, keine Abdeckung. Das ist eine andere Frage und Christophs. ⇒ Fund E weiter abgestuft: der Sticky-Client vom 08-20 reproduzierte sich nicht (Treppe: sauberer Wechsel ap2→ap1, 0 % über 57 s). Nicht umsetzen, bevor ein Sticky-Fall erneut gemessen ist. ⚠️ Korrektur zum 22:43-Lauf: „Küche ist ein Loch für beide APs" gilt nur für die äußerste Ecke — im normalen Aufenthaltsbereich hat die Referenz dort 1 % Verlust bei −71 dBm. ▶️ Start ohne Werkzeugkette:bash docs/tp25-runde.sh [name]. Legt den Lauf unterdocs/messdaten/tp25-runde-<name>/an, friert die AP-Karte ein, startet Konsole (Port 3031) und Messung, sagt die vom Interface gelesene Adresse fürs Telefon an und löst beim Beenden (Ctrl-C) den Pin wieder. Auswertung danach mittp25-gehweg-auswertung.py --dir …. ⏸️ Stand bei Sitzungsende 2026-08-22: Rundgang noch nicht gegangen. Pin gelöst, Automatik aus,crs326-coreunverändert (dieaccess-liststeht unter keiner ComplianceRule, es gibt also nichts zu committen). Erster Messwert nebenbei: am Arbeitsplatz iPhone ap2 −68, S22 auf ap1 gezwungen −77…−78; ohne Pin geht das S22 sofort auf ap2/5 GHz −71. 📋 Übergabe:handoff-tp25-session-20260821.md. ✅ TransaktionTEST-ether3-trunk-ap1-sideboardam 2026-08-22 zurückgerollt und geschlossen (Scopebridge-vlan) —ether3ist wieder untagged VLAN40, Compliance zurück auf 92/92. Und das passiert TROTZ aktivem 802.11k/v und FT — live geprüft:st-mainmitrrm=yes/wnm=yes,ft-over-ds=yes. Die Merkregelref_ft_is_not_roaming(„11k/v fehlen") ist damit historisch. Reihenfolge der Maßnahmen (Doku §6, respektiert die User-Randbedingung „kein neuer AP, solange nicht alles aus den vorhandenen rausgeholt ist"): erst die Lücke messen → 5 GHz auf 20 MHz statt 20/40 (+3 dB Link-Budget, für 1,2 Mbit Call irrelevant an Durchsatz) → Fund E (signal-range-Boden am Manager) → 2,4 GHz NICHT vorschnell drosseln (dort hängen ~20 IoT-Geräte) → dritter AP zuletzt. Restliste (Stand 2026-08-18): Fund A–D ✅ · Drift-Luecke ✅ (mit TP28, 92/92) · offen: Fund E (access-listmitsignal-range-Boden — ⚠️ gehoert jetzt auf den Manager, nicht mehr auf die APs) · Fund F (5:05-Takt bei IoT-Trennungen, am Manager nachmessen — die AP-Tabellen sind unter CAPsMAN leer) · Re-Walk + Dead-Spot-Kartierung (hands-on). Alles drei ist Messarbeit gegen die korrigierte Basis, keine Konfigurationsarbeit mehr. Warum eigener TP: Christoph hat am 2026-08-16/17 sechs konkrete Beobachtungen gemeldet und ausdrücklich einen TP dafür verlangt. Sie hängen alle an derselben Ursache-Klasse (Funkparameter, die nicht nach Manual gesetzt sind), gehören also zusammen. TP25 übernimmt den offenen Rest von TP3.3 (Re-Walk, Dead-Spot-Kartierung) — dieselbe physische Arbeit, doppelt geführt wäre Unsinn. TP3.2/TP3.3 bleiben als Historie stehen. User-Randbedingung (2026-08-17, wörtlich): „ich weigere mich einen anderen access point zu kaufen solange ich nicht das gefühl habe, wir haben alles aus dem ap rausgeholt." Das ist die Abnahmebedingung dieses TPs — keine Hardware-Empfehlung, bevor die Parameter stimmen.
- ⚠️ Ausgangslage: Drift ist bestätigt, aber NICHT die Ursache. Christoph hat am 08-16/17 selbst an den APs
gespielt („drift ist garantiert. es hat vorher aber auch nicht funktioniert"). Der Audit unten ist gegen den
Ist-Stand gefahren (
/interface/wifi/export+/interface/wifi/monitor+ Log, beide APs, 2026-08-17 14:01). Zwei der Funde sind älter als die Experimente und stammen aus der TP3-Neuprovisionierung.
🔴 Fund A — 2,4 GHz läuft auf 40 MHz, obwohl das Profil 20 MHz sagt (Beobachtung 4)
- Christophs Frage war berechtigt, aber der Adressat ist ein Override, keine Entscheidung. Das Channel-Profil
ist korrekt:
add band=2ghz-ax frequency=2412 name=ch-2g width=20mhz. Überschrieben wird es inline am Radio:set [find default-name=wifi2] channel.band=2ghz-ax .skip-dfs-channels=10min-cac .width=20/40mhz→ das Inline-Override gewinnt gegen das verlinkte Profil.monitorbeweist es: ap12412/ax/Ce, ap22462/ax/eC—Ce/eC= 40 MHz. Niemand hat 20/40 „gewählt"; es ist genau die Override-Klasse, die CLAUDE.md für den TP3-Bring-up schon dokumentiert („Werks-Inline-Overrides auf wifi1/wifi2 überschreiben das verlinkte Profil") — damals nur fürconfiguration.ssid/security.*bereinigt, fürchannel.*nie. - Warum 40 MHz auf 2,4 GHz falsch ist (Manual-Ebene, nicht Geschmack): es gibt nur 3 überlappungsfreie
20-MHz-Kanäle. ap1 belegt mit
2412/Ce≈ 2402–2442, ap2 mit2462/eC≈ 2442–2482 → die beiden APs decken zusammen praktisch das ganze Band ab. Jeder Nachbar-AP überlappt zwangsläufig einen von beiden. Dazu halbiert 40 MHz die spektrale Leistungsdichte → ~3 dB weniger Reichweite bei gleicher Sendeleistung. Und der Nutzen ist null: IoT-Clients sind fast alle 20-MHz-only. Das ist die „miserable Reichweite" aus Beobachtung 4. - Fix: die Inline-
channel.*-Overrides aufwifi1/wifi2leeren (!channel), damit die Profile greifen. Nebenbefund:skip-dfs-channels=10min-cacaufwifi2ist bedeutungslos — im 2,4-GHz-Band gibt es keine DFS-Kanäle. Copy-Paste-Spur, harmlos, gehört trotzdem raus.
🔴 Fund B — ap2 sendet auf 5 GHz mit 9 dBm statt 18 dBm (Beobachtungen 1+2)
- Gemessen: ap1
wifi1tx-power: 18, ap2wifi1tx-power: 9— bei identischer Hardware und identischem Profil. 9 dB Unterschied = Faktor ~8 in der Leistung, ap2s 5-GHz-Zelle hat grob ein Drittel des Radius von ap1. - ✅ BEHOBEN 2026-08-17: ap2s 5-GHz-Radio läuft jetzt mit 18 dBm (
5220/ax/Ce/I). Messreihe am Gerät:Zustand Kanal tx-power ap2 vorher 5745/ax/Ceee(80 MHz, ohne/I)9 ap2 nach Frequenzwechsel 5220/ax/eeCe/I(80 MHz, mit/I)9 ⬅️ unverändert! ap2 nach Breitenkorrektur 5220/ax/Ce/I(40 MHz)18 ✅ ap1 durchgehend 5180/ax/Ceee/I→5180/ax/Ce/I18 → 18 - 🔴 Ehrliche Korrektur: meine erste Begründung war falsch, und die zweite auch nicht vollständig.
Ich hatte die 9 dBm auf ETSI-Band C (ch149 ohne
/I-Flag) zurückgeführt. Widerlegt: der Wechsel ins Indoor-Band bei gleicher Breite ließ die Leistung auf 9 dBm. „80 MHz kostet generell Leistung" trägt auch nicht — ap1 fuhr 80 MHz im selben Band mit 18 dBm. Der Fix ist gemessen, der Mechanismus ist es nicht. - 🔬 Kohärente Resthypothese (nicht bewiesen, aber testbar): es sind zwei Effekte, je einer pro Kanal —
(a)
5745/Ceee= ETSI-Band-C-Limit (die erste Theorie gilt für diesen Kanal weiter), und (b)5220/eeCe= das Kontrollkanal liegt nicht am Blockanfang (eeCestattCeee), was das Radio derated. Das würde ap1s5180/Ceee=18 und ap2s5220/eeCe=9 gleichzeitig erklären. Diskriminierender Test: ap2 testweise auf5180/Ceee— 18 dBm ⇒ Hypothese (b) trägt; 9 dBm ⇒ es ist gerätespezifisch (dann ist ap2s Radio der Verdächtige, relevant für die Hardware-Frage!). Nicht nötig für den Betrieb, aber vor einem Hardwarekauf wissenswert. - ⚠️ Die TP3-Notiz „Kanäle non-DFS ap1 ch36/ch1, ap2 ch149/ch11" hatte trotzdem keinen tragenden Grund — s. eigener Absatz „Herkunft der ch149-Notiz" unten.
- 🎯 Der Fix löst Fund B und C in einem Zug — und er ist nicht offensichtlich: unter ETSI Austria existiert
im Indoor-Band (5180–5240) nur ein einziger 80-MHz-Block (
5180/Ceee= ch36–48). Zwei APs können dort also nicht beide 80 MHz fahren, ohne sich zu überlappen — genau deshalb ist ap2 überhaupt auf 5745 gelandet. Mit 40 MHz gehen beide sauber ins Indoor-Band:AP neu Kanäle Leistung Belegung ap1 5180/Ce36+40 18 dBm 5170–5210 ap2 5220/Ce44+48 18 dBm 5210–5250 Beide /I-freigegeben (aus der Radio-Tabelle bestätigt), überlappungsfrei, +9 dB für ap2.
🔴 Fund C — 80 MHz auf 5 GHz kostet Reichweite, die hier fehlt (Beobachtung 1)
ch-5g width=20/40/80mhz, laufend5180/ax/Ceeebzw.5745/ax/Ceee= 80 MHz. Dieselbe Sendeleistung auf die vierfache Bandbreite verteilt kostet ~6 dB effektiven SNR am Zellenrand gegenüber 20 MHz, ~3 dB gegenüber 40 MHz. In einer 2-AP-Wohnung mit Terrasse ist Spitzendurchsatz das falsche Optimierungsziel — Randabdeckung und Stabilität sind das richtige.- Beleg, dass genau das das Terrassen-Symptom ist: ap1-Log, Telefon steht still im Halter:
-81→ roamt auf 2,4 GHz-82→ zurück-83→disconnected, connection lost, signal strength -88. −88 dBm ist unter der Nutzbarkeitsschwelle. Das ist kein Roaming-Problem (Christoph sagt selbst „ich red da nicht mal von roaming"), sondern Link-Budget — und dagegen hilft Breite runter, nicht drehen.
🔴 Fund D — w2-iot trägt einen unzulässigen Channel-Override auf einem Slave-VAP (Beobachtung 3)
- ap1:
add channel.band=2ghz-n .width=20mhz configuration=cfg-iot … master-interface=wifi2 name=w2-iot - ap2:
add channel.width=20mhz configuration=cfg-iot … master-interface=wifi2 name=w2-iot - Ein Slave-VAP teilt das Radio des Masters und kann keinen eigenen Kanal haben. Auf ap1 erzwingt das
Override zusätzlich
2ghz-n, während der Masterwifi2auf2ghz-axläuft — ein Band-Mismatch zwischen Master und Slave ist keine unterstützte Konfiguration. Das ist der Mechanismus hinter „alle SSIDs sind da,-iotbeharrlich nicht, und plötzlich ist es wieder da": der VAP fällt aus der Beacon-Rotation und kommt bei einem Re-Apply zurück. - 📌 Und es ist der Beweis für Beobachtung 6: die beiden APs sind hier nicht identisch (ap1 mit Band+Width, ap2 nur Width). Eine generierte Config kann das nicht produzieren — das ist Handarbeit, und zwar auf genau dem Objekt, das keine Handarbeit verträgt.
🟠 Fund E — keine access-list, also kein Signal-Boden gegen klebende Clients (Beobachtung 2)
/interface/wifi/access-listist auf beiden APs leer. Damit gibt es keinensignal-range-Boden — ein Client darf hängen bleiben, bis die Verbindung zusammenbricht, statt frühzeitig abgestoßen zu werden. Das ist der Standard-RouterOS-Griff gegen genau dieses Symptom.- Beleg für das Kleben: ap2-Log, Client
56:71:6C:22:E6:A9flappt in 22 Minuten sechsmal zwischenwifi1↔wifi2bei −62…−83 dBm. Und:F2:62:4C:E1:AF:09@wifi2 disconnected, not responding, signal strength -47— Abbruch bei ausgezeichneten −47 dBm. Beides zusammen = Band-Oszillation ohne Steering-Politik, nicht schlechte Abdeckung. - ⚠️ Nebenbefund: die TP3.2-Access-List, die den P750W an ap1 pinnte („überlebt ap2-Re-Provision"), ist beim Rebuild 2026-08-08 verlorengegangen — im Export beider APs steht keine einzige Access-List-Zeile. Laut CLAUDE.md ist der Pin nicht mehr nötig (L3-GW liegt auf dem Core), der Verlust war aber unbemerkt.
ft=yes ft-over-ds=nowar korrekt für den damaligen Standalone-Betrieb (over-DS braucht ein Inter-AP-Protokoll) — kein Fund, nur zur Abgrenzung festgehalten. 📌 Seit TP28 gilt das nicht mehr: unter CAPsMAN istft-over-ds=yesaktiv, weil der Manager genau dieses Inter-AP-Protokoll mitbringt.
🟡 Fund F — IoT-Clients trennen exakt alle ~5:05 bei gutem Signal (offen, präzise vermessen)
12:55:29 connected -59 → 13:00:36 disconnected -59 (5:07)
13:17:27 connected -63 → 13:22:32 disconnected -63 (5:05)
13:35:32 connected -60 → 13:40:37 disconnected -59 (5:05)
13:57:31 connected -59 → 14:02:35 disconnected -58 (5:04)
- −59 dBm ist ein gutes Signal. Eine auf 3 Sekunden reproduzierbare 5-Minuten-Periode ist ein Timer, kein Funk.
- 🚫 Ausdrücklich NICHT die alte Power-Save-Merkregel wiederbeleben — die ist am 2026-08-13 als Fehldiagnose
zurückgezogen worden (
ref_wifi_powersave_multicast, Drucker war schlicht aus). Dieser Befund ist ein anderer: vier saubere Messpaare mit konstanter Periode. - Kandidaten + der Test, der sie trennt: (a) periodischer VAP-Re-Apply durch Fund D → prüfen, ob ap2
(ohne Band-Override) dieselbe Periode zeigt; (b) DHCP-Lease/Renew-Interaktion →
lease-timeder beiden MACs (38:A5:C9:C0:73:1E,38:A5:C9:BC:33:31) gegen die Periode legen; (c) das Gerät selbst mit 5-min-Duty-Cycle → dann bleibt es nach Fund-D-Fix unverändert. Erst nach dem Fund-D-Fix erneut messen — sonst misst man zwei Effekte übereinander.
🧭 Beobachtung 5 — „alle Welt sagt CAPsMAN, nur wir sagen Nautobot GC. Hilfe oder Last?"
- Klare Antwort: es sind keine Alternativen, sie lösen verschiedene Probleme. CAPsMAN = Runtime-Control-Plane
fürs WLAN (ein Ort für Radio-Settings, sofortiger Push, dynamische VAPs). Nautobot GC = Config-as-Code-SoT
- Drift-Erkennung über die ganze Flotte (Core, Branch, beide APs). Man kann beides haben; das Reibungspunkt ist nur, dass CAPsMANs dynamische Objekte für GC unsichtbar sind (der Grund von 2026-07-22, und der gilt).
- 🔎 Aber eine Begründung von damals hält der Prüfung nicht stand. Der Entscheid nannte als ersten Grund „WLAN dauerhaft instabil, besonders wenn beide APs laufen". Das WLAN ist nach dem Standalone-Rebuild weiterhin instabil — die These „CAPsMAN war die Ursache" ist damit empirisch geschwächt. Die Funde A–E sind Funkparameter; CAPsMAN hätte sie weder verursacht noch geheilt. Der Rebuild hat ein Symptom umgezogen, keine Ursache beseitigt.
- Wo GC hier tatsächlich Last war: es hat diesen Drift nicht verhindert. Die Compliance deckt
wifi-steeringab (seit TP3.3), aber offensichtlich nicht die Channel-/Inline-Override-Fläche — sonst wären Fund A und D als Drift aufgeschlagen. Das ist eine Lücke im Feature-Set, kein Argument gegen GC. - Ehrliches Urteil (meine Empfehlung): GC als SoT behalten — es ist das Einzige, was Hand-Tuning davon
abhält, sich still zu akkumulieren, und genau das ist hier passiert. Aber: GC ist kein WLAN-Tuning-Werkzeug.
Der Ausweg ist nicht CAPsMAN, sondern die Parameter einmal nach Manual richtig zu setzen und dann mit einer
Compliance-Feature auf
/interface/wififestzunageln. Bei genau 2 APs ist der Kanal-/Leistungsplan eine Einmalentscheidung, kein Laufzeitproblem — der Hauptvorteil von CAPsMAN greift hier also kaum. (Wenn ein dritter AP dazukäme, wäre die Abwägung neu zu führen.)
🔎 Herkunft der ch149-Notiz (Christophs Frage 2026-08-17: „wie kam es zu dieser Notiz?")
- Nachverfolgt bis Commit
03f328f, 2026-06-18, CAPsMAN-Ära. Wortlaut der Commit-Message: „Kanal-Plan non-DFS/überlappungsfrei: ap1 ch36+ch1, ap2 ch149+ch11 (Auto-Channel hatte beide APs auf 5500-DFS/2437 gelegt = Co-Channel)". - 🎯 Das gelöste Problem war Co-Channel, nicht DFS. Auto-Channel hatte beide APs auf denselben Kanal gelegt; der Fix war, überhaupt zu pinnen. Dass die Wahl auf 36/149 fiel, ist das FCC-Standardpaar aus jedem Tutorial — „non-DFS" wurde als Begründung nachträglich mitgeschrieben, war aber nie eine geprüfte Anforderung. Christophs Einschätzung ist damit belegt: es gibt keinen Grund, Frequenzbänder auszunehmen.
- 📌 Und ein Detail, das die Sache entschärft:
skip-dfs-channels=10min-cacschließt DFS gar nicht aus. Es überspringt nur Kanäle, die die 10-Minuten-CAC brauchen (Wetterradar-Band 5600–5650). Der Rest des DFS-Bands bliebe nutzbar. Ausgeschlossen wurde DFS in Wahrheit durch das hartefrequency=-Pinning — wo nichts ausgewählt wird, wirkt kein Skip. (Die Overrides sind mit Schritt 2 ohnehin weg.) - Konsequenz für den Kanalplan: das DFS-Band 5500–5700 ist eine echte Option und liegt bisher brach —
11 zusätzliche Kanäle, in ETSI ohne
/I-Beschränkung. Preis: CAC-Wartezeit beim Start und im Radar-Fall ein erzwungener Kanalwechsel (30 min Sperre). Bei Christophs aktuellem Symptombild (Abbrüche) wäre ein radar-getriggerter Wechsel unangenehm — deshalb jetzt nicht, aber es ist der Reservekanalraum, falls ein dritter AP dazukommt und 40 MHz nicht mehr reicht.
📡 Beobachtung 4b — „könnte 2ghz-g nicht besser zu IoT passen?"
- Verfügbar auf diesem Radio (
/interface/wifi/radio):2ghz-g:20mhz·2ghz-n:20mhz,20/40mhz·2ghz-ax:20mhz,20/40mhz. - ❌ Für Reichweite bringt es nichts.
band=setzt die höchste angebotene Generation, nicht die einzige — ein2ghz-ax-AP ist rückwärtskompatibel, g/n-Clients assoziieren normal. Und ein schwacher Client fällt über die Ratenadaption von selbst auf die robusten niedrigen Raten.bandändert weder Sendeleistung noch Empfängerempfindlichkeit. - ✅ Für Interoperabilität ist der Gedanke aber richtig. Billige ESP-/Realtek-IoT-Stacks haben
dokumentierte Probleme mit 802.11ax-Beacons (HE-Capabilities, PMF).
2ghz-nnimmt die HE-Elemente aus dem Beacon und kann Assoziationswackler beheben — ein Kompatibilitäts-, kein Abdeckungsargument. - 🎯 Pointe: genau dieser Instinkt steckte schon im Fehler.
channel.band=2ghz-naufw2-iot(Fund D) war exakt der Versuch, IoT ein legacy-freundlicheres Band zu geben. Die Absicht war richtig, der Mechanismus falsch —bandist eine Eigenschaft des Radios, nicht eines Slave-VAPs. Alle 2,4-GHz-SSIDs teilenwifi2. - Empfehlung, falls Fund F (5-Minuten-Takt) nach dem Override-Fix bleibt:
wifi2global auf2ghz-n— die saubere Version dessen, was der Override wollte. Kostet real nichts (kein 2,4-GHz-Client hier braucht ax-Raten,dirtyvader-mainauf 2,4 GHz ist ohnehin Fallback).2ghz-gNICHT als ersten Schritt: die 20-MHz-Bindung ist richtig, aber 54 Mbit/s-Deckel und kein HT für alle 2,4-GHz-Clients ist ein echter Verlust ohne Zusatznutzen gegenübern.gist die Eskalationsstufe, nicht der Einstieg.
🏠 Deckenmontage-APs — bringen sie einen echten Vorteil? (Christophs Überlegung 2026-08-17)
- Der Gewinn liegt in Platzierung und Antennendiagramm, nicht im Silizium. Ein cAP ax ist dieselbe Chip-Generation und ebenfalls 2×2 wie der hAP ax² — mehr Rohleistung gibt es nicht. Was er gibt: ein nach unten optimiertes Diagramm, freie Sichtlinien von der Decke, PoE-Montage ohne Möbel davor.
- 🔴 Aber die Entscheidung wäre heute blind gewesen. Vor dieser Session lagen ~9 dB auf ap2 brach (Fund B), 2,4 GHz verschenkte ~3 dB an 40 MHz (Fund A) und der 5-GHz-Zellenrand ~3 dB an 80 MHz (Fund C). Hardware zu kaufen, um Fehlkonfiguration zu kompensieren, ist der teuerste Weg. Genau das deckt sich mit Christophs eigener Randbedingung („nicht kaufen, bevor alles aus dem AP raus ist").
- ✅ Jetzt ist der Boden gelegt (beide APs 18 dBm, überlappungsfrei, 20 MHz auf 2,4). Die Entscheidung gehört an den Re-Walk (Schritt 5). Bleiben danach Dead Spots — Terrasse, Kanten —, dann ist es ein Platzierungsproblem, und Deckenmontage ist die richtige Antwort. Dann stellt sich aber zuerst die billigere Frage: reicht Umhängen der vorhandenen APs? „Drehen hat nicht geholfen" passt zu einer Abschattung, die Drehen nicht behebt — Versetzen schon.
- 📌 Falls es auf drei APs hinausläuft, wird die CAPsMAN-Abwägung neu geführt (s. Beobachtung 5): bei 3 APs ist koordinierte Kanal-/Leistungsverwaltung erstmals ein Laufzeit- und nicht mehr ein Einmalproblem. Und der diskriminierende Test aus Fund B (ist ap2s Radio gerätespezifisch schwach?) gehört vor einen Kauf.
📋 Umsetzungsreihenfolge (alles via GC, gestaffelt, ap2 zuerst)
- ✅ Fund D DURCH (2026-08-17) —
channel.*-Overrides vonw2-iotauf beiden APs entfernt.w2-iotist danach auf ap1 und ap2BR(bound + running) → Beobachtung 3 strukturell erledigt. Dateien:routeros/tp25-schritt2-fix-overrides-ap2.rsc,routeros/tp25-schritt1-3-ap1.rsc. - ✅ Fund A DURCH (2026-08-17) — Inline-
channel.*aufwifi1/wifi2geleert. 2,4 GHz läuft jetzt auf 20 MHz (2412/axbzw.2462/ax, keinCe/eCmehr), tx-power 15 dBm. ap1 ch1 / ap2 ch11 = überlappungsfrei mit Platz für ch6 in der Nachbarschaft. - ✅ Fund B+C DURCH (2026-08-17) —
ch-5gaufwidth=20/40mhz; ap15180/ax/Ce/I, ap25220/ax/Ce/I, beide 18 dBm (ap2 vorher 9). Zellen benachbart, überlappungsfrei (5170–5210 / 5210–5250).- 🔴 GOTCHA, der zwei Deploys gekostet hat:
/interface/wifi/set <if> !channellöscht die Inline-Sub-Property-Overrides NICHT — es wirft nicht, es tut nichts. Danach standchannel.widthunverändert da, obwohl Profil undconfigurationkorrekt auflösten. Richtig ist einzeln:!channel.width !channel.band !channel.skip-dfs-channels. Dasselbe Muster wie der bekannte!configuration.ssid !security.*-Griff aus dem TP3-Bring-up — nur nie aufchannel.*angewandt. - ⚠️ Zwischenzustand war schlechter als der Ausgangszustand: weil die Breite noch auf 80 MHz stand, rutschte ap2 mit der neuen Frequenz in denselben 80-MHz-Block wie ap1 (beide ch36–48) = genau die Co-Channel-Lage, die 2026-06-18 wegkonfiguriert werden sollte. Merke: bei Kanalarbeit Breite VOR Frequenz ändern, sonst erzeugt man auf dem Weg eine Kollision.
- 🔴 GOTCHA, der zwei Deploys gekostet hat:
- 🔜 Fund E —
access-listmitsignal-range-Boden je AP; Schwellen erst nach dem Re-Walk festlegen. (Hinweis aus der P750W-Historie:/interface/wifihat keindisconnect-timeout/keepalivemehr — das gab es nur im altenwireless-Paket, AX-Radios können nicht zurück. Der Signal-Boden ist damit der einzige verbleibende Griff gegen klebende Clients.) - Re-Walk + Dead-Spot-Kartierung (der übernommene TP3.3-Rest) — erst jetzt, gegen die korrigierte Basis. Vorher gemessene Werte sind wertlos.
- ⏳ Drift-Lücke — Teil 1 GESCHLOSSEN, Teil 2 offen und jetzt exakt vermessen (2026-08-17).
- ✅ Der akute Teil ist zu: die neuen Werte stehen in der SoT (
nautobot/ingest-ap-configcontext.py:radios[5g].width20/40/80mhz→20/40mhz,DEVICE_CHANNELS[ap2][5g]149→44), Config-Context gepatcht, dann Backup → Intended → Compliance → 72/72, keine Drifts. Damit kann ein künftiger Deploy die Fixes nicht mehr zurückdrehen. (Bemerkenswert:widthfür 2,4 GHz stand dort die ganze Zeit korrekt auf20mhz— die SoT war richtig, nur das Gerät hat sie nicht befolgt. Der Beweis, dass das Problem der Inline-Override war und nicht die Datenlage.) - ✅ ERLEDIGT 2026-08-18 (mit dem TP28-GC-Umbau). Die
wifi-*-Features haengen jetzt am Core, die APs sind auf diecap-Zeile eingedampft, und drei neue Rules (wifi-capsman,wifi-provisioning,wifi-cap) decken den Rest ab. 92/92 compliant. Die unten beschriebene Luecke auf/interface wifiist damit gegenstandslos: ein CAP hat keine Inline-Overrides mehr. Der historische Befund bleibt als Begruendung stehen: - 🔴 Der Erkennungsteil bleibt offen. Die 18 Compliance-Rules abgefragt — es fehlen genau zwei Sektionen:
vorhanden fehlt /interface wifi channel·… configuration·… datapath·… security·… steering/interface wifi(die Interface-Sektion)/ip firewall nat/ip firewall filter - Folge 1 (WLAN): die fünf
wifi-*-Features decken nur die Profilobjekte ab. Die Inline-Overrides leben in/interface wifi— deshalb sind Fund A und D seit dem 2026-08-08 unentdeckt geblieben, obwohl die Flotte durchgehend „compliant" meldete. Genau die Lücke, die ich unter Beobachtung 5 vermutet hatte; sie ist jetzt belegt, nicht vermutet. Erschwerend: die VAP-MAC-Adressen sind gerätespezifisch (Template Zeile ~220 nimmt sie bewusst raus), eine Rule auf diese Sektion braucht also erstlocal_config_context_dataje AP. - 📋 Vorarbeit
/ip firewall filter(2026-08-17, Reconnaissance — vor dem Template-Bau nötig):crs326-core25 Regeln (defconf + TP10 + 6 TP5-Holes + 11 TP5-E2 + Log-Regel) ·crs326-branch0 ·ap1/ap2je 12 defconf-Regeln (Werksreste: input-seal, fasttrack, ipsec-Zeilen, sogar „accept to local loopback (for CAPsMAN)" — inert, weil die APs nicht routen, aber vorhanden). ➡️ Zwei Entscheidungen, bevor die Rule scharf gemacht wird, sonst meldet sie sofort flächendeckend Drift: (a) APs: die 12 defconf-Regeln als Sollzustand ins Template schreiben oder sie abräumen (sie tun nichts — ein reiner AP hat keineforward-Kette zu schützen). Empfehlung: abräumen, sonst schreibt man Werksmüll als Absicht in die SoT — dasselbe Argument wie beitelnetin TP16.1. (b) branch: 0 Regeln ist der korrekte Sollzustand und muss im Template auch als leer gerendert werden. - ✅ Folge 2 — GESCHLOSSEN (2026-08-17, TP26):
/ip firewall filterhat jetzt eine Compliance-Rule. Vorher gab es nurip-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.
- ✅ Der akute Teil ist zu: die neuen Werte stehen in der SoT (
- ⚠️
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 backupje AP vorher. - Abh.: TP22 ✅ (GC-Deploy-Pipeline). Übernimmt den offenen Rest von TP3.3, verwandt TP3.2 (Coverage-Doku
docs/wifi-p750w-coverage-and-map.md). Kein Blocker für TP5/TP6 — läuft parallel.
TP39 · Gitea #68 — LXC-Hygiene auf pve: Resolver-Altlasten, networking.service, DB-Reverse-Lookup
Auslöser: ein 10-Sekunden-Hänger auf gitea, gefunden am Rand des TP16.3-§5-Flips. Er hatte mit
dem Flip nichts zu tun, war aber nur deshalb sichtbar, weil zum ersten Mal jemand systematisch
gemessen hat. Beim Beheben kam eine zweite, unabhängige Altlast zum Vorschein. Beide sind
Hygiene an denselben pve-LXCs und gehören in ein Wartungsfenster — deshalb ein TP, nicht zwei.
Was am 2026-09-01 bereits erledigt ist (Ausgangslage, nicht Aufgabe)
- Ursache des Hängers: MariaDB (LXC 302,
10.40.20.23) hatteskip-name-resolveauskommentiert ⇒ Reverse-Lookup bei jeder neuen Verbindung;/etc/resolv.confzeigte auf den toten10.40.41.254(VLAN1-Altschema). Gemessen: 10.010 ms je Lookup. Pool-Verbindungen waren schnell ⇒ das Symptom wirkte sporadisch. - Blast-Radius, per Verbindungstabelle belegt: an dieser DB hängen Vaultwarden (
.127), Home Assistant (.105) und gitea (.157). - Fix ausgerollt (
pct set <id> --nameserver 10.40.20.1+ Reboot) für fünf LXCs:302 mariadb,102 mqtt5,106 influxdb2,107 redis,150 iob-exposed. Nachher: Lookup 21–24 ms, gitea 0 von 25 Proben langsam (vorher ~10 % bei 10,1 s).
Scope (alle Punkte erledigt)
- ✅ ERLEDIGT 2026-09-01:
skip-name-resolveaktiviert. Vorhermysql.usergelesen (User gab den DB-Zugang per/root/.my.cnf) — kein einziger Grant lautet auf einen DNS-Hostnamen, alle sind%/ IP-Literal /localhost. Damit kannskip-name-resolveniemanden aussperren; der Reverse-Lookup war reiner Ballast. Gesetzt als eigenes Drop-in/etc/mysql/mariadb.conf.d/90-skip-name-resolve.cnf(nicht die#-Zeile in50-server.cnfeditiert — Paket-Update-stabil),@@skip_name_resolve=1nach Neustart verifiziert. Wirkung: gitea/vw/hass je 0 von 12 frischen Anfragen langsam, max 0,25 s. Alle drei Clients danach wieder verbunden. Die Ursache ist damit beseitigt, nicht nur entschärft. 🔴 Sicherheitsvorfall dabei: die.my.cnftrugpassword <wert>ohne=, die Maskierung griff nicht ⇒ das root-DB-Passwort ist ins Transkript geraten und gehört rotiert (→ TP30). - ✅ ERLEDIGT 2026-09-01:
networking.service+ifupdown-wait-online.servicein101,102,106,107repariert. Ursache — dieselbe Altlast wie beim Resolver: in/etc/network/interfacesstanden nochauto-Stanzas aus dem alten VLAN1-Schema (eth0→10.40.41.x) und aus früheren Versuchen (veth16,veth24, ein Tippfehlereth01) — alle auf Interfaces, die es im Container nicht gibt.ifup -ascheiterte daran, während das echteveth20sauber hochkam: „failed" bei funktionierendem Netz. Fix: nur die toten Stanzas entfernt (Backup je Container:/etc/network/interfaces.bak-20260901),lo/veth20/veth20.2unangetastet. Beweis ist ein echter Neustart, nicht der Servicestatus:106neu gestartet ⇒ influxdb kam nach 5 s von selbst hoch,networking active, null fehlgeschlagene Units. Genau der Fall, der vorher scheiterte. 🔑 Nicht durch die Session verursacht:101wurde vor dem Fix nie angefasst und zeigte dasselbe Bild — die Container liefen nur 13+ Tage ohne Neustart, deshalb war es unsichtbar. 🟡 Rest, bewusst liegen gelassen:run-rpc_pipefs.mount(101, 150) undproxmox-regenerate-snakeoil.service(108) — vorbestehend, ohne Bezug zu Netz oder DNS. - ✅ ERLEDIGT 2026-09-01 (im selben Fenster aufgetaucht): LXC 302 war zu 100 % voll (62/65 GB),
Rootfs
+30Gonline gewachsen ⇒ 95 GB / 69 %, MariaDB lief durch. 🔴 Das ist ein Puffer, kein Fix: 59 GB davon sind diehomeassistant-DB (states.ibdallein 41 GB), die unbegrenzt wächst (~1 GB/Tag) — die dauerhafte Lösung ist HA-seitig und liegt in TP40. - ✅ ERLEDIGT 2026-09-01: Resolver-Sweep durchgezogen — pve UND NAS. pve: alle 13 LXCs
(
101,102,105,106,107,108,110,111,112,130,150,302,400) tragennameserver 10.40.20.1, kein.41.254mehr — nicht nur die fünf geänderten. NAS (DS923) via Portainer-API ep14: alle 20 Container gelistet, keiner mit.41.254-DNS-Override; alle laufenden lösen über den Embedded-Resolver (127.0.0.11) in 66–110 ms auf (rc=0), inkl. Grenzfallgitea(erstellt 2026-07-10, um den Host-Fix herum) — kein eingefrorener Dead-Resolver, kein Recreate nötig. NAS-Host/etc/resolv.conf=10.40.20.1. Als wiederkehrende Kontrolle bleibt der Sweep als CLAUDE.md-Gotcha verankert (pve-Einzeiler + Synology-DSM-Fallstrick von 2026-07-10). - ✅ ERLEDIGT 2026-09-01: Abnahme-Regel festgeschrieben. „Vor jedem geplanten LXC-Neustart
systemctl --failedlesen und danach die Ports gegen vorher vergleichen" steht als CLAUDE.md-Gotcha (Fallinfluxdb2wäre sonst still durchgerutscht).
Abhängigkeiten
- Keine blockierenden. Punkt 1 brauchte DB-Credentials (siehe TP30, Credential-Bestand).
- Punkt 2 war unabhängig und lief zuerst.
Abgrenzung
- Nicht TP16.3: dort geht es um cloudflared/Tunnel: der DNS-Fund kam nur dabei ans Licht.
- Nicht TP14.2a: das war 2026-07-10 derselbe Fehlertyp an anderen Hosts (NAS + LXC 400) und ist abgeschlossen. Dass er hier erneut auftrat, ist genau die Begründung für Punkt 4: die Klasse wurde damals an den bekannten Stellen behoben, nie im Bestand gesucht.
- Nicht TP31/TP34 (Caddy) und nicht TP11 (Monitoring) — obwohl gilt: ein Monitoring, das DB-Verbindungszeiten kennt, hätte diesen Fall Monate früher gezeigt.
- Nicht TP40: der HA-Recorder-Wildwuchs (Punkt 3) ist HA-seitig und ein eigenes TP.
TP34 · Gitea #24 — Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle)
➡️ Fortsetzung 2026-09-22:
TP34.2 — Interne DNS-Namen als Daten(Gitea #73, Prosa indocs/teilprojekte.md→### TP34.2). Dort lebt der Daten → gerenderte Config-Gedanke weiter; verworfen bleibt nur das Caddyfile-Rendering (dieser Abschnitt hier). 🔴 Nachtrag 2026-09-08 (verworfen): Der Ansatz „Caddyfile via Golden Config rendern" ist zurückgezogen (Commitsd63dc7b,bca8f6e; Gitea-Issue #24 →status:dropped, closed). Der420.teilzeitladen.xyz-Block wurde wieder aus dem GC-gerenderten Caddyfile entfernt; der Caddyfile bleibt manuell incaddy/Caddyfile. Gründe: kein zweites SSoT-Modell für Proxy-Routen nötig, TP37 deckt die Dienst-Doku alsipam.Servicebereits ab, und der einzige akute Anwendungsfall ließ sich mit einem manuellen Block lösen. Text unten unverändert als Konzept-Historie.
Konzept + Architektur-Skizze:
docs/handoff-20260827-inventur-und-architektur.md— bitte dort weiterlesen (Architektur-Abschnitt).
- Scope: Reverse-Proxy-Hosts werden im Nautobot-Datenmodell gepflegt (Site, Host, Backend-Spec). Golden Config rendert den Caddyfile aus den Daten, Diff-Check gegen die Live-Version auf
caddy-bf1, Compliance-Checks + Transaktionen identisch zum bestehenden Workflow für Router-Configs. - Auslöser (Inventur 2026-08-27): der Caddyfile (
bf-infra/caddy/Caddyfile) ist heute manuell gepflegt — kein Drift-Check, keine Transaktionen, andere Projekte können keine Sites anlegen ohne Christoph. Lösung: Nautobot/GC, kein Caddy-API-Sidecar (kein zweites SSoT). - Erster Anwendungsfall:
terpene.teilzeitladen.xyz → http://10.40.20.167:8890(Mac-mini-Backend, dort PostgREST + sync + web via lokalem Caddy:8890). Vor TP34: manueller Quick-Win-Caddy-Block. - Abh.: TP22 (GC-Pipeline) ✅ · TP23 (DNS/Caddy-Voraussetzungen) ✅ Stufe 1 · 🔴 NEU 2026-09-06: TP37 Punkt 1+2 — Caddy rendert Config aus Daten, die Backend-Dienste müssen als
ipam.Servicein Nautobot existieren, sonst gibt es nichts zu rendern. TP37 vor TP34. - Datenmodell (entschieden 2026-09-06): native Modelle — Backend =
ipam.Service, Proxy-Route = Relationship/CustomField Frontend↔Backend, GC-Job rendert den Caddyfile. Keine eigene App (konsistent zu TP44). - Status: 🔜 Stub; wartet auf TP37 P1+2. Quick-Win
terpene.teilzeitladen.xyz → 10.40.20.167:8890als manueller Caddy-Block ist Schritt 0 des Runbooks. Plan:handoff-20260906-tp37-34-36-plan.md.
TP44 · Gitea #33 — Cloudflare-Estate als Dokumentations-SSoT in Nautobot
Entscheid (User, 2026-09-02): die volle CF-Estate (Tunnel + WARP-Connector + VPC-Service + Hyperdrive + Workers + alle Access-Apps) als strukturierte, abfragbare SSoT in Nautobot abbilden — etappenweise: manuell jetzt, Sync später. Nautobot kann CF nicht steuern → „SSoT" heißt Dokumentations-SSoT; CF bleibt operativer Master. Detail-Handoff:
handoff-20260902-cf-estate-nautobot-ssot.md.
- Warum eigenes TP, nicht TP36: TP36 ist eng auf
teilprojekte.md-Live-Daten geschnitten; gleiche Idee (Nautobot als Doku-SSoT), andere Dimension. TP44 = nächste freie Nummer nach TP43. - Modell (native
nautobot.cloud, Nautobot 3.1.7 — keine eigene App):Manufacturer "Cloudflare"→CloudAccount(393c051f…) →CloudResourceType ×6→CloudNetwork ×4(bf-public/fm/terpene-db/bf-core-mesh) +CloudService ×14; Service↔Tunnel über das Through-Modellcloud-service-network-assignments(3 Rows). IDs/Ports/Hostnames/Origins je Objekt inextra_config. - Werkzeug:
nautobot/tp44-cf-estate-seed.py— idempotenter Seeder (Re-Run = 26/26 „existiert"), Datenstand inline (Live-CF-Inventur 2026-09-02). Token ausdocs/nas-vlan20/stacks/210-nautobot.yml. - ✅ Verifikation 2026-09-06 (live gegen die API): CloudAccount 1 · ResourceType 6 · CloudNetwork 4 · CloudService 14 — unverändert seit 09-02.
- 🔴 Gotchas:
CloudService.cloud_networksistread_only(nur Through-Rows schreiben/lesen) · VPC-Service-API unterconnectivity/directory/services(PUT, voller Body) · VPC-Objekte tragen ihren Identifier inservice_id, NICHTid(kostete im Sync einen Fehl-Match) · ⚠️ DRIFT-KORREKTUR 2026-09-10: die frühere Zeile „Repo-CF_API_TOKENdarf kein Workers-VPC → über dencloudflare-MCP" war falsch. Live getestet liest derCF_API_TOKENaus~/.secrets/credentials.envHyperdrive und VPC und Workers (alle 200). Der schmale Token istCF_DNS_API_TOKEN(403). Dercloudflare-MCP ist der remote OAuth-MCP (kein API-Token) und für einen serverseitigen Job ohnehin nicht nutzbar. - ✅ Etappe 2 Teil A (2026-09-08): IPAM-Prefixe live.
10.40.0.0/16(container, Routebf-core-mesh) +10.101.0.0/24(network, Routefm) angelegt vianautobot/tp44-ipam-prefixes.py; der Seeder-Re-Run hat die zweicloud-network-prefix-assignmentseingehängt (count=2, Idempotenz-Gegenprobe grün). - ✅ Etappe 2 Teil B (2026-09-10): Live-Sync als Nautobot-Job — DURCH. Governance (User 2026-09-09):
periodische externe→Nautobot-Syncs leben als Nautobot-Jobs in
bf-infra/jobs/, in Nautobot geplant — kein per-Task-Container/-Cron. Runtimejobs/cf_estate_sync.py(CFEstateSync, ORM, read-only Pull, 403-tolerant, Verwaisung =extra_config.stalestatt Löschen). Token = Nautobot-Secretcf-api-token(Provider env →CF_API_TOKENam Worker, in210-nautobot.ymlverdrahtet). Schedule: täglich 03:00Z (ScheduledJob "CF Estate Sync – taeglich"). Verifiziert: Dry-Run + Commit-Run sauber, 4 Networks / 14 Services, alle Endpoints lesbar, 0 Drift. Der REST-Einmalproofnautobot/tp44-cf-sync.pybleibt als workstation-seitiges Diagnose-Werkzeug liegen (nicht die kanonische Runtime).- 🔴 Drei load-bearing Funde (Detail-Handoff
handoff-20260910-tp44-teilb-sync-live.md): (1) Wurzel-__init__.pyim Repo ist Pflicht — Nautobot lädt Git-Repo-Jobs viapkgutil.walk_packages([GIT_ROOT]), das Namespace-Packages (ohne__init__.py) NICHT entdeckt; ohne die Datei bleibtbf_infra.jobsunsichtbar (Symptom: Sync SUCCESS + „No jobs were registered"). bf-infra ist das erste Git-Repo mitextras.job. (2)register_jobs()gehört ins Paket-__init__, nicht nur ins Submodul. (3)Meta.has_sensitive_variables=Falsenötig, sonst verweigert Nautobot das Scheduling.
- 🔴 Drei load-bearing Funde (Detail-Handoff
- Beziehung zu TP37: TP44 hat TP37 Punkt 3 (CF-Connectoren) vorweggenommen — dieselbe native-Modell- Linie, die TP37 P1+2 (Substrat/Dienste) fortsetzt.
TP41 · Gitea #30 — CF-Access-Reparatur + Zero-Trust-Konsolidierung — Auth-Kern seit 2026-09-01 komplett; Gelis WARP-Client am 2026-09-10 via Android erfolgreich eingerichtet (letzter Blocker weg, User-Bestätigung). Optionale Restpunkte (T6 Rate-Limit, geli-CGNAT-Policy-Cleanup) bewusst nicht gezogen; Keystore-Rotation läuft unter TP30 #7.
Auslöser: CF-Access zwang Christoph und Geli täglich zum OTP-Login (soll: 30 Tage); GitHub/Google
„funktionieren nicht". Root-Causes: Team-Domain-Rename bf4→emsenhuber (Provider-Callback veraltet),
App-Session 24h, diverse Ordnungs-/Sicherheitslecks. Vollständiger Verlauf + offene Schritte:
docs/handoff-20260901-tp41.md. Branch tp41-cf-access-repair.
✅ Live erledigt: Session 720h (Wildcard/vw/Warp-Login) · login_method-Loch zu (reusable Policy
bf-users = nur email:christoph+email:geli) · 8e44f5d1 von 4 Apps auf nur Terpenfinder
entkoppelt · Access-Gruppen zt-humans/zt-home/zt-automation, Policies zeigen darauf · vw voll
Bypass (Lebensader offen) + vw/admin per WAF-Regel öffentlich geblockt (CF-Edge + Mobilfunk
verifiziert) · API-Token auf das vollständige …4148 konsolidiert (User hat Service-Tokens- + Zero-Trust-
Write ergänzt), altes …2174 revoken.
✅ T4 DURCH (2026-09-01, Variante B): ein Access-Service-Token zt-svc (65f1821a, rotiert) über
Gruppe zt-automation; Terpene-Worker per wrangler secret put TERPENE_SVC_CLIENT_ID auf zt-svc
umgestellt (Worker-Pin index.js:44); terpene-verify+-v2 gelöscht; test_whoami grün.
Token-Altlast geklärt: b00722 = LIVE Caddy-DNS-Token (LXC130 caddy.env, SSoT), d47435 = stale
Kopie (kein Consumer) → User revoket d47435; credentials.env-Kopie auf b00722 realignt.
✅ T3 APPLIED (2026-09-01): Default-Profil (0197d1b3; das custom „Cloudflare Mesh" matcht nur den
warp_connector) fallback_domains += emsenhuber.net → [10.40.20.36, 10.40.20.37]; Tunnel-Route
10.40.0.0/16 (d1da7c8a) da, kein 10/8-Exclude → routbar. ⏳ Client-Verify: WARP neu verbinden.
✅ T2 DURCH (2026-09-01): WAF-Regel f26744eb gelöscht; Caddy vw-Block respond @cf_admin 404 bei
Header CF-Connecting-IP (LXC130). Verify: Edge /admin=404, lokal/WARP /admin=200. ✅
✅ T5 DURCH (2026-09-01, User-bestätigt): GitHub-Login läuft; Google-Login läuft nach dem
Consent-Screen-Fix (§A des Follow-up-Handoffs: User Type Internal→External/veröffentlicht).
Callback für beide https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback.
❌ Facebook/Meta für TP41 abgesagt (2026-09-01, User-Entscheid): optional, kein Bedarf — Geli ist
über OTP angelikahy@outlook.de + Google pillepalle670@gmail.com voll gedeckt. Keine Facebook-App,
kein CF-Facebook-IdP angelegt → nichts aufzuräumen. Instagram hat ohnehin keinen CF-IdP.
✅ App-Launcher (D1): je eine Bookmark-Kachel vw/hass/terpenfinder, Wildcard-Kachel raus, Launcher
gestylt (Follow-up-Handoff §D, Policies unverändert).
✅ Geli in WARP — CF-seitig nichts zu tun (2026-09-01 live geprüft): Device-Enrollment läuft über
die App „Warp Login App" (6c32fe23…, type warp) → Policy bf-users → Gruppe zt-humans, die
Gelis beide Mails schon enthält → sie darf bereits enrollen (deshalb war „Device enrollment
permissions" nicht als fehlendes Setting zu finden). Terpenfinder-geli-Policy lässt sie per E-Mail durch.
✅ Client am 2026-09-10 via Android erfolgreich eingerichtet (WARP installiert, Team emsenhuber,
Login OTP angelikahy@outlook.de — User-Bestätigung); damit ist der einzige verbliebene Handgriff erledigt.
🔑 Permission-Frage beantwortet: CF-seitig keine nötig. Für generelle WARP/Enrollment/User-Verwaltung
per Account-Token: Access: Apps and Policies → Edit + Access: Organizations, IdPs, and Groups → Edit
(User erteilt 2026-09-01). Seat-Verwaltung (/access/seats) bleibt per MCP gesperrt — 10405 Method not allowed for this authentication scheme (Endpoint will User-Token, nicht Account-Token; kein Scope-Fix,
für Enroll irrelevant).
🔻 Optionale Restpunkte (bewusst nicht gezogen, kein Blocker): T6 optional Rate-Limit ·
🔴 TERPENE_ANDROID_KEYSTORE_PW-Rotation (→ TP30 Posten #7, Transkript-Leak) · Security-Cleanup:
die geli-Terpenfinder-Policy hat OR-Semantik und enthält den breiten CGNAT-Bereich
94.154.138.0/24 als IP-Include → jeder aus dieser geteilten Range käme ohne Login rein. Über WARP ist
der Egress ohnehin Cloudflare (nicht diese IP) → der IP-Include wäre dann überflüssig und entfernbar.
d47435-Revoke ✅ · T3-WARP-Client-Verify ✅ (User, 2026-09-01).
Abgrenzung: hass/gitea bleiben (diese Runde) öffentlich; Terpenfinder-Human-Policies nicht angefasst; Gitea-Least-Privilege = eigener künftiger TP (jedes Projekt repo-scoped Login, Admin nur Claude/Christoph).
- Bezug TP11 (Monitoring): eine Plattenfüllstand-Warnung hätte das Wochen früher gezeigt.
TP43 · Gitea #32 — dw-Standort-DNS-Uplink (site-spezifische Overrides)
Kurz zwischen 2026-09-11 verworfen und am selben Tag reopened: die 420-Prämisse war gegenstandslos
(public CF-Worker, via WARP/TP41 gelöst), aber die interne BF-Namensauflösung über WG am dw blieb
dabei offen (portainer.bf.emsenhuber.net am dw nicht erreichbar). Korrigierter Scope + verworfene
420-Historie stehen jetzt aktiv in teilprojekte.md. Gitea-Issue #32 = status:todo · thema:firewall-dns.
TP42 · Gitea #31 — Namens-Vereinheitlichung: ein interner Suffix bf.emsenhuber.net — ein interner Suffix bf.emsenhuber.net, .bf.lan raus, .16 (adguard_bf1) abgebaut, Compliance 140/140. Offen nur der an TP37 gekoppelte Nautobot-Doku-Teil.
Auslöser (2026-09-01, TP41-Randbefund): live gemessen liefern die realen Client-Resolver
10.40.20.36/.37 *.emsenhuber.net → 10.40.20.40 (Caddy) — korrekt. Daneben existiert aber ein
zweiter, gedrifteter interner Namensraum: der Core trägt in /ip dns static 11 Einträge auf
*.bf.lan, der Caddyfile doppelt jeden internen Namen als *.bf.emsenhuber.net, und die alten
AdGuard .16/.17 antworten noch mit nginx*.bf.emsenhuber.net bzw. totem VLAN1 10.40.41.123.
Christoph: „aus emsenhuber.net wurde schon wieder bf.lan — das müssen wir ein für alle mal aus allen
Geräten rausprügeln und in Nautobot festhalten."
Ziel: genau ein interner Namensraum emsenhuber.net (Split-Horizon .36/.37 → .40). .bf.lan
und .bf.emsenhuber.net werden entfernt; Sollzustand in Nautobot dokumentiert.
Scope (Reihenfolge = eigene Session):
- Bestandsaufnahme aller Fundstellen: Core
/ip dns static(*.bf.lan), DHCP-Optiondomain/Search-Domain je Netz, Caddyfile-Aliase (*.bf.emsenhuber.net), AdGuard-Rewrites.36/.37, stale.16/.17, Geräte-identity. - Entscheidung Zielschema (nur
emsenhuber.net, ggf.bf.emsenhuber.netals einzige interne Zone — Christoph-Entscheid) und Migrationsreihenfolge ohne DNS-Loch. - Umsetzen: Core-DNS + DHCP + Caddyfile angleichen; stale
.16/.17klären/abbauen. - Nautobot: interne Namen/Records als Sollzustand erfassen (Bezug TP37 Datenmodell).
Abgrenzung: kein CF-Public-DNS-Umbau (Zone emsenhuber.net öffentlich bleibt); kein Resolver-Swap
(.36/.37 bleiben); .1-als-DNS-Reste auf Clients sind separat/tolerierbar (User: „bis jetzt kein
Problem"). Abh.: TP37 (Nautobot-Datenmodell) für Punkt 4; sonst nichts Offenes.
✅ Bestandsaufnahme LIVE (2026-09-02) — Drift hat 80 % schon erledigt
Gegen die Geräte gemessen (MikroMCP + dig), nicht aus dem Handoff:
| Fundstelle | Handoff 09-01 | Live 09-02 |
|---|---|---|
Core /ip dns static |
11× *.bf.lan |
✅ 0× .bf.lan — 10× *.bf.emsenhuber.net (deckt sich mit GC-Template Z.284–293) |
DHCP domain (7 Netze) |
„prüfen" | emsenhuber.net (GC-Template Z.133 = gleich ⇒ keine Drift), DNS .36/.37 |
.36/.37 (Soll) |
aktiv | vw.emsenhuber.net→.40 ✅ · macmini.bf.emsenhuber.net→.20.167 ✅ · macmini.emsenhuber.net→leer ❌ |
| Caddyfile | *.bf.emsenhuber.net-Aliase |
unverändert, konsistent mit Core-Static |
.16/.17 |
tot | laufen (:53), liefern totes VLAN1; kein Core-Objekt (Firewall/NAT/DNS-Upstream/Addr-List) hängt an .16 |
Kernkonflikt: DHCP verteilt emsenhuber.net (bare), Records leben unter bf.emsenhuber.net ⇒ bare macmini löst nicht.
✅ Entscheidungen (User, 2026-09-02)
- Zielschema =
bf.emsenhuber.net(der wenig-Arbeit-Weg): DHCP-domain →bf.emsenhuber.net, dann löstmacminibare korrekt; Core-Static + Caddyfile bleiben (tragen schon.bf.). Öffentliche Zoneemsenhuber.netbleibt getrennt. .16(adguard_bf1) abbauen,.17(adguard_fm2 = Standort FM) NICHT anfassen.
✅ Umsetzung DURCH (2026-09-02)
- (A) DHCP-domain
emsenhuber.net → bf.emsenhuber.netüber GC ✅ — kein Direkt-Write:mikrotik_routeros.j2Z.133 gehoben →push-gc-template.py(Commit7a4068c4, Nebenbefund: das Remote-Template hing dem lokalen hinterher — es trug noch*.bf.lan+router.lan, obwohl Gerät+lokal längst.bf.emsenhuber.netfuhren; der Push hat das GC-Repo an den Live-Stand angeglichen) → GitRepo-Sync (SUCCESS) → manueller ConfigPlantp42-dhcp-domain(set [find] domain=…, weiladddas Netz doppelt anlegen würde) → Deploy an crs326-core → Live 7/7 = bf.emsenhuber.net, Compliance 140/140, keine Drifts. Der Job steht dauerhaft innautobot/gc-configplan.py. - (B)
.16-Teardown ✅ —adguard_bf1lag im geteilten Portainer-Stack 195adguard(Docker-LXC.126, ep2 — nicht ep14) zusammen mitadguard_fm2(.17, Standort FM!). Deshalb nicht Stack löschen, sondern compose auf nur.17getrimmt + Stack redeployt (Prune):.16-Container weg,.16:53tot;.17läuft (⚠️ ~40 s mit-neugestartet durch den Redeploy — kurzer FM-DNS-Blip, danach sauber). Rollback-compose gesichert. 🧹 Daten-Dirs/opt/docker/adguard_bf1/*bleiben als harmlose Leichen auf dem LXC. - (C) Nautobot-Soll (Scope-Punkt 4) bleibt an TP37 gekoppelt (Datenmodell), separat — kein Blocker.
Status: ✅ Namensraum vereinheitlicht (2026-09-02) — ein interner Suffix bf.emsenhuber.net,
.bf.lan raus, .16 abgebaut, Compliance 140/140. Offen nur der TP37-gekoppelte Nautobot-Doku-Teil.
Handoff: docs/handoff-20260901-tp42-naming.md.