Files
bf-infra/docs/cf-tunnel-mapping.md
Christoph Emsenhuber 17c8fd0d24 docs 📄 TP16: bf-nas als eigener Tunnel nachgezogen (Legacy-Monolith gelöscht) + hass-400 prĂ€zisiert
- bf-nas neu = 220c9958 (frisch, config_src=cloudflare); Ingress 1:1, 8 CNAMEs
  umgebogen, 2 Connectoren (pve host-net / macmini bridge).
- WARP-Route 10.40.0.0/16 via PATCH teamnet/routes tunnel_id umgezogen
  (sonst DELETE-Block 1023 "private network routes").
- Legacy 70d6a4cf/bf.emsenhuber.net GELÖSCHT; .env CF_BF_TUNNEL_ID aktualisiert.
- Writes nur via CF_API_TOKEN (CF-MCP OAuth = read-only).
- hass-400 = rein Origin-Layer (hass/vw/gitea sind bypass): HA trusted_proxies
  fehlt .20.10/.20.167 → use_x_forwarded_for + IPs + Restart (user-gated, kein SSH).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 20:36:37 +02:00

289 lines
23 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.
# Cloudflare-Tunnel — Mapping & #1033-Diagnose (Single Source of Truth)
> **Aktueller Stand: → §10 (2026-07-10, TP16 UMGESETZT ✅).** §9 = Analyse/Zielbild, §10 = As-Built.
> Abschnitte 1–8 sind Historie (Track A, 2026-06-30); die „3 Connectors gut/Zielbild"-Aussagen dort sind
> durch §9/§10 **ĂŒberholt** (Round-Robin = macvlan-Host-Isolation → 1/N-AusfĂ€lle). Track A aus `docs/handoff-cf-tunnel-1033.md`.
## 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.
---
## 10. AS-BUILT 2026-07-10 (TP16 umgesetzt) — reziprokes 3-Tunnel-HA ✅
> Gebaut & verifiziert in eigener Session. Round-Robin-#1033 **strukturell weg** (Loop-Gegentest 0×530 ĂŒber alle 19 Live-FQDNs, HA per Host-Ausfall-Sim bewiesen). Schritte 1–4+HA durch; **Schritt 5 (Access/WARP + `vw`) offen** (user-gated).
### 10.1 Reachability-Matrix (die Basis, read-only gemessen)
Einzige Blindheit im System: **NAS-Connector (host-net) ↔ NAS-Docker-macvlan** (Kernel-Isolation). Alles andere cross-host-L2 / inter-VLAN-geroutet erreichbar.
- **NAS-`vlan20` = macvlan** (parent `ovs_eth0`): gitea `.157`, grafana `.109`, pve-mcp `.173`, omada `.175`, vw `.127`, drawio `.139`, prometheus `.151`, iob_slave `.33` → **NAS-Connector blind**.
- **pve-LXC-400-`vlan20` = ipvlan** (parent `veth20`): adguard `.16/.17`, omada-mcp `.176` → pve-Connector blind, aber **keine davon ist Tunnel-Origin** → irrelevant.
- **macmini** = alles Docker-**bridge + Port-Publish** auf `.20.167` → keine Blindheit.
- `ccu .232`=RaspberryMatic(qemu/330), `iobroker .107`=iob-exposed(lxc/150), `z2m25 .106`=lxc/112, `hass/ha-mcp .105`=haos(qemu/100) = **pve-GĂ€ste auf vmbr/VLAN20** → von allen erreichbar (keine Docker-macvlan-Kinder).
- **Ergebnis:** pve **und** macmini erreichen je 100 % der Live-Origins; NUR NAS ist fĂŒr seine 5 eigenen macvlan-Dienste blind. Darum: NAS darf nie bf-nas fahren.
### 10.2 Die 3 Tunnel (config_src=cloudflare, token-managed Ingress)
| Tunnel | ID | Dienste | Connectoren (2/Tunnel) |
|---|---|---|---|
| **bf-nas** ⚠ *ID ĂŒberholt, s. §11* | ~~`70d6a4cf`~~ → **`220c9958-401b-4111-9451-f3db09bba2d5`** (2026-07-12 frisch) | gitea, grafana, pve-mcp, omada, vw, ds-bf, 3k23uow7 (+gateway-dw→404) | **pve + macmini** |
| **bf-pve** (neu) | `f7fdf3a6-
-b0f273794d09` | pve, j44d6tua, ccu, iobroker, z2m25, portainer, hass, ha-mcp | **NAS + macmini** |
| **bf-mm** (neu) | `7a322261-
-8ebce99f5ed1` | n8n, n8n-mcp, gitea-mcp, 82unkpb5 | **pve + NAS** |
Prinzip: **jeder Host-Dienst wird von den Connectoren der ANDEREN Hosts bedient** → Host-Ausfall lĂ€sst jeden Tunnel ≄1 Connector = voll HA. Innerhalb eines Tunnels kein Route-Pinning (CF round-robined) — aber beide Connectoren erreichen 100 % → Round-Robin schadet nicht.
### 10.3 Connector-Roster (6 = 2/Host, Docker `cloudflare/cloudflared:latest`, `restart=unless-stopped`)
| Host (Portainer ep) | Container | Tunnel | Netz |
|---|---|---|---|
| pve-LXC (ep2) | `cloudflared-bfnas` (c80a7db) · `cloudflared-bfmm` (faa0960) | bf-nas · bf-mm | host |
| NAS (ep14) | `cloudflared-bfpve` (97312b5) · `cloudflared-bfmm` (963217983) | bf-pve · bf-mm | host |
| macmini (ep20) | `cloudflared-bfnas` (5c5b3ba) · `cloudflared-bfpve` (3339f86) | bf-nas · bf-pve | bridge |
Tokens: nur im Container-Env + jederzeit via `GET /accounts/
/cfd_tunnel/<id>/token` (Bearer `CF_API_TOKEN`). Tunnel-IDs in `mcp/cloudflare/.env` (`CF_BF/PVE/MM_TUNNEL_ID`). **Nicht** als Compose-Stacks angelegt (raw Portainer-API-Container) → bei Neuaufbau: Container mit `TUNNEL_TOKEN=<token>` + `tunnel --no-autoupdate run`.
### 10.4 As-built Verifikation
- Loop-Smoke 19 FQDNs ×5: **0×530**. gitea/omada/vw/ds-bf/pve/portainer/ccu/iobroker/z2m25/n8n/n8n-mcp/82unkpb5 = 200; grafana 302 (Access); pve-mcp 400 (MCP-Handshake); hass 400 / ha-mcp 403 (Access davor, s. Schritt 5); gitea-mcp 404 (App-Pfad).
- HA-Sim: macmini-Host down → bf-nas via pve (4 conns), bf-pve via NAS (4 conns), bf-mm unberĂŒhrt (8) — alle Dienste weiter 200. Restore → alle 3 Tunnel 8 conns.
### 10.5 Cleanup gemacht
- Tote CNAMEs gelöscht: `pbs`, `nginx-bf`, `hermes`, `hermes-geli`. NAS-cloudflared-Leichen `oc-tzcharlie`/`oc-johnny2` entfernt.
- `gateway-dw` (192.168.178.1, nur via WG) bleibt CNAME→bf-nas = **404** (kein BF-Connector hat die WG-Route). **Offen: klĂ€ren/entfernen.**
### 10.6 Schritt 5 Access-Strang — TEILWEISE ✅ (2026-07-10)
**✅ `vw`-Leck geschlossen:** vw-App (`1dbc45ca`) hatte 1 Policy = **bypass/everyone (öffentlich)**. Ersetzt durch 2 eigene (engere als die Wildcard!) Policies: `non_identity bf4-home-ip` (`90.146.35.38/32` = Heim ohne Login) + `allow christoph` (email `christoph@emsenhuber.com`, **kein** `login_method:*`). Bypass war eine **reusable** Policy `a8129e37` → nicht via App/Policies-DELETE löschbar, sondern per **App-PUT detacht** (nur die 2 neuen im `policies`-Array). Verifiziert: Heim = 200, kein `everyone` mehr; Account-weiter Sweep = **keine** App mehr öffentlich. Heim-IP `90.146.35.38` = aktuell (== bf4-DNS).
**🔮 NEUER FUND (wichtiger als vw!) — Wildcard `*.emsenhuber.net` (`16aaec78`) zu offen:** Policy `christoph` hat `include: email:christoph OR login_method:github OR login_method:google`. **`login_method:<idp>` als include matcht JEDEN, der sich via GitHub/Google einloggt** — nicht nur christoph. D.h. **jeder GitHub-/Google-User erreicht nach Login alle internen Dienste** (hass, grafana, portainer, pve, gitea, 
). Fix = die zwei `login_method`-Includes raus (nur `email:christoph` + ggf. weitere erlaubte Mails + `non_identity bf4` + `claude-mcp`). **NICHT einseitig geĂ€ndert** (Ă€ndert Login-Verhalten ĂŒberall) → User-Entscheidung. War im Memory schon als „Policy christoph verschlanken" geflaggt.
**⏞ `hass` 400 / `ha-mcp` — zwei getrennte Layer:**
- **Access-Layer (remote):** HA-Companion-App kann kein interaktives Access-Login → Fix = iPhone in **WARP** enrollen (`Warp Login App` `6c32fe23` `allow:christoph` existiert → christoph darf enrollen). Client-seitig, braucht User am GerĂ€t. Vom Heim-Netz (bf4-IP) ohnehin ohne Login erreichbar.
- **Origin-Layer:** `hass.emsenhuber.net` gibt **vom Heim-Netz** (Access passt via bf4-IP) trotzdem **400** (CF `server:cloudflare`, aber Origin-verursacht) = **HA lehnt den Request ab** — HA-`http:`-Config (`use_x_forwarded_for` + `trusted_proxies` inkl. cloudflared-Range, ggf. Host-Allowlist). **Separates HA-Thema, NICHT Tunnel/Access** — offen.
**gateway-dw** (192.168.178.1, nur via WG) = CNAME→bf-nas = 404 (kein BF-Connector hat WG-Route). Offen: Route bauen oder CNAME entfernen.
---
## 11. Nachtrag 2026-07-12 — bf-nas als EIGENER Tunnel nachgezogen ✅
§10 hatte bf-nas noch als **wiederverwendeten Legacy-Monolith** `70d6a4cf` (Name „bf.emsenhuber.net") gefahren. Jetzt sauber getrennt:
- **Neuer Tunnel `bf-nas` = `220c9958-401b-4111-9451-f3db09bba2d5`** (config_src=cloudflare, Ingress 1:1 kopiert). 2 Connectoren neu: pve `cloudflared-bfnas` (host-net), macmini `cloudflared-bfnas` (`cloudflared_default` bridge).
- **8 CNAMEs** (gitea/grafana/pve-mcp/omada/vw/ds-bf/3k23uow7/gateway-dw) auf den neuen Tunnel umgebogen.
- **WARP-Route `10.40.0.0/16`** (vnet `1480b545-
`) via `PATCH /accounts/
/teamnet/routes/{id}` `{tunnel_id}` umgezogen — **sonst Block:** DELETE-Tunnel scheitert mit `1023 „private network routes"`.
- **Legacy-Tunnel `70d6a4cf`/`bf.emsenhuber.net` GELÖSCHT.** `mcp/cloudflare/.env CF_BF_TUNNEL_ID` = neue ID.
- Zero-downtime: neue Connectoren parallel hoch → CNAMEs → alte Container/Tunnel weg. Verifiziert: gitea/omada/vw/ds-bf 200, grafana 302, pve-mcp 400 (MCP-Bare-GET), bf-nas 2 Connectoren healthy.
- **Writes gehen NUR ĂŒber `CF_API_TOKEN` (curl/Bearer)** — der `cloudflare`-MCP (OAuth) ist read-only (Create-Tunnel → `10000 Authentication error`).
**hass-400 (2026-07-12 prĂ€zisiert):** `hass`/`vw`/`gitea` sind aktuell wieder auf **`bypass`** (App „hass, vw, gitea") → der 400 ist **rein** der Origin-Layer, **nicht Access**. HA-Log: „Received X-Forwarded-For header from an untrusted proxy **10.40.20.10**". Die reziproken bf-pve-Connectoren (macmini `.20.167`, NAS `.20.10`) fehlen in HAs `http.trusted_proxies`. **Fix** = beide IPs + `use_x_forwarded_for: true` + Core-Restart. **Kein SSH-Key auf HA `.20.105` → user-gated** (oder Zugang geben). Access-HĂ€rtung (bypass→WARP) bleibt der zweite, device-gated Schritt.