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

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.