From 2e13594bd58635fdba5126702b03c27eb2a92397 Mon Sep 17 00:00:00 2001 From: Christoph Emsenhuber Date: Fri, 17 Jul 2026 14:38:19 +0200 Subject: [PATCH] =?UTF-8?q?docs=20=F0=9F=94=91=20CF-Zugang=20unmissverst?= =?UTF-8?q?=C3=A4ndlich:=20MCP=20read-only=20vs=20CF=5FAPI=5FTOKEN-Write?= =?UTF-8?q?=20(fix=20fresh-session=20permission-trap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Frische Sonnet-Delegations-Session lief in die '10000 Authentication error'-Falle: sie versuchte CF-Writes über den read-only MCP. Root Cause: .claude.json referenziert nur die MCP-URL, NIE den Token in mcp/cloudflare/.env → kalter Agent kennt den Write-Pfad nicht. - Handoff-Prompt: prominenter 'CF-KOMMUNIKATION'-Block (2 getrennte Pfade, exakte curl- Kommandos, '10000 = kein Rechteproblem, Pfad wechseln'-Hinweis im Ablauf). - cf-tunnel-mapping.md §11: gleiche Klarstellung als SSoT-Callout inkl. Verifikation (no-op vnet-PATCH: MCP→10000, curl→success). 'Claude hat zig Tunnel erstellt' = immer via curl+Token, NIE via MCP. Co-Authored-By: Claude Opus 4.8 --- docs/cf-tunnel-mapping.md | 7 ++++++ docs/tp16.1-session-handoff-prompt.md | 35 +++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/cf-tunnel-mapping.md b/docs/cf-tunnel-mapping.md index 1770208..36beee5 100644 --- a/docs/cf-tunnel-mapping.md +++ b/docs/cf-tunnel-mapping.md @@ -285,6 +285,13 @@ Tokens: nur im Container-Env + jederzeit via `GET /accounts/…/cfd_tunnel// - 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`). +> ⚠️ **CF-Zugang für frische Sessions — die häufigste Stolperfalle (2× reproduziert 2026-07-17):** Es gibt **zwei getrennte** CF-Zugänge, und `~/.claude.json` verweist NUR auf den read-only-MCP (`https://mcp.cloudflare.com/mcp`), **nicht** auf den Write-Token → ein frischer Agent weiß nichts vom Token und meldet fälschlich „fehlende Permissions". +> - **`cloudflare`-MCP** (`mcp__cloudflare__docs/search/execute`, OAuth): **strikt read-only**. Reads/Spec-Suche/Batch super; **jeder** Write → `10000: Authentication error` (erwartet, KEIN echtes Rechteproblem). +> - **`CF_API_TOKEN` in `mcp/cloudflare/.env`** (scoped, `valid & active`): **der Write-Pfad.** Damit wurde das komplette 3-Tunnel-HA gebaut. Verifiziert 2026-07-17 mit identischem no-op-vnet-PATCH: MCP → `10000`, curl+Token → `success:True`. +> - **Muster:** `cd ~/dev/bf-network-r6/mcp/cloudflare && set -a; . ./.env; set +a` → dann `curl -H "Authorization: Bearer $CF_API_TOKEN" …/accounts/$CF_ACCOUNT_ID/`. Keys im .env: `CF_API_TOKEN/CF_ACCOUNT_ID/CF_ZONE_ID/CF_{BF,PVE,MM}_TUNNEL_ID`. +> - Alle Calls über `api.cloudflare.com` → **WARP-unabhängig** (Rollback klappt auch bei totem Privatpfad). +> - **Klarstellung „Claude hat doch zig Tunnel erstellt/geändert":** ja — aber immer über curl+Token, **nie** über den MCP. Der MCP war nie der Write-Pfad. + **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. --- diff --git a/docs/tp16.1-session-handoff-prompt.md b/docs/tp16.1-session-handoff-prompt.md index ff0fa91..5a4260f 100644 --- a/docs/tp16.1-session-handoff-prompt.md +++ b/docs/tp16.1-session-handoff-prompt.md @@ -27,13 +27,35 @@ Weg: nativer WireGuard-Mesh-Node auf ap1 (kein Container/LXC/neue HW), vnet-Rout 10.40.0.0/16 (Route-ID 5546dcb6-5901-4da6-8d91-b17f94703f71) von bf-pve auf den Mesh-Node umhängen. Rollback = 1 PATCH zurück auf f7fdf3a6 (bf-pve). +‼️ CLOUDFLARE-KOMMUNIKATION — ZUERST LESEN, SONST LÄUFST DU GEGEN DIE WAND ‼️ +Es gibt ZWEI getrennte CF-Zugänge. Verwechseln = die "fehlende Permissions"-Falle: + + A) Der `cloudflare`-MCP (Tools mcp__cloudflare__docs/search/execute), registriert in + ~/.claude.json als https://mcp.cloudflare.com/mcp. Der ist OAuth-basiert und STRIKT + READ-ONLY. Reads/Spec-Suche/Batch-Lesen: super. JEDER Write (POST/PUT/PATCH/DELETE) + scheitert mit "10000: Authentication error". Das ist ERWARTET, KEIN echtes Rechte- + problem und KEIN Grund aufzugeben oder Christoph nach Permissions zu fragen. + ⚠️ .claude.json enthält NUR die MCP-URL, KEINEN Verweis auf den Token — der Token + lebt komplett getrennt (siehe B). Ein frischer Agent weiß das NICHT von selbst. + + B) Der scoped API-Token CF_API_TOKEN in mcp/cloudflare/.env — DAS ist der Write-Pfad. + Damit wurde das gesamte TP16-3-Tunnel-HA (Tunnel erstellt/geändert/gelöscht) gebaut. + Verifiziert 2026-07-17: MCP-PATCH → 10000-Fehler, identischer curl-PATCH → success:True. + + REGEL: Reads gern via MCP (schnell, batchbar). ALLE Writes via curl+CF_API_TOKEN, so: + cd ~/dev/bf-network-r6/mcp/cloudflare && set -a; . ./.env; set +a + curl -s -X POST -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \ + --data '{...}' "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/" + Verfügbare Env-Keys (Namen, keine Werte): CF_API_TOKEN, CF_ACCOUNT_ID, CF_ZONE_ID, + CF_BF_TUNNEL_ID, CF_PVE_TUNNEL_ID, CF_MM_TUNNEL_ID. + Neuen Mesh-Node-Token holen: GET /accounts/$CF_ACCOUNT_ID/warp_connector//token via curl+Token. + Alle CF-API-Calls gehen über api.cloudflare.com → WARP-UNABHÄNGIG (Rollback klappt auch, + wenn der private Pfad gerade tot ist). SSoT-Detail: cf-tunnel-mapping.md §11. + RAHMENBEDINGUNGEN: - Christoph ist ZUHAUSE (physischer ap1-Zugriff → Recovery via Power-Cycle möglich). - ap1 = einziger Edge/SPOF; MikroMCP live (mcp__mikromcp__*). Writes IMMER erst plan_changes/dryRun, dann apply_plan. ap1 device-mode=home → kein Scheduler/fetch. -- CF-Writes NUR via CF_API_TOKEN (curl/Bearer) — der cloudflare-MCP ist read-only. - Token/IDs in mcp/cloudflare/.env. Alle CF-API-Calls laufen über api.cloudflare.com, - also WARP-unabhängig (Rollback geht auch wenn der private Pfad tot ist). - wgcf-connector läuft als Docker-Einmal-Call auf macmini oder pve (ssh macmini / pve-mcp). - PrivateKey aus der .conf → ~/.secrets bzw. mcp/cloudflare/.env, NICHT committen. @@ -58,9 +80,12 @@ SCHON GEKLÄRT (nicht nochmal aufrollen): Nur nach dem Scharfschalten Ping gegenprüfen (§4.5). - IPv6 bewusst NICHT (v4-only; Mesh-site-to-site-v6 laut Guide broken). -ABLAUF: Plan-Gate zuerst (POST warp_connector → wenn Free-Plan das ablehnt: STOPP, -LXC-auf-pve-Fallback, §6). Dann §4.1→§4.5 des Runbooks. Bei jedem Schritt reversibel +ABLAUF: Plan-Gate zuerst — POST /accounts/$CF_ACCOUNT_ID/warp_connector {"name":"bf-ap1-mesh"} +via curl+CF_API_TOKEN (NICHT via MCP — der kann nicht schreiben!). Wenn Free-Plan das ablehnt: +STOPP, LXC-auf-pve-Fallback, §6. Dann §4.1→§4.5 des Runbooks. Bei jedem Schritt reversibel halten; die 2 User-Gates oben mit Christoph koordinieren. +⚠️ Falls du irgendwo "10000: Authentication error" siehst: du hast versehentlich den MCP zum + Schreiben benutzt. Kein Rechteproblem — auf curl+CF_API_TOKEN wechseln (siehe CF-KOMMUNIKATION oben). ROUTE-UMZUG (§4.4) — Weg A zuerst, Weg B als Fallback: - Weg A: PATCH /accounts/…/teamnet/routes/5546dcb6… {tunnel_id: }