Teilprojekte + MikroMCP + WLAN-Vorarbeit: Steuerungsdok, Research, MCP-Setup, CAPsMAN-Asbuilt, AP-Trunk-Guides + Port-Map

- docs/teilprojekte.md: kanonisches Projektsteuerungsdokument (TP1–TP13 + TP-R)
- docs/research/: RouterOS-Capabilities-Sweep (TP-R) + VPN-Vergleich (TP10)
- mcp/: MikroMCP + Portainer-MCP Docker-Compose, routers.yaml, READMEs, .gitignore
- routeros/: ap1-manager.rsc, ap2-cap.rsc, CAPsMAN-Flat-Asbuilt, WLAN-Handover
- switch/cli/03-trunk-ap-ports.cli + switch/ui-guides/01-trunk-ap-ports.md: AP-Trunk-Konfiguration
- docs/allnet-ge8-trunk-klickanleitung.md: GE8 Hybrid→Trunk Schritt-für-Schritt
- inventory/bf-core-ports: gi1/gi2 als TRUNK zu ap1/ap2 eingetragen (gesetzt 2026-06-09)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christoph Emsenhuber
2026-06-15 08:42:03 +02:00
parent 1f6e2a000b
commit e688b37b60
20 changed files with 980 additions and 1 deletions

View File

@@ -0,0 +1,29 @@
# Klickanleitung — ALLNET GE8 von Hybrid → Trunk (R0)
**Gerät:** ALLNET ALL-SG8316M, `http://10.40.41.11` (FW 2.2.1). **Du klickst** (deine Creds).
**Ziel:** Port **GE8** (Uplink zum Omada-Switch) wird ein sauberer Trunk — **genau wie GE1/GE2** (deine bestehenden AP-Trunks).
## Zielzustand GE8
- **Mode:** `Trunk` (aktuell noch `Hybrid`)
- **Native / PVID:** VLAN **1** (untagged)
- **Tagged VLANs:** **10, 20, 30, 40, 90, 99, 100**
## Schritte
1. **Login** Web-UI `http://10.40.41.11`.
2. Geh dorthin, wo du **Port 1/2 auf Trunk** gestellt hast (VLAN- bzw. Switching-/Port-Bereich, „802.1Q VLAN" / „Interface Settings").
3. **Referenz ansehen:** Öffne **GE1** (oder GE2) und merk dir die Einstellung — das ist dein funktionierender Trunk-Template (Mode=Trunk, PVID=1, Tagged=10,20,30,40,90,99,100).
4. **GE8 identisch setzen:**
- Mode: `Hybrid` → **`Trunk`**
- PVID/Native: **1** (untagged)
- Tagged: **10,20,30,40,90,99,100**
- ⚠️ Falls der Mode-Wechsel die VLAN-Mitgliedschaft zurücksetzt: die Tagged-VLANs **neu hinzufügen** (du hattest sie schon mal alle drauf).
5. **Apply / OK.**
6. **In Flash sichern:** Menü **SAVE → „Save Configuration to FLASH" → Apply** (sonst ist es nach einem Reboot weg).
## Gegencheck (danach)
- GE8 zeigt **Mode=Trunk**, Tagged-Liste korrekt.
- Geräte hinter dem Omada (`.10`, `.167`, `.247`) sind **weiter erreichbar** (kurzer Ping) — native VLAN 1 trägt sie wie bisher.
- Sag mir „GE8 ist Trunk" → dann ist R0 durch, weiter mit R1 (Omada Controller).
> Merke (für alle künftigen ALLNET-Schritte): **ALLNET = Klickanleitung von mir, du führst aus.** Der CLI/Telnet-Weg ist
> wegen 1-VTY-Line + geänderter Creds zu fummelig — Klick-Guides sind zuverlässiger.

View File

@@ -0,0 +1,203 @@
# RouterOS-Capabilities für hAP ax² (BF-Netz, RouterOS 7.23.1)
> Recherche-Report — Stand 2026-06-15
> Ziel: Verstehen, was RouterOS 7.23 für ein Prosumer-Multi-VLAN-Heimnetz kann, und empfehlen, was bei **knappem CPU/RAM** passt.
## 0. Hardware-Fakten (live von ap1 abgefragt)
| Eigenschaft | Wert | Bedeutung |
|---|---|---|
| Modell | hAP ax² (`C52iG-5HaxD2HaxD`) | ARM64, IPQ-6000 |
| RouterOS | **7.23.1 stable** (build 2026-06-02) | aktuell |
| CPU | ARM64, **864 MHz, 4 Cores** | solide, aber kein Kraftpaket |
| RAM | **1 GB total** — im Leerlauf ~681 MB frei | **der echte Engpass** |
| Flash | 128 MB total, ~94 MB frei | begrenzt → Container nur klein |
| Lizenz | Level 4 | reicht für alles hier Relevante |
**Konsequenz für alle Empfehlungen:** RAM ist die harte Grenze. Jeder Container kostet 10–100 MB. Mehr als 2–3 kleine Container parallel + WLAN + Routing wird eng. CPU-intensive Dinge (TLS-Terminierung, Web-Proxy unter Last, VPN-Durchsatz) treffen die 4 schwachen Cores. Faustregel: **native Pakete bevorzugen, Container sparsam, alles Schwere auf die NAS auslagern.**
**Installierte vs. verfügbare Pakete (live):** Aktiv sind nur `routeros` + `wifi-qcom`. Als *available/disabled* liegen bereits auf dem Gerät: `container`, `calea`, `dude`, `iot` (MQTT/Modbus), `gps` (LoRa), `openflow`, `user-manager`, `zerotier`, `wireless`, `tr069-client`, `ups`, `rose-storage`. Aktivieren = `/system package enable …` + Reboot, kein Download nötig.
---
## 1. Gateway-/Router-HA via VRRP
**Userfrage: „Was, wenn ap1 ausfällt?"**
**(a) Was es macht:** VRRP (Virtual Router Redundancy Protocol) lässt zwei hAP eine gemeinsame **virtuelle Gateway-IP je VLAN** teilen. Der Master mit höherer Priority hält die virtuelle IP; fällt er aus, übernimmt der Backup binnen ~3× advertisement-interval (Default 1 s → ~3 s Umschaltung). Clients behalten dasselbe Default-Gateway.
**(b) Verfügbarkeit:** **Nativ** in RouterOS (`/interface/vrrp`), kein Paket. VRRPv3 für IPv4+IPv6.
**(c) Nutzen:** Echtes Gateway-Failover je VLAN. Mit zwei VRRP-Instanzen pro VLAN (kreuzweise Master/Backup) sogar Load-Sharing möglich.
**(d) CPU/RAM-Kosten:** Vernachlässigbar (nur kleine Multicast-Advertisements). Kein Problem.
**(e) Empfehlung: VIELLEICHT (für VLANs mit echtem HA-Bedarf, z. B. MAIN 10 / INFRA 20).** VRRP-Last ist gratis, aber der Betriebsaufwand für *echtes* Failover ist hoch — siehe Gotchas. Für ein Heimnetz reicht oft simpler: zweiter hAP als kalter Ersatz + Config-Backup.
### Config-Skizze (kreuzweises Master/Backup, pro VLAN)
```rsc
# ap1 — Master für VLAN10, Backup für VLAN20
/interface vrrp add name=vrrp-vlan10 interface=vlan10 vrid=10 priority=200 version=3
/interface vrrp add name=vrrp-vlan20 interface=vlan20 vrid=20 priority=100 version=3
/ip address add address=10.40.41.1/24 interface=vrrp-vlan10 ;# virtuelle GW-IP
/ip address add address=10.40.42.1/24 interface=vrrp-vlan20
# ap2 — gespiegelt: Backup für VLAN10, Master für VLAN20
/interface vrrp add name=vrrp-vlan10 interface=vlan10 vrid=10 priority=100 version=3
/interface vrrp add name=vrrp-vlan20 interface=vlan20 vrid=20 priority=200 version=3
/ip address add address=10.40.41.1/24 interface=vrrp-vlan10
/ip address add address=10.40.42.1/24 interface=vrrp-vlan20
```
### Gotchas (wichtig!)
- **RouterOS kann NICHT „Owner" sein** → die virtuelle IP darf nicht gleichzeitig die echte Interface-IP eines Routers sein. Jeder Router braucht zusätzlich eine eigene reale IP pro VLAN (z. B. .2 / .3), die virtuelle (.1) liegt auf dem VRRP-Interface.
- **Die VRRP-IP muss auf Master UND Backup identisch konfiguriert sein**, sonst werden Advertisements verworfen.
- **VRRP umfasst nur die IP/Routing-Ebene — NICHT den Rest.** DHCP-Server, Firewall-/NAT-Regeln, DNS, Routen müssen auf **beiden** Routern identisch gepflegt werden, sonst ist nach Failover „Gateway up, aber Internet/DHCP tot". Das ist der eigentliche Betriebsaufwand. Tipp: DHCP-Server auf beiden mit identischem Pool/Gateway, oder DHCP-Failover-Lease-Sync vermeiden (Split-Pool).
- Advertisement-interval **nicht unter 1 s** → sonst Flapping.
- WAN-Seite: Failover des Internet-Uplinks ist ein *separates* Problem (siehe §10 Multi-WAN), VRRP löst nur das LAN-Gateway.
- Quellen: [VRRP (help.mikrotik.com)](https://help.mikrotik.com/docs/spaces/ROS/pages/81362945/VRRP), [VRRP Configuration Examples](https://help.mikrotik.com/docs/spaces/ROS/pages/128221211/VRRP+Configuration+Examples)
---
## 2. WLAN-Mesh vs. Wired Backhaul
**Ausgangslage:** Beide APs haben **verdrahtete Trunk-Uplinks** (alle VLANs).
**(a)/(c) Optionen:**
| Ansatz | Was | Für uns |
|---|---|---|
| **Wired backhaul + CAPsMAN** | Beide APs per Kabel am Trunk, gleicher Bridge/VLAN; zentrale WLAN-Config via CAPsMAN-Controller; APs broadcasten dieselben SSIDs mit 802.11r/k/v-Roaming | **Empfohlen.** Voller Speed, kein Funk-Tribut, nahtloses Roaming |
| **WLAN-Mesh (WDS / wireless station-backhaul)** | Ein AP funkt zum anderen als Backhaul | Nur sinnvoll, wenn *kein* Kabel da wäre — ist es aber. Halbiert Funk-Durchsatz, mehr Latenz |
**(b) Verfügbarkeit:** CAPsMAN ist nativ im `wifi-qcom`-Paket (ROS7 „WiFi", `/interface/wifi/capsman`). Ein hAP kann gleichzeitig CAP **und** CAPsMAN-Controller sein (kein extra Gerät nötig). 802.11r/k/v Roaming + Steering nativ.
**(d) CPU/RAM:** CAPsMAN-Controller für 2 APs ist trivial-leicht. WLAN-Mesh kostet mehr (zwei Radios busy).
**(e) Empfehlung: WIRED BACKHAUL + CAPsMAN nutzen, Mesh WEGLASSEN.** Kabel ist da → keinen Funk-Backhaul-Nachteil einkaufen.
### Loop-Risiko über Router/LAN — wichtig
Wenn **beide** APs mit allen VLAN-Trunks am selben L2-Netz hängen und zusätzlich die WLAN-Bridges dieselben Broadcast-Domains überbrücken, kann ein **L2-Loop** entstehen (Trunk-A ↔ Switch ↔ Trunk-B ↔ über AP-Bridge zurück). Gegenmittel:
- **RSTP/MSTP auf den Bridges aktiv lassen** (`protocol-mode=rstp`) — fängt versehentliche Loops ab.
- Sauberes Bridge-VLAN-Filtering; nur der Trunk-Port ist Tagged-Member, kein Doppelpfad.
- **Kein gleichzeitiges WDS/Mesh, während Wired-Backhaul aktiv ist** — das ist der klassische Loop-Erzeuger (zwei parallele Pfade zwischen denselben APs). Genau deshalb: entweder/oder, nicht beides.
- Quellen: [WiFi / CAPsMAN](https://help.mikrotik.com/docs/spaces/ROS/pages/224559120/WiFi), [Forum: mesh with wifi ax](https://forum.mikrotik.com/t/mesh-with-wifi-routeros-ax-wi-fi-6/181917)
---
## 3. Access-Control / Identity (RADIUS, 802.1X, EAP-TLS, dyn. VLAN)
**(a) Was es macht:** WPA2/WPA3-**Enterprise** (802.1X) authentifiziert *jeden User/jedes Gerät* einzeln gegen einen RADIUS-Server — statt eines geteilten PSK. **EAP-TLS** = Client-Zertifikat pro User/Gerät (kein Passwort). Der RADIUS kann pro Auth eine **dynamische VLAN-Zuweisung** zurückgeben (Tunnel-Type=VLAN, Tunnel-Medium-Type=802, **Tunnel-Private-Group-ID=<VLAN-ID>**) → Gerät landet automatisch im richtigen VLAN, egal an welcher SSID/welchem Port.
**(b) Verfügbarkeit auf 7.23:**
- **User-Manager v5** = eingebauter RADIUS-Server (Paket `user-manager`, liegt bereits available auf dem Gerät). Kann EAP-TLS, EAP-TTLS, PEAP. Offizielles Howto: „Enterprise wireless security with User Manager v5".
- WiFi-Interfaces: `authentication-types=wpa2-eap,wpa3-eap` nativ.
- **Dot1X** (Paket-frei, nativ) für **wired 802.1X** an Switch-Ports mit dynamischer VLAN-Zuweisung — ABER: dyn. VLAN im Switch-Chip nur auf Geräten mit HW-VLAN-Filtering; **nicht** auf SMIPS. Der hAP ax² ist kein SMIPS, dyn. VLAN am Port ist hier grundsätzlich möglich — in der Praxis am Heim-Switch aber eher Spielerei.
**LDAP-Backend (User hat openldap-Container):** **User-Manager v5 spricht KEIN LDAP.** Er hat eine eigene lokale User-DB. Will man die openldap als Wahrheitsquelle, führt der Weg über **FreeRADIUS** (mit `ldap`-Modul) — das läuft *nicht* sinnvoll als 90-MB-Container auf dem hAP, sondern auf der NAS.
**(c) Nutzen:** Pro-Gerät-Identität, Zertifikats-Login (kein WLAN-Passwort-Teilen), automatische VLAN-Einsortierung (IoT→30, Gäste→90 etc.). Stark für ein segmentiertes Netz.
**(d) CPU/RAM:** User-Manager-Paket ist klein (~344 KB Code), die Last entsteht bei EAP-Handshakes (TLS-Krypto). Für ein Heimnetz mit Dutzenden Geräten ist das auf dem hAP **vertretbar**, aber RAM-Budget im Auge behalten.
**(e) Empfehlung:**
- **RADIUS-Server: FreeRADIUS auf der NAS = beste Option** (LDAP-Anbindung an openldap, robust, kein hAP-RAM-Verbrauch, überlebt AP-Reboots). hAP-WLAN zeigt nur auf die NAS-RADIUS-IP. → **NUTZEN (NAS).**
- **User-Manager v5 auf dem Router = VIELLEICHT**, als einfache/standalone Alternative *ohne* LDAP, wenn man keine NAS-Abhängigkeit will. Pragmatisch und in 1 h aufgesetzt, aber Userverwaltung getrennt von openldap.
- **EAP-TLS pro Gerät: NUTZEN für stationäre/eigene Geräte**, aber Zertifikats-Rollout (CRL, Enrollment) ist Pflege-Aufwand → für Gäste/fremde Geräte lieber PEAP (User+Passwort) oder simpler WPA2/3-PSK je VLAN-SSID.
- **Einfachste administrierbare Option für daheim:** pro VLAN eine eigene SSID mit eigenem WPA3-PSK. Enterprise/802.1X nur dort, wo Pro-Gerät-Identität wirklich gebraucht wird.
- Quellen: [Enterprise wireless security w/ User Manager v5](https://help.mikrotik.com/docs/spaces/ROS/pages/92635137/), [User Manager](https://help.mikrotik.com/docs/spaces/ROS/pages/2555940/User+Manager), [Dot1X](https://help.mikrotik.com/docs/spaces/ROS/pages/328090/Dot1X), [multiduplikator/mikrotik_EAP (GitHub, EAP-TLS+CRL+WPA3)](https://github.com/multiduplikator/mikrotik_EAP)
---
## 4. Schlagwortliste (Schnellbewertung)
| Thema | Was | Verfügbar 7.23 | Nutzen / CPU-RAM | Empfehlung |
|---|---|---|---|---|
| **RoMON** | L2-Management-Overlay (Router ohne IP per MAC erreichen) | Nativ | Quasi gratis | **NUTZEN** — bequemes Management beider APs auch ohne IP, Lifesaver bei Fehlkonfig |
| **IPv6 (intern)** | SLAAC/DHCPv6, ND, Firewall | Nativ | Gering | **NUTZEN** — IPv6-Firewall nicht vergessen (Default offen!) |
| **IPv6 (extern, 3 Standorte)** | DHCPv6-**PD** (Prefix Delegation), pro Standort /56 o. /60 → Sub-Prefixe je VLAN | Nativ (`/ipv6 dhcp-client … pool`, `/ipv6 pool`) | Gering | **NUTZEN, falls ISP IPv6+PD liefert.** Pro Standort eigener Präfix; FritzBoxen FM/BF/DW als CPE können PD weiterreichen — Topologie klären |
| **LoRa** | LoRaWAN-Gateway-Funktion | Paket `gps`/`lora` — aber **hAP ax² hat KEINE LoRa-Hardware** | – | **WEGLASSEN** — kein Funkmodul vorhanden |
| **MQTT** | IoT-Paket: MQTT-Publish aus Scripts/Scheduler | Paket `iot` (available) | Klein | **VIELLEICHT** — nett für „Router meldet Status an HA", aber HA/NAS macht das besser. Optional |
| **SNMP** | Monitoring-Agent (CPU, RAM, Traffic, IF) | Nativ | Gering | **NUTZEN** — Basis fürs Monitoring (siehe icinga). Read-only Community + FW-Regel |
| **Email settings** | SMTP-Versand aus Scripts (`/tool e-mail`) | Nativ | Gering | **NUTZEN** — Alerts (Netwatch, Failover) per Mail |
| **NTP server** | Zeit-Server fürs LAN | Nativ | Gering | **VIELLEICHT** — als interner NTP für IoT/MGMT-VLAN sinnvoll; sonst NTP-Client reicht |
| **ZeroTier** | P2P-Mesh-VPN | Paket `zerotier` (ARM, available) | Spürbar: bis ~60 % CPU bei Last, RAM-Footprint | **WEGLASSEN/VIELLEICHT** — funktioniert, aber CPU-hungrig auf dem hAP. Für Remote-Zugriff lieber Back-to-Home/WireGuard (§unten) |
| **Cloudflare One / WARP** | CF Zero Trust Tunnel | **Kein natives Paket**; nur als `cloudflared`-Container | Container-RAM + CPU; macvlan-Konflikte (siehe DNS-Projekt-Notizen) | **WEGLASSEN auf dem Router** — CF-ZT gehört auf NAS/dedizierten Host, nicht auf den RAM-knappen AP |
| **Load-Balancing / Failover (Multi-WAN)** | PCC + recursive routing / Netwatch | Nativ | Gering–mittel | **NUTZEN bei >1 WAN** — siehe §10 |
| **OpenFlow** | SDN-Controller-Steuerung | Paket `openflow` (available) | – | **WEGLASSEN** — kein SDN-Controller im Heimnetz, sinnlos |
| **User-Manager** | siehe §3 | Paket (available) | Klein–mittel | **VIELLEICHT** — RADIUS standalone ohne LDAP |
| **CALEA** | Lawful-Intercept (behördl. Mitschnitt) | Paket `calea` (available) | – | **WEGLASSEN** — reines Compliance-Feature, irrelevant |
| **icinga / check_routeros (Monitoring)** | Icinga/Nagios-Plugin via API/SNMP | Extern (auf Monitoring-Host) | 0 am Router | **NUTZEN** — `DinoTools/monitoring-check_routeros` gegen SNMP/API; CPU/RAM/IF/Temp/WLAN |
| **spectral-scan** | Funk-Spektrum-Analyse (Störer-Suche) | Nativ im WiFi-Tool (`/interface/wifi spectral-scan`) | Kurzzeitig, on-demand | **NUTZEN (ad-hoc)** — super zur Kanalwahl/Störer-Diagnose, läuft nur bei Bedarf |
Quellen u. a.: [ZeroTier](https://help.mikrotik.com/docs/spaces/ROS/pages/83755083/ZeroTier), [SNMP](https://help.mikrotik.com/docs/spaces/ROS/pages/8978519/SNMP), [RoMON](https://help.mikrotik.com/docs/spaces/ROS/pages/8978569/RoMON), [check_routeros (GitHub)](https://github.com/DinoTools/monitoring-check_routeros), [Load Balancing](https://help.mikrotik.com/docs/spaces/ROS/pages/4390920/Load+Balancing)
---
## 5. Reverse Proxy — Erwartung „nein" muss korrigiert werden
**Bisherige Erwartung: RouterOS hat keinen Reverse Proxy. → Stimmt für ROS ≤ 7.21, aber NICHT mehr für 7.22+.**
- RouterOS hatte lange nur einen **Forward/Transparent-Web-Proxy** (`/ip proxy`, deprecated, Caching) — das ist KEIN Reverse Proxy.
- **Neu seit 7.22:** nativer **Reverse Proxy** unter `/ip/reverse-proxy`. Kann: HTTPS-Terminierung mit **ACME/Let's Encrypt**, **SNI-basiertes Routing** mehrerer Hostnames auf interne IPv4-Backends:Port, setzt `X-Forwarded-For`/`-Proto`. Da die APs auf **7.23.1** laufen, ist das **vorhanden**.
**Kann es nginx-proxy-manager ersetzen?** Für simple Fälle ja, **aber nicht voll:**
- ❌ Kein WebSocket, kein gRPC, keine Sticky Sessions, kein WAF, kein Auth-Layer, keine Log/Header-Manipulation, **nur IPv4-Backends**.
- ⚠️ **TLS läuft auf der Router-CPU** → auf hAP/hEX kann Last die CPU auf 100 % treiben.
**(e) Empfehlung: WEGLASSEN als NPM-Ersatz auf dem hAP.** NGINX Proxy Manager auf der NAS behalten (WebSocket/Backend-Vielfalt/RAM). Den nativen Reverse-Proxy höchstens für **1–2 triviale interne HTTPS-Dienste** nutzen, wenn man die NAS gerade nicht einbinden will. Wichtigste Korrektur: „RouterOS hat keinen Reverse Proxy" ist seit 7.22 **falsch** — es hat einen, nur einen schlanken.
- Quellen: [Native Reverse Proxy 7.22 Guide (bigmike.help)](https://bigmike.help/en/devops/native-reverse-proxy-in-mikrotik-routeros-7-22-complete-setup-guide/), [Proxy (help.mikrotik.com)](https://help.mikrotik.com/docs/spaces/ROS/pages/132350000/Proxy)
---
## 6. mDNS-Repeater (7.16+) + Container-Reflector — bestätigt
- **Bestätigt:** Seit **7.16** ist ein **mDNS-Repeater nativ eingebaut**: `/ip/dns/set mdns-repeat-ifaces=bridge,vlan-iot,vlan-main`. Relayed mDNS (`.local`, AirPlay/Chromecast/Discovery, HomeKit-Bonjour) **zwischen ausgewählten VLANs** — genau das, was man fürs IoT/MAIN-Cross-Discovery braucht. **Kostet quasi nichts.** → **NUTZEN.**
- **Container-Reflector** (forum: „Reflector — cross-VLAN casting mDNS+SSDP+DIAL", **<10 MB RAM**): nötig nur, wenn man **zusätzlich SSDP/DIAL** (DLNA, manche Smart-TVs) reflektieren muss, was der native mDNS-Repeater NICHT abdeckt. → **VIELLEICHT**, nur wenn SSDP-Geräte zicken; sonst spart man sich den Container.
- Quellen: [mikrotikonlineclub v7.16](https://mikrotikonlineclub.com/2024/10/03/whats-up-mikrotik-v7-16/), [Reflector-Container (Forum)](https://forum.mikrotik.com/t/reflector-cross-vlan-casting-mdns-ssdp-dial-as-a-routeros-container-10-mb-ram/271098), [mag1024/mikrotik-docker-mdns-repeater](https://github.com/mag1024/mikrotik-docker-mdns-repeater)
---
## 7–10 hier zusammengefasst: 5 nicht-offensichtliche Features für ein CPU/RAM-knappes Setup
Diese geben viel Nutzen pro Byte RAM — alle **nativ, kein Container, vernachlässigbare Last:**
1. **Netwatch** (`/tool netwatch`) — pingt Hosts/Gateways, triggert Scripts. Damit baut man **WAN-Failover, Service-Watchdogs und Mail-Alerts** ohne Zusatzsoftware. Herzstück eines schlanken HA-Setups. **NUTZEN.**
2. **Scheduler + Scripts** (`/system scheduler`, `/system script`) — Auto-Backups (`/export` + Mail), nächtliche Cron-Jobs, Reaktion auf Events. Ersetzt viele „Ich-bräuchte-dafür-einen-Container"-Wünsche. **NUTZEN.**
3. **DoH — DNS over HTTPS** (`/ip/dns set use-doh-server=… verify-doh-cert=yes`) — verschlüsselter Upstream-DNS direkt am Router, plus statische DNS-/FWD-Einträge. Passt zur bestehenden DNS-Infra (AdGuard/CF). Geringe Last. **NUTZEN/VIELLEICHT** (je nach DNS-Architektur — ihr filtert ohnehin via CF/AdGuard).
4. **Back-to-Home VPN** (ROS 7.12+, ARM64 ✓) — **WireGuard-basierter** Fernzugriff per MikroTik-App/QR, NULL Server-Config, funktioniert hinter CGNAT/NAT. WireGuard ist der **CPU-effizienteste** VPN-Typ (~24 % CPU @ 1000 conns in Vergleichstests, vs. ZeroTier ~62 %). → **NUTZEN statt ZeroTier** für Remote-Zugriff auf BF. Sehr geringer Footprint.
5. **Graphing + SNMP → externes Monitoring (icinga/Grafana auf NAS)** — der Router liefert nur Zahlen (gratis), die Auswertung/Speicherung läuft extern. Vermeidet `dude`/Container-Monitoring auf dem RAM-knappen Gerät. **NUTZEN.** (`calea`/`dude` lokal → **WEGLASSEN**.)
Bonus: **`/tool/graphing`** (eingebaute RRD-Graphen) ist leichtgewichtig für schnellen Blick ohne externes System.
Quellen: [Back To Home](https://help.mikrotik.com/docs/spaces/ROS/pages/197984280/Back+To+Home), [WireGuard](https://help.mikrotik.com/docs/spaces/ROS/pages/69664792/WireGuard), [Failover (WAN Backup)](https://help.mikrotik.com/docs/spaces/ROS/pages/26476608/Failover+WAN+Backup)
---
## 10. Multi-WAN / Load-Balancing & Failover (Detail)
**(a)** Mehrere Internet-Uplinks bündeln (Load-Balance via **PCC** = Per-Connection-Classifier) oder als Backup (**Failover** via Routen-`distance` + `check-gateway` + Netwatch + **recursive routing**).
**(b)** Alles **nativ**, kein Paket.
**(c)** Relevant nur, wenn ein Standort >1 WAN hat (z. B. DSL + LTE). Am BF mit FritzBox als einzigem Uplink → erst relevant, wenn zweiter Uplink dazukommt.
**(d)** Gering bis mittel (PCC-Mangle pro Verbindung). Auf dem hAP unkritisch bei Heim-Bandbreiten.
**(e) Empfehlung: NUTZEN, sobald ein zweiter Uplink existiert** — sonst PARKEN. Failover (Netwatch + recursive route) ist simpler und robuster als PCC-Load-Balance; für daheim meist die bessere Wahl.
Quellen: [Load Balancing](https://help.mikrotik.com/docs/spaces/ROS/pages/4390920/Load+Balancing), [Failover (WAN Backup)](https://help.mikrotik.com/docs/spaces/ROS/pages/26476608/Failover+WAN+Backup), [vishnunuk/mikrotik-dual-wan-loadbalance-failover (GitHub)](https://github.com/vishnunuk/mikrotik-dual-wan-loadbalance-failover)
---
## Gesamt-Empfehlungsmatrix (TL;DR)
| Kategorie | Empfehlung |
|---|---|
| **Sofort nutzen (nativ, ~0 RAM)** | RoMON · Netwatch · Scheduler/Scripts · SNMP · Email-Alerts · mDNS-Repeater (7.16+) · spectral-scan (ad-hoc) · IPv6 intern · Wired-Backhaul + CAPsMAN (802.11r/k/v) · Back-to-Home/WireGuard für Remote |
| **Vielleicht / situativ** | VRRP-Gateway-HA (nur MAIN/INFRA, hoher Pflegeaufwand) · User-Manager v5 als Standalone-RADIUS · EAP-TLS für eigene Geräte · IPv6-PD extern (falls ISP) · NTP-Server · MQTT · Multi-WAN (sobald 2. Uplink) · Reflector-Container (nur bei SSDP/DLNA) · DoH |
| **Auf die NAS auslagern** | FreeRADIUS (+LDAP/openldap) · NGINX Proxy Manager · icinga/Grafana-Monitoring · Cloudflare One/WARP (cloudflared) |
| **Weglassen** | LoRa (keine HW) · OpenFlow · CALEA · ZeroTier (CPU-hungrig → WireGuard nehmen) · `dude` lokal · nativer Reverse-Proxy als NPM-Ersatz |
**Drei zentrale Korrekturen/Erkenntnisse:**
1. **Reverse Proxy:** RouterOS 7.22+ HAT einen nativen Reverse-Proxy (`/ip/reverse-proxy`, ACME/HTTP-2, SNI) — die Annahme „nein" ist überholt. Ersetzt NPM aber NICHT (kein WS/gRPC, nur IPv4, TLS auf Router-CPU).
2. **„Was wenn ap1 ausfällt?":** VRRP löst Gateway-Failover technisch elegant und gratis, aber echtes HA verlangt **identische DHCP/Firewall/NAT-Pflege auf beiden** Geräten — das ist der Haken, nicht die VRRP-Last.
3. **RAM ist König:** Bei 1 GB gilt „nativ vor Container, NAS vor Router". RADIUS, Reverse-Proxy, CF-Tunnel, Monitoring gehören auf die NAS; der hAP macht Routing/WLAN/VRRP/Netwatch.

View File

@@ -0,0 +1,102 @@
# VPN-Vergleich: WireGuard (RouterOS↔FritzBox) vs. Cloudflare Zero Trust / WARP
> Recherche-Report · Stand 2026-06-15 · Kontext: Multi-Site-Heimnetz **FM / BF / DW**, je eine **FritzBox**; Standort **BF** zusätzlich **MikroTik hAP ax²** (RouterOS 7.23.1), der künftig BF-Router wird. CF Zero Trust + WARP bereits im Einsatz (siehe DNS-Infra-Projekt).
---
## TL;DR / Empfehlung
**Hybrid, kein Entweder-Oder.** Für ein Mesh über **drei FritzBox-Standorte**, von denen zwei (FM, DW) **nur eine FritzBox** haben, ist der saubere gemeinsame Nenner:
- **Site-to-Site-Backbone via natives WireGuard auf den FritzBoxen** (FRITZ!OS ≥ 7.50), mit **BF als Hub** (MikroTik hAP ax² als WG-Server, da statisch erreichbar / als künftiger BF-Router ohnehin Endpoint). FM und DW sind WG-Clients zum Hub → Hub-&-Spoke-Mesh.
- **Cloudflare WARP/Zero Trust bleibt für Remote-User-Zugriff** (Laptop/Handy von unterwegs → Heimnetze) und als Identitäts-/Access-Layer. Das tut es heute schon und ist dafür die bessere Lösung als ein klassisches Road-Warrior-WireGuard.
**Warum nicht WARP für Site-to-Site?** WARP/WARP-Connector kann eine FritzBox **nicht direkt** ansprechen — es braucht **an jedem Standort einen Linux-Host hinter der FritzBox** (WARP-Connector / `cloudflared`). An reinen FritzBox-Standorten (FM, DW) ist dieser Host nicht vorhanden und müsste erst beschafft/betrieben werden. Das erhöht Betriebsaufwand und Hardware-Fußabdruck, während die FritzBox WireGuard **out-of-the-box** kann.
**Wichtigste Einschränkung beim WG-Pfad:** mindestens **ein** Standort muss **öffentlich erreichbar** sein (kein CGNAT, idealerweise statisch oder DynDNS). Das wird der **Hub (BF/MikroTik)**. Liegt BF selbst hinter CGNAT, kippt die Empfehlung — dann ist der CF-/WARP-Connector-Pfad (der ausschließlich ausgehende Verbindungen nutzt) der robustere Backbone.
---
## 1. Kann WARP eine FritzBox direkt ansprechen?
**Nein.** WARP (der Client) bzw. der **WARP-Connector** koppeln Netze **nicht** mit einer FritzBox-Gegenstelle, sondern mit Cloudflares Edge.
- Der **WARP-Connector** ist Software (der Cloudflare-One-Client `warp-cli` im Headless-Modus bzw. `cloudflared`), die auf **einem Linux-Host** läuft und als **Subnet-Router** das gesamte hinterliegende LAN zu Cloudflare bringt. ([CF One Docs – WARP Connector](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/warp-connector/), [Site-to-Site](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/warp-connector/site-to-site/))
- Damit ein **FritzBox-LAN/-Dienst** über CF erreichbar wird, muss also **hinter** der FritzBox ein Linux-Host stehen (Raspberry Pi, NUC, VM, Container), der den Connector betreibt. Die FritzBox selbst kann **weder** WARP-Connector **noch** `cloudflared` ausführen.
- **OS-Anforderung:** WARP/Connector läuft auf **Linux (apt-/yum-basiert: Ubuntu, Debian, CentOS, RHEL)**, außerdem Windows/macOS für reine Clients — **nicht** auf FRITZ!OS. ([WARP-Client Docs](https://developers.cloudflare.com/warp-client/))
- **Port-Footprint:** der Connector-Prozess (`cloudflared` MASQUE-Pfad) alloziert **~50.000 Ports** auf dem Host — also ein dediziertes Gerät, kein „nebenbei".
**Konsequenz für FM/DW (nur FritzBox):** Ohne zusätzlichen Always-on-Linux-Host kein WARP-Site-to-Site. An BF wäre ein Linux-Host theoretisch vorhanden/möglich, aber die FritzBoxen in FM/DW bleiben das Problem.
---
## 2. WireGuard FritzBox ↔ MikroTik – Interop & Gotchas
**Machbar und erprobt.** FRITZ!OS unterstützt WireGuard ab **7.50**, RouterOS v7 hat WireGuard nativ. Mehrere dokumentierte Real-World-Setups koppeln genau diese beiden. ([Bouni Blog 2026](https://blog.bouni.de/posts/2026/site-to-site-wireguard-vpn-between-fritzbox-and-mikrotik/), [Shaw-IoT Blog](https://blog.shaw-iot.co.uk/2023/04/wireguard-vpn-between-mikrotik-routeros.html), [MikroTik-Forum](https://forum.mikrotik.com/t/configuration-issue-between-fritz-box-wireguard-server-and-mikrotik-client/175777))
### Rollenverteilung
- **MikroTik = Server** (LISTEN auf z.B. UDP 51820), **FritzBox = Client**. Die FritzBox importiert eine WG-Config-Datei (`.conf`) unter **Internet → Freigaben → VPN (WireGuard)** und gibt dort den Endpoint des MikroTik an (IP **oder DynDNS-Hostname**).
- Diese Richtung ist robust, weil der MikroTik der stabil erreichbare Hub ist und die FritzBox als Client persistent rauswählt.
### Kritische Gotchas
1. **Keine IP-Adresse auf dem WireGuard-Interface (MikroTik-Seite) setzen.** Wird dem WG-Interface eine Adresse zugewiesen, bricht das Routing zwischen den Sites. Adressierung/Routing nur über `AllowedIPs` + statische Routes. (Der häufigste Stolperstein in allen Anleitungen.)
2. **`AllowedIPs` = Tunnelnetz + jeweilige LAN-CIDRs.** Beide Seiten müssen die LAN-Subnetze der Gegenstelle in `AllowedIPs` führen, sonst kein Cross-Site-Routing.
3. **MTU.** FritzBox nutzt typ. **1412** (WireGuard + IPv6 + PPPoE-Overhead); WG-Default ist 1420. Bei PPPoE/IPv6-Pfaden MTU angleichen, sonst Fragmentierung/Hänger.
4. **`PersistentKeepalive = 25`** auf der FritzBox-(Client-)Seite für NAT-Traversal/Handshake-Stabilität.
5. **Firewall (MikroTik):** Input-Regel für UDP-Listen-Port + Forward-Regeln für den Cross-Site-Traffic; ggf. kein NAT zwischen den getunnelten Subnetzen.
### NAT / Endpoint-Erreichbarkeit (der entscheidende Punkt)
- WireGuard braucht **mindestens einen öffentlich erreichbaren Endpoint**. Ausgehende Verbindungen funktionieren auch hinter CGNAT, **eingehende nicht**. ([Firewalla-Community](https://help.firewalla.com/hc/en-us/community/posts/38610335671443-WireGuard-behind-CGNAT-5G-Connection-T-Mobile-5G-Business-Internet), [IPv64-Forum (DE)](https://v64.tech/t/wireguard-auf-fritzbox-per-ipv4-cgnat/749))
- **Dynamische IP** ist kein Problem, **CGNAT schon.** Der Hub (BF/MikroTik) muss also eine **public IP** haben (statisch oder via **DynDNS/MyFRITZ**). Dynamische public IP → DynDNS-Hostname als Endpoint (FritzBox akzeptiert FQDN-Endpoints; in einem dokumentierten Fall kam der Handshake erst mit FQDN statt roher IP zustande).
- **Wenn der Hub hinter CGNAT liegt:** Hub-&-Spoke über WireGuard ist dann **nicht** direkt machbar (keine Seite eingehend erreichbar). Optionen: ISP-Option „echte IPv4"/DS-Lite-Ausnahme, IPv6-only-Tunnel (nur wenn **alle** Sites stabiles IPv6 haben), oder Umstieg auf den **CF-/WARP-Connector-Pfad** (nur ausgehend → CGNAT-immun).
### Kann der MikroTik-Hub den Container-Weg gehen statt nativem WG?
Nicht empfehlenswert auf dem **hAP ax²**: 1 GB RAM, aber nur **128 MB Onboard-Flash und kein USB**. Container (cloudflared/WireGuard-Image) brauchen Netzwerk-Storage als Workaround — fragil. ([MikroTik-Forum: hAP ax2 storage & containers](https://forum.mikrotik.com/t/hap-ax2-storage-and-containers/166157)) → **Natives** RouterOS-WireGuard nutzen, nicht containerisieren.
---
## 3. Pro / Contra im Direktvergleich
| Kriterium | (A) WireGuard FritzBox↔MikroTik (Hub=BF) | (B) Cloudflare Zero Trust / WARP(-Connector) |
|---|---|---|
| **Performance** | Direkter Tunnel, kein Umweg über Edge → niedrigste Latenz, voller LAN-Speed (CPU/MTU-limitiert). | Traffic läuft über Cloudflare-Edge (Hairpin) → Zusatz-Latenz; auf Free-Plan **Daten-Cap** (10 GB Free, danach 15 GB/User; Mehrverbrauch $1/GB). |
| **Admin-Aufwand** | Einmalige WG-Config je Site; FritzBox-Import per `.conf`; keine zusätzliche HW an FM/DW. Gotchas (keine Interface-IP, MTU) müssen sitzen. | **Linux-Host je Site** nötig (Beschaffung + Betrieb + Updates), v.a. an reinen FritzBox-Standorten FM/DW. Zentrale Policy/Routes im CF-Dashboard. |
| **NAT-Traversal** | Braucht **1 public Endpoint** (Hub). CGNAT am Hub = K.O. | **CGNAT-immun** — Connector baut nur **ausgehende** Verbindungen zur Edge auf. Stärke dieses Pfads. |
| **Zuverlässigkeit** | Sehr hoch, solange Hub erreichbar; keine Cloud-Abhängigkeit. SPOF = Hub-Site. | Abhängig von Cloudflare-Verfügbarkeit + Linux-Host je Site (mehr bewegliche Teile). |
| **Kosten** | 0 €, Hardware vorhanden (FritzBoxen + hAP ax²). | Free-Plan bis **50 User**, per-User-Modell, kein Bandbreiten-Preis — aber **Daten-Cap** + Bedarf an zusätzlicher Linux-HW/Strom je Site. ([CF ZT Plans](https://www.cloudflare.com/plans/zero-trust-services/)) |
| **Observability** | RouterOS-Logs/Torch/Traffic-Monitor (gut, lokal). FritzBox: spärlich. Kein zentrales Dashboard. | Zentrales **CF Zero Trust Dashboard**, Logs, Device-Posture, Access-Policies, Audit. Klar überlegen. |
| **Fit zum Bestand (CF One/WARP)** | Orthogonal — koexistiert problemlos mit CF-DNS-Filtering (CGPS) und WARP-Remote-Access. | Nutzt vorhandene CF-One-Tenant; konsistente Identität/Policy. Aber erzwingt HW-Ausbau an FritzBox-only-Sites. |
| **Remote-User-Zugriff (unterwegs)** | WG-Road-Warrior je Site separat zu pflegen. | **Stärke von WARP** — ein Client, Identitäts-basiert, Split-Tunnel, Posture. Bereits live. |
---
## 4. Empfehlung für FM / BF / DW
**Backbone = WireGuard, Remote-Access = WARP.** Konkret:
1. **Site-to-Site-Mesh über natives WireGuard.**
- **Hub = BF / MikroTik hAP ax²** als WG-**Server** (nativ, kein Container). Setzt **public IP an BF** voraus (statisch oder DynDNS/MyFRITZ; **kein CGNAT**).
- **FM und DW** = FritzBox-WG-**Clients** zum BF-Hub (Hub-&-Spoke). Damit brauchen die reinen-FritzBox-Standorte **keinen** zusätzlichen Host.
- Gotchas beachten: keine IP aufs WG-Interface (MikroTik), `AllowedIPs` = Tunnelnetz + alle LAN-CIDRs, MTU 1412, `PersistentKeepalive=25`, MikroTik-Firewall Input/Forward.
- Optional FM↔DW direkt (full mesh) nachrüsten, sobald beide einen erreichbaren Endpoint haben — sonst läuft FM↔DW über den BF-Hub.
2. **WARP / Zero Trust bleibt für Remote-User** (Laptop/Handy von außerhalb → Heimnetze) **und** als Identitäts-/Access-/Observability-Layer. Kein Umbau des bestehenden CF-One-Einsatzes nötig; ergänzt das WG-Backbone statt es zu ersetzen.
3. **Trigger zum Umschwenken auf den CF-WARP-Connector-Pfad als Backbone:** Falls **BF (oder kein Standort) eine eingehend erreichbare public IP** hat (CGNAT/DS-Lite ohne Ausweg). Dann an jedem Standort einen kleinen Linux-Host (Pi o.ä.) mit WARP-Connector, weil dieser nur ausgehend verbindet und damit CGNAT-immun ist — zulasten von Zusatz-HW, Edge-Latenz und Daten-Cap.
**Voraussetzung-Check vor Umsetzung:** WAN-Anbindung **jedes** Standorts prüfen (public vs. CGNAT/DS-Lite, statisch vs. dynamisch, IPv4/IPv6). Das entscheidet zwischen Pfad A (mind. Hub public) und Pfad B (CGNAT-tolerant).
---
## Quellen
- [Bouni – Site-to-Site WireGuard FritzBox↔MikroTik (2026)](https://blog.bouni.de/posts/2026/site-to-site-wireguard-vpn-between-fritzbox-and-mikrotik/)
- [Shaw-IoT – WireGuard MikroTik RouterOS v7 ↔ FRITZ!Box 7530](https://blog.shaw-iot.co.uk/2023/04/wireguard-vpn-between-mikrotik-routeros.html)
- [MikroTik-Forum – FRITZ!Box WG-Server ↔ MikroTik Client](https://forum.mikrotik.com/t/configuration-issue-between-fritz-box-wireguard-server-and-mikrotik-client/175777)
- [Cloudflare One – WARP Connector (Overview)](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/warp-connector/)
- [Cloudflare One – WARP Connector Site-to-Site](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/warp-connector/site-to-site/)
- [Cloudflare WARP-Client – unterstützte OS](https://developers.cloudflare.com/warp-client/)
- [Cloudflare Zero Trust – Plans & Pricing](https://www.cloudflare.com/plans/zero-trust-services/)
- [Firewalla-Community – WireGuard hinter CGNAT](https://help.firewalla.com/hc/en-us/community/posts/38610335671443-WireGuard-behind-CGNAT-5G-Connection-T-Mobile-5G-Business-Internet)
- [IPv64-Forum (DE) – WireGuard auf FritzBox per IPv4-CGNAT](https://v64.tech/t/wireguard-auf-fritzbox-per-ipv4-cgnat/749)
- [MikroTik-Forum – hAP ax2 Storage & Containers (128 MB Flash)](https://forum.mikrotik.com/t/hap-ax2-storage-and-containers/166157)

107
docs/teilprojekte.md Normal file
View File

@@ -0,0 +1,107 @@
# 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 | (FB-Transfer) | zur FritzBox |
IP-Blöcke: `.1–10` Router/APs (ap1=.1, ap2=.2) · `.11–20` Switches (ALLNET=.11, Omada=.12). GW je VLAN = `.1`.
⚠️ Switch-VLAN-DB trägt noch **40=UNTRUSTED** (alt) und **kein 50** → beim Switch-Schritt umbenennen + vlan50 anlegen.
## Ist-Stand (Kurz)
ALLNET-Core `.11` (FW2.2.1, VLANs 10/20/30/40/90/99/100 benannt; GE8→Trunk in Arbeit). Omada-Switch `.12` (Standalone, Creds `omada/.secrets`).
2× hAP ax² (7.23.1): ap1 `.1` (Core P1), ap2 `.2` (Core P2 — **bleibt vorerst**). FB6660 = Router/Telefon (`.254`).
Kontrolle: MikroMCP (MikroTik) live · ALLNET = Klickanleitungen (inline) · Omada → Controller (TP2).
> ⚠️ **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, Technitium, Omada-Controller) laufen auf **NAS/pve**, nicht am hAP.
---
## Teilprojekte
### TP1 — ALLNET Core-Switch finalisieren ▸ läuft
- **GE8 Hybrid→Trunk** (Omada-Uplink): native vlan1 + tagged 10,20,30,40,90,99,100 → Klickanleitung, User klickt. Danach: vlan40 umbenennen MEDIA, **vlan50 (UNTRUSTED) anlegen**, GE8 um 50 ergänzen.
- Abh.: keine. Ergebnis: Core trägt alle VLANs an P1/P2/P8.
### TP2 — Omada Access-Switch + Controller ▸ als Nächstes
- **Omada Software Controller als Container auf DS923 (BF)** → Switch `.12` adoptieren → Uplink/ap2-Port=Trunk(all), lokale=Access. Dann **omada-mcp** (realtydev) an Controller.
- Abh.: TP1 (GE8 Trunk). research: omada-mcp-Setup.
### TP3 — WLAN / CAPsMAN ▸ teilweise blockiert
- **`bound`-Problem** sauber lösen (MikroMCP, doku-gegründet) → Test-WLAN „BF-Main" → SSID→VLAN-Datapaths.
- **DoH-Upstream auf APs = Cloudflare** (`/ip dns use-doh-server=https://cloudflare-dns.com/dns-query verify-doh-cert=yes`). Rest der AP-Config noch ~default.
- **SSID-Strategie (Entscheid):** NICHT naiv 1 SSID je VLAN + MAC-Filter. Besser: **eine 802.1X-SSID mit dynamischer VLAN-Zuweisung** (RADIUS, → TP8) für fähige Geräte; **PSK-SSIDs** für IoT/Guest/Media (Geräte ohne 802.1X). Einheitliche Nomenklatur `BF-…`. Hidden ≠ Sicherheit (nur Obscurity); MAC-Filter = schwaches Minimum, **EAP-TLS/Zert deutlich besser** (TP8).
- **Mesh = NEIN** (beide APs wired-trunk → Loop-Risiko via Router/LAN; Mesh nur sinnvoll ohne wired backhaul). Research bestätigt in TP-R.
- Abh.: TP8 (für 802.1X). research: CAPsMAN-bound, mesh.
### TP4 — Router-Cutover (hAP#1 = Router) ▸ disruptiv, geplant
- Per-VLAN L3-Interface `.1`, **DHCP** (RouterOS), **DNS=Technitium**, **NAT**, FB→**Bridge-Mode/Exposed-Host**.
- **FB-Bridge testen** (LAN4-Native-Bridge-Hack) → kein Double-NAT; sonst Exposed-Host-Fallback.
- Abh.: TP1, TP3. Ziel: VLAN-SSILs nutzbar + Telefonie-Fix aktiv.
### TP5 — Firewall & Inter-VLAN-Policy
- **Deny-by-default + least-privilege.** MAIN→INFRA nur Whitelist-Dienste; MAIN↔MEDIA allow (+mDNS); UNTRUSTED/GUEST nur Internet; MGMT isoliert; Router-input gehärtet.
- **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.
### 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
- **Built-in mDNS-Repeater** (7.16+) MAIN↔MEDIA; Cast/SSDP optional via <10MB-Container. Firewall-Holes (TP5).
- Abh.: TP4, TP5.
### 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 ▸ Research fertig (`docs/research/vpn-comparison.md`)
- **Empfehlung:** **Hybrid** — **WireGuard Site-to-Site-Backbone** (BF/hAP = WG-**Hub**, FM/DW = FritzBox-**Spokes**, hub&spoke, **KEINE Zusatz-HW**) **+ WARP für Remote-User** (ergänzt, ersetzt nicht).
- **WARP kann FBs NICHT direkt** ansprechen → bräuchte Connector-Host hinter der FB (an reinen-FB-Standorten FM/DW unattraktiv).
- **Vorab-Check (User, entscheidend):** WAN je Standort — **public/dynamisch (OK: DynDNS/MyFRITZ) vs. CGNAT/DS-Lite am BF-Hub (= K.O. → dann CF/WARP-Pfad, CGNAT-immun)**.
- WG-Gotchas: keine IP aufs WG-IF (MikroTik), AllowedIPs=Tunnel+LAN-CIDRs, MTU 1412, Keepalive 25. ap1 hat noch KEIN WG (Neuaufbau).
- Abh.: WAN-Check; Hub sinnvoll nach TP4 (Router-Cutover).
### 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`.
### 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.
### 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
1. **Jetzt:** TP1 (GE8) → TP2 (Omada Controller). Parallel: Research (TP-R, TP10) laufen.
2. **Dann:** TP3 (WLAN-bound + DoH) — 802.1X-Teil wartet auf TP8/Research.
3. **Cutover-Block:** TP4 (Router) → TP5 (Firewall) → TP6 (QoS) → TP7 (mDNS). Disruptiv, geplant.
4. **Nachgelagert/Research-getrieben:** TP8 (Access), TP9 (HA), TP10 (VPN), TP11 (Monitoring), TP12 (IPv6), TP13 (Spaß).

View File

@@ -1,4 +1,6 @@
port,ist,downstream,behalten,soll,notiz
1,ap1 (hAP ax² #1) Trunk-Uplink,10.40.41.1,ja,Trunk zu ap1,"TRUNK gesetzt 2026-06-09: native vlan1 + tagged 10,20,30,40,90,99,100. Provisorisch. Vorher: Sonos Sub (verdrängt -> SonosNet/WLAN)"
2,ap2 (hAP ax² #2) Trunk-Uplink,10.40.41.2,ja,Trunk zu ap2,"TRUNK gesetzt 2026-06-09: native vlan1 + tagged 10,20,30,40,90,99,100. Provisorisch. Vorher: ap1"
4,Uplink Wohnzimmer-Switch (smart managed),,bis neue Switches produktiv,neues Gerät,interim — wird ersetzt
8,Uplink Arbeitszimmer-Switch (smart managed),10.40.41.10; 10.40.41.167; 10.40.41.247,bis neue Switches produktiv,neues Gerät,interim — wird ersetzt
15,pve,,ja,beibehalten,
1 port ist downstream behalten soll notiz
2 1 ap1 (hAP ax² #1) Trunk-Uplink 10.40.41.1 ja Trunk zu ap1 TRUNK gesetzt 2026-06-09: native vlan1 + tagged 10,20,30,40,90,99,100. Provisorisch. Vorher: Sonos Sub (verdrängt -> SonosNet/WLAN)
3 2 ap2 (hAP ax² #2) Trunk-Uplink 10.40.41.2 ja Trunk zu ap2 TRUNK gesetzt 2026-06-09: native vlan1 + tagged 10,20,30,40,90,99,100. Provisorisch. Vorher: ap1
4 4 Uplink Wohnzimmer-Switch (smart managed) bis neue Switches produktiv neues Gerät interim — wird ersetzt
5 8 Uplink Arbeitszimmer-Switch (smart managed) 10.40.41.10; 10.40.41.167; 10.40.41.247 bis neue Switches produktiv neues Gerät interim — wird ersetzt
6 15 pve ja beibehalten

View File

@@ -1,10 +1,13 @@
# Core-Switch ALL-SG8316M (sw1, 10.40.41.239) — Port-Map
> Ist-Belegung. Ports 4/8/15/16 **behalten** (4+8 interim bis neue Switches produktiv).
> Übrige Ports (1–3, 5–7, 9–14): noch nicht erfasst — gemeinsam ergänzen.
> **gi1/gi2 = Trunks zu ap1/ap2** (gesetzt 2026-06-09, provisorische Belegung).
> Übrige Ports (3, 5–7, 9–14): noch nicht erfasst — gemeinsam ergänzen.
| port | ist | downstream | behalten | soll | notiz |
|---|---|---|---|---|---|
| 1 | **ap1 (hAP ax² #1) Trunk-Uplink** | 10.40.41.1 | ja | Trunk zu ap1 | **TRUNK 2026-06-09**: native vlan1 + tagged 10,20,30,40,90,99,100. Provisorisch. Vorher: Sonos Sub (verdrängt → SonosNet/WLAN) |
| 2 | **ap2 (hAP ax² #2) Trunk-Uplink** | 10.40.41.2 | ja | Trunk zu ap2 | **TRUNK 2026-06-09**: native vlan1 + tagged 10,20,30,40,90,99,100. Provisorisch. Vorher: ap1 |
| 4 | Uplink Wohnzimmer-Switch (smart managed) | | bis neue Switches produktiv | neues Gerät | interim — wird ersetzt |
| 8 | Uplink Arbeitszimmer-Switch (smart managed) | 10.40.41.10; 10.40.41.167; 10.40.41.247 | bis neue Switches produktiv | neues Gerät | interim — wird ersetzt |
| 15 | pve | | ja | beibehalten | |

5
mcp/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
# Secrets & runtime — niemals committen
**/.env
**/config/identities.yaml
**/config/audit.ndjson
# routers.yaml ist OK im Git (keine Secrets, nur Hosts); identities.yaml NICHT (Token-Hashes).

32
mcp/INVENTORY.md Normal file
View File

@@ -0,0 +1,32 @@
# MCP-Inventar — BF (Single Source of Truth gegen "1000 MCP-Leichen")
> **Regel:** Jeder MCP-Server, der für BF läuft, steht **hier** — sonst existiert er nicht.
> Kein lokaler Ad-hoc-`npx`-Wildwuchs auf Laptops. Zentral = Docker auf einem Host, FQDN-adressiert.
> Wer einen MCP abschaltet, **streicht die Zeile** (oder setzt Status `retired` mit Datum).
## Aktive / geplante MCPs
| MCP | Zweck / Geräte | Host | Transport / Endpoint | Image | Config | Status |
|---|---|---|---|---|---|---|
| **MikroMCP** (AliKarami) | MikroTik hAP ax² ap1/ap2 (RouterOS 7) — WLAN/CAPsMAN, später Router-Cutover | **jetzt: lokal (dieser Mac)** / Ziel: Mac mini `.167` Docker | jetzt **stdio** (`npx mikromcp serve`) / Ziel HTTP `:3000` | `ghcr.io/alikarami/mikromcp:latest` (HTTP) bzw. npm `mikromcp` (stdio) | `mcp/mikromcp/` + Claude-Code user-config | 🟢 **live (stdio), doctor 12/12, in Claude Code ✓Connected** |
| **omada-mcp** (realtydev) | TP-Link Omada Controller → ES208G (+ künftige Omada-Geräte) | tbd (Controller = pve-LXC `10.40.41.126`) | HTTP (stream) | `jmtvms/tplink-omada-mcp` (Fork prüfen) | `mcp/omada/` (tbd) | 🔴 wartet auf Controller+Adoption |
| **portainer-mcp** (offiziell) | Docker-Überblick **5 Hosts** (pve/ds923/odroid/macmini/ds415) via Portainer | Portainer-Server **läuft** auf `.126:9443` **v2.40.0** | stdio (uvx) o. Docker-HTTP, **read-only** | `portainer/portainer-mcp` / `mcp-portainer` | `mcp/portainer/` (Token in .env ✓) | 🟠 **blockiert: Portainer 2.40 hat keinen passenden MCP (nur 2.41/2.42)** → Portainer bumpen; + lokal kein uvx/docker |
| ~~ALLNET-MCP~~ | ALLNET ALL-SG8316M Core-Switch | — | — | — | — | ⛔ **bewusst NICHT** (Telnet/1-VTY/15-min-Lock auf Core = zu fragil). User-Entscheid: erst beschriebener Weg, sonst Omada-Core-Tausch. |
Legende: 🟢 live · 🟡 staged (Config da, nicht deployed) · 🔴 blockiert · ⛔ bewusst nicht gemacht
## Anti-Sprawl-Regeln
1. **Zentral statt lokal:** MCPs laufen als Container auf einem festen Host, nicht als `npx` pro Laptop.
2. **Eine Zeile pro MCP** in dieser Tabelle. Kein Eintrag → abschalten.
3. **Config im Git** (`mcp/<name>/`), Secrets nur in `.env` (gitignored).
4. **FQDN statt IP**, sobald eingerichtet (DNS-Rewrite) → Endpoint-Spalte updaten.
5. **Review-Datum:** mind. halbjährlich diese Tabelle gegen tatsächlich laufende Container prüfen
(`docker ps` auf den Hosts).
## ALLNET — warum kein MCP
ALL-SG8316M (Core) nach FW-2.2.1-Flash: **Web-UI tot, nur Telnet-CLI, kein SSH/REST/SNMP-Write,
nur 1 VTY-Line, ~15 min Busy-Lock bei Stale-Sessions.** Ein MCP darüber wäre auf dem **Core-Switch**
(an dem alles hängt) fragil und lockout-gefährlich. → Management bleibt bei der bestehenden
Telnet-CLI-Toolchain (`switch/cli/`). **Strategische Option:** Core-Switch (Methusalem, Bj. 2015)
gegen einen **Omada-Switch** tauschen → fällt unter denselben Omada-Controller/omada-mcp.
Das ist Hardware-Ausgabe + Core-Cutover → **User-Entscheidung** (offen).

49
mcp/README.md Normal file
View File

@@ -0,0 +1,49 @@
# MCP-Control-Plane — BF
Zentrale, versionierte MCP-Server für BF. Übersicht aller MCPs: **[INVENTORY.md](INVENTORY.md)**.
Ziel: ein nachvollziehbarer Satz MCPs (gegen "1000 MCP-Leichen"), zentral als Container, FQDN-adressiert.
## MikroMCP (MikroTik ap1/ap2)
REST-primär + guarded SSH; RouterOS-7-nativ; Safety: dry-run, `plan_changes`/`apply_plan`/`rollback_change`,
Confirmation-Tokens, RBAC, Audit-Log. Image: `ghcr.io/alikarami/mikromcp:latest`.
### Zwei Betriebsarten
- **A — lokal stdio (schnell, kein Netz-Exposure):** läuft dort wo Claude läuft, RBAC = built-in superadmin,
keine Tokens/Secret nötig. Gut für sofortige WLAN-Arbeit. Trotzdem in INVENTORY eintragen.
- **B — Docker HTTP auf Mac mini (zentral, Ziel):** `docker-compose.yml`. Erfordert Confirmation-Secret +
Bearer-Token-Identität. Endpoint später hinter NPM (FQDN+Auth).
### RouterOS-User (beide APs) — NICHT admin verwenden
```
/user group add name=mcp policy=read,write,api,rest-api,test,ssh,sniff,!ftp,!policy,!password
/user add name=mcp-api group=mcp password=<stark>
```
(`ftp` nur falls `upload_file` gebraucht wird; `sniff` nur für `torch`. SSH-Dienst muss laufen für
ping/traceroute/torch/run_command — REST blockt diese Befehle generell.)
### B deployen (Mac mini 10.40.41.167)
```
openssl rand -hex 32 # -> MIKROMCP_CONFIRMATION_SECRET
# identities.yaml aus identities.example.yaml bauen (Token: openssl rand -hex 32, dann bcrypt-Hash):
node -e "const b=require('bcryptjs');b.hash(process.argv[1],12).then(console.log)" <raw-token>
scp -r mcp/mikromcp 10.40.41.167:/opt/docker/mikromcp
ssh 10.40.41.167 'cd /opt/docker/mikromcp && cp .env.example .env' # .env + config/identities.yaml füllen
ssh 10.40.41.167 'cd /opt/docker/mikromcp && docker compose up -d && docker compose logs --tail=50'
```
Smoke-Test: `curl -s http://10.40.41.167:3000/health` bzw. MCP-Initialize mit Bearer-Token.
### In Claude Code einhängen
- **A (stdio):** `claude mcp add mikromcp -- npx -y mikromcp` + ENV (`MIKROMCP_CONFIG_PATH`, `ROUTER_AP1_USER/PASS`, …).
- **B (http):** `claude mcp add --transport http mikromcp http://10.40.41.167:3000` (Header `Authorization: Bearer <raw-token>`).
Nach FQDN: URL auf `https://<fqdn>` umstellen.
## omada-mcp (TP-Link ES208G)
Wartet auf: Omada-Controller (≥6.1.x, `../../omada/docker-compose.yml`, Ziel pve-LXC 10.40.41.126) **up** +
ES208G **adoptiert**. Env: `OMADA_BASE_URL`, `OMADA_CLIENT_ID/SECRET`, `OMADA_OMADAC_ID`, `OMADA_SITE_ID`,
`OMADA_STRICT_SSL=false` (self-signed). Tools: Switch-Ports/VLAN/Firewall CRUD. Details: INVENTORY.md.
## Sicherheit (wichtig)
Ein MikroMCP/omada-mcp-HTTP-Endpoint kann Infrastruktur administrieren. Daher: nur auf LAN-IP binden,
dedizierte Nicht-admin-User, Confirmation-Secret gesetzt, Audit-Log an, später NPM+Auth+TLS+FQDN davor.

11
mcp/mikromcp/.env.example Normal file
View File

@@ -0,0 +1,11 @@
# MikroMCP BF — Secrets. Kopiere zu .env (gitignored), fülle Werte.
#
# Confirmation-Secret (Pflicht im HTTP-Modus): openssl rand -hex 32
MIKROMCP_CONFIRMATION_SECRET=
# Dedizierter RouterOS-User (NICHT admin) — anlegen lt. README.md §RouterOS-User.
# Policies nötig: read,write,api,rest-api,test,ssh,sniff (ftp nur für upload_file).
ROUTER_AP1_USER=mcp-api
ROUTER_AP1_PASS=
ROUTER_AP2_USER=mcp-api
ROUTER_AP2_PASS=

View File

@@ -0,0 +1,30 @@
# MikroMCP Router-Registry — BF hAP ax²
# Credentials NICHT hier, sondern via ENV (envPrefix -> ROUTER_<PREFIX>_USER/PASS in .env).
# APs sprechen REST über PLAIN HTTP auf Port 80 (verifiziert: curl ...:80/rest funktioniert).
# -> tls.enabled: false (rest-client.ts: scheme = tls.enabled ? https : http)
# Sobald www-ssl auf den APs aktiv ist, auf port 443 + tls.enabled:true + fingerprint umstellen.
routers:
ap1:
host: "10.40.41.1"
port: 80
tls:
enabled: false
rejectUnauthorized: true # Pflichtfeld lt. Schema; ohne Wirkung bei enabled:false
credentials:
source: "env"
envPrefix: "ROUTER_AP1" # -> ROUTER_AP1_USER, ROUTER_AP1_PASS
tags: ["bf", "wifi", "capsman-manager", "future-router"]
rosVersion: "7.23"
ap2:
host: "10.40.41.2"
port: 80
tls:
enabled: false
rejectUnauthorized: true # Pflichtfeld lt. Schema; ohne Wirkung bei enabled:false
credentials:
source: "env"
envPrefix: "ROUTER_AP2" # -> ROUTER_AP2_USER, ROUTER_AP2_PASS
tags: ["bf", "wifi", "cap"]
rosVersion: "7.23"

View File

@@ -0,0 +1,35 @@
# MikroMCP — BF, Docker auf Mac mini (10.40.41.167)
# Prebuilt-Image (kein Source-Build nötig). HTTP/streamable für Remote-Clients.
#
# SECURITY: Dieser Endpoint kann RouterOS administrieren. Er ist NUR durch Bearer-Token
# (identities.yaml, bcrypt) + Confirmation-Secret geschützt. Daher:
# - ports auf das Mgmt-/LAN-Interface binden, NICHT 0.0.0.0 ins Internet,
# - später hinter NPM (FQDN + Auth/TLS) hängen,
# - dedizierter RouterOS-User 'mcp-api' (NICHT admin) — siehe ../README.md.
#
# Deploy (auf dem mini):
# scp -r mcp/mikromcp 10.40.41.167:/opt/docker/mikromcp
# ssh 10.40.41.167 'cd /opt/docker/mikromcp && cp .env.example .env && $EDITOR .env'
# ssh 10.40.41.167 'cd /opt/docker/mikromcp && docker compose up -d && docker compose logs -f'
services:
mikromcp:
image: ghcr.io/alikarami/mikromcp:latest
container_name: mikromcp
restart: unless-stopped
environment:
MIKROMCP_TRANSPORT: http
MIKROMCP_PORT: "3000"
MIKROMCP_BIND_HOST: "0.0.0.0" # im Container; Exposure via ports-Mapping unten begrenzen
MIKROMCP_CONFIG_PATH: /app/config/routers.yaml
MIKROMCP_IDENTITIES_PATH: /app/config/identities.yaml
MIKROMCP_CONFIRMATION_SECRET: ${MIKROMCP_CONFIRMATION_SECRET}
MIKROMCP_AUDIT_LOG_PATH: /app/config/audit.ndjson
MIKROMCP_HTTP_RATE_LIMIT_RPM: "60"
MIKROMCP_LOG_LEVEL: info
env_file:
- .env # ROUTER_AP1_USER/PASS, ROUTER_AP2_USER/PASS, secret
volumes:
- ./config:/app/config # routers.yaml + identities.yaml + audit.ndjson
ports:
- "10.40.41.167:3000:3000" # nur auf LAN-IP des mini binden (nicht überall)

41
mcp/portainer/README.md Normal file
View File

@@ -0,0 +1,41 @@
# portainer-mcp (offiziell) — BF
Überblick über die Docker-Landschaft via Portainer. Übersicht aller MCPs: [../INVENTORY.md](../INVENTORY.md).
## Ist-Stand (2026-06-09)
- **Portainer-Server läuft** auf `https://10.40.41.126:9443`, **v2.40.0**, managed **5 Endpoints**:
`pve` (lokal), `nas-bf (ds923+)`, `odroid-m1`, `macmini`, `nas-fm (ds415+)`.
- **API-Token** vorhanden (admin) → in `.env` (gitignored).
- **Blocker:** `portainer-mcp` gibt es nur als **2.41.x / 2.42.x**, jeweils = gleiche Portainer-Minor.
**2.40 hat keinen passenden MCP** → Portainer auf `.126` auf **2.42.x** bumpen (sauberster Weg).
## Weg A — lokal stdio via uvx (least-invasive, kein Portainer-Touch nötig zum Probieren)
Voraussetzung: `uv` installieren (`brew install uv` oder `curl -LsSf https://astral.sh/uv/install.sh | sh`).
```
# NACH Portainer-Bump auf 2.42 (oder Versuch 2.41 gegen 2.40):
claude mcp add portainer -s user \
-e PORTAINER_URL=https://10.40.41.126:9443 \
-e PORTAINER_API_KEY=ptr_... \
-e PORTAINER_TLS_VERIFY=0 \
-- uvx --from "mcp-portainer~=2.42.0" mcp-portainer
```
Read-only erzwingen: über MCP-Config/Profil (siehe portainer-mcp `docs/configuration.md` → „read-only capabilities").
## Weg B — Docker HTTP auf Mac mini (.167), zentral hinter FQDN (wie ha-mcp/MikroMCP-Ziel)
```
docker run -d --name portainer-mcp -p 17717:17717 \
-e PORTAINER_URL=https://10.40.41.126:9443 \
-e PORTAINER_API_KEY=ptr_... \
-e PORTAINER_TLS_VERIFY=0 \
-e PORTAINER_MCP_AUTH_TOKEN=<gate-secret> \
-e PORTAINER_MCP_ALLOWED_HOSTS=<fqdn-or-167-ip>:17717 \
portainer/portainer-mcp:2.42
# Client:
claude mcp add portainer --transport http http://<mini>:17717/mcp \
--header "Authorization: Bearer <gate-secret>" \
--header "X-Portainer-API-Key: ptr_..."
```
## Versions-Policy (Doku)
Match MCP-Minor = Portainer-Minor. Tabelle: nur 2.41.x↔2.41.x, 2.42.x↔2.42.x. Kein 2.40.
TLS: self-signed → `PORTAINER_TLS_VERIFY=0`.

63
routeros/HANDOVER-wifi.md Normal file
View File

@@ -0,0 +1,63 @@
# Übergabe-Prompt: hAP ax² WLAN/CAPsMAN-Setup (BF)
```
Du übernimmst die WLAN-Einrichtung von zwei MikroTik hAP ax². ARBEITE DOKU-GEGRÜNDET
(MikroTik RouterOS 7 "wifi"/CAPsMAN, help.mikrotik.com) — KEINE Trial-and-Error-Schleifen.
Lies ZUERST die Doku zu: /interface/wifi, CAPsMAN, configuration, datapath, security,
channel, provisioning. Verstehe das "bound"-Konzept, BEVOR du etwas änderst.
ZIEL
- ap1 = CAPsMAN-Manager + AP, ap2 = CAP (zieht Config von ap1).
- Erst ein TEST-WLAN auf dem aktuellen FLAT-Netz (Bridge, KEIN VLAN), SSID "BF-Main"
(Name egal). Verifiziere: Client verbindet, Roaming ap1<->ap2.
- Bänder: wifi1 = 5 GHz (5ghz-ax), wifi2 = 2,4 GHz (2ghz-ax) — verifiziert.
- WPA3-only für BF-Main ist gewünscht/ok. Country = Austria. Temp-Passphrase (User
setzt echte später), z.B. "BFtest-2026-tmp".
ZUGANG
- ap1 = 10.40.41.1, ap2 = 10.40.41.2. user=admin pw=46484b9952#P
- REST über HTTP funktioniert: curl -s -u 'admin:46484b9952#P' http://10.40.41.1/rest/interface/wifi
ACHTUNG: nested-set via REST ({"channel":{"band":..}} bzw. "channel.band") hat beim
Vorgänger NICHT zuverlässig gegriffen (kam als None zurück). Lieber SSH/CLI ODER
korrekten REST-Pfad aus der Doku verifizieren.
- SSH geht (1. Login fragt "software license? [Y/n]" -> n). Tools: telnet/expect (macOS).
Python 3.14 hat KEIN telnetlib.
STAND
- Beide auf RouterOS 7.23.1 + RouterBOOT 7.23.1, Identity ap1/ap2, Mgmt-IP .1/.2 auf der
Bridge (untagged vlan1). Default-Bridge (ether2-5 + wifi). ether1=WAN ungenutzt. Uplink=ether2.
DAS PROBLEM (Kern!)
- Vorgänger hat CAPsMAN halb aufgesetzt (auf ap1: security/datapath/configuration/
provisioning; auf ap2: cap). Kopplung lief (ap2 bei ap1 registriert, state=Ok).
- ABER die wifi-Interfaces sind "bound=true" (CAPsMAN-gebunden) -> lokale
`set channel.band/configuration.*` werden IGNORIERT -> channel=None, running=false,
es funkt NICHTS. Auch nach `capsman/cap disable` + `provisioning remove` blieb bound=true.
- VERMUTUNG (DOKU PRÜFEN!): Im CAPsMAN-Modell gehört Band/Kanal in die configuration bzw.
in ein /interface/wifi/channel-Profil + provisioning mit supported-bands (je Radio das
passende Config). cfg-test hatte KEINEN Kanal -> gebundene Interfaces ohne Kanal -> aus.
Klär aus der Doku: wie löst man "bound" sauber (ggf. komplettes Reset der wifi-Config,
ggf. Reboot/Power-Cycle), und wie setzt man Band/Kanal im CAPsMAN-Modell korrekt.
ZU TUN
1. wifi-Config sauber entwirren (bound lösen). Sauberer Reset ODER korrekt über CAPsMAN.
2. Test-WLAN BF-Main hochbringen (beide Bänder, beide APs, gleiche SSID), Client testen,
Roaming testen. (Standalone-inline ist erlaubt, falls CAPsMAN für den Schnelltest zickt
— User will aber eigentlich CAPsMAN: ap2 zieht von ap1.)
3. ERST danach SSID->VLAN (datapath vlan-id) — nutzbar aber erst NACH Router-Cutover.
CONSTRAINTS / SAFETY
- HEUTE/aktuell NICHTS Riskantes, KEIN Router-Cutover. Nur WLAN-Test.
- APs tragen noch keinen Haushalts-Traffic; das Hauptnetz läuft über die FritzBox (unberührt).
- User ist ein paar Tage außer Haus, arbeitet remote mit. Beide APs an SCHALTBAREN
Steckdosen (Remote-Not-Aus) -> bei riskanten Änderungen IMMER Auto-Rückfall-Timer setzen
(/system scheduler, der nach X Min zurückstellt, außer du bestätigst).
- Mgmt der APs (.1/.2 auf Bridge/vlan1) NICHT aussperren.
KONTEXT/REPO
- ~/dev/bf-network-r6/ : Gesamt-Übergabe HANDOVER.md, VLAN-Plan docs/vlan-plan.md,
geplante (noch NICHT verifiziert korrekte) Configs routeros/ap1-manager.rsc / ap2-cap.rsc,
IP-Plan: .1-10 Router/APs, .11-20 Switches; VLANs 10/20/30/40/90/99/100.
ERWARTUNG: präzise nach Doku, keine Rate-Schleifen. Bei Unklarheit: Doku-Stelle nennen, dann handeln.
```

54
routeros/README.md Normal file
View File

@@ -0,0 +1,54 @@
# hAP ax² Setup — CAPsMAN + VLAN (Design & Plan, REVIEW vor Apply)
Stand: beide auf RouterOS **7.23.1** + RouterBOOT 7.23.1. Namen/IPs gesetzt:
**ap1 = 10.40.41.1** (künftiges Gateway/Router) · **ap2 = 10.40.41.2** (CAP). Default-Bridge (ether2–5+wifi, vlan-filtering aus).
> ⚠️ **Status: NUR PLAN.** An den Geräten bisher nur: Firmware 7.23.1, Identity ap1/ap2, Stray-IP weg, **Mgmt-IP→.1/.2**.
> Exakte 7.23-Syntax (wifi/capsman/provisioning/scheduler) wird **vor Apply gegen das Gerät validiert**.
## Hardware-Realität
- **WiFi 6 (ax)**, dual-band 2,4+5 GHz. **MLO ist NICHT verfügbar** (MLO = WiFi 7/802.11be → bräuchte hAP be³). „MLO wenn möglich" entfällt.
## Rollen
- **ap1 = CAPsMAN-Manager + AP** (später zusätzlich **Router** — L3/DHCP/DNS/NAT/CAKE = **separater Cutover**, NICHT hier).
- **ap2 = CAP** (zieht Wireless-Config von ap1 @ 10.40.41.1).
## ⚠️ Topologie / Verkabelung (Klärungsbedarf)
- **ap1** → **Core-Switch Port 2** (direkt). ✓ Guter Trunk-Kandidat.
- **ap2** → hinter **TP-Link TL-SG108E** → Core-Switch **Port 8**. Damit ap2 die VLANs **getaggt** bekommt, müsste **auch der TP-Link trunken** (kann 802.1Q, aber fummelige UI). **Empfehlung:** ap2 im Wartungsfenster **direkt an einen freien Core-Port** (z.B. Port 3) → sauberer Trunk, keine TP-Link-VLAN-Config.
- **ether1 = WAN — Achtung:** Für **ap1 (Router)** ist ether1 = **WAN zur FB** (Internet); der **LAN-Trunk** zum Core bleibt **ether2** → ap1 braucht **2 Kabel**. Für **ap2 (reiner AP)** gibt es kein WAN; **ein** Uplink (Trunk) genügt. → Den LAN-Trunk auf ether1 zu legen wäre für den Router falsch. **Finale Verkabelung bitte bestätigen.**
## Bridge-VLAN-Layout (beide APs)
- **Uplink ether2 = Trunk:** tagged `10,20,30,40,90,99,100` **+ native/untagged vlan1** (= aktuelles Mgmt-Netz, .1/.2).
- **Mgmt bleibt erreichbar** (untagged vlan1), solange der Switch-Port native vlan1 untagged bleibt.
- `vlan-filtering=yes` zuletzt — mit **Auto-Rollback** (5 min) gegen Lockout.
## WLAN (SSID → VLAN via CAPsMAN-Datapath)
| SSID | VLAN | Security |
|---|---|---|
| `BF-Main` | 10 (MAIN) | **WPA3-only** |
| `BF-IoT` | 30 (IOT) | WPA2/WPA3-PSK |
| `BF-Guest` | 90 (GUEST) | WPA2/WPA3-PSK |
Beide Bänder (2,4+5 GHz ax). **Temp-Passphrase** (Platzhalter `BFtest-2026-tmp`) — User setzt echte in Ruhe.
> VLAN-SSIDs bekommen erst **nach dem Router-Cutover** DHCP/Gateway. Sofort-Test optional via Temp-SSID auf **native vlan1** (FB-DHCP).
## Apply-Reihenfolge (wenn freigegeben)
1. **Switch:** AP-Uplink-Port(s) → Trunk (tagged 10,20,30,40,90,99,100 + native vlan1). [ap2 erst sinnvoll, wenn direkt am Core ODER TP-Link trunkt]
2. **ap1:** Bridge-VLAN → CAPsMAN-Manager → (Auto-Rollback) vlan-filtering=yes.
3. **ap2:** Bridge-VLAN → CAP enable (manager=10.40.41.1).
4. Verifizieren: ap2 im Manager; SSIDs auf beiden Radios; Mgmt erreichbar. Rollback canceln.
## Safety — Auto-Rollback
```
/system scheduler add name=vlan-rollback interval=5m \
on-event="/interface bridge set [find name=bridge] vlan-filtering=no; /system scheduler remove vlan-rollback"
```
## Offene Punkte (User)
- Finale Verkabelung bestätigen (ap1: ether1→FB-WAN, ether2→Core-Trunk; ap2: direkt an Core vs. TP-Link trunken).
- Switch-Mgmt-IP: `.3` oder `.239` (da `.2` jetzt = ap2).
- Echte WLAN-Passphrasen (später).
## Dateien
- `routeros/ap1-manager.rsc` · `routeros/ap2-cap.rsc`

47
routeros/ap1-manager.rsc Normal file
View File

@@ -0,0 +1,47 @@
# ===== ap1 (10.40.41.155) — CAPsMAN-Manager + AP + VLAN-Bridge =====
# RouterOS 7.23.1. NUR PLAN — Syntax vor Apply gegen Gerät validieren.
# Platzhalter <...> ersetzen. L3/Router-Teil (DHCP/DNS/NAT/CAKE) NICHT hier (separater Cutover).
# --- 1) Bridge-VLAN-Tabelle (Uplink ether2 = Trunk, native vlan1 = Mgmt) ---
/interface bridge vlan
add bridge=bridge vlan-ids=10,20,30,40,90,99,100 tagged=bridge,ether2
add bridge=bridge vlan-ids=1 untagged=ether2,ether3,ether4,ether5 tagged=bridge
/interface bridge port
set [find interface=ether2] pvid=1 ;# native/untagged = vlan1 (Mgmt)
# --- 2) WLAN Security (Passphrasen vom User) ---
# TEMP-Passphrase (Platzhalter) — User setzt echte später
/interface wifi security
add name=sec-main authentication-types=wpa3-psk passphrase="BFtest-2026-tmp" ;# WPA3-only (User)
add name=sec-iot authentication-types=wpa2-psk,wpa3-psk passphrase="BFtest-2026-tmp"
add name=sec-guest authentication-types=wpa2-psk,wpa3-psk passphrase="BFtest-2026-tmp"
# --- 3) Datapath = VLAN-Zuordnung (Bridge + vlan-id) ---
/interface wifi datapath
add name=dp-main bridge=bridge vlan-id=10
add name=dp-iot bridge=bridge vlan-id=30
add name=dp-guest bridge=bridge vlan-id=90
# --- 4) Configuration je SSID ---
/interface wifi configuration
add name=cfg-main ssid="BF-Main" security=sec-main datapath=dp-main country=Austria
add name=cfg-iot ssid="BF-IoT" security=sec-iot datapath=dp-iot country=Austria
add name=cfg-guest ssid="BF-Guest" security=sec-guest datapath=dp-guest country=Austria
# --- 5) CAPsMAN-Manager aktivieren (CA/Cert generiert RouterOS automatisch) ---
/interface wifi capsman
set enabled=yes interfaces=bridge ca-certificate=auto certificate=auto
# --- 6) Provisioning: pro Radio Master(BF-Main)+Slaves(IoT,Guest) dynamisch anlegen ---
/interface wifi provisioning
add action=create-dynamic-enabled supported-bands=2ghz-ax \
master-configuration=cfg-main slave-configurations=cfg-iot,cfg-guest
add action=create-dynamic-enabled supported-bands=5ghz-ax \
master-configuration=cfg-main slave-configurations=cfg-iot,cfg-guest
# --- 7) SAFETY: Auto-Rollback, DANN vlan-filtering an ---
/system scheduler
add name=vlan-rollback interval=5m \
on-event="/interface bridge set [find name=bridge] vlan-filtering=no; /system scheduler remove vlan-rollback"
/interface bridge set [find name=bridge] vlan-filtering=yes
# Nach bestätigtem Zugriff: /system scheduler remove vlan-rollback

21
routeros/ap2-cap.rsc Normal file
View File

@@ -0,0 +1,21 @@
# ===== ap2 (10.40.41.156) — CAP (zieht Config von ap1) + VLAN-Bridge =====
# RouterOS 7.23.1. NUR PLAN — Syntax vor Apply gegen Gerät validieren.
# --- 1) Bridge-VLAN-Tabelle (identisch zu ap1: Uplink ether2 Trunk, native vlan1 Mgmt) ---
/interface bridge vlan
add bridge=bridge vlan-ids=10,20,30,40,90,99,100 tagged=bridge,ether2
add bridge=bridge vlan-ids=1 untagged=ether2,ether3,ether4,ether5 tagged=bridge
/interface bridge port
set [find interface=ether2] pvid=1
# --- 2) CAP aktivieren: Manager = ap1, Wireless slaves in die Bridge ---
/interface wifi cap
set enabled=yes discovery-interfaces=bridge caps-man-addresses=10.40.41.1 slaves-datapath=bridge
# (ap2 zieht security/datapath/configuration/provisioning vom Manager → SSIDs erscheinen automatisch)
# --- 3) SAFETY: Auto-Rollback, DANN vlan-filtering an ---
/system scheduler
add name=vlan-rollback interval=5m \
on-event="/interface bridge set [find name=bridge] vlan-filtering=no; /system scheduler remove vlan-rollback"
/interface bridge set [find name=bridge] vlan-filtering=yes
# Nach bestätigtem Zugriff: /system scheduler remove vlan-rollback

View File

@@ -0,0 +1,45 @@
# ===== AS-BUILT 2026-06-09: CAPsMAN BF-Main, FLACH (bridge/vlan1, KEIN VLAN) =====
# Angewendet via MikroMCP (run_command). ap1=10.40.41.1 (Manager+AP), ap2=10.40.41.2 (CAP).
# Verifiziert: beide APs, beide Bänder = SSID BF-Main, WPA3-only + FT, state=running, remote-cap Ok.
# WICHTIGSTE LEKTION (kostete den Vorgänger den Erfolg):
# - "bound=true" ist NORMAL (Master-IF mit Radio+Config), KEIN Fehler.
# - Ein CAP wird nur provisioniert, wenn auf seinen Interfaces
# configuration.manager=capsman-or-local gesetzt ist (default=local → kontaktiert CAPsMAN NIE).
# Reset setzt es auf default zurück → nach reset neu setzen!
# - Manager-eigene Radios kann CAPsMAN NICHT via configuration.manager=capsman managen
# → lokal die Configuration-Profile direkt zuweisen (Doku).
# ---------- ap1 = MANAGER + AP ----------
/interface/wifi/channel
add name=ch-2g band=2ghz-ax width=20mhz
add name=ch-5g band=5ghz-ax width=20/40/80mhz ;# 5560 (DFS) auto -> 1min CAC; ggf. non-DFS pinnen
/interface/wifi/security
add name=sec-main authentication-types=wpa3-psk passphrase="BFtest-2026-tmp" ft=yes ft-over-ds=yes
/interface/wifi/datapath
add name=dp-main bridge=bridge ;# FLACH: nur bridge, kein vlan-id (VLAN kommt nach Cutover)
/interface/wifi/configuration
add name=cfg-main-5g ssid=BF-Main mode=ap country=Austria security=sec-main datapath=dp-main channel=ch-5g
add name=cfg-main-2g ssid=BF-Main mode=ap country=Austria security=sec-main datapath=dp-main channel=ch-2g
/interface/wifi/capsman
set enabled=yes ;# interfaces=bridge, ca/cert auto (waren vorhanden)
/interface/wifi/provisioning
add action=create-dynamic-enabled supported-bands=5ghz-ax master-configuration=cfg-main-5g
add action=create-dynamic-enabled supported-bands=2ghz-ax master-configuration=cfg-main-2g
# ap1 eigene Radios lokal zuweisen (Master kann sich nicht selbst per CAPsMAN managen):
/interface/wifi
reset wifi1 ; set wifi1 configuration=cfg-main-5g disabled=no
reset wifi2 ; set wifi2 configuration=cfg-main-2g disabled=no
# ---------- ap2 = CAP ----------
/interface/wifi
reset wifi1 ; reset wifi2
set wifi1,wifi2 configuration.manager=capsman-or-local ;# <-- DER SCHLÜSSEL, sonst keine Provisionierung
enable wifi1,wifi2
/interface/wifi/cap
set enabled=yes discovery-interfaces=bridge caps-man-addresses=10.40.41.1
# ---------- Verifikation ----------
# ap1: /interface/wifi/capsman remote-cap print -> ap2 STATE=Ok
# ap1: /interface/wifi monitor wifi1,wifi2 once -> state=running, SSID BF-Main
# ap2: /interface/wifi print detail -> "managed by CAPsMAN ...", BR (bound+running)
# Backups vorher: pre-capsman-2026-06-09.backup auf beiden APs.

View File

@@ -0,0 +1,21 @@
# === BF Core-Switch sw1 (ALL-SG8316M, FW 2.2.1) — Trunk-Ports für hAP-APs ===
# Reproduzierbar: . switch/.secrets && expect switch/cli/run-cli.exp switch/cli/03-trunk-ap-ports.cli
# Belegung (provisorisch, 2026-06-09): gi1 = ap1 (10.40.41.1), gi2 = ap2 (10.40.41.2).
# Absicht: native vlan1 untagged (Mgmt/Flachnetz bleibt, kein Lockout) + tagged 10,20,30,40,90,99,100.
# NICHT-DISRUPTIV: nur AP-Ports (tragen keinen Haushalts-Traffic); vlan1 bleibt überall untagged.
# Syntax am Gerät verifiziert: 'switchport trunk allowed vlan add <LIST>' / 'native vlan <id>'.
# Angewendet + verifiziert (POST show vlan: gi1-2 tagged auf 10..100; vlan1 weiter untagged). save=Success.
configure
interface gi1
switchport mode trunk
switchport trunk native vlan 1
switchport trunk allowed vlan add 10,20,30,40,90,99,100
exit
interface gi2
switchport mode trunk
switchport trunk native vlan 1
switchport trunk allowed vlan add 10,20,30,40,90,99,100
exit
end
save
show vlan

View File

@@ -0,0 +1,79 @@
# ALLNET ALL-SG8316M — Web-UI-Guide: Trunk-Port für einen hAP-AP
> ✅ **STATUS 2026-06-09: gi1 (ap1) + gi2 (ap2) bereits getrunkt** — via Telnet-CLI ausgeführt
> (`switch/cli/03-trunk-ap-ports.cli`), `show vlan` POST verifiziert (gi1-2 tagged auf 10/20/30/40/90/99/100,
> vlan1 weiter untagged), `save` ok, Mgmt + APs erreichbar. Diese UI-Anleitung bleibt als **Referenz/Verifikation**
> und Vorlage für künftige Ports. Syntax `switchport trunk allowed vlan add <LIST>` am Gerät bestätigt.
> **Methode:** Claude erklärt Absicht + Klickpfad, **du klickst**. UI = Realtek-OEM (Backbone-SPA),
> FW 2.2.1.2956, erreichbar unter **https://10.40.41.239** (Login `claudecode`, PW in `switch/.secrets`).
> Labels unten sind aus der echten `lang/defLang.js` des Geräts gezogen — sollten exakt passen;
> falls eine Bezeichnung leicht abweicht, geht's um die **Absicht** (steht je Schritt dabei).
## Was wir wollen (Absicht in einem Satz)
Den Switch-Port, an dem ein hAP hängt, zu einem **Trunk** machen:
**VLAN 1 untagged (native)** = Mgmt/aktuelles Flachnetz bleibt drauf, **VLANs 10,20,30,40,90,99,100 tagged**.
So trägt der Port später die SSID→VLAN-Tags (Phase B), **und das jetzige Flach-WLAN „BF-Main" auf vlan1 läuft unverändert weiter.**
### CLI-Äquivalent (nur zum Gegenchecken — du machst es im UI)
```
interface gi<PORT>
switchport mode trunk
switchport trunk native vlan 1
switchport trunk allowed vlan add 10,20,30,40,90,99,100
```
## ⚠️ Bevor du klickst — Sicherheit (Familiennetz läuft!)
- **NUR den AP-Uplink-Port anfassen.** Finger weg von **Port 4, 8, 15, 16** (live: Wohnzimmer-/Arbeitszimmer-Switch, pve, Fritzbox).
- **VLAN 1 bleibt überall untagged** → die Switch-Mgmt-IP (.239, vlan1) bleibt erreichbar. **Kein Lockout.**
- **Management VLAN NICHT ändern** (bleibt 1). Das ist ein separater Cutover-Schritt mit Aussperr-Risiko.
- Welcher Port ist der AP? Laut Plan **ap1 = Port 2** (direkt am Core). **Bitte bestätigen** und unten `<PORT>` einsetzen.
→ **ap2** hängt aktuell hinter dem TL-SG108E an **Port 8 (live!)** — **diesen Port NICHT trunken.** Für ap2 siehe Abschnitt unten.
- Nicht dringend: Fürs aktuelle Flach-WLAN-Testen ist **gar keine** Switch-Änderung nötig. Dieser Trunk ist **Phase-B-Vorbereitung** (taggte VLANs bekommen erst nach dem Router-Cutover Gateway/DHCP).
## Klickpfad
### 0) Login & Vorprüfung
1. Browser → **https://10.40.41.239** → Login `claudecode`.
2. Menü **VLAN → Create VLAN**: prüfen, dass **10, 20, 30, 40, 90, 99, 100** in „Created VLAN" stehen.
(Sollten schon da sein — VLAN-DB + Namen sind angelegt. Falls eine fehlt: ID eintragen → **Add/Apply**.)
### 1) Port-Modus & PVID setzen — `VLAN → Port Setting`
1. Menü **VLAN → Port Setting** (Tabelle „Port Setting Table").
2. Zeile **Port `<PORT>`** auswählen → **Edit** (öffnet „Edit Port Setting").
3. Felder:
- **Mode** = **Trunk** *(falls „Trunk" zickt, geht auch **Hybrid** — alle Ports stehen eh auf Hybrid; Hybrid + Membership unten erreicht dasselbe.)*
- **PVID** = **1** *(untagged-Verkehr landet in vlan1 = Mgmt/Flachnetz)*
- **Accept Frame Type** = **All** *(tagged + untagged annehmen)*
- **Ingress Filtering** = **Enabled** *(nur Frames erlaubter VLANs — sauber; optional)*
4. **Apply/OK**.
### 2) VLAN-Mitgliedschaft des Ports — `VLAN → Membership`
Hier legst du pro VLAN fest, wie Port `<PORT>` Mitglied ist: **U**ntagged / **T**agged / leer (kein Mitglied).
1. Menü **VLAN → Membership** (Tabelle „Membership Table", Achse VLAN × Port).
2. **VLAN 1** editieren → Port `<PORT>` = **Untagged (U)** *(native; Mgmt/Flachnetz)*
3. **VLAN 10** editieren → Port `<PORT>` = **Tagged (T)**. Ebenso **20, 30, 40, 90, 99, 100** = **Tagged (T)**.
*(In der „Edit"-Maske oft per Klick durch die Zustände U → T → leer, oder Auswahl „Active/Tagged Member".)*
4. Sicherstellen: Port `<PORT>` ist bei den **anderen** VLANs **nicht** ungewollt untagged.
5. **Apply/OK** je VLAN.
### 3) Persistieren (sonst nach Reboot weg!)
- Oben rechts das **Save**-Symbol (Disketten-Icon) klicken → schreibt Running→Startup.
*(CLI-Äquivalent wäre `save`.)*
## Verifikation
- **VLAN → Membership**: Port `<PORT>` = U bei VLAN1, T bei 10/20/30/40/90/99/100.
- Switch-UI weiter erreichbar (https://10.40.41.239) → **kein Lockout**.
- WLAN **BF-Main** (vlan1) am hAP funktioniert unverändert (Client bekommt weiter FB-DHCP).
- Optional Gegencheck per CLI (Telnet, 1 VTY, sauber ausloggen): `show vlan`, `show running-config` → der Port zeigt `switchport ... vlan ...`.
## Sonderfall ap2 (Port 8 ist live!)
ap2 hängt hinter dem **TL-SG108E** am **Core-Port 8**, der **.10/.167/.247 trägt**. Optionen:
- **Jetzt nichts tun** — ap2 funkt „BF-Main" untagged auf vlan1 über den bestehenden Pfad (fürs Flach-WLAN-Testen reicht das).
- **Sauber (empfohlen vor Phase B):** ap2 in einem Wartungsfenster an einen **freien Core-Port** (z.B. Port 3) umstecken → diesen Port nach genau dieser Anleitung trunken. Dann muss der TL-SG108E nicht 802.1Q können.
- Trunk über Port 8 (TL-SG108E müsste taggen) = fummelig → **nicht empfohlen**.
## Offen / von dir bestätigen
- [ ] **ap1-Port** = wirklich Port **2**? (sonst `<PORT>` anpassen)
- [ ] **ap2-Verkabelung**: Port 8 lassen vs. an freien Core-Port umstecken?
- [ ] Jetzt schon Trunk vorbereiten (safe) oder erst zum Phase-B-Cutover?