Files
bf-infra/docs/tp10-vpn-migration.md
Christoph Emsenhuber 48754f446d TP10 🔧 WG live: Key-Mixup + stale bf4 + DW-Dual-Address behoben, DW→10.95.10.0/24
Live-Debug-Session (Double-NAT): WG-Hub ist jetzt aktiv, FM+DW-Tunnel UP.
- Root Causes behoben: (1) beide ap1-Peers trugen faelschlich ap1s EIGENEN Public-Key
  P/bzt... statt der FB-Keys dzRY.../FqYZ... (2) bf4.emsenhuber.net war stale -> DW-Dial-in
  (CGNAT) lief erst danach. (3) DW-Dual-Address 192.168.178.1/24,10.95.10.1/24 -> FRITZ!OS
  macht 10.95.10.1 primaer u. koppelt das LAN nicht -> Single-Address-Regel.
- DW standardisiert auf 10.95.10.0/24 (Geli renumbert vor Cutoff): wg-dw.conf single,
  ap1 peer dw allowed-address=10.95.10.0/24, Route 10.95.10.0/24 -> wg-hub. Routing verifiziert (0% Loss).
- Klickanleitung: DW-Renumber + Single-Address-Lehre; Doku/Digest auf Live-Stand.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 21:00:07 +02:00

91 lines
7.7 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.
# TP10 — Multi-Site-VPN (2× AVM-S2S → 2× WireGuard, Hub auf ap1)
> **Single Source of Truth** für TP10. Research: `docs/research/vpn-comparison.md` · IPv6: Memory `project-ipv6-state`.
> Plan-Scratch (historisch, teils überholt): `~/.claude/plans/pure-wibbling-graham.md`.
## 🟢 STATUS 2026-06-25: CUTOVER-READY — Apply-Skript gestaged, wartet auf Bridge-Tag
ap1-Live-Stand verifiziert; alle ap1-Änderungen in **`routeros/tp10-cutover-apply.rsc`** gebündelt (idempotent):
WG-Peers säubern+enable, Spoke-Routen, **Input-Chain WAN-Seal** (🔴 ap1 bekommt Public-IP → Management/Resolver dicht),
ether1 `use-peer-dns=no`. FM-`.conf`-Endpoint auf **`bf4…`** umgestellt. Klick-Anleitungen:
`routeros/fritzbox-wg-lanlan-klickanleitung.md` (FM-FB) + `routeros/fritzbox-bf-bridge-cutover-klickanleitung.md` (BF-FB).
Modus: **stagen → am Bridge-Tag 1× Apply + ether1 umstecken** (Runbook unten). FritzBox = kein MCP (UI/Klick).
**🟢 Live-Stand 2026-06-25 (WG-Hub ist bereits AKTIV im Double-NAT, nicht mehr geparkt):**
- **FM-Tunnel UP** (`peer fm`, bidirektional, kam per ap1-Initiation hoch; FM-FB hat unseren `.conf`-Key übernommen).
- **DW-Tunnel UP** (`peer dw`, CGNAT-Dial-in via `bf4`; rx>13 MiB). DW-Routing zu `10.95.10.x` von ap1 verifiziert (0% Loss).
- **Behobene Fehler dieser Session:** (1) beide ap1-Peers trugen fälschlich ap1s **eigenen** Public-Key `P/bzt…` → auf
die FB-Keys (`dzRY…`/`FqYZ…`) korrigiert. (2) **`bf4` war stale** (falsche IP) → gefixt, danach DW-Dial-in ok.
(3) **DW-Dual-Address** brach die LAN-Kopplung → ap1+Config auf **Single `10.95.10.0/24`** vereinheitlicht.
- **Offen:** Geli renumbert ihr LAN auf `10.95.10.0/24` + WG-`Address`=`10.95.10.1/24` (single) → dann BF↔Geli-Hosts
end-to-end. Danach Bridge-Cutover (löst Inbound-Forward-Abhängigkeit ganz auf).
## 🅿️ STATUS 2026-06-17: VERTAGT — gebündelt mit dem FB-Bridge-Cutover
TP10 wird **nicht** mehr als Parallel-Migration vorab gemacht, sondern **zusammen mit dem permanenten FB-Bridge-Cutover**
— denn **VPN-auf-FB und FB-Bridge schließen sich aus** (Bridge = Modem = keine VPN-Terminierung). Bonus: am Bridge-Tag
hat **ap1 die echte Public-IP** → **kein FB-Port-Forward-Umweg** mehr, Spokes zeigen direkt auf ap1 (via DDNS).
- **Beide VPN laufen vorerst über die BF-FB:** ~~FM = IPsec~~ → **FM = FB-WG** (IPsec längst gekillt), **DW = FB-WG**.
- **DW-Config ist aber schon bei Geli vor Ort gestaged** (2026-06-17, seltener Zugriff genutzt) — wird erst aktiv,
wenn die ap1-Seite live geht (s.u. „Offen").
## Root Cause des FM-PoC (bewiesen) — der zentrale Lerneffekt
FM-WG-Versuch schlug fehl: Ping auf realen FM-Host `10.101.0.10` kam aus `10.255.255.2` zurück ⇒ **die FB masqueradet
den Tunnel.** **Ursache:** WG-Interface-`Address` war eine **Transfernetz-IP** → FRITZ!OS = Einzelgerät-Modus = NAT.
**AVM nutzt Proxy-ARP statt Transfernetz** → die FB-WG-`Address` **muss die eigene LAN-IP sein**. Damit: kein NAT,
echte LAN-IPs, LAN-LAN sauber. (Gleiche Ursache wie der alte „NetBIOS routet nicht"-Fehlschlag.)
## Eckdaten
| Objekt | Wert |
|---|---|
| Hub `wg-hub` (ap1) | UDP **51821**, MTU 1412, **keine IF-IP**, Key `P/bztIk13cAmLHbN6oHGGnWAKLZsqR5TXAbFP+NGGBk=` |
| **Endpoint (Spokes)** | **`bf4.emsenhuber.net:51821`** — DDNS via Cloudflare (Zone `emsenhuber.net`, **proxied=false**, TTL 120) → `86.56.201.104`. Überlebt IP-Wechsel **und** FB-Bridge. NICHT MyFRITZ (stirbt im Bridge). |
| BF-Seite (AllowedIPs der Spokes) | `10.40.0.0/16` |
| FM | LAN `10.101.0.0/24` (GW .254). **IPsec gekillt → bereits FB-WG** (peert heute mit BF-FB; FM-FB horcht auf `abxhutfgsid9snmy.myfritz.net:52476`, erreichbar/kein CGNAT). FB-WG-`Address` = **`10.101.0.254/24`** (LAN-IP!). Migration = Peer-Endpoint auf `bf4…:51821` umbiegen. ap1-peer1 bekommt FM-Endpoint → **bidirektional** |
| DW/Geli | **CGNAT v4**, Antennengem. Geroldsgrün. LAN **auf `10.95.10.0/24` renumbered** (vor Cutoff). FB-WG-`Address` = **`10.95.10.1/24` (SINGLE!)**. ⚠️ **Dual-Address `192.168.178.1/24, 10.95.10.1/24` war ein Fehler** — FRITZ!OS macht 10.95.10.1 primär u. koppelt das LAN nicht → Single-Address-Regel. ap1 `peer dw` = allowed-address `10.95.10.0/24` |
| Keepalive | Spoke-Seite `PersistentKeepalive=25` (CGNAT-Dial-out) |
**Spoke-Configs (Private-Keys, gitignored):** `routeros/.secrets/wg-fm.conf`, `routeros/.secrets/wg-dw.conf`.
**ap1-Park-Zustand:** Peers **disabled**, WG-Routen **entfernt** (FM/DW laufen über FB-Default), `wg-hub` bleibt
(Key erhalten), Firewall-Regeln bleiben (TP5-Vorarbeit). NAT braucht nichts (Egress wg-hub ≠ masq-Interface bridge/ether1).
## ✅ ap1-Seite — gestaged in `routeros/tp10-cutover-apply.rsc` (am Bridge-Tag anwenden)
Das Skript erledigt idempotent (Live-Stand 2026-06-25 verifiziert):
- **peer1 (FM)** allowed-address `10.101.0.0/24` (Transfernetz-/32 raus), enable. Key `dzRY0lnn…fyiVE=`.
- **peer2 (DW)** allowed-address `192.168.178.0/24,10.95.10.0/24` (Transfernetz-/32 raus, künftiges Netz rein), enable.
Key `FqYZLztQ…PbzUw=` (falls Gelis FB **eigene** Keys erzeugt → deren Public-Key eintragen).
- Routen `10.101.0.0/24`, `192.168.178.0/24`, `10.95.10.0/24` → `wg-hub`.
- **Input-WAN-Seal** (est/rel · drop invalid · WG51821 · dhcp68 · icmp · LAN · **drop WAN**) — schließt
telnet/ftp/ssh/api/winbox/www + offenen Resolver/53 gegenüber dem Internet, sobald ether1 die Public-IP hat.
- ether1-DHCP `use-peer-dns=no` (DoH bleibt einzige DNS-Quelle).
Hinweis: **NAT, Forward-FW (wg-hub), Default-Fallback-Route, masquerade-ether1 sind bereits korrekt** — nicht im Skript.
- Verify: `list_wireguard_peers` Handshake; SMB/445 per IP auf FM-/Geli-Host → **Quelle = echte LAN-IP**, nicht
`10.255.255.x`. **NetBIOS-Lehre:** per IP/DNS testen, nie Broadcast/Netzwerkumgebung.
## DW-Gotchas
- **2 WG zum selben Zielnetz**: Gelis FB lehnt zwei WG-Verbindungen mit überlappenden AllowedIPs (`10.40.0.0/16`) ab
→ **direkter Swap** (alten Geli↔BF-FB-WG entfernen, neuen Geli↔ap1 anlegen), kein Parallelbetrieb. On-site oder via
temporärem Admin-Tunnel zu anderem Zielnetz.
- **Fernzugang zu Gelis FB**: MyFRITZ-v4 tot (CGNAT). Sobald Geli↔ap1 steht → FB unter `192.168.178.1` über den Tunnel
erreichbar (Endpoint später proaktiv pflegen, solange Tunnel läuft).
## 💡 DW-Variante: v6-direkt statt CGNAT-Spoke (für später)
Gelis CGNAT ist **nur v4**; ihre FB hat **öffentliches natives IPv6** (`2a0e:7a02:31c:3000::/56`, rotiert ~30h → MyFRITZ),
**v6-Inbound-Port offen** → von außen über v6 erreichbar.
- **PoC/Fernwartung jetzt:** Christophs **WARP** gibt outbound-v6 (Liwest v4-only) → `Christoph(WARP-v6) → CF-Edge →
Gelis v6-FB`. CGNAT-immun, reversibel. Nur Fernwartung (Calls laufen eh über Messenger-Relays).
- **Daueform:** echtes v6 auf BF via **HE-6in4** → **direktes WG ap1↔Geli-FB über v6**, kein CF im Datenpfad, **umgeht die
ganze Hub-&-Spoke-CGNAT-Gymnastik** (v6↔v6 symmetrisch erreichbar). Inner-Tunnel bleibt IPv4 (Gelis Geräte v6-agnostisch).
## Cutover-Sequenz (am Bridge-Tag, ein Rutsch)
1. ap1-Seite live (peers/routes, s.o.), Spoke-Configs an FM+DW (FM-`.conf` neu mit LAN-IP-Address).
2. Verify je Spoke (echte LAN-IP-Quelle, SMB/445 per IP).
3. Alte AVM-Tunnel abbauen (FM-IPsec; DW-FB-WG/Server 51820).
4. **Liwest-Anruf** → FB Bridge/Modem, ap1 = Edge mit Public-IP (DDNS zeigt weiter dorthin) → Portfreigabe entfällt.
5. TP5-Firewall auf ap1 finalisieren (WG-Regeln behalten).
6. Entblockt: NAS/Controller-IP-Migration (IP-Plan Phase 3), Double-NAT weg.
**Follow-up:** DDNS-Auto-Updater für `bf4` auf NAS/pve (statt manuell bei IP-Wechsel).
## Reversibilität
ap1-Seite vollständig per `manage_*`/`action=remove` rückbaubar. Alte AVM-Tunnel erst nach Verify abschalten →
jederzeit reaktivierbar. FB-Bridge bis Liwest-Anruf reversibel (`routeros/wan-cutover-runbook.md`).