Files
bf-infra/docs/tp16.1-warp-mesh-native-ap1.md
Christoph Emsenhuber d52cf16e0b docs 📋 TP16.1: Konzept+Runbook Private Access via native Cloudflare Mesh (WireGuard) auf ap1
Incident-Nachgang 2026-07-16: ICMP über den cloudflared-WARP-Pfad ist strukturell
kaputt (TCP ok überall, Ping fm 36%/bf 100%/dw 100% Loss) — cloudflared ist ein
QUIC-L7-Proxy, kein WireGuard. Richtungsentscheid: Private Access (unterwegs ->
10.40.0.0/16 inkl. ICMP) wandert vom cloudflared-Proxy auf einen nativen
Cloudflare-Mesh-Node (WireGuard) auf ap1 -- kein Container/TUN/LXC/neue HW
(RouterOS-Container haben kein /dev/net/tun -> hAP ax3 löst es nicht, zudem WiFi6).
Public-FQDNs bleiben unverändert auf dem cloudflared-3-Tunnel-HA.

- Neu: docs/tp16.1-warp-mesh-native-ap1.md (Konzept + vollständiges Runbook +
  gemessener Account-Ist-Stand, Team emsenhuber.cloudflareaccess.com)
- cf-tunnel-mapping.md §13: ICMP-Dreiländer-Befund; "bf-pve wegen USV" REVIDIERT
  (Begründung invertiert -- bf-pve-Connectoren laufen auf NAS+macmini, nicht pve)
- cf-tunnel-mapping.md §14 + teilprojekte.md TP16.1: Richtungsentscheid dokumentiert

Scharfschalten = eigene Session (CF-Prereqs sind account-weit, treffen Live-WARP).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:10:00 +02:00

124 lines
9.2 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.
# TP16.1 — Private Access via native Cloudflare Mesh (WARP Connector) auf ap1
> **Status: Konzept + Runbook fertig (2026-07-16), Scharfschalten = eigene Session.**
> Selbst-tragend: eine frische Session kann das mit diesem Doc + `docs/cf-tunnel-mapping.md` straight bauen.
> SSoT-Kontext: `docs/cf-tunnel-mapping.md` §13/§14, Memory `project_cf_tunnel_1033`.
## 1. Warum überhaupt / Root Cause
**Incident 2026-07-16 (unterwegs):** keine BF-IPs über WARP. Diagnose:
- **TCP über den CF-WARP-Pfad funktioniert** (SSH, alle Web-UIs, MCP-Endpoints erreichbar) —
- **ICMP ist strukturell kaputt.** Dreiländer-Ping-Befund: fm **36 % Loss** (ICMP-Proxy über QUIC-Connector,
funktioniert aber mies), bf **100 %** (macmini-Connector läuft seit dem http2-Fix von heute = QUIC-los →
ICMP-unfähig; zusätzlich cloudflared-Container ohne Ping-Sockets), dw **100 %** (192.168.0.0/16 steht in der
WARP-Split-Tunnel-Exclude → Pings betreten den Tunnel gar nicht).
**Kernursache:** cloudflared ist **kein** WireGuard, sondern ein QUIC/HTTP2-L7/L4-Proxy. ICMP darüber ist
Zusatz-Gefrickel (Account-ICMP-Flag + QUIC-Transport + `ping_group_range`-sysctl je Host) und war nie
zuverlässig eingerichtet. **Der WARP-Client selbst spricht WireGuard** — die passende Gegenstelle für einen
*sauberen* privaten L3-Zugang ist deshalb **Cloudflare Mesh (WARP Connector)**, ebenfalls WireGuard.
## 2. Entscheidungsweg (was verworfen wurde und warum)
- **WG-Roadwarrior (eigene WG-Peers je Gerät):** ❌ verworfen — User will KEINE Extra-App/kein Profil pro Gerät.
„Ein Client = WARP für alles" bleibt Anforderung.
- **Alle ZT-Anbieter mit Helper-Host** (CF WARP Connector als Daemon-Host, Tailscale, NetBird, Twingate):
brauchen dauerhaft einen Linux-Host → verletzt „Router = einziger SPOF, keine Abhängigkeit zu anderen Rechnern".
- **Connector als RouterOS-Container:** ❌ nicht möglich — RouterOS-7-Container haben **kein `/dev/net/tun`-
Passthrough**; der WARP-Connector-Daemon braucht ein TUN-Device. Gilt auf **jeder** Router-HW (hAP ax²/ax³/CRS/RB5009).
→ **hAP ax³ löst das NICHT** (und ist zudem Wi-Fi 6, nicht 7 — kein WLAN-Gewinn ggü. ax²). HW-Kauf ist vom
Tunnel-Fix **entkoppelt** (separat unter TP15 zu bewerten, falls 2,5G/USB/CPU gewünscht).
- **✅ Gewählt: Cloudflare Mesh als NATIVES WireGuard-Interface auf ap1.** Cloudflare Mesh spricht WireGuard,
RouterOS kann natives WireGuard (der TP10-Hub *ist* schon einer). Ein Mesh-Node wird als WG-Peer zu einem
CF-PoP registriert — **kein Container, kein TUN, kein LXC, keine neue HW.** Erfüllt „ap1 = einziger SPOF"
am besten, keine macvlan-Blindheit (ap1 routet alle VLANs nativ L3), ICMP/TCP/UDP nativ.
Quelle/Vorlage: animmouse „Setup Cloudflare WARP Connector on MikroTik" + „Setup Cloudflare Mesh using WireGuard".
Ehrliche Einschränkung: **von uns noch nicht gebaut** — starker, technisch schlüssiger Lead; echter Beweis = bauen+pingen.
## 3. Ist-Stand Account (gemessen 2026-07-16, read-only)
- Team-Domain: **`emsenhuber.cloudflareaccess.com`** → Mesh-Node-Identität = `warp_connector@emsenhuber.cloudflareaccess.com`
- **Noch KEIN** `warp_connector`-Tunnel im Account (`GET /accounts/…/warp_connector` = []).
- Device-Settings: **`use_zt_virtual_ip: false`** (Unique-Device-IP AUS — muss für Mesh AN).
- Split-Tunnel-Modus = **Exclude**; Exclude-Liste enthält u.a. **`100.64.0.0/10`** (schluckt die Mesh-Overlay-Range
`100.96.0.0/12` → Mesh-Traffic würde aktuell NICHT durch WARP gehen). Enthält NICHT `10.0.0.0/8` → deshalb geht
`10.40.0.0/16` schon heute über WARP (= warum TCP funktioniert).
- vnet-Route `10.40.0.0/16` (vnet `1480b545…`, Route-ID **`5546dcb6-5901-4da6-8d91-b17f94703f71`**) zeigt aktuell
auf **cfd_tunnel `bf-pve`** (`f7fdf3a6…`). Das bleibt der **Fallback**, bis Mesh bewiesen ist — nichts vorher löschen.
- ap1-WireGuard IST-Stand: 1 Interface `wg-hub` (listen 51821, MTU 1412), Peers `fm` (10.101.0.0/24) + `dw` (10.95.10.0/24).
Das neue Mesh-Interface ist **separat** (outbound zum CF-PoP, kein Listen-Port) → keine Kollision.
## 4. Runbook (nächste Session — Reihenfolge)
### 4.0 Plan-Probe (billig, reversibel) — ZUERST
`POST /accounts/{account_id}/warp_connector {name:"bf-ap1-mesh"}` via `CF_API_TOKEN` (curl/Bearer — der `cloudflare`-
MCP ist read-only, s. §11 der Mapping-Doc). Erfolgt der Create → Mesh ist im Free-ZT-Plan erlaubt. Scheitert er mit
Plan-/Auth-Fehler → **Stopp, Fallback = LXC-auf-pve-WARP-Connector** (alter Plan, ebenfalls dokumentiert).
Token danach: `GET /accounts/…/warp_connector/{tunnel_id}/token` → das ist das `eyJhIjoi…In0=`-Register-Token.
### 4.1 CF-Prerequisites setzen (⚠️ account-weit, trifft LIVE-Geräte → 1× kurzer WARP-Reconnect einplanen)
1. **Unique Device IP AN:** `PATCH /accounts/…/devices/settings {use_zt_virtual_ip:true}` (Dashboard: Team & Resources →
Devices → Management → „Assign a unique IP address to each device").
2. **„Allow all Cloudflare One traffic to reach enrolled devices" AN** (gleiche Seite).
3. **Device-Profile „Cloudflare Mesh"** anlegen: Match `identity.email == warp_connector@emsenhuber.cloudflareaccess.com`,
Tunnel-Protokoll = **WireGuard** (`POST /accounts/…/devices/policy`).
4. **Split-Tunnel-Exclude anpassen** (`PUT /accounts/…/devices/policy/exclude` — ⚠️ ersetzt die GANZE Liste, erst GET,
dann editiert zurückschreiben): `100.64.0.0/10` **raus**, dafür `100.64.0.0/11` + `100.112.0.0/12` **rein**
(= 100.64/10 minus 100.96/12 → Mesh-Overlay `100.96.0.0/12` läuft nun durch WARP statt als „local" behandelt zu werden).
### 4.2 WireGuard-Config extrahieren (einmalig, ephemer)
Auf macmini oder pve (Docker vorhanden):
```
docker run --rm -v $(pwd):/app/output ghcr.io/animmouse/wgcf-connector <REGISTER_TOKEN>
```
→ erzeugt `wgcf-connector-<id>.conf` mit: **PrivateKey**, **Address** (`100.96.x.y/32`), Peer-**PublicKey**
(= CF-Wellknown `bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=`), **Endpoint** (`162.159.193.x:2408`).
Registriert den Node via CF-API (macht Netz-Call), läuft danach nie wieder. **PrivateKey nach `mcp/cloudflare/.env`
o. `~/.secrets`** (nicht committen).
### 4.3 ap1 nativ konfigurieren (MikroMCP: `plan_changes` dryRun → `apply_plan`)
```
/interface wireguard add name=cf-mesh mtu=1420 private-key="<PrivateKey aus .conf>"
/interface wireguard peers add interface=cf-mesh name=cf-pop \
public-key="bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=" \
endpoint-address=162.159.193.1 endpoint-port=2408 \
allowed-address=0.0.0.0/0,::/0 persistent-keepalive=25s
/ip address add address=<100.96.x.y>/32 interface=cf-mesh
/ip route add dst-address=100.96.0.0/12 gateway=cf-mesh
```
- Endpoint: falls die Config `162.159.192.x` liefert → `162.159.193.x` nehmen (Latenz-Tuning laut Guide).
- MTU 1420 aus dem Guide; gegen unsere Hub-MTU 1412 gegenprüfen (ggf. angleichen bei Path-MTU-Problemen).
- **Kein** Extra-Static-Route für den Rückweg nötig (anders als der LXC-Plan): ap1 IST der L3-Router aller VLANs.
- Firewall: forward ist aktuell permissiv (TP5-Deny offen) → kein neues Loch nötig; falls doch ein Drop greift,
gezielte Accept `100.96.0.0/12 ↔ 10.40.0.0/16` dokumentiert ergänzen.
- ⚠️ **Governance:** „Config nur via Nautobot" (TP21) → diese ap1-Zeilen entweder über Nautobot GC abwickeln
oder als vom User genehmigte Ausnahme dokumentieren (Nachtrag in GC als Follow-up).
### 4.4 Subnetz-Route + vnet-Route umziehen
- Im Mesh-Node **`10.40.0.0/16` als CIDR-Route** announcen (Dashboard Networks → Routes: Node = neuer Mesh-Tunnel,
oder API).
- vnet-Route `5546dcb6…` von `bf-pve` auf den **neuen `warp_connector`-Tunnel** umhängen:
`PATCH /accounts/…/teamnet/routes/5546dcb6… {tunnel_id: <warp_connector_id>}`.
- **Rollback jederzeit:** PATCH zurück auf `f7fdf3a6…` (bf-pve) — cloudflared/bf-pve bleibt die ganze Zeit bestehen.
### 4.5 Verifikation (Abnahme)
- MacBook, WARP **connected**: `ping 10.40.20.105`, `ping 10.40.10.1`, `ping 10.40.99.12` → **verlustfrei**
(Regressions-Gegenprobe zu heute: fm 36 % / bf 100 %).
- TCP-Gegenprobe inkl. NAS-macvlan-IP direkt: `ssh 10.40.20.167`, `https://10.40.20.100:8006`, `10.40.20.157:3000`
(gitea) mehrfach → Beweis „keine Blindheit".
- FQDN-Smoke (Stichprobe gitea/hass/pve über `*.emsenhuber.net`) → der cloudflared-Public-Teil (3-Tunnel-HA) blieb unberührt.
## 5. Danach (Cleanup, teils ins „vertagt"-Gespräch)
- Nach Mesh-Beweis: `warp-routing` auf bf-nas/bf-pve/bf-mm ggf. auf `false` (Hygiene — Public-Tunnel bedienen keine
privaten Netze mehr). CF-vnet-Route-Historie bereinigen.
- **Vertagt (User „müssen wir noch reden, hat Zeit"):** 4 tote Tunnel (TeilzeitCharlie/coolify/johnny2/openclaw),
Ghost-Connector-Session bf-pve (arm64-Leiche vom 12.07.), `gateway-dw`-CNAME.
## 6. Risiken / Fallbacks
- Einziger Eingriff mit Nutzer-Impact = vnet-Route-Umzug → Rollback = 1 PATCH zurück auf bf-pve.
- CF-Prerequisites sind account-weit (Unique-IP-ReIP, Split-Tunnel) → 1× kurzer WARP-Reconnect; alle reversibel.
- Plan-Gate: wenn `warp_connector`-Create scheitert → LXC-auf-pve-WARP-Connector als Fallback (TUN-Passthrough
`c 10:200 rwm`, `warp-cli connector new`, ap1-Static-Route `100.96.0.0/12`→LXC).
- ax³/ZeroTier/Tailscale = separate Eval-Fußnoten, nicht Teil dieses Fixes.