Files
bf-infra/docs/teilprojekte.md

45 KiB
Raw Blame History

BF-Netzwerk — Teilprojekte (kanonische Steuerung, Stand 2026-06-10)

Zweck: Das große Netz-Projekt in einzeln durchziehbare Teilprojekte (TP) zerlegt — jedes mit klarem Scope, aktuellen Entscheidungen, Abhängigkeiten und Status. Jedes TP ist so geschnitten, dass es eine frische Session mit sauberem Kontext straight abarbeiten kann. Architektur/Historie: ~/.claude/plans/ich-will-das-delegieren-atomic-sunrise.md.

Kanonisches VLAN-Modell (gültig — überschreibt ältere Tabellen)

VLAN Name Subnetz (Ziel) Zweck
10 MAIN 10.40.10.0/24 Trusted (Handy/Laptop/Apple Watch)
20 INFRA 10.40.20.0/24 NAS/VMs/Docker/HA
30 IOT 10.40.30.0/24 Smart-Home (HA-managed), Waage, Fitness-Tracker
40 MEDIA 10.40.40.0/24 Sonos, AppleTV, TV, VuPlus, Cast-Ziele (getauscht ggü. früher)
50 UNTRUSTED 10.40.50.0/24 Spielekonsole, eBook-Reader, Low-Trust-Internet
90 GUEST 10.40.90.0/24 nur Internet
99 MGMT 10.40.99.0/24 Switch/AP/Hypervisor-Mgmt
100 WAN (Arris-Transfer) zum Arris-Kabelmodem (Liwest, Bridge-Mode, Public-IP an ap1)
IP-Blöcke: .1–10 Router/APs (ap1=.1, ap2=.2) · .11–20 Switches (ALLNET=.11, Omada=.12). GW je VLAN = .1.

Ist-Stand (Kurz)

ALLNET-Core .11 (FW2.2.1, VLANs 10/20/30/40/50/90/99/100; GE1/GE2/GE8 Trunk; TP1 ✅ 2026-06-15). Omada-Switch .12 (adopted, TP2 ✅ 2026-06-15; Trunk-ALL auf P1+P2, Access-Profile auf P3-P8; Profile noch PVID=1 bis Omada-PVID-Fix). Omada-Controller .175 (DS923/macvlan, mbentley 6.2, 🟢 live). omada-mcp .176 (pve-LXC, StreamableHTTP, 🟢 live, 84 read-Tools; Controller-API v2 intern via christoph@emsenhuber.com). 2× hAP ax² (7.23.1): ap1 .1 (ALLNET P1) — TP4 ✅ 2026-07-01: Router + WAN-Edge (VLAN-Subinterfaces, DHCP, DNS, NAT, Public-Edge). ap2 .2 (Omada P2 — Trunk). Edge-Cutover ✅ 2026-07-01: FB6660 physisch entfernt (Liwest-Kabelmodemtausch, kein Zurück), Arris-Kabelmodem im Bridge-Mode; WAN = sw1 gi16 Access VLAN100 → gi15 Trunk → ap1 ether2 → vlan100 auf bridge (NICHT ether1); ap1 hält Public-IP direkt (Liwest, kein CGNAT), Double-NAT weg. Telefonie war auf der FB und wird nicht weitergeführt. Vorarbeit: TP10-Kern durch (2026-06-27, WG-Hub live) → Bridge-Gate vorher gelöst. Runbook: routeros/wan-cutover-runbook.md. Kontrolle: MikroMCP (MikroTik) live · ALLNET = Klickanleitungen · Omada → Controller + omada-mcp 🟢. Nächster Schritt: Omada-PVID-Fix (MAIN→PVID10, INFRA→PVID20, untagNetworkIds bereinigen) + IP-Migration Geräte + TP5 Deny-by-default fertigziehen (Sonos-/HA-/mDNS-Holes und WAN-Input-Seal stehen bereits).

🎯 Ziel: sauberes System „from scratch", keine Leichen/Altlasten. Migrations-Session-Endstand = VLAN1 + altes cudy-WLAN komplett weg (VLAN1 nur noch Mgmt, defconf-Client-DHCP zurückgezogen, cudy-Uplinks aufs Ziel-Client-VLAN getaggt oder cudy abgebaut). Unterpunkte/Aufräum-Liste bei Migration: (a) die Interim-Härtung ap2 wifi1/wifi2 frame-types=admit-only-vlan-tagged (TP3.1, 2026-07-06) bleibt gültig — verschwindet automatisch mit VLAN1; (b) st-main rrm/wnm = reines Roaming-Provisorium, prüfen ob nach Migration noch nötig; (c) cudy1 = verbleibender aktiver VLAN1-Leak (Dual-DHCP-Race, Doku Memory project_vlan1_dhcp_incident). Bis dahin sind diese Griffe Krücken, kein Zielzustand. ⚠️ HW-Constraint hAP ax²: 1 GB RAM, aber nur 128 MB Flash + KEIN USB → Container auf dem Router NICHT praktikabel. Folge: native RouterOS-Features bevorzugen (z.B. Built-in-mDNS statt Container); Container (mDNS-Reflector, BIND9-DNS, Omada-Controller) laufen auf NAS/pve, nicht am hAP.


Teilprojekte

TP1 — ALLNET Core-Switch finalisieren ▸ ✅ FERTIG (2026-06-15)

  • ✅ 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 — Omada Access-Switch + Controller ▸ ✅ FERTIG (2026-06-15)

  • ✅ Omada Controller 6.2.10.17 auf DS923 (macvlan .175): omada/docker-compose.yml, Stack via Portainer endpointId=14. Wizard abgeschlossen (configured=true), Creds in mcp/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….
  • ✅ 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, muss nativeNetworkId=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 hat untagNetworkIds=[VLAN1, VLAN20, VLAN10] (3 untagged!) statt [VLAN10]. Access-INFRA hat untagNetworkIds=[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.

TP3 — WLAN / CAPsMAN ▸ ✅ KERN FERTIG (2026-06-18) — routeros/tp3-capsman.rsc

  • ✅ 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-SSIDs install*/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 via set + 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 in dhcp-v40. Household geschlossen, iOS-App findet alle Geräte (mDNS via Repeater). Inventar/IPs = SSoT docs/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/infra einstampfen (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.

TP3.1 — ap2 VLAN-Trunk-Fix ▸ ✅ Config live (2026-07-01) — routeros/tp3.1-ap2-vlan.rsc

  • Root Cause: ap2 (CAP, local forwarding) hatte bridge vlan-filtering=no → datapath.vlan-id wurde 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 auf 10.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. Danach remote-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-main im OG → Lease muss dhcp-v10/10.40.10.x sein (nicht defconf/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); defconf und dhcp-v10 boten parallel → offering ... without success + Minutentakt-Flapping. bridge-ARP auf ap1 = 333 Einträge (flache VLAN1 lebt voll weiter; IoT/Shelly untagged auf 10.40.41.2xx). Griff: auf ap2 die Master-Radio-Bridge-Ports wifi1/wifi2 von frame-types=admit-all auf admit-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). ether2 bleibt admit-all (VLAN1-Mgmt/Trunk, kein Lockout). Rollback: frame-types=admit-all auf 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ätzlich st-main rrm=yes wnm=yes (802.11k/v, behandelt nur das Roaming-Symptom). SSoT-Detail: Memory project_vlan1_dhcp_incident.

TP3.2 — WLAN Coverage / P750W-Discovery ▸ ⏳ teil-erledigt (2026-07-02) — docs/wifi-p750w-coverage-and-map.md

  • ✅ Brother P750W (VLAN30) gelöst: DHCP-client-id-Fix (matcht über MAC → feste 10.40.30.5); an ap1 gepinnt (geordnete wifi-access-list accept w2-iot → blanket reject, überlebt ap2-Re-Provision) — dozende Legacy-Clients nur am co-located-GW ap1 per ARP erreichbar, CAP ap2 nicht; mDNS vlan30 in mdns-repeat-ifaces+5353 → in MAIN auffindbar. Druck+Selbsttest OK. Web-UI http://10.40.30.5/general/information.html.
  • ✅ Nebenbei: multicast-enhance=enabled (iot+media), Guest ft=yes, INFRA-SSID(20) angelegt (nur ap2), Steering-Profil st-main/neighbor-group=bf-main auf beide Main-Configs.
  • Nomenklatur: dynamische ap2-CAP-Slaves (wifi13–22) nicht praktikabel umbenennbar (name-format unzuverlässig) → Map dokumentiert statt umbenannt. Backups bf-ap{1,2}-pre-nomen-20260702.backup/.rsc auf den Geräten.
  • ⏳ Offene Coverage-Arbeit → ausgelagert nach TP3.3 (Fortsetzung in neuer Session).

TP3.3 — WLAN Coverage-Kur ▸ 🔜 TODO (Fortsetzung, neue Session) — docs/wifi-p750w-coverage-and-map.md

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-main auf 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:

  1. 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/scan je AP (störend — wirft Clients kurz ab) gegen Abend-Congestion. Output → SSoT-Doku.
  2. 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.
  3. INFRA(20) auf ap1 ergänzen (fehlt — sendet nur auf ap2): lokaler w2-/w5-infra-Slave analog w2-/w5-media.
  4. 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 — Router-Cutover (hAP#1 = Router + WAN-Edge) ▸ ✅ FERTIG (2026-07-01)

  • ✅ 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.1 als Bootstrap; FB-Upstream abgelöst). Statische Einträge für alle Infra-Hosts unter bf.lan (13 Einträge, Transition-IPs bis PVID-Fix).
    • ⚠️ Auto-Suffix .lan (RouterOS-Einschränkung, kann nicht auf leer gesetzt werden) — TP5-Cleanup.
  • ✅ 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 im input-Chain, list_firewall_rules 2026-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 unter bf.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 — Firewall & Inter-VLAN-Policy ▸ ⏳ TEIL-LIVE (Sonos/HA-Holes + WAN-Seal gebaut, Deny-by-default steht aus)

  • 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.
  • ✅ Bereits live (verifiziert list_firewall_rules 2026-07-02):
    • 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 (aktuell noch permissiv nach fasttrack); UNTRUSTED/GUEST auf Internet-only pinnen; MGMT isolieren; IoT→INFRA-Whitelist bauen.
  • 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 ✅.

TP5.1 — DNS-Visibility & Flow-Observability für Low-Trust-Geräte (Airfryer-Fall) ▸ vorgemerkt

  • Kontext (2026-07-08/09): Airfryer „airschreier" (Philips/Versuni, ESP, 10.40.30.180) bekam per DHCP-Option 6 dns 1.1.1.1 als Override, weil das OTA-Update über den ap1-DoH-Gateway-Pfad nicht durchging (DoH-Latenz beim primitiven ESP-Stack — kein Content-Block, via Gateway-Logs bewiesen, s. memory/ref_esp_ota_doh_not_block). Nebenwirkung: public 1.1.1.1 = anonymer Consumer-Resolver ≠ accountgebundener Gateway-DoH (px35ynlol3.cloudflare-gateway.com) → DNS-Sicht auf das Gerät weg, Gerät umgeht zudem die Filterung.
  • (a) DNS-Redirect statt Geräte-Override (der dauerhafte Fix): dst-nat „UDP/53 (+TCP/53) von Low-Trust-Src → auf einen plain Resolver umbiegen" gibt Logging zurück UND funktionierendes OTA (kein langsamer DoH-Pfad fürs Gerät). Redirect-Ziel-Optionen: (i) ap1-Resolver mit nicht-DoH-Upstream für dieses Src-Set, (ii) direkt public 1.1.1.1 (dann nur Flow-Logging), (iii) eigener plain-Resolver. Sauberer als „Gerät verschwindet auf 1.1.1.1". Verortung: Teil des UNTRUSTED-Internet-only-Pinnings (TP5-„Offen"); Entscheidung v50-DNS-Policy (gefiltert vs. plain) hängt dran.
  • (b) Live-Torch als Ad-hoc-Observability: DNS ist bei direktem 1.1.1.1 blind, Flows nicht (NATen über ap1). torch auf vlan30/vlan50 gefiltert auf die Geräte-IP zeigt Ziel-IPs live (Versuni → AWS eu-west-1 IoT erkennbar). Voraussetzung: Gerät aktiv. Merkregel: Airfryer nur online wenn er kocht → Capture ans Einschalten koppeln.
  • Abh.: UNTRUSTED-Move des Airfryers (Kandidat, s. VLAN50) + TP5-Deny-by-default. Kein Blocker.

TP6 — QoS/CAKE + Call-Quality-A/B-Test ▸ DAS Ziel

  • CAKE am WAN-Upload (~85–95 % Linerate) → Bufferbloat weg. Verifikation waveform.com → A/A+.
  • ⚠️ Vor „Erfolg": A/B-Test, denn Kollegen-Befund sagt DE-Calls = internat. Pfad AT↔DE, nicht Heimnetz → ggf. WARP statt/zusätzlich CAKE. Nicht am einen Telefonat festmachen.
  • Abh.: TP4.

TP7 — Media-Discovery (mDNS) für VLAN 40 ▸ ✅ FERTIG (2026-07-02) — docs/tp7-mdns.md

  • ✅ Built-in mDNS-Repeater aktiv: /ip/dns set mdns-repeat-ifaces=vlan10,vlan20,vlan40,vlan30,vlan90,bridge (RouterOS 7.23.1; vlan90+bridge=VLAN-1 seit TP7.2 2026-07-03). MAIN/INFRA/IOT/GUEST/VLAN1 ↔ MEDIA. Reversibel (Feld leeren). Realbestand: MAIN=iOS-Client + MacBook, INFRA=Home Assistant, MEDIA=10× Sonos (siehe docs/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/5353 auf 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 — SSDP-Reflector (macOS-Sonos-App über VLAN-Grenze) ▸ vorgemerkt

  • 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/1900 auf 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 — HA↔Sonos static-host binding + VLAN1/GUEST-Discovery ▸ ✅ FERTIG (2026-07-03) — docs/sonos-inventar.md

  • Root Cause (widerlegt frühere Doku): HA-media_player.*-Sonos alle unavailable. HA sitzt nicht auf VLAN 20, sondern noch auf 10.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.105 in configuration.yaml (Backup .bak-sonos-20260703). advertise_addr fixt die UPnP-Event-Callbacks trotz HA-Multi-Homing (.105/172.16.0.18/docker). Core-Restart → alle 6 Online-Zonen idle/playing (Wohnzimmer-Push verifiziert = Callbacks OK). Terrasse .198 offline = kein Entity (kommt beim Einschalten). Kurzes Flapping direkt nach Restart = Settling, danach stabil.
  • ✅ Nebeneffekt: mit bridge im 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/bridge brauchte nichts (schon via TP10-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).
  • Offen/später: HA→VLAN 20 (IP-Migration nach Omada-PVID-Fix) → dann nur advertise_addr auf neue IP; macOS-Desktop-App weiter via SSDP-Reflector TP7.1. Abh.: TP7 ✅, TP5-Holes ✅.

TP8 — Identity & Access-Control ▸ research-gated

  • RADIUS = FreeRADIUS auf der NAS (✏️ User-Manager v5 kann KEIN LDAP → openldap nur via FreeRADIUS anbindbar).
  • EAP-TLS (Zert) je Gerät + dynamische VLAN-Zuweisung (RADIUS-Attribut Tunnel-Private-Group-ID). Einfachste Heim-Alternative: pro VLAN eine SSID mit WPA3-PSK (kein RADIUS) — Abwägung Komfort vs. Admin-Aufwand.
  • Abh.: TP3. (Research erledigt, s. TP-R.)

TP9 — Gateway-/Router-HA ▸ research-gated

  • „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 — Multi-Site VPN ▸ ✅ KERN DURCH (2026-06-27) — 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) und peer dw (10.95.10.0/24, CGNAT-Dial-in) mit frischem Handshake + Traffic. Public-Edge direkt — ap1 hört UDP/51821 auf vlan100 (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/24 renumbert, FB-WG single 10.95.10.1/24, Keepalive 25, Endpoint bf4…:51821. End-to-End von macmini/Linz → Gelis 24/7-APs 10.95.10.246/.247 sauber (echte LAN-IPs, kein 10.255.255.x-NAT-Leak).
  • 💡 Root Cause (FM-PoC bewiesen): FB masqueradet WG, wenn die Interface-Address eine 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, Key P/bzt…, MTU 1412, keine IF-IP). Endpoint = DDNS bf4.emsenhuber.net:51821 (Cloudflare, DNS-only → Public-IP). Apply gebündelt in routeros/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.net auf NAS/pve, damit der A-Record der Public-IP folgt (falls Liwest sie tauscht). Aktuell manuell in Cloudflare gepflegt.

TP11 — Monitoring & Mgmt-Control-Plane ▸ research-gated

  • MikroMCP + omada-mcp + SNMP/icinga-mikrotik, RoMON, NTP, E-Mail-Alerts, Netwatch. → Teil von docs/research/routeros-capabilities.md.
  • CF-Tunnel #1033 Track A ✅ live (2026-06-30): Round-Robin-1033er über 3 asymmetrische Connectors behoben durch Reduktion auf pve-only Connector (NAS + macmini scheiterten an pve-lokalen/stalen Origins). SSoT: docs/cf-tunnel-mapping.md. Track B/C läuft über TP14 (Ingress bereits v116 .41→.20 für NAS; pve-Connector→VLAN20 via TP14 Session B = #1033-Zielbild).

TP12 — IPv6 (intern + extern, 3 Standorte) ▸ research-gated

  • Konzept für FM/BF/DW. → TP-R.

TP13 — „Botschafts-WLANs" ▸ fun, low-prio

  • Nutzlose SSIDs mit Botschaft („Kanal 500 bitte nicht nutzen"), offenes WLAN mit Captive-Portal das auf statische Info-HTML zeigt (Nachbarschafts-WLAN-Tuning, Auto-Kanalwechsel). Idee: wer's sieht, kann auch stören → Infoseite = beste Adresse. ⚠️ Recht prüfen (Impressum/TMG, Störerhaftung bei offenem WLAN — User privat). RouterOS-Hotspot/Captive-Portal kann das.

TP14 — Host/Container-IP-Migration VLAN1→VLAN20 (Docker-Cutover NAS+pve) ▸ ⏳ WIP — docs/nas-vlan20/RUNBOOK.md, Handoff docs/nas-vlan20/handoff/

  • ✅ NAS (DS923, ep14) migriert (2026-07-09/10): Docker von default_external (macvlan .41) auf ein vlan20-Macvlan (10.40.20.0/24, gw .1, parent ovs_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_external muss weg für vlan20) + 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); vw 200 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, ipvlan parent=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).

TP14.1 — Session A: NAS fertigstellen ▸ ✅ DURCH (2026-07-10); 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:3306 erreichbar ✓), 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.json mcpServers.pve-mcp NEU 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:3306 down (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!).
  • ⏸️ VERTAGT — omada-controller Inform-Adresse → 10.40.20.175 + sw2 re-adopt (2026-07-10): Login an der Controller-UI https://10.40.20.175:8043 schlägt fehl (Christoph kommt nicht rein) → Recovery blockiert, verschoben. Unkritisch: sw2 „Disconnected" ist reiner Management-Loss — sw2 (ES208G Easy-Managed) switcht mit letzter Config weiter, Netz läuft (Live-Traffic bestätigt). Kein Auto-Fix: Open API hat kein Inform/Hostname-Setting, kein Controller-Admin-Login lokal, sw2 = statische IP .41.12 → keine DHCP-Option-138-Recovery. Wenn Login wieder geht: UI → Settings → Controller → „Controller Hostname/IP" = 10.40.20.175, dann sw2 forget+re-adopt (L3-Discovery). Vorher Controller-Login klären (Passwort-Reset / Recovery — Creds liegen nicht lokal).
  • 🐞 Gotcha gefunden: Portainer-Stack 111 (gitea) hatte den vlan20-Networks-Block auskommentiert (Vorsession-Artefakt) → Container landete auf gitea_default/172.18. Fix = Redeploy mit Disk-File docs/nas-vlan20/stacks/111-gitea.yml als Override.

TP14.2 — Session B: pve-Docker-LXC (.126) → VLAN20 ▸ ✅ DURCH (2026-07-10) (ipvlan)

  • ✅ 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. Files docs/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 — Token claude@pam!claude hat kein VM.Config.Network; UI-Edit, dann Reboot via API mit VM.PowerMgmt). Portainer wandert auf https://10.40.20.126:9443.
  • 🐞 Gotcha: in-Container-Iface heißt jetzt veth20, NICHT eth0 (UI setzte Name analog net1=veth16) → Docker vlan20=ipvlan parent=veth20 (nicht eth0 wie im Runbook). cloudflared(host)/portainer(bridge) unberührt.
  • ✅ CF-Connector db713b30 jetzt in VLAN20 (Tunnel bf.emsenhuber.net healthy/8 conns) = löst TP11-Track-B/C (#1033-Zielbild). Ingress portainer .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:9443 HTTP 200 (LXC 400 running, net0 veth20 tag=20 gw/ns=.20.1), omada-mcp .20.176→Controller .20.175 v6.2.10.17 (HTTPS :8043 200), pve-mcp .20.173 liefert Proxmox-Config, adguard .20.16/.20.17 HTTP :80 302→login (nicht HTTPS/:3000).

TP14.2a — pve-mcp Single-Session-Fix + VLAN20-Host-DNS ▸ ✅ (2026-07-10)

  • pve-mcp „Failed to connect": Ursache = mcp-pve v0.4.8 kann im HTTP-Transport nur eine MCP-Session (ein globaler StreamableHTTPServerTransport, sessionIdGenerator gesetzt) → 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/list liefert pve_*, 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.conf noch auf totes .41.254 → docker pull ghcr.io scheitert (EAI_AGAIN / 5s-Resolver-Timeout; Egress zu ghcr-IP 140.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 überschrieb resolv.conf; Fix = Schnittstelle „DNS manuell" 10.40.20.1 (Christoph) → NAS pullt wieder direkt. Merkregel Synology: GUI-DNS ≠ was dockerd liest (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) → Portainer POST /endpoints/14/docker/images/load → Stack-Redeploy pullImage:false. Gotcha: laufende Container frieren den 127.0.0.11-Upstream zum Erstellzeitpunkt ein (Recreate nötig; für pve-mcp egal — Proxmox per IP .41.100). Memory ref_pve_mcp_singlesession_and_vlan20_dns.

TP14.3 — Session C: Dormante Stacks vlan20-tauglich + Referenz-Sweep ▸ 🔜 TODO

  • transform.py auf core(43)/openclaw(92)/openclaw2(97)/oc20260307(119)/openspeedtest(74)/speedtest_tracker(80)/technikscheiss(42) → .new (42/43 waren default_internal → vlan20-only).
  • Referenz-Sweep .41→.20: ap1 bf.lan-DNS (MikroMCP, ap1 via 10.40.10.1), CLAUDE.md, ~/.claude.json, docs/ip-plan.md, CF-Ingress-Rest.

TP14.4 — Session D: CF-Access-Profil für Claude ▸ 🔜 TODO (nicht cutoff-kritisch)

  • CF-Token „claude code mcp" hat jetzt Access: Service Tokens: Write+Read → claude-mcp rotieren (POST …/access/service_tokens/{id}/rotate) → CF_ACCESS_CLIENT_ID/_SECRET in mcp/cloudflare/.env (chmod600). Memory ref-cf-access-claude-profile.

TP14.5 — Session E: Freigabe-Gate → TP5-Firewall ▸ 🔜 (ZULETZT)

  • Erst wenn TP14.1–14.3 durch (alle Origins/Connectoren in VLAN20) → dann TP5 (Deny-by-default) starten. Reines Reihenfolge-Gate, kein eigener Change.

TP15 — HW-Refresh: Core-Switch + OG-Verteiler ▸ 🔜 PLANUNG — docs/hw-refresh-requirements.md

  • Ziel: ALLNET-Core (sw1, 5,8W) + 2 Branch-Switches (je 1,5W) ablösen durch energieeffizientere, zentral managebare Lösung mit PoE + DC-USV.
  • Architektur: Unten (Diele) = lüfterloser Core-Switch mit PoE, PoE-powered von oben (gepuffert). Oben (Arbeitszimmer) = Switch mit PoE + DC-USV (48V-Bus, LiFePO4).
  • Anbieter-Recherche: MikroTik (RouterOS) ⭐, TP-Link Omada, Ubiquiti UniFi, Netgear, Aruba Instant On, Zyxel, Cisco. Favorit: MikroTik (RouterOS, Config-as-Code, MikroMCP).
  • Kandidaten unten: CRS318-16P-2S+OUT (16 PoE, lüfterlos, ~16W, ~€286) ⭐ oder CRS326-24G-2S+RM (24 Ports, lüfterlos, ~10W, ~€200) + PoE-Injektor.
  • Kandidaten oben: CRS328-24P-4S+RM (24 PoE, 4× SFP+, ~25W, ~€400) ⭐ oder CRS418-8P-8G-2S+5axQ2axQ-RM (16 Port, 8 PoE, WiFi 6, ~19W, ~€403).
  • WiFi: hAP be³ Media (WiFi 7, 5× 2,5G, ~€179) als separater AP ⭐ vs. CRS418 (WiFi 6 integriert).
  • DC-USV: MeanWell LRS-150-48 + DDR-120-48 + LiFePO4 20Ah (~€190) — 48V-Bus, ~2,5h Laufzeit bei 100W.
  • Energiebilanz: Neue Lösung ~35–60W (je nach Variante) vs. IST ~15W (nur Switching). Jahreskosten +€50–105.
  • Offene Entscheidungen: Variante (A/B/C/D), Mac mini auf USV?, PVE-Standort, WiFi-Strategie.
  • Nächster Schritt: Entscheidungen treffen, dann Konfiguration + Bestellung.
  • Abh.: TP14 (IP-Migration VLAN1→VLAN20 sollte abgeschlossen sein, damit Ziel-IPs feststehen).

TP16 — CF-Tunnel: Round-Robin killen + reziprokes HA ▸ ✅ KERN UMGESETZT (2026-07-10) — docs/cf-tunnel-mapping.md §10, #1033

✅ Umgesetzt (2026-07-10, eigene Session): reziprokes 3-Tunnel-HA live (bf-nas 70d6a4cf / bf-pve f7fdf3a6 / bf-mm 7a322261), 6 Connectoren (2/Host, je Fremdhost), 19 FQDNs Loop-Smoke 0×530, HA per Host-Ausfall-Sim bewiesen. Round-Robin-#1033 strukturell weg. As-Built = docs/cf-tunnel-mapping.md §10. Offen: Schritt 5 Access-Strang (vw bypass→geschützt via WARP, hass/ha-mcp 400/403 → iPhone-WARP-Enrollment) = user-gated; gateway-dw (WG→404) klären.

  • Symptom (User): FQDNs über CF werden sporadisch / „sehr unsicher" aufgelöst = #1033-Muster zurück („jeden 3. Schuss eine Niete"). User hat alle 3 cloudflared-Images + Container aktualisiert/neu gestartet.

  • ✅ Root-Cause endgültig (User-Diagnose bestätigt): macvlan/ipvlan-Host-Isolation. Ein cloudflared-Connector ist blind für macvlan/ipvlan-Container auf seinem EIGENEN Host (Linux-Kernel-Regel), erreicht aber Fremdhost-L2 + co-lokierte Bridge-Container. Mehrere Connectoren auf EINEM Tunnel = geteilter Ingress + CF-Round-Robin → jede Origin, die auf dem Host eines Connectors liegt, fällt bei ~1/N aus. Strukturell, nicht durch „Origins fixen" heilbar. Bsp: omada .20.175/pve-mcp .20.173/gitea .20.157/grafana .20.109 = NAS-macvlan → vom NAS-Connector NICHT erreichbar.

  • Invariante: innerhalb EINES Tunnels ist kein Route→Connector-Pinning möglich (alle Connectoren teilen Ingress, CF round-robined). „Ausgewählte Routen für ausgewählte Connectoren" = getrennte Tunnel.

  • Ziel-Design (HA): reziproke Per-Host-Tunnel — jeder Host-Dienst wird von den Connectoren der ANDEREN Hosts bedient (nie vom eigenen):

    Tunnel (= Dienste eines Hosts) Connectoren auf HA
    pve-Dienste NAS + macmini 1 abdrehbar
    NAS-Dienste (omada/pve-mcp/gitea/grafana/…) pve + macmini 1 abdrehbar
    macmini-Dienste (.20.167) pve + NAS 1 abdrehbar

    3 Tunnel, jeder Host fährt 2 cloudflared → Host-Ausfall ⇒ jeder Tunnel ≥1 Connector = voll HA. Voraussetzung: jede Origin L2-erreichbar.

  • Ist-Inventory (live 2026-07-10, s. cf-tunnel-mapping.md §9): Ingress v119, 24 Hostnames, 2 live Connectoren. DOWN/stale: pbs .20.135, nginx-bf .41.123 (noch VLAN1!), hermes+hermes-geli .20.167. Zu klären (Host/Netz): vw .20.127/ccu .20.232/iobroker .20.107/z2m25 .20.106 — ggf. vw/ccu auf VLAN20-macvlan heben. gateway-dw (192.168.178.1) = WG-Sonderfall.

  • CF-Access-Strang (verzahnt, s. TP11 Track-B): hass-400 in der HA-iPhone-App = CF-Access davor (Companion-App kann Access-Login nicht) → Fix ohne Passthrough: iPhone in WARP enrollen (Device-Identity erfüllt Access; „Warp Login App" existiert bereits allow:christoph). ⚠️ vw = aktuell bypass (öffentlich!) → von bypass auf geschützt heben. „Passthrough-Hosts sind die kritischen" (User).

  • Umsetzungs-Reihenfolge (für die eigene Session): (1) Reachability-Matrix je Host (pve/NAS/macmini → jede Origin, read-only) BEVOR gruppiert wird; (2) Interim-Sofortfix: bf-Tunnel auf pve-only (pve erreicht alles außer gateway-dw) → 0×1033, reversibel; (3) reziprokes 3-Tunnel-HA bauen (CNAMEs re-pointen, 6 Connectoren, Token je Tunnel; NAS/macmini-Alt-Token entfernen); (4) tote Origins bereinigen; (5) Access-Strang (WARP + vw); (6) Loop-Gegentest.

  • Abh.: TP14.1/14.2 ✅. Verwandt: TP11 (CF-Tunnel-Track-B/C + Access), #1033. SSoT: docs/cf-tunnel-mapping.md. Memory project_cf_tunnel_1033.

TP-R — Router-Capabilities-Sweep ▸ FERTIG (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 · CAPsMAN + 802.11r/k/v (Fast-Roaming statt Mesh) · 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.

Reihenfolge / Abhängigkeiten

✅ TP16 (CF-Tunnel Round-Robin/macvlan-Host-Isolation → reziprokes 3-Tunnel-HA) KERN UMGESETZT 2026-07-10 (#1033 strukturell weg). Offen nur Access-Strang (WARP/vw) = user-gated. As-Built docs/cf-tunnel-mapping.md §10.

  1. TP1 (GE8) → TP2 (Omada Controller). ✅ erledigt 2026-06-15.
  2. TP4 (Router-Cutover L3-Infra + WAN-Edge). ✅ erledigt 2026-06-15 (L3) + 2026-07-01 (Edge-Cutover, FB physisch weg).
  3. Jetzt: Omada-PVID-Fix — Omada Access-Profile korrigieren (PVID 10/20, untagNetworkIds bereinigen, sicher P3/P5/P6 zuerst), dann IP-Migration NAS/macmini/pve auf VLAN-Subnetze + DNS-Einträge updaten. IP-Migration NAS/pve = TP14 (NAS ✅ 2026-07-10, pve 🔜 Session B).
  4. Dann: TP5 (Deny-by-default fertigziehen — Sonos-/HA-/mDNS-Holes + WAN-Input-Seal stehen bereits; TP5.1 = DNS-Redirect + Live-Torch für Low-Trust-Geräte/Airfryer hängt dran) → TP6 (QoS/CAKE). TP7 (mDNS) ✅ 2026-07-02 (inkl. HA/vlan20), TP3 (WLAN/CAPsMAN) ✅ 2026-06-18, TP3.1 (ap2-VLAN-Trunk) ✅ 2026-07-01, TP3.2 (P750W/Discovery) ✅ 2026-07-02, Sonos-Migration ✅ 2026-07-02 (alle 10 auf VLAN 40). ⏳ TP3.3 (WLAN-Coverage-Kur) offen — Fortsetzung neue Session (docs/wifi-p750w-coverage-and-map.md).
  5. TP10 (VPN) ✅ Kern durch (2026-06-27) + Edge-Cutover (2026-07-01) → DURCH. Offen nur: DDNS-Auto-Updater.
  6. Nachgelagert/Research-getrieben: TP8 (Access), TP9 (HA), TP11 (Monitoring + CF-Tunnel-Track-B/C), TP12 (IPv6), TP13 (Spaß).