Files
bf-infra/HANDOVER.md

183 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BF-Netzwerk — Übergabe (Netzwerk · Routing · VLAN · Sprachtelefonie)
> **Archiv-Dokument** (Stand: Phase A abgeschlossen). Aktuelle Projektsteuerung → `docs/teilprojekte.md`.
> Session-Kontext → `CLAUDE.md` (wird automatisch geladen).
>
> **Referenzen (Historie, optional):** Ursprungs-Vergleich `~/.claude/plans/welche-kosteng-nstigen-alternativen-zu-memoized-sparkle.md` ·
> Projekt-Memory `project_bf_network_r6` · Repo `~/dev/bf-network-r6/` (Git).
---
## 0. Auftrag der nächsten Session
1. **Phase A jetzt** umsetzen (Switch-VLAN-Vorbereitung, non-disruptiv) — siehe §9.
2. **Phasen B–D planen & ausführen**, sobald die 2× MikroTik hAP ax² produktiv sind (hAP-Cutover, Firewall, Adress-Migration).
3. Doku/Memory aktuell halten (`inventory/build.py`, Memory `project_bf_network_r6`).
**Kickoff-Prompt** zum Starten: §15.
## 1. Ziel & Treiber
Günstige, **lokal/kostenlos verwaltete** Alternative zu UniFi/Omada über Router+WiFi+Switch. K.O.-Kriterien:
lokaler Gratis-Controller · VLAN · QoS · Multi-SSID→VLAN · DNS/DHCP-Redundanz · (6 GHz – bewusst zurückgestellt).
Konkrete Treiber am Standort **BF**:
- **Sprachtelefonie/Call-Qualität** (Hauptmotiv): Cable-Upload sättigt → **Bufferbloat** → Jitter in Telefonie/Calls.
Lösung = echtes **WAN-QoS (CAKE/SQM)** am neuen Router. (Bezug: ungelöstes Thema aus `project_network_calls_openwrt`.)
- **AdGuard-Forwarder an BF ablösen**: lokaler Router/DNS soll DoH→Cloudflare + lokale Rewrites selbst können.
- **Familienverträglichkeit**: WLAN + **Telefon** dürfen beim Umbau nur minimal/kurz ausfallen.
## 2. Architektur-Entscheidung „R6+C2" (kompakt, mit Begründung)
- **Kein** Anbieter bietet *einen* gratis lokalen Single-Pane über Router+WiFi+Switch **+** 6 GHz **+** Router-HA.
Router-HA entfällt (DNS/DHCP-Redundanz genügt) → Feld öffnet sich.
- **Gewählt: MikroTik** (RouterOS). Gründe: kann **CAKE/SQM** (Call-Fix), **DNS** (DoH/Rewrites), **VLAN/QoS**,
**CAPsMAN** (zentrale WiFi-Config ohne Extra-Controller), nativer **DHCP**; günstig; minimale Box-Zahl.
- **Hardware: 2× hAP ax²** (WiFi 6 2,4+5 GHz, **kein 6 GHz** — bewusst, spart €, Refresh in 3–4 J.; 5×1G).
- **Core-Switch behalten**: ALLNET ALL-SG8316M kann 802.1Q (Trunk/Access/Hybrid + PVID) → tauglich, kein Tausch.
- **FB6660** bleibt **Cable-Modem + Telefonanlage**; Routing/DHCP/DNS/QoS wandert auf hAP#1.
- **C2 = DNS/DHCP-Strategie**: DHCP **nativ RouterOS** (Split-Scope); DNS = **Technitium-Container auf pve + fm**.
## 3. Topologie
**Ist (heute):** FB6660 = Router/Gateway `10.40.41.254`, alles flach in VLAN 1; Core-Switch verteilt nur L2.
```
Internet ─ FB6660 (Modem+Telefon+Router .254) ─ Core-Switch sw1 (10.40.41.239, flach) ─ Clients/Server/NAS/pve
```
**Ziel (nach Cutover):**
```
Internet ─ FB6660 (Modem+Telefon, "Exposed Host"→hAP#1) Telefon bleibt an FB
│ (WAN-VLAN untagged)
Core-Switch sw1 (VLAN-Trunk-Verteiler, 802.1Q)
├─ Trunk → hAP ax² #1 (Router: NAT/DHCP/DNS/Firewall/CAKE, CAPsMAN-Manager)
├─ Trunk → hAP ax² #2 (AP, CAPsMAN-managed)
└─ Access-Ports je VLAN (lokale Geräte)
```
**Geräte:** FB6660 · sw1 `10.40.41.239` · 2× hAP ax² (erwartet) · Mac mini `pve` `10.40.41.167` (macOS, L2-lokal zu sw1) ·
NAS `nas-bf` `10.40.41.10`. Switch-Ports Ist (`inventory/bf-core-ports.csv`): **4**→Wohnzimmer-Switch, **8**→Arbeitszimmer-Switch
(.10/.167/.247), **15**→pve, **16**→FB (.246 auf FB-LAN4). 4/8/15/16 **behalten** (4+8 interim bis neue Switches da).
## 4. VLAN-Modell · Adressplan · Firewall
| VLAN | Name | Subnetz (Ziel) | Interim | Zweck |
|---|---|---|---|---|
| 10 | **MAIN** | 10.40.10.0/24 | **vorerst 10.40.41.0/24** | Trusted-Clients **+ Media** (Sonos/AppleTV/TV/SAT/Drucker) |
| 20 | **INFRA** | 10.40.20.0/24 | **vorerst vorhandene 172.x** | Server, VMs, Docker, NAS-Workloads, HA |
| 30 | **IOT** | 10.40.30.0/24 | — | Smart-Home (HA-managed) |
| 40 | **UNTRUSTED** | 10.40.40.0/24 | — | Spielekonsole & Low-Trust-Internet |
| 90 | **GUEST** | 10.40.90.0/24 | — | nur Internet (abgesetzt; 50–89 frei für künftige VLANs) |
| 99 | **MGMT** | 10.40.99.0/24 | Switch vorerst .239 | Switch/AP/Hypervisor-Mgmt-Interfaces |
| 100 | **WAN** | (FB-Transfer) | — | zur Fritzbox |
**Konventionen:** Gateway je VLAN = `.1` (hAP#1) · Switch-Mgmt = `10.40.99.2` · 3. Oktet = VLAN-ID · alles RFC1918.
**Warum so (Kurz-Begründung der Diskussion):**
- **INFRA ≠ MGMT** (Workloads vs. Steuer-Interfaces = andere Vertrauensstufe).
- **Media auf MAIN** (nicht aus Vertrauen, sondern weil **mDNS/SSDP nicht über VLANs** quert; Sonos-Steuerung vom Handy soll trivial bleiben).
- **UNTRUSTED (40) ≠ IOT (30)**: Konsole ist kein IoT → Name nicht verwässern.
- **Adressierung `10.40.<vlanid>.0/24`**: altes 172.40/50/99 lag **außerhalb RFC1918** (privat=172.16–31) = öffentlicher Raum → korrigiert.
**Firewall = Least-Privilege** (NICHT „Main→alle", sonst wäre INFRA entwertet):
- Default **deny** inter-VLAN, dann gezielt erlauben.
- **Main→Infra:** nur Whitelist-Dienste (NAS-Shares, HA-UI, Proxmox-UI auf def. Ports).
- **Infra→Main:** grds. deny (Ausnahmen gezielt: Backups/Notifications).
- **IoT/Guest/Untrusted→intern:** deny — nur Internet.
- **MGMT (99):** aus Main nicht erreichbar.
- **mDNS-Strategie:** discovery-abhängige Media auf MAIN (kein Reflector nötig); Nicht-Discovery-Zugriff (NAS-UI/HA) via Firewall + DNS/Hostname.
**IP-Detailentscheide:** VPNchristoph zieht von `.1` weg (wird Gateway; IP egal). vpnjoern `.2` gekickt → frei.
`.10` nas-bf bleibt vorerst (Umzug nach INFRA später). `.246`/`.247` bleiben. FB=`.254`.
## 5. Routing / DHCP / DNS
- **Router:** hAP#1 = NAT, Inter-VLAN-Routing, Firewall (§4), CAKE auf WAN (§6).
- **DHCP:** **nativ RouterOS** je VLAN. Split-Scope für Redundanz: #1 `.50–.150`, #2 `.151–.250`. Option 6 (DNS) = beide Technitium-IPs.
- **DNS:** 2× **Technitium**-Container auf **pve (10.40.41.167)** + **fm (DS415+)**. **DoH→Cloudflare** (Filterprofil je Wunsch),
lokale **Rewrites/Split-Horizon** (aus AdGuard-Bestand migrieren). **Adlists in Technitium AUS** — CF-DoH filtert. Sync zwischen den 2 Instanzen.
→ AdGuard-Forwarder an BF wird damit obsolet (Original-Ziel). Mac mini nicht im kritischen Pfad (DHCP/DNS-Failover über 2 Instanzen).
## 6. Sprachtelefonie / Call-Qualität (Kern-Treiber)
- **Telefon bleibt an der FB6660** (DOCSIS-Telefonie tief verdrahtet) → beim Cutover **nicht anfassen**, Anrufe laufen weiter.
- **Call-/Video-Jitter** kommt vom **Bufferbloat am Cable-Upload** (typ. ~1000/50, Upload sättigt schnell).
→ **CAKE/SQM auf dem WAN-Interface (vlan100) des hAP#1**, Upload-Rate **~85–95 % der real gemessenen FB-Upload-Linerate**,
iterativ via waveform.com/dslreports kalibrieren. Switches können das NICHT (kein Packet-Scheduling); FB-QoS reicht nicht.
- **Cutover-Priorität „Familie muss telefonieren":** Phase B startet mit WiFi + CAKE *innerhalb von Stunden*, nur vlan10 aktiv;
volle Segmentierung danach. Max. ~30 min Ausfall einplanen/ankündigen.
- **Verifikation:** Bufferbloat-Test unter parallelem Upload-Stress bleibt niedrig; reale Telefonie ohne Jitter.
## 7. WiFi
- **CAPsMAN** auf hAP#1 (Manager), hAP#2 als CAP → zentrale Wireless-Config, gleiche SSIDs, Roaming.
- 3 SSIDs → VLAN-Mapping (MAIN/IOT/GUEST; UNTRUSTED je nach Bedarf). Phase B startet mit **einer** SSID „BF-Main"→vlan10.
- WiFi 6 auf 2,4+5 GHz (kein 6 GHz).
## 8. Aktueller Stand (erledigt)
- ✅ Switch `sw1` **auf FW 2.2.1.2956 geflasht** (von 1.0). IP blieb `.239`; Cred-Store gewiped → `claudecode`-Account wiederhergestellt.
- ✅ **VLAN-DB 10/20/30/40/100** angelegt + `save` (alle Ports noch VLAN 1 → **null Disruption**, Netz läuft).
- ✅ Repo + Tooling: CLI-Runner, `.cli`-Files, CLI-Referenz, kanonisches Inventar (`bf.csv`/`build.py`), Port-Map, VLAN-Plan, Runbooks.
- ⚠️ FW 2.2.1 hat Web-UI umgebaut → alte `dispatcher.cgi`-cmd-Codes tot. **Konfig nur via Telnet-CLI** (kein SSH).
## 9. Implementierungs-Phasen
### Phase A — Switch-VLAN-Vorbereitung (JETZT, non-disruptiv, kein Reboot, kein Port-Move)
Tooling: `cd ~/dev/bf-network-r6/switch && . ./.secrets && expect cli/run-cli.exp cli/<datei>.cli`
1. `show running-config` → `switch/cli/running-PRE.txt` sichern (klärt zugleich **Netzmasken-Syntax** von `ip address`).
2. `vlan 90`, `vlan 99` anlegen (neues `cli/02-vlan-extend.cli`, analog `01-vlan-db.cli`).
3. **VLAN-Namen** setzen (MAIN/INFRA/IOT/UNTRUSTED/GUEST/MGMT) — Namens-Syntax erst per `?` erkunden.
4. `save`; mit `show vlan` verifizieren.
> Vor Schritt 2 Mini-Entscheid bestätigen: **Guest=90** (empfohlen) vs 50.
### Phase B — hAP-Cutover (wenn hAP ax² produktiv) — DISRUPTIV, ankündigen
- Trunk-Ports sw1→hAP#1/#2 (tagged 10/20/30/40/90/100); FB-Port = Access untagged WAN.
- hAP#1: Gateway `.1` je VLAN, **DHCP** (Split-Scope), **DNS**→Technitium, **CAKE** auf WAN, **CAPsMAN**, SSID(s).
- FB: DHCP aus, „Exposed Host" → hAP#1-WAN. **Telefon unangetastet.**
- Start „nur vlan10" für schnelles WLAN+Telefon, dann Segmentierung.
- Switch-Mgmt nach vlan99 ziehen: `management-vlan vlan 99` + `ip address 10.40.99.2` (Reihenfolge-Gotcha → Reachability!).
### Phase C — Firewall (Least-Privilege) am hAP — Regelwerk §4.
### Phase D — Adress-Migrationen (behutsam): MAIN 10.40.41→10.40.10; INFRA 172.x→10.40.20; NAS .10→INFRA.
### Backlog / weitere Planung
- 4G/5G-WAN-Failover (USB-Modem an hAP#1 oder separater MikroTik-LTE) — optional, nachrüstbar.
- 6E/WiFi7-Hardware-Refresh in 3–4 J.
- Switch-Upgrade auf 2,5G (Branch/Core) bei Bedarf.
- Container-Konsolidierung Docker→vlan20/INFRA (mit Übergangs-Brücke für alte IPs).
- Restliche Switch-Ports erfassen (mit User), Port→VLAN-Zuordnung finalisieren.
## 10. Switch-CLI (FW 2.2.1, Telnet, IOS-artig) — Kompakt
Login `claudecode` (Passwort in `switch/.secrets`). Prompts `sw1>`→`sw1#`→`sw1(config)#`. **Nur 1 VTY-Line!**
- mgmt-IP ansehen (enable): `show ip` · setzen (config): `ip address <ip>` + `ip default-gateway <ip>` (Maske-Syntax noch bestätigen)
- mgmt-VLAN (config): `management-vlan vlan <id>` · ansehen `show management-vlan`
- VLANs (config): `vlan <liste>` z.B. `vlan 10,20,30,40,100` · ansehen `show vlan`
- Ports: `interface gi<n>` → `switchport mode {access|hybrid|trunk}` · `switchport access vlan <id>` · `switchport trunk native/allowed ...`
- Persistieren: `save` · Dump: `show running-config` (Paging `--More--`→Space) · Version: `show version`
- **NICHT vorhanden:** `interface vlan`, `show ip interface`, `terminal datadump`. Details: `switch/cli/CLI-REFERENCE.md`.
## 11. Gotchas
- **Switch: nur 1 Telnet-VTY**, reapt stale Sessions schlecht (~15 min „busy") → seriell, **sauber ausloggen**, bei busy warten statt hämmern.
- **`save` nicht vergessen** (sonst nach Reboot weg).
- FW-Flash-Default wäre 192.168.1.1/admin/admin (hier blieb IP; gut für Recovery zu wissen).
- Cutover: Alt-Lease-Clients zeigen noch auf FB `.254` → hAP#1 temporär Secondary-IP `.254` bis Renew.
- mgmt-VLAN-Wechsel = Lockout-Risiko (VLAN muss existieren + Port muss es tragen).
- `inventory/IPs.xlsx`/`bf.csv` enthalten echte IPs/MACs → bei öffentlichem Remote vorher prüfen.
## 12. Zugang / Dateien
- **Switch:** `telnet 10.40.41.239`, `claudecode` (`switch/.secrets`).
- **Mac mini (pve):** `ssh 10.40.41.167`. **DS415+ (fm):** siehe `reference_ds415_docker` (Memory).
- **Repo:** `~/dev/bf-network-r6/` — Schlüssel: `HANDOVER.md` (dies), `docs/vlan-plan.md`, `switch/cli/`, `inventory/` (`build.py`).
## 13. Offene Entscheidungen
- Guest-VLAN-ID **90** (empfohlen) vs 50 — vor Phase A.2.
- Netzmasken-Syntax `ip address` final bestätigen (Phase A.1).
- DNS-Filterprofil bei Cloudflare (Families o.ä.) — Phase B/Backlog.
## 14. Verifikation (End-to-End)
- **A:** `show vlan` zeigt 10/20/30/40/90/99/100 mit Namen; in `show running-config`; `save`=Success.
- **B:** SSID→VLAN-Tag greift; Client verbindet; DHCP/DNS vom hAP; **Bufferbloat-Test niedrig unter Last (CAKE)**; **Telefon ohne Jitter**; CAPsMAN sieht hAP#2.
- **C:** IoT/Guest erreichen Main/Infra nicht; Handy erreicht Whitelist-Dienste; **Sonos-Steuerung funktioniert**.
## 15. Kickoff-Prompt (copy-paste an die Nachfolge)
```
Übernimm das BF-Netzwerk-Projekt (Netzwerk/Routing/VLAN/Sprachtelefonie): Implementierung + weitere Planung.
LIES ZUERST die komplette Übergabe: ~/dev/bf-network-r6/HANDOVER.md (alles drin: Architektur+Gründe, Phasen, CLI, Gotchas, Zugänge).
Memory: project_bf_network_r6. Repo: ~/dev/bf-network-r6/ (Git).
STAND: Switch 10.40.41.239 auf FW 2.2.1 geflasht, VLAN-DB 10/20/30/40/100 angelegt+saved, alle Ports noch VLAN1
(Netz läuft, FB ist noch Router/Telefon). Switch-Konfig NUR via Telnet-CLI (Login claudecode, PW in switch/.secrets);
nur 1 VTY-Line → seriell, sauber ausloggen, bei "busy" warten.
JETZT Phase A (non-disruptiv, §9): running-config sichern → vlan 90+99 anlegen → VLAN-Namen setzen → save → show vlan.
Runner: cd ~/dev/bf-network-r6/switch && . ./.secrets && expect cli/run-cli.exp cli/<datei>.cli
Vorher mit User bestätigen: Guest-VLAN-ID 90 vs 50.
Danach Phasen B–D planen/ausführen, sobald die hAP ax² produktiv sind (Cutover: Telefon muss durchlaufen, CAKE gegen Jitter).
```