Files
bf-infra/docs/tp10-vpn-migration.md

110 lines
9.6 KiB
Markdown
Raw Permalink 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-27: KERN DURCH — beide WG live auf ap1-Hub, Bridge entblockt
**TP10-Kern erreicht:** beide AVM-Tunnel auf **2× WireGuard mit Hub auf ap1** migriert, noch im Double-NAT über die
BF-FB-Portfreigabe (51821 → ap1). Live verifiziert: `peer fm` (`10.101.0.0/24`, bidirektional) **und** `peer dw`
(`10.95.10.0/24`, CGNAT-Dial-in) mit frischem Handshake + Traffic; **keine Stale-Route** mehr (`192.168.178` raus).
- **DW/Geli on-site abgeschlossen (2026-06-27):** Geli auf `10.95.10.0/24` renumbert, FB-WG **single `10.95.10.1/24`**,
Keepalive 25, Endpoint `bf4…:51821`; alter Geli↔BF-FB-WG sauber geswappt (nur noch der neue Tunnel in Gelis VPN-Liste).
**End-to-End verifiziert:** macmini/Linz → Gelis 24/7-APs **`10.95.10.246/.247`** (fixe IP) sauber erreichbar,
echte LAN-IPs, **kein `10.255.255.x`**-NAT-Leak. FM-IPsec gekillt.
- **→ FB-Bridge entblockt:** die FB terminiert keine Tunnel mehr. **Rest:** WAN-Input-Seal (Block C aus
`routeros/tp10-cutover-apply.rsc`) + **Liwest-Anruf** → ether1 = Public Edge, Double-NAT weg; danach BF-FB-eigenen
WG-Server 51820 abräumen; DDNS-Auto-Updater für `bf4` auf NAS/pve.
- **⚠️ Rückweg-Gotcha behoben (2026-06-28):** `peer dw` war gesund (Handshake, rx/tx beidseitig), aber
**dw → BF = no response**. Root Cause: die BF-Infra hängt auf `10.40.41.0/24` und bezieht DHCP/Default-GW von der
**FritzBox** (ap1-DHCP auf `bridge` = disabled) → Antworten an `10.95.10.x` gehen an die FB, die keine Route zu den
Spoke-Netzen mehr hat → Blackhole. Frühere „verifiziert" waren **ap1-sourced bzw. WARP**, nie ein LAN-`.41`-Host.
**Fix (Interim, Double-NAT):** 2 Statikrouten auf der BF-FB — `10.95.10.0/24` + `10.101.0.0/24 → 10.40.41.1` (ap1).
Voll transparent (echte LAN-IPs), deckt FM mit ab. **DW ohne WARP getestet ✅.** Anleitung:
`routeros/fritzbox-bf-static-routes-klickanleitung.md`. Beim Bridge-Cutover obsolet (FB raus aus dem Pfad).
## 🟢 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.
- **✅ Erledigt (2026-06-27):** Geli auf `10.95.10.0/24` renumbert, WG-`Address`=`10.95.10.1/24` (single) → BF↔Geli-Hosts
end-to-end verifiziert (s. Status-Block oben). Nächster Schritt = 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 `10.95.10.0/24` (single — Gelis FB sourct daraus; Dual-Address war ein Fehler), enable.
Key `FqYZLztQ…PbzUw=`. **✅ live + verifiziert.**
- Routen `10.101.0.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). Tunnel steht (2026-06-27) → FB unter **`10.95.10.1`** über den
Tunnel erreichbar (nach Renumber; Endpoint 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`).