Files
bf-infra/docs/cf-tunnel-mapping.md
Christoph Emsenhuber 884e51edd6 docs 📄 TP16 turnkey: CF-Tunnel Round-Robin=macvlan-Host-Isolation → reziprokes HA (Umsetzung eigene Session)
Root-Cause endgültig (User-Diagnose bestätigt): ein cloudflared ist blind NUR
für macvlan/ipvlan-Container auf seinem EIGENEN Host → mehrere Connectoren auf
1 Tunnel + Round-Robin = 1/N garantierte 1033 ("jeden 3. Schuss eine Niete").
Kein Route→Connector-Pinning innerhalb eines Tunnels → HA nur über getrennte
Tunnel: reziprokes Per-Host-Design (jeder Dienst von den anderen Hosts bedient,
3 Tunnel/2 cloudflared je Host = voll HA gegen Single-Host-Ausfall).

- cf-tunnel-mapping.md §9: Invariante + Live-Inventory v119 (Access-Modi,
  DOWN-Origins pbs/nginx-bf/hermes×2) + Ziel-Design + Umsetzungsreihenfolge;
  Abschnitte 1-8 als Historie markiert.
- teilprojekte.md TP16 umgeschrieben: Root-Cause, reziprokes HA, Access-Strang
  (hass-400=CF-Access→WARP, vw=bypass→schützen), Status "dokumentiert,
  Umsetzung = eigene Session".
- Reine Doku, keine Tunnel-/DNS-/Container-Änderung.

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

15 KiB
Raw Blame History

Cloudflare-Tunnel — Mapping & #1033-Diagnose (Single Source of Truth)

Aktueller Stand: → §9 (2026-07-10, TP16). Abschnitte 1–8 sind Historie (Track A, 2026-06-30); die „3 Connectors gut/Zielbild"-Aussagen dort sind durch §9 überholt (Round-Robin = macvlan-Host-Isolation → 1/N-Ausfälle). Track A aus docs/handoff-cf-tunnel-1033.md. TP16 = Analyse turnkey, Umsetzung eigene Session.

1. Alle Tunnel im Account (393c…66c36)

Tunnel ID Status Conns Verwendung
bf.emsenhuber.net 70d6a4cf-…-91fab4fa7270 healthy 12 (=3 Connectors) BF-Dienste — relevant
fm.emsenhuber.net b697d124-…-384cced4db1a healthy 4 (1 Connector) FM-Standort (nas-fm), separat
TeilzeitCharlie 6c784c98-… down 0 tot
coolify 4f54ad8a-… down 0 tot
johnny2 acc73eb5-… down 0 tot
openclaw 7a8f7b53-… down 0 tot (odroid-m1, offline)

2. bf-Tunnel — die 3 Connectors (Round-Robin!)

Fingerprint via Colo-Locations (CF-API ↔ lokale cloudflared-Logs) + Arch. Wichtig: DS923+ = AMD Ryzen = amd64; macmini = Apple Silicon = arm64.

CF-Connector arch Host (Portainer) LAN-IP Docker-Netz Vantage
1856dfc3-… arm64 macmini (ep20) 10.40.20.167 bridge cloudflared_default VLAN20
db713b30-… amd64 pve-LXC (ep2) 10.40.20.126 host VLAN20 (TP14.2 2026-07-10 → #1033-Zielbild)
d7454e68-… amd64 nas-bf DS923 (ep14) 10.40.41.10 host VLAN1/.41

Alle 3 fahren denselben Tunnel-Token (tunnel run, token-managed Ingress im Dashboard). CF round-robined Requests über alle 3 → jeder Origin muss von allen 3 Vantages erreichbar sein, sonst sporadisch 1033.

Leichen auf dem NAS (exited, harmlos, aufräumen): oc-tzcharlie-cloudflared, oc-johnny2-cloudflared.

3. Ingress (token-managed, v104) — Reachability je Connector

Quelle: macmini aktiv geprobt; pve/NAS aus echten cloudflared-Fehler-Logs (tail 2000). OK = erreichbar, FAIL = no route / down, ? = nicht beobachtet (vermutl. OK).

Hostname Origin pve NAS macmini Befund
pve https://10.40.41.100:8006 OK ? OK ok
hass http://10.40.41.105:8123 OK FAIL OK NAS no-route (sporadisch)
ha-mcp http://10.40.41.105:9583 OK FAIL? OK wie hass
pbs https://10.40.41.135:8007 ? ? FAIL macmini no-route
n8n http://10.40.41.167:5678 FAIL FAIL FAIL .167 STALE (Host weg)
mcp-ms365 http://10.40.41.167:3005 FAIL FAIL FAIL .167 STALE
hermes http://10.40.41.167:9119 FAIL FAIL FAIL .167 STALE
gitea-mcp http://10.40.41.167:3000 FAIL FAIL FAIL STALE → läuft auf 10.40.20.167:3000
n8n-mcp http://10.40.41.167:3001 FAIL FAIL FAIL STALE → läuft auf 10.40.20.167:3001
82unkpb5 (ssh) ssh://10.40.41.167:22 FAIL FAIL FAIL STALE → macmini 10.40.20.167:22
vw http://10.40.41.127:80 OK FAIL (1736×) FAIL pve-lokaler Container — nur pve erreicht
ccu http://10.40.41.232:80 OK ? OK wahrsch. pve-lokal
iobroker http://10.40.41.19:8080 ? FAIL FAIL nur pve? prüfen
gateway-dw http://192.168.178.1 ? ? FAIL DW-Netz, nur über WG — kein BF-Connector hat die Route
gitea http://10.40.41.157:3000 OK ? OK ok (macmini transient)
nginx-bf http://10.40.41.123:81 OK ? OK ok
ds-bf http://10.40.41.10:8080 OK OK OK ok
portainer https://10.40.20.126:9443 OK OK OK TP14.2: Origin .41→.20.126; Tunnel-Smoke 200
grafana http://10.40.41.109:3000 ? ? OK ok
pve-mcp http://10.40.41.173:3000 ? ? OK ok
gateway-bf http://10.40.41.254 OK ? OK ok (FB)
j44d6tua (ssh) ssh://10.40.41.100:22 OK ? OK ok
3k23uow7 (ssh) ssh://10.40.41.10:22 OK OK OK ok
(catch-all) http_status:404 — — — —

4. DNS-Probleme (Zone emsenhuber.net, 1b5bc02f…)

Orphan-CNAME → bf-Tunnel, aber KEINE Ingress-Regel → 404:

  • mcp-qdrant.emsenhuber.net, ssh-nasbfnew.emsenhuber.net

CNAME → tote/gelöschte Tunnel → konstante 1033:

  • oc, dashboard, drawio → openclaw (down)
  • jc → johnny2 (down) · charlie → TeilzeitCharlie (down) · coolify → coolify (down)
  • oc2 → d8df70a7…, oc3 → 3702dc6e…, win11test → de818071… — Tunnel existiert nicht mehr

(FM-Tunnel-CNAMEs ds-fm/gateway-fm → b697d124… healthy = ok, separat.)

5. Root-Cause #1033 (zusammengefasst)

  1. 3 Connectors mit asymmetrischer Reachability + Round-Robin = sporadisch 1033 (Kernursache, log-bewiesen).
  2. pve-lokale Container (vw .127, ccu .232) nur vom pve-Connector erreichbar (macvlan, kein LAN-Route von NAS/macmini).
  3. Stale Origin .41.167: macmini nach VLAN20 (10.40.20.167) gewandert → 5 Dienste zeigen ins Leere.
  4. gateway-dw braucht WG-Route — kein BF-Connector hat sie.
  5. DNS-Müll: 9 CNAMEs auf tote Tunnel (konstante 1033) + 2 Orphans (404).

6. Fix-Plan (gestaffelt — Freigabe nötig)

Stufe 1 — Sofort-Entschärfung — ✅ ANGEWENDET 2026-06-30:

  • bf-Tunnel auf nur pve-Connector reduziert (NAS ep14 + macmini ep20 cloudflared gestoppt, reversibel via start).
  • Verifiziert: Tunnel healthy, 1 Connector (db713b30/pve). Smoketest vw 4×200 (vorher 1736 Fehlversuche), hass/portainer 302. Kein 1033 mehr.

Stufe 2 — Stale-Origins fixen (Dashboard-Ingress) — OFFEN, braucht Entscheidungen: Die .167-Dienste laufen real auf dem macmini (ep20, VLAN20 10.40.20.167) — aber uneinheitlich:

  • gitea-mcp → 10.40.20.167:3000 ✓ · n8n-mcp → 10.40.20.167:3001 ✓ · 82unkpb5 ssh → 10.40.20.167:22 ✓ (saubere Host-Ports)
  • n8n (n8nio/n8n): kein Host-Port (pub=[]) → nur im Docker-Netz, von pve NICHT routbar. Entscheidung: Port publishen ODER macmini-lokalen Connector ODER stilllegen.
  • hermes: 2 Instanzen — hermes-christoph 10.40.20.167:8642, hermes-geli 10.40.20.167:8643. Ingress-Port 9119 obsolet → klären, welche hermes.emsenhuber.net bedienen soll.
  • mcp-ms365: auf keinem Host gefunden → Ingress + DNS entfernen?
  • ⚠️ Vor Repoint zu verifizieren: erreicht der pve-Connector (.41.126, FB-Default-GW!) überhaupt VLAN20 (.20.167)? → beim Apply per Smoketest prüfen, sonst Rollback.

Stufe 3 — DNS-Hygiene:

  • Tote CNAMEs löschen: oc,oc2,oc3,win11test,jc,charlie,coolify,dashboard,drawio.
  • Orphans mcp-qdrant,ssh-nasbfnew: Ingress-Regel ergänzen oder CNAME löschen.
  • NAS-Leichen oc-tzcharlie/oc-johnny2 entfernen.

7. CHANGE-SET — ✅ KOMPLETT 2026-06-30

Zugang über scoped API-Token in mcp/cloudflare/.env (OAuth-MCP blieb read-only). A1 + A2 + A3 alle angewendet. Endzustand: Tunnel healthy/1 Connector (pve), Ingress v106, 23 Ingress-Hostnames ↔ 23 DNS-CNAMEs, keine Waisen, keine CNAMEs auf tote Tunnel.

✅ Erledigt

  • A1: n8n-Compose-Port 10.40.41.167→10.40.20.167 (Stack 174 redeploy, Volume/Encryption-Key erhalten, /healthz 200). NAS-Leichen oc-tzcharlie/oc-johnny2 entfernt.
  • A2 (Ingress v106): gitea-mcp/n8n-mcp/82unkpb5/n8n/hermes → .20.167; hermes-geli (:8643) neu; mcp-ms365 entfernt. Keine .41.167-Origins mehr. pve→VLAN20 verifiziert (n8n-mcp 200 via bf4).
  • App-Level-Notizen (kein 1033): gitea-mcp 404 auf / (Sub-Pfad?), hermes 502 (Origin .20.167:8642 erreicht, App liefert 502) — separat prüfen.

✅ A3 (DNS) erledigt

  • hermes-geli CNAME → 70d6a4cf….cfargotunnel.com (proxied) angelegt → jetzt erreichbar (302).
  • Gelöscht: oc,oc2,oc3,win11test,jc,charlie,coolify,dashboard,drawio,mcp-ms365, mcp-qdrant,ssh-nasbfnew.
  • Konsistenz verifiziert: 23↔23, keine Orphans, keine toten Tunnel-Verweise.

Ursprünglicher Plan (Referenz)

A. Portainer (Write vorhanden — kann sofort, careful):

  • macmini n8n-Container mit -p 5678:5678 neu erstellen (Volumes/ENV erhalten!) → Origin 10.40.20.167:5678.
  • NAS-Leichen entfernen: oc-tzcharlie-cloudflared, oc-johnny2-cloudflared (exited).

B. Tunnel-Ingress 70d6a4cf… (PUT /configurations) — Ziel-Origins:

Hostname NEU alt
gitea-mcp http://10.40.20.167:3000 .41.167:3000
n8n-mcp http://10.40.20.167:3001 .41.167:3001
82unkpb5 (ssh) ssh://10.40.20.167:22 .41.167:22
n8n http://10.40.20.167:5678 .41.167:5678 (nach A)
hermes http://10.40.20.167:8642 .41.167:9119
hermes-geli (NEU) http://10.40.20.167:8643 —
mcp-ms365 Regel löschen .41.167:3005

⚠️ Vor B: pve→VLAN20-Reachability per Smoketest verifizieren (1 Repoint, extern testen, sonst Rollback — pve hat FB-Default-GW).

C. DNS (Zone 1b5bc02f…) — CNAMEs löschen:

oc, oc2, oc3, win11test, jc, charlie, coolify, dashboard, drawio, mcp-ms365. Neu anlegen: hermes-geli.emsenhuber.net CNAME → 70d6a4cf-aa1d-4a91-b918-91fab4fa7270.cfargotunnel.com (proxied). Orphans mcp-qdrant, ssh-nasbfnew: ohne Ingress → löschen (oder Ingress ergänzen, falls Dienst gewünscht — offen).

Stufe 4 — Zielbild (überlappt Track C / IP-Migration):

  • Origins auf konkret routbare IPs in VLAN20 konsolidieren, dann HA-Connector-Paar (z.B. pve + NAS) beide in VLAN20, sodass jeder Connector jede Origin erreicht. gateway-dw über WG-fähigen Connector lösen.
  • TP5-Firewall ZULETZT (erst wenn alle Origins/Connectors in VLAN20).

8. Update 2026-07-09 — NAS→VLAN20-Cutover + Ingress v116

Nach NAS-DSM-Cutover auf 10.40.20.10 und Docker-Migration auf ein Macvlan vlan20 (alle NAS-Container jetzt 10.40.20.x, s. docs/nas-vlan20/):

Ingress v115→v116 (via scoped Token, cf_repoint): 6 Origins .41→.20 repointet — ha-mcp .105:9583, 3k23uow7(NAS-ssh) .10:22, gitea .157, vw .127, grafana .109, pve-mcp .173. Keine .41-Stale unter den migrierten Hosts mehr. Bleibt .41: pve .100, j44d6tua .100, portainer .126, nginx-bf .123, gateway-bf .254.

Connector-Reachability — geklärt (kein Routing-Problem): Der pve-Connector .41.126 erreicht VLAN20 — vw.emsenhuber.net → 200 über den Tunnel (Vaultwarden .20.127 läuft). ap1 macht das Inter-VLAN-Routing VLAN1↔VLAN20, das steht. Ein 502 direkt nach dem Ingress-PUT war transient (Connector-Origin-Cache/ARP noch nicht warm), verschwindet nach kurzer Zeit. grafana 502 = Container exited (starten → geht). Kein pve-Static-Route nötig.

Bleibt offen (Stufe 4, Connector-Vantage — nicht dringend): Round-Robin-Asymmetrie #1033, falls mehrere Connectors aktiv: macmini (.20.167, VLAN20) erreicht NAS-Macvlan, scheitert aber an pve-lokalen Origins/pbs/gateway-dw; NAS-eigener host-net-Connector taugt nicht (Host↔eigene-Macvlan- Isolation). Zielbild = ein Connector, der alles erreicht — löst sich weitgehend von selbst, sobald pve (+ Connector) mit dem PVID1-Cutoff in VLAN20 wandert (dann sind Origins+Connector im selben L2).


9. Ist-Inventory & Endanalyse 2026-07-10 (TP16) — SSoT-Stand

⚠️ Die „3 Connectors sind gut/Zielbild"-Framings der Abschnitte 2/6/8 oben sind überholt — maßgeblich ist dieser Abschnitt. Analyse turnkey; Umsetzung = eigene Session (User-Entscheidung).

9.1 Invariante (die Regel, an der alles hängt)

  • Ein cloudflared-Connector ist blind NUR für macvlan/ipvlan-Container auf seinem EIGENEN Host (Linux-Kernel: Host ↔ eigene macvlan/ipvlan-Children isoliert). Fremdhost-L2 + co-lokierte Bridge-Container erreicht er sehr wohl.
  • Mehrere Connectoren auf EINEM Tunnel = geteilter Ingress + CF-Round-Robin. Jede Origin, die auf dem Host eines Connectors als macvlan/ipvlan liegt, fällt bei ~1/N der Requests aus (#1033, „jeden 3. Schuss eine Niete"). Strukturell — nicht durch „Origins fixen" heilbar, solange ein Connector Origins seines eigenen Hosts bedient.
  • Kein Route→Connector-Pinning INNERHALB eines Tunnels. „Ausgewählte Routen für ausgewählte Connectoren" gibt es nur über getrennte Tunnel (CNAME → jeweiliger Tunnel; pro Tunnel eigene Connectoren).

9.2 Live-Inventory (gemessen 2026-07-10, Ingress v119, 24 Hostnames + catch-all, 2 live Connectoren b797ee1b/f480dc69)

CF-Access: vw = bypass (ÖFFENTLICH!) ⚠️ · hass & Rest geschützt via Wildcard *.emsenhuber.net (allow:christoph / non_identity:bf4 / allow:claude-mcp).

Hostname Origin Live Host/Netz (zu verifizieren)
pve / j44d6tua(ssh) .41.100:8006 / :22 UP Proxmox-Host (VLAN1)
hass / ha-mcp .20.105:8123 / :9583 UP HA-Host .105
pbs .20.135:8007 DOWN Proxmox Backup Server
n8n / hermes / hermes-geli / gitea-mcp / n8n-mcp / 82unkpb5(ssh) .20.167:* n8n/mcp UP · hermes+hermes-geli DOWN macmini
portainer .20.126:9443 UP pve-LXC (host-net)
nginx-bf .41.123:81 DOWN noch VLAN1!
ds-bf / 3k23uow7(ssh) .20.10:8080 / :22 UP NAS-Host
gitea / grafana / pve-mcp .20.157 / .20.109 / .20.173 UP NAS-macvlan (NAS-Connector-blind)
omada .20.175:8043 UP NAS-macvlan (NAS-Connector-blind)
ccu / vw / iobroker / z2m25 .20.232 / .20.127 / .20.107:8081 / .20.106:8080 UP Host/Netz unklar → messen
gateway-dw 192.168.178.1 — nur via WG (kein BF-Connector hat Route)

9.3 Ziel-Design: reziproke Per-Host-Tunnel (HA)

Jeder Host-Dienst wird von den Connectoren der anderen Hosts bedient (nie vom eigenen), gegenseitig:

Tunnel (= Dienste eines Hosts) Connectoren auf HA
pve-Dienste NAS + macmini 1 abdrehbar
NAS-Dienste (omada/pve-mcp/gitea/grafana/…) pve + macmini 1 abdrehbar
macmini-Dienste (.20.167) pve + NAS 1 abdrehbar

3 Tunnel, jeder Host fährt 2 cloudflared (für die 2 anderen Tunnel) → Host-Ausfall ⇒ jeder Tunnel ≥1 Connector = voll HA. Der macmini ist vollwertiger dritter Knoten (nicht „vergessen").

9.4 Umsetzungs-Reihenfolge (eigene Session)

  1. Reachability-Matrix je Host (pve/NAS/macmini → jede der 24 Origins, read-only) — klärt v.a. vw/ccu/iobroker/z2m25 (Bridge nur-eigener-Host? macvlan? ipvlan-auf-pve → dann pve-blind!). Ergebnis bestimmt die Tunnel-Gruppierung.
  2. Interim-Sofortfix: bf-Tunnel auf pve-only (pve erreicht alles außer gateway-dw) → 0×1033. Reversibel.
  3. Reziprokes 3-Tunnel-HA bauen: 3 Tunnel anlegen, ~24 CNAMEs re-pointen, 6 Connectoren (2/Host, je eigenes Token), Alt-Token aus NAS/macmini-cloudflared entfernen. vw/ccu ggf. auf VLAN20-macvlan heben (dann L2-erreichbar).
  4. Tote Origins bereinigen: pbs, nginx-bf (noch .41!), hermes, hermes-geli.
  5. Access-Strang (Track B): hass-400 ohne Passthrough → iPhone in WARP enrollen; vw von bypass → geschützt.
  6. Loop-Gegentest aller FQDNs (0×1033), gateway-dw als WG-Sonderfall klären/entfernen.