Beide hAP ax² neu als Standalone-Access-Points provisioniert, kein CAPsMAN mehr: - ap1 10.40.99.11 (core ether15), ap2 10.40.99.12 (branch ether24) - Uplink geraeteseitig auf ether1 (PoE-Port, poe-out=off); ether2 aus Trunk entfernt - 6 SSIDs (main WPA3+FT; infra/iot/media/untrusted/guest WPA2+3), iot nur 2,4 GHz, media FT=no; jede SSID mit eigenem datapath bridge+vlan-id -> TP3.1-Leck strukturell weg - Kanaele non-DFS: ap1 ch36/ch1, ap2 ch149/ch11 - Einheitliches Admin-PW auf allen 4 MikroTik (core/branch/ap1/ap2) Nautobot As-built (nautobot/ingest-ap-rebuild.py): ap1/ap2 Rolle Wireless AP + Active, Mgmt .99.11/.99.12, ether1-Trunk, stale L3-Objekte (vlan10-90/100, wg-hub) entfernt; crs326-core primary_ip4 auf .99.1 korrigiert. Verifiziert per GraphQL. Doku: CLAUDE.md Hardware-Tabelle + teilprojekte.md TP3 aktualisiert. Configs/PSKs liegen gitignored unter routeros/.secrets/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
77 lines
11 KiB
Markdown
77 lines
11 KiB
Markdown
# BF-Netzwerk — Projekt-Kontext (auto-read)
|
||
|
||
**Standort BF:** VLAN-segmentiertes Heimnetz auf MikroTik/RouterOS. Ziel: CAKE/QoS gegen Bufferbloat,
|
||
DNS/DHCP-Ablösung, WLAN via CAPsMAN, Firewall Least-Privilege, Multi-Site VPN.
|
||
|
||
**Für jede TP-Session: zuerst `docs/teilprojekte.md` lesen** — enthält kanonischen Stand, Scope, Abhängigkeiten
|
||
und Reihenfolge aller Teilprojekte. Kein anderer Kontext nötig.
|
||
|
||
---
|
||
|
||
## VLAN-Modell (kanonisch)
|
||
| VLAN | Name | Subnetz | Zweck |
|
||
|---|---|---|---|
|
||
| 10 | MAIN | 10.40.10.0/24 | Trusted (Handy/Laptop) |
|
||
| 20 | INFRA | 10.40.20.0/24 | NAS/VMs/Docker/HA |
|
||
| 30 | IOT | 10.40.30.0/24 | Smart-Home |
|
||
| 40 | MEDIA | 10.40.40.0/24 | Sonos/AppleTV/TV/Cast |
|
||
| 50 | UNTRUSTED | 10.40.50.0/24 | Konsole/Low-Trust |
|
||
| 90 | GUEST | 10.40.90.0/24 | nur Internet |
|
||
| 99 | MGMT | 10.40.99.0/24 | Switch/AP/Hypervisor-Mgmt |
|
||
| 100 | WAN | (Arris-Transfer) | zum Arris-Kabelmodem (Liwest, Public-IP) |
|
||
|
||
GW je VLAN = `.1` · APs: ap1=`.1`, ap2=`.2` · Switches: ALLNET=`.11`, Omada=`.12`
|
||
|
||
---
|
||
|
||
## Hardware & Zugang
|
||
| Gerät | IP | Zugang |
|
||
|---|---|---|
|
||
| ALLNET Core-Switch (sw1) | 10.40.41.11 (interim, VLAN1) | `telnet 10.40.41.11` · User: `claudecode` · PW: `switch/.secrets` |
|
||
| ~~Omada Access-Switch (sw2)~~ | — | ❌ **abgebaut 2026-07-23** (TP15 Branch-Tausch) — durch `crs326-branch` in Technik OG ersetzt, physisch entfernt |
|
||
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99; temp VLAN10 `.10.2`) · Bootstrap Rev4 2026-08-08 | RouterOS 7.19.5 · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `routers.yaml` (live nach MCP-Neustart) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap2) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
|
||
| **crs326-core** (CRS326, Technik UG) | **10.40.99.1** (VLAN99-SVI = L3-GW; same-subnet-Fallback `10.40.10.1`) · Identity `crs326-core` | RouterOS 7.19.5 · `admin`/`~/.secrets` (`CRS326_CORE_*`) · MikroMCP routerId `crs326-core` (nach MCP-Neustart) · **TP15/TP21.1 ✅ 2026-08-08: PRODUKTIVER L3-Router** (ersetzt ap1) — Routing/DHCP (7 Server + 54 Leases)/DNS (plain `1.1.1.1`, DoH-Cloudflare-TODO)/NAT/WG-Hub (fm+dw live); WAN `vlan100`=Liwest `90.146.33.177` · sw-id 4W04-URHT, MAC 04:F4:1C:B4:17:76 |
|
||
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS 7.23.2 · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` (live nach MCP-Neustart) · **TP3-Rebuild ✅ 2026-08-08: reiner Standalone-AP, KEIN CAPsMAN** — Uplink `ether1` (PoE-Port, `poe-out=off`) an crs326-core `ether15`; 6 SSIDs dirtyvader-main/-infra/-iot/-media/-untrusted/-guest, ch36/ch1; jede SSID mit `datapath` (TP3.1-Leck gefixt) · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
|
||
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS 7.23.2 · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP3-Rebuild ✅ 2026-08-08: reiner Standalone-AP** — Uplink `ether1` (PoE) an crs326-branch `ether24`; identisch zu ap1, ch149/ch11 · MAC D0:EA:11:4D:40:3A · Config `routeros/.secrets/ap2-prov-base.rsc` |
|
||
| **🔑 Einheitliches Admin-PW (2026-08-08)** | alle 4 MikroTik (core/branch/ap1/ap2) | user `admin`, gleiches PW (`~/.secrets/credentials.env` → `ROUTER_*_PASS`/`CRS326_*_PASS`; „Überlebensversicherung", User-Vorgabe). Werks-Defaults ap1/ap2 damit obsolet. |
|
||
| NAS (nas-bf, DS923) | 10.40.20.10 | SSH `adm.christoph@10.40.20.10` (kein PW nötig) · Docker (Portainer endpointId=14) |
|
||
| platform-pg (LXC 105, pve) | 10.40.20.20 | SSH via pve (`pct exec 105 --`) · **TP20 ✅ 2026-07-16: PG16, DB `nautobot`, Creds `postgres/.secrets`** |
|
||
| Nautobot (Portainer-Stack, NAS) | 10.40.20.30 | Portainer ep14, Stack Id 203 · **TP21 ✅ 2026-07-16: `ghcr.io/nautobot/nautobot:3.1.7`, DB=platform-pg, Creds in `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored)** — Golden-Config-App/Device-Adoption noch offen |
|
||
| ~~Omada-Controller~~ | — | ❌ **entfernt 2026-07-16** (User hat den Container gelöscht — overkill für 1 Switch auf der Abschussliste, s. TP2.1/TP15) |
|
||
| ~~omada-mcp~~ | — | ❌ **entfernt 2026-07-16** — mit dem Controller gelöscht. MCP-Eintrag in Claude-Settings/`~/.claude.json` ist verwaist (Server wird nie mehr connecten), Aufräumen dort noch offen |
|
||
| pve-mcp | 10.40.20.173 | **StreamableHTTP `http://10.40.20.173:3000/` (Root-Pfad, NICHT /sse)** · NAS-Stack ep14 (=nas-bf `.20.10`, NICHT LXC .126!) id 202 (vlan20-only, TP14.1 2026-07-10) · **mcp-pve v0.6.1 (Upgrade 2026-07-10: Single-Session-Bug 0.4.8 „Server already initialized" gefixt, TP14.2a)** · `~/.claude.json` ✓ |
|
||
| Proxmox (pve) | 10.40.20.100 | `ssh root@10.40.20.100` (SSH-Key ✓) · **TP14 2026-07-13: Host-Mgmt VLAN1→VLAN20** (vmbr0.20 + Default-GW-Flip); `.41.100` bleibt interim ohne Route |
|
||
| Docker-LXC (auf pve) | 10.40.20.126 | Portainer CE 2.40.0 (`https://10.40.20.126:9443`) · **TP14.2 2026-07-10: LXC 400 net0 tag=20/.20.126 (iface heißt jetzt `veth20`, NICHT eth0); Docker-Netz `vlan20`=ipvlan parent `veth20`; adguard_bf1 .20.16, adguard_fm2 .20.17** |
|
||
| Mac mini | 10.40.41.167 | `ssh macmini` |
|
||
| Arris-Kabelmodem | (Bridge-Mode, keine Mgmt-IP im BF-LAN) | Liwest-Edge, physisch an sw1 gi16 · **FritzBox 6660 seit 2026-07-01 komplett ausgebaut** (Liwest-Tausch, kein Zurück); Telefonie war auf der FB und wird nicht weitergeführt |
|
||
|
||
---
|
||
|
||
## Tooling
|
||
- **MikroTik (hAP ax²):** MikroMCP-Server live verbunden → `mcp__mikromcp__*`-Tools verwenden.
|
||
Reads immer safe; Writes mit `dryRun:true` previwen, dann `apply_plan`.
|
||
- **ALLNET-Switch:** kein MCP — nur Telnet-CLI (IOS-artig, FW 2.2.1). Runner:
|
||
`cd ~/dev/bf-network-r6/switch && . ./.secrets && expect cli/run-cli.exp cli/<datei>.cli`
|
||
Klickanleitungen in `switch/ui-guides/` für manuelle Schritte.
|
||
- **Omada-Switch (sw2):** seit TP2.1 (2026-07-16) **standalone ohne Controller**, direkt über eigenes Web-UI konfiguriert. Der Controller ist mittlerweile **komplett gelöscht** (User 2026-07-16, overkill für 1 Switch auf der Abschussliste) — Omada-Ecosystem hat generell keine Rolle mehr im Netz (TP15-Korrektur). **omada-mcp ebenfalls gelöscht**, MCP-Registrierung in Claude-Settings ist verwaist.
|
||
- **Docker-Management:** Portainer API `https://10.40.20.126:9443`, Key in `mcp/portainer/.env`.
|
||
Ablösung durch Komodo (native MCP) geplant.
|
||
|
||
---
|
||
|
||
## Kritische Gotchas
|
||
- **ALLNET: nur 1 Telnet-VTY** — stale Sessions blockieren ~15 min. Sauber ausloggen (`exit exit`), nie hammern.
|
||
- **`save` nicht vergessen** nach ALLNET-Änderungen (sonst nach Reboot weg).
|
||
- **hAP ax² hat 128 MB Flash, kein USB** → Container NICHT auf dem Router; Container laufen auf NAS/pve.
|
||
- **VLAN20-Docker-Hosts: Host-DNS nach dem Umzug prüfen (2026-07-10, TP14.2a):** NAS + pve-LXC zeigten `/etc/resolv.conf` noch auf totes `.41.254` → `docker pull` ghcr scheitert (`EAI_AGAIN`, aber Egress ok!). Fix = `.20.1`: LXC `pct set 400 --nameserver 10.40.20.1`; **Synology-Falle: DSM-„Allgemein"-DNS ≠ was `dockerd` liest** — Interface zieht DNS per DHCP → Fix an der *Netzwerkschnittstelle* „DNS manuell". Laufende Container frieren den `127.0.0.11`-Upstream zum Erstellzeitpunkt ein (Recreate nötig). Merkregel: `docker-pull-hängt` + `dns.lookup EAI_AGAIN` aber `TCP zu ghcr-IP:443 ok` = toter Resolver, nicht Egress.
|
||
- **ALLNET VLAN-DB final (TP1 ✅):** 40=MEDIA, 50=UNTRUSTED; GE1/GE2/GE8 alle als Trunk mit 10/20/30/40/50/90/99/100.
|
||
- **Omada-Switch Port 2 = ap2** (Trunk all VLANs), Uplink-Port → ALLNET GE8 (Trunk all), Restports = Access.
|
||
- **Mesh = NEIN** (beide APs haben wired Trunk-Uplink → Loop-Risiko).
|
||
- **ap2 (CAP) braucht `vlan-filtering=yes` mit ether2-Trunk (TP3.1 ✅ 2026-07-01):** local forwarding → `datapath.vlan-id` wird nur bei vlan-filtering auf die Leitung geschrieben. Ohne → ALLE ap2-WLAN-Clients ungetaggt in VLAN1 (defconf/10.40.41.x). Nur Master-Radios wifi1/wifi2 sind Bridge-Ports (Slave-VAPs forwarden darüber) → wifi1/wifi2 müssen manuell tagged-Member je Client-VLAN sein (CAPsMAN legt das auf dem CAP NICHT an). As-built `routeros/tp3.1-ap2-vlan.rsc`. VLAN1 MUSS untagged=bridge,ether2 bleiben (Mgmt/MCP-Pfad 10.40.41.2, kein Scheduler → Recovery = Power-Cycle OG). Widerlegt „ein CAP hält keine Config" (galt nur für Manager-Forwarding).
|
||
- mgmt-VLAN-Wechsel am Switch = Lockout-Risiko: VLAN muss existieren + Port muss es tragen, in einem Schritt.
|
||
- **Omada ES208G = Easy Managed** → Controller-adoptierbar (ab 6.1.x), nur Basis-VLAN/QoS im Controller (kein ACL/Policy-Routing).
|
||
- **TP4 ✅: ap1 ist L3-Router.** Bridge mit vlan-filtering=yes; VLAN1 untagged (Mgmt/Transition); vlan10-99 Subinterfaces mit DHCP+DNS. DNS: 13 statische A-Records bf.lan, **Upstream seit 2026-06-16 = DoH Cloudflare Gateway** (servers=1.1.1.1 Bootstrap). Omada-PVID-Fix (→ .10/.20-Subnetze) ist nächster Schritt.
|
||
- **✅✅ Edge-Cutover vollzogen (2026-07-01): FritzBox komplett ausgebaut, Arris-Kabelmodem im Bridge-Mode.** Liwest hat die FB6660 dauerhaft gegen ein Arris-Kabelmodem getauscht (physisch weg, kein Zurück). WAN läuft über den Core-Switch (Arris→sw1 gi16 Access VLAN100→gi15 Trunk→ap1 ether2→`vlan100` auf bridge), NICHT über ether1. ap1 zieht öffentliche Liwest-IP direkt → Double-NAT weg, ap1 = Public-Edge. Vorarbeit dazu: TP10 (beide VPN FM/DW von FB auf ap1-WG-Hub migriert, 2026-06-27) hat den Bridge-Mode entblockt. Telefonie war auf der FB und wird **nicht weitergeführt** (User-Bestätigung 2026-07-02). Details/Runbooks: `routeros/wan-cutover-runbook.md`.
|
||
- **ap1 RouterOS-Scripting (device-mode=home):** **scheduler + fetch blockiert** (`not allowed by device-mode`) → keine Scheduler in Scripts, Autonomie via Loop-Script. **`[/ping]` gibt nil in 7.23**, ICMP geblockt → Reachability via `:resolve` (server=1.1.1.1 = Routing-Test, ohne server = DoH). MikroMCP-Tools können droppen → Fallback REST `http://10.40.41.1/rest` (Creds = ROUTER_AP1 in `~/.claude.json`).
|
||
- **WLAN dozende Legacy-Clients nur auf ap1 erreichbar, NICHT via CAP ap2 (2026-07-02, P750W-Fall):** L3-GW liegt auf ap1 → ARP-Broadcast an schlafenden Client wird nur am co-located AP zuverlässig zugestellt; Remote-CAP ap2 puffert Broadcast-ARP unzuverlässig. Fix = geordneter wifi-access-list-Pin auf ap1 (`0 accept interface=w2-iot` → `1 reject` ohne Interface = überlebt ap2-Re-Provision). **Merkregel: DHCP-geht-aber-Ping-nicht = ARP/Power-Save, NICHT Routing/L2/MTU/Switch.** Coverage-Kanten/Terrasse grenzwertig (−76..−89 dBm, 4-Radio-Ping-Pong); TX schon am AT-Max (18/15 dBm, kein Hebel); Steering `neighbor-group=bf-main` gesetzt; echter Fix = Platzierung (offen, Tageslicht). SSoT `docs/wifi-p750w-coverage-and-map.md`.
|