Files
bf-infra/docs/warp-egress-native-crs326.md

7.5 KiB

WARP-Egress — nativer Consumer-WARP (WireGuard) auf dem crs326-core

Status: ❌ VERWORFEN 2026-09-26 — Cloudflare blockt inoffizielle Consumer-WARP-WireGuard-Clients. Live gebaut, verifiziert, dann vollständig zurückgebaut. Key + Backup bleiben zur Nachvollziehbarkeit liegen.

➡️ Nachtrag §6 (selber Tag, zweiter Durchgang): Der Mesh-Tunnel cf-mesh trägt als ziel-basierter Ausgang und erreicht den Origin mit 200 (Core kommt als 104.28.207.39, warp=on, colo=VIE heraus — dieselbe IP wie der WARP-Client). Lösung ist dauerhaft über Nautobot/Golden Config aktiv (Template nautobot/mikrotik_routeros.j2, Abschnitt [10b]). Der frühere „Origin blockt CF-IPs"- Befund war ein Messfehler — korrigiert in §6.3.

1. Kontext / Warum

  • Cannaleo-Origin 164.90.191.7 (blaueblueten.de, DigitalOcean multi-tenant, ~400 Vhosts) blockt die Heim-IP 90.146.33.177 hart (leerer 403, live 2026-09-25).
  • Scope (User-Vorgabe 2026-09-25): nicht der ganze Outbound, sondern genau eine Ziel-IP (164.90.191.7/32 — blaueblueten.de apex + www, beide identisch). Nur Privatbestellungen, Traffic überschaubar gering.
  • Terpenfinder wird NICHT über diesen Weg in Betrieb genommen (eigene, saubere Lösung — siehe §5).

2. Was gebaut wurde (2026-09-26, live)

  1. Consumer-WARP-Key per wgcf registriert (ViRb3 v2.3.0, Wegwerf-Konto via api.cloudflareclient.com). → mcp/cloudflare/.env (CF_WARP_CLIENT_PRIVKEY, gitignored) + ~/.secrets/wgcf-client/ (account + profil).
  2. Auf crs326-core (WG-Zeilen via sshpass -e, Rest per MikroMCP/ssh):
    • /interface wireguard add name=warpout mtu=1280 private-key=… comment="WARP Egress (privat)"
    • Peer warp-cf-pop: public-key bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, endpoint engage.cloudflareclient.com:2408, allowed-address=0.0.0.0/0, persistent-keepalive=25s
    • /ip address add 172.16.0.2/32 interface=warpout
    • /routing table add name=warpout fib + /ip route add 0.0.0.0/0 gateway=warpout routing-table=warpout
    • /routing rule add dst-address=164.90.191.7/32 action=lookup-only-in-table table=warpout
    • NAT masquerade out-interface=warpout + forward accept out-interface=warpout
  3. Verifiziert: Key korrekt (abgeleiteter Public-Key == Router-Public-Key HTFM3gj3FyT0EjWkG+2LLmvtxaFz1kH/P1iDwM0HswI=), Konto „Active" (wgcf status).

3. Befund: Handshake schlägt fehl

  • Peer warp-cf-pop: rx=0, kein last-handshake — Cloudflare antwortet nie auf den WG-Handshake, egal welcher Endpoint (162.159.192.1 / .193.2 / .193.5).
  • Ursache (recherchiert): Cloudflare blockt inoffizielle WireGuard-Clients für Consumer-WARP. Der offizielle Client setzt ein spezielles Handshake-Feld (reserved/Client-ID, z. B. b91981), das RouterOS (und jedes plain-wgcf-Profil) nicht setzt; dazu Abuse-Prevention. Der Mesh-Connector cf-mesh läuft nur, weil das ein anderes Produkt ist (Zero Trust, nicht Consumer).
  • Quellen: ViRb3/wgcf Issue #542 · #515 · #158.

4. Abbau (2026-09-26)

  • Alle 8 Objekte entfernt (Routing-Regel, Route, Tabelle, NAT, Firewall, Adresse, Peer, Interface). Core wieder im Ursprungszustand — keine Drift, Golden-Config-Compliance unverändert.
  • Backup pre-warp-egress-20260925.backup liegt auf dem Core (vor dem Versuch, TP22-Regel).
  • CF_WARP_CLIENT_PRIVKEY bleibt in mcp/cloudflare/.env (nutzlos, da Client geblockt; kann bei Bedarf entfernt werden).

5. Weg vorwärts

⚠️ Durch §6 überholt (2026-09-26). Die Grundannahme hier — „geteilte CF-IPs werden geblockt, WARP liefert 403" — war falsch und ist in §6.3 korrigiert. WARP-Client und cf-mesh-Ausgang erreichen den Origin beide mit 200. Eine Dedicated Egress IP ist damit nicht nötig.

  • Bleibt gültig: Consumer-WARP über natives RouterOS-WG ist auf absehbare Zeit blockiert (separates Produkt, betrifft nicht cf-mesh).

6. Nachtrag 2026-09-26: Mesh-Exit trägt und erreicht den Origin (200) — Lösung dauerhaft

Frage: Kann der bereits laufende cf-mesh-Tunnel (TP16.1) als Ziel-basierter Ausgang dienen, statt eines separaten Consumer-WARP? Antwort: ja — und er erreicht den Origin mit 200. Die Lösung ist dauerhaft über Nautobot/Golden Config aktiv (Template-Abschnitt [10b]).

6.1 Der Origin-Weg ist jetzt vermessen (vorher nur angenommen)

blaueblueten.de geht direkt zum DO-Droplet, kein Cloudflare im Pfad (Zertifikat = Let's Encrypt CN=blaueblueten.de vom 11.08., kein cf-ray, kein server-Header, kein /cdn-cgi/trace — CF setzt cf-ray immer). Der 403 kommt also vom Origin, nicht vom Edge.

Der Block ist rein quell-IP-basiert: voller Safari-/Chrome-User-Agent ändert nichts, HTTP→HTTPS-Redirect (302) funktioniert, erst der HTTPS-Request antwortet 403 mit content-length: 0.

6.2 Mesh als Exit — funktioniert

Temporär gebaut (Tabelle meshtest + 0.0.0.0/0 via cf-mesh + Regel nur auf 1.1.1.1/32), dann gemessen:

/tool fetch url="http://1.1.1.1/cdn-cgi/trace" mode=http
→ ip=104.28.207.39   warp=on   gateway=on   colo=VIE

Der Core kommt also über den Mesh-Tunnel als Cloudflare-IP heraus (vorher 90.146.33.177). ⚠️ Merkregel: für cdn-cgi/trace mode=http nehmen, nicht mode=https — über HTTPS liefert RouterOS nur den 69-Byte-Datei-Header (# … by RouterOS, # software id =), die Nutzdaten fehlen. Das sieht wie ein leerer Download aus, ist aber nur der falsche Fetch-Modus.

6.3 KORREKTUR: der frühere „403 über Mesh" war ein Messfehler — der Weg trägt

Der erste Test hatte nur die Regel 1.1.1.1/32 → meshtest gesetzt und dann das Ziel gemessen. Für das Ziel griff die Regel nicht → der Request lief über die Heim-IP (90.146.33.177) raus. Der gemeldete 403 war also 403 über die Heim-IP, nicht über den Mesh-Ausgang.

Beweis (A/B in einem Durchgang, Regel 164.90.191.7/32 → egress-cannaleo):

Regel aktiv     → https://blaueblueten.de/  → 200 (168 KiB)
Regel deaktiv   → https://blaueblueten.de/  → 403 (fällt auf Heim-IP zurück)

Merke: action=lookup-only-in-table für Ziel A routet Ziel B nicht — nur messen, was tatsächlich umgeleitet ist. Dieselbe CF-IP (104.28.207.39) erreicht den Origin via WARP-Client und via cf-mesh.

6.4 Rückbau (vollständig)

Alle Objekte entfernt (Regel, Route, Tabelle, Testdateien). /routing table print = nur main, /routing rule print = leer, Default-Route wieder 90.146.33.1%vlan100. cf-mesh unberührt und gesund (Handshake 4 s). Keine Drift.

6.5 Was daraus folgt

  • Der Core-Teil ist gelöst und wiederverwendbar: routing-table + 0.0.0.0/0-Route + routing rule dst-address=<ziel>/32 action=lookup-only-in-table + masquerade out-interface=<wg-x>. Nur ein Ziel betroffen, Rest unberührt. Genau so gebaut, verifiziert, zurückgebaut.
  • Offen bleibt allein das Transportmittel. CF scheidet aus (Ziel blockt CF). Der Rest des Vorschlags aus §5 steht: eigener Ausgang über einen externen WireGuard-Host. Ein DO-VPS ist dabei der naheliegendste Kandidat — der Miner fährt heute schon erfolgreich über eine DO-IP gegen genau diesen Origin.
  • 🔴 Der Core hat heute keinen zweiten Ausgang. Kein zweites WAN, kein zweites Gateway — jeder künftige Egress braucht erst ein Interface, das ihn trägt.