Routing-Regel statt Mangle: Client-VLANs -> Routing-Tabelle warpout, Router-Infra (wg-hub/cf-mesh/DNS/NTP) bleibt auf Liwest. Nur Plan, nichts ausgeführt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8.8 KiB
WARP-Egress — nativer Consumer-WARP (WireGuard) auf dem crs326-core
Status: PLAN (noch nicht ausgeführt) · 2026-09-25 · TP-Nummer bei Anlage vergeben (nächste freie, Stand TP46). Zweck: ausgehenden Client-Verkehr (alle VLANs) über Cloudflare egressen → geteilte CF-IP statt blockierter Heim-IP
90.146.33.177. Router-eigene Infra bleibt auf Liwest. Werkzeuge: MikroMCP (plan_changes→apply_plan) für den Router-Block · CF-MCP zum Verifizieren ·wgcfnur für den einen Consumer-WARP-Key ·sshpassnur für die WG-Zeilen, die MikroMCP nicht kann (TP16.1 §4.3). Muster: TP16.1 (docs/tp16.1-warp-mesh-native-crs326.md) — dort natives WG für Ingress, hier für Egress.
1. Kontext / Warum
- Cannaleo-Origin
164.90.191.7(DigitalOcean, multi-tenant, ~400 Vhosts) blockt die Heim-IP90.146.33.177hart (leerer403, live 2026-09-25). Crawler ist aus, Projekt auf Eis — nur noch privates Surfen/Bestellen. - Ziel: CF-Egress für alle Clients/VLANs (nur die zwei aktiven Nutzer, keine Einschränkung nötig).
2. Entscheidung & Nicht-Ziele
- Gewählt: nativer Consumer-WARP als zweites WG-Interface
warpoutaufcrs326-core. Clients über WARP, Router-Infra über Liwest (Policy-Route via Routing-Regel → Routing-Tabellewarpout). - Verworfen: WARP-Client als RouterOS-Container (kein
/dev/net/tun); Mesh-Node als Egress (egressed über die eigene Public-IP = die blockierte); cloudflared (reiner Ingress); Default-Route-Flip (würde die WG-Transporte vonwg-hub/cf-mesh/warpoutmitreißen → fm/dw kaputt, Hairpin). - Nicht-Ziel: Dedicated Egress (paid) — bewusst „vorerst" geteilte CF-IP.
3. Ist-Stand (live 2026-09-25)
crs326-core(ROS 7.24.1): WGcf-mesh(Ingress100.96.0.6/32) +wg-hub(FM/DW). Kein Container am Core.- APs fahren
cfd-min-arm64-cloudflared-Container (bf-public, ~75 MB RAM, Flash nur ~54 MB frei) → nicht anfassen. - Firewall deny-by-default beide Ketten (TP5) → Egress braucht explizite
forward-Regel. - Routing: Default
0.0.0.0/0 → 90.146.33.1(vlan100). Nur Routing-Tabellemain, keine Mangle-Marks.
4. CF-MCP: Account verifizieren (read-only, Schritt 0)
Mit mcp__cloudflare__execute gegenlesen (bestätigt 2026-09-25): warp_connector = nur bf-core-mesh
(Mesh, nicht Client) · egress_cidr_pairs = [] (kein Dedicated Egress). → es gibt noch keinen WARP-Client.
⚠️ Grenze des CF-MCP: die Consumer-WARP-Registrierung (PrivateKey + Reserved-IPs) läuft über
api.cloudflareclient.com, NICHT über die Account-API — dafür gibt es keinen CF-API-Endpoint. Der CF-MCP kann den Account verifizieren, aber den Client-Key nicht erzeugen. Dafür §5 (wgcf), genau einmal.
5. Einmalig: Consumer-WARP-Key (wgcf, nicht wgcf-connector)
docker run --rm -v $(pwd):/app/output ghcr.io/animmouse/wgcf register
docker run --rm -v $(pwd):/app/output ghcr.io/animmouse/wgcf generate # → wgcf-profile.conf
- ⚠️
wgcf(Consumer) ≠wgcf-connector(Mesh). Das Repo hat bisher nur den Connector benutzt. .confliefert: PrivateKey,Address = 172.16.0.2/32(+ v6 → ignorieren, v4-only), Peer-PublicKeybmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=(= gleicher CF-Wellknown-Key wie Mesh), Endpointengage.cloudflareclient.com:2408→162.159.192.x/.193.x, MTU 1280.- PrivateKey →
~/.secrets/mcp/cloudflare/.env(CF_WARP_CLIENT_PRIVKEY,chmod 600, nie in Git).
6. RouterOS — MCP-first
Primärpfad: mcp__mikromcp__plan_changes (dryRun, reviewen) → mcp__mikromcp__apply_plan.
Ausnahme (WG): MikroMCP kann WG-PrivateKey nicht, endpoint="IP:Port" wird falsch zerlegt,
persistent-keepalive fehlt (TP16.1 §4.3) → diese 4 Zeilen einmal via sshpass -e (Key aus .env
interpoliert, nicht im Literal; Fehlerausgabe sed-maskieren — CLAUDE.md-Regel).
# (a) sshpass — WG-Bring-up (Interface+Key, Peer mit endpoint/keepalive)
/interface wireguard add name=warpout mtu=1280 private-key="<CF_WARP_CLIENT_PRIVKEY>" comment="WARP Egress (privat)"
/interface wireguard peers add interface=warpout name=warp-cf-pop \
public-key="bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=" \
endpoint-address=<162.159.192.x|193.x> endpoint-port=2408 \
allowed-address=0.0.0.0/0 persistent-keepalive=25s
# (b) MCP plan_changes→apply_plan — alles ohne Secret
/ip address add address=172.16.0.2/32 interface=warpout comment="WARP client (v4)" # manage_ip_address
/routing table add name=warpout fib # manage_routing_table
# lokale Routen in warpout — PFLICHT, sonst läuft VLAN↔VLAN über den Tunnel!
/ip route add dst-address=10.40.10.0/24 gateway=vlan10 routing-table=warpout # manage_route (local)
/ip route add dst-address=10.40.20.0/24 gateway=vlan20 routing-table=warpout # manage_route (local)
# … analog vlan30/vlan40/vlan50/vlan90 (die exakten /24 aus den Connected-Routes übernehmen)
/ip route add dst-address=0.0.0.0/0 gateway=warpout routing-table=warpout # manage_route (Internet via WARP)
# Routing-Regel je Client-VLAN — „die Ausnahme direkt über den WG-Tunnel", kein Mangle
/routing rule add interface=vlan10 action=lookup-only-in-table table=warpout comment="Client -> WARP" # manage_routing_rule
/routing rule add interface=vlan20 action=lookup-only-in-table table=warpout
# … analog vlan30/vlan40/vlan50/vlan90
/ip firewall nat add chain=srcnat out-interface=warpout action=masquerade comment="WARP egress" # kein NAT-Tool → run_command
/ip firewall filter add chain=forward in-interface=vlan10,vlan20,vlan30,vlan40,vlan50,vlan90 \
out-interface=warpout action=accept comment="WARP egress fwd" # manage_firewall_rule
- Warum Routing-Regel statt Default-Route-Flip:
main-Default bleibt90.146.33.1→ der WG-Transport vonwarpout/cf-mesh/wg-hub(Endpunkt-IPs) und die Router-eigenen Dienste (DNS-DoH, NTP) laufen weiter über Liwest. Nur Client-Ingress (VLANs) wird umgeleitet → kein Hairpin, fm/dw und cf-mesh bleiben unberührt. - Scope: alle Client-VLANs (10/20/30/40/50/90).
vlan99(Mgmt) +vlan100(WAN) bewusst nicht umgeleitet. - DNS: bleibt auf dem Core (DoH→CF-Gateway, TP23); nur der Verbindungs-Traffic der Clients geht durch WARP.
7. Nautobot / Golden Config
- Vorher
/system backup→pre-warp-egress-<datum>.backup(TP22-Regel 3). - WG-Bring-up direkt (Ausnahme #4-Muster: Privkey nicht GC-deploybar); Route/Mangle/NAT/Firewall/Adresse normal.
- Ist-Stand → Nautobot intended config: Privkey als
<<REDACTED>>(byte-identisch zurConfigReplace-Maske). - Compliance-Features ggf. um neue Sektionen erweitern, dann
--refresh-compliance→ grün, keine Drifts. - TP-Anlage (nach User-Okay): Gitea-Issue +
### TPnnindocs/teilprojekte.md. - Diese Datei am Ende auf
✅ AUSGEFÜHRT+ As-Built-Werte setzen.
8. Verifikation
- Beliebiges Client-Gerät:
curl -s https://cloudflare.com/cdn-cgi/trace→warp=on,ip=104.28.x.x(nicht90.146.33.177). - Cannaleo-Test:
curl -s -o /dev/null -w "%{http_code}\n" https://blaueblueten.de/→ 200 (vorher 403). - Regression (wichtig!):
wg-hub-Peersfm/dw+cf-mesh-Peercf-popweiterhinlast-handshake < 60s; WARP-Zugriff aufs BF-Netz (Mesh) weiter ok. Beweist: Router-Infra blieb auf Liwest, nichts mitgerissen. warpout-Peer:last-handshake < 10s, rx/tx laufen.
9. Rollback
- Routing-Regeln
disable(Clients fallen aufmain-Default = Liwest zurück) ODERwarpout-Interfacedisable. - Router-Infra war nie betroffen → fm/dw/cf-mesh unberührt. Reversibel; Backup §7.1.
10. Gotchas
- Kein Container am Core (arm 32-bit, 2,9 MB frei) — natives WG ist kein Container: ein paar Config-Zeilen. AP-Flash-Enge (54 MB) ist hier nicht im Spiel.
- MikroMCP-WG-Lücken (TP16.1 §4.3): PrivateKey,
endpoint-Zerlegung,persistent-keepalive→ sshpass. - Name ohne Bindestrich (
warpout) für GC-Tauglichkeit. - WARP = geteilte CF-IP: verbirgt die Heim-IP, ersetzt aber nicht „sauber" (manche Seiten flaggen VPN/CF-IPs).
- Kein Auto-Failover: stirbt WARP (Handshake weg), verlieren Clients den Internetzugang (Mark bleibt, Interface ist L3-mäßig „up"); die Router-Infra läuft weiter über Liwest → Router bleibt per MikroMCP erreichbar, Rollback §9. Netwatch-Failover = optional, später.
- Verifikation über TCP/HTTP (curl), nicht
nc -z(trügt hinter Proxys, TP16.1 §4.5).
11. Offen vor Start
- TP-Nummer + Gitea-Issue (User-Okay) + Prosa-Abschnitt.
- Consumer-WARP-Konto (wgcf
register= neues Wegwerf-Konto, geteilte IP, bewusst).