diff --git a/docs/allnet-ge8-trunk-klickanleitung.md b/docs/allnet-ge8-trunk-klickanleitung.md new file mode 100644 index 0000000..1691d14 --- /dev/null +++ b/docs/allnet-ge8-trunk-klickanleitung.md @@ -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. diff --git a/docs/research/routeros-capabilities.md b/docs/research/routeros-capabilities.md new file mode 100644 index 0000000..62d74ec --- /dev/null +++ b/docs/research/routeros-capabilities.md @@ -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=**) → 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. diff --git a/docs/research/vpn-comparison.md b/docs/research/vpn-comparison.md new file mode 100644 index 0000000..c699341 --- /dev/null +++ b/docs/research/vpn-comparison.md @@ -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) diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md new file mode 100644 index 0000000..f9a8422 --- /dev/null +++ b/docs/teilprojekte.md @@ -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ß). diff --git a/inventory/bf-core-ports.csv b/inventory/bf-core-ports.csv index 7f0de3e..ee3ed44 100644 --- a/inventory/bf-core-ports.csv +++ b/inventory/bf-core-ports.csv @@ -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, diff --git a/inventory/bf-core-ports.md b/inventory/bf-core-ports.md index 7d92849..2f49c13 100644 --- a/inventory/bf-core-ports.md +++ b/inventory/bf-core-ports.md @@ -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 | | diff --git a/mcp/.gitignore b/mcp/.gitignore new file mode 100644 index 0000000..106607c --- /dev/null +++ b/mcp/.gitignore @@ -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). diff --git a/mcp/INVENTORY.md b/mcp/INVENTORY.md new file mode 100644 index 0000000..14110aa --- /dev/null +++ b/mcp/INVENTORY.md @@ -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//`), 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). diff --git a/mcp/README.md b/mcp/README.md new file mode 100644 index 0000000..62a096d --- /dev/null +++ b/mcp/README.md @@ -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= +``` +(`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)" + +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 `). + Nach FQDN: URL auf `https://` 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. diff --git a/mcp/mikromcp/.env.example b/mcp/mikromcp/.env.example new file mode 100644 index 0000000..1c71aeb --- /dev/null +++ b/mcp/mikromcp/.env.example @@ -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= diff --git a/mcp/mikromcp/config/routers.yaml b/mcp/mikromcp/config/routers.yaml new file mode 100644 index 0000000..879de10 --- /dev/null +++ b/mcp/mikromcp/config/routers.yaml @@ -0,0 +1,30 @@ +# MikroMCP Router-Registry — BF hAP ax² +# Credentials NICHT hier, sondern via ENV (envPrefix -> ROUTER__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" diff --git a/mcp/mikromcp/docker-compose.yml b/mcp/mikromcp/docker-compose.yml new file mode 100644 index 0000000..e22667b --- /dev/null +++ b/mcp/mikromcp/docker-compose.yml @@ -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) diff --git a/mcp/portainer/README.md b/mcp/portainer/README.md new file mode 100644 index 0000000..09aeaf7 --- /dev/null +++ b/mcp/portainer/README.md @@ -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= \ + -e PORTAINER_MCP_ALLOWED_HOSTS=:17717 \ + portainer/portainer-mcp:2.42 +# Client: +claude mcp add portainer --transport http http://:17717/mcp \ + --header "Authorization: Bearer " \ + --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`. diff --git a/routeros/HANDOVER-wifi.md b/routeros/HANDOVER-wifi.md new file mode 100644 index 0000000..3b13e00 --- /dev/null +++ b/routeros/HANDOVER-wifi.md @@ -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. +``` diff --git a/routeros/README.md b/routeros/README.md new file mode 100644 index 0000000..e77da91 --- /dev/null +++ b/routeros/README.md @@ -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` diff --git a/routeros/ap1-manager.rsc b/routeros/ap1-manager.rsc new file mode 100644 index 0000000..b3c4c54 --- /dev/null +++ b/routeros/ap1-manager.rsc @@ -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 diff --git a/routeros/ap2-cap.rsc b/routeros/ap2-cap.rsc new file mode 100644 index 0000000..5bb7225 --- /dev/null +++ b/routeros/ap2-cap.rsc @@ -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 diff --git a/routeros/capsman-flat-asbuilt.rsc b/routeros/capsman-flat-asbuilt.rsc new file mode 100644 index 0000000..4840da8 --- /dev/null +++ b/routeros/capsman-flat-asbuilt.rsc @@ -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. diff --git a/switch/cli/03-trunk-ap-ports.cli b/switch/cli/03-trunk-ap-ports.cli new file mode 100644 index 0000000..d55c6d8 --- /dev/null +++ b/switch/cli/03-trunk-ap-ports.cli @@ -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 ' / 'native vlan '. +# 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 diff --git a/switch/ui-guides/01-trunk-ap-ports.md b/switch/ui-guides/01-trunk-ap-ports.md new file mode 100644 index 0000000..d26677b --- /dev/null +++ b/switch/ui-guides/01-trunk-ap-ports.md @@ -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 ` 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 + 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 `` 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 ``** 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 `` Mitglied ist: **U**ntagged / **T**agged / leer (kein Mitglied). +1. Menü **VLAN → Membership** (Tabelle „Membership Table", Achse VLAN × Port). +2. **VLAN 1** editieren → Port `` = **Untagged (U)** *(native; Mgmt/Flachnetz)* +3. **VLAN 10** editieren → 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 `` 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 `` = 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 `` anpassen) +- [ ] **ap2-Verkabelung**: Port 8 lassen vs. an freien Core-Port umstecken? +- [ ] Jetzt schon Trunk vorbereiten (safe) oder erst zum Phase-B-Cutover?