Files
bf-infra/docs/tp16.3-nautobot-mesh-only-runbook.md
Christoph Emsenhuber 914ff980b5 TP16.3 und TP14.4 als ausfuehrbare Runbooks
Beide TPs waren "Recherche durch / Umsetzung offen" bzw. "TODO" -- also
jeweils eine Zeile, aus der eine frische Session nicht losarbeiten kann.

TP16.3: der Schnitt (nautobot aus dem bf-nas-Ingress) ausformuliert, mit
Vorbedingungen, PUT-Ablauf und Rollback. Zwei Dinge stehen jetzt explizit
drin, die den TP sonst kippen: Mesh-Hostname-Routes sind Egress und
veroeffentlichen nichts -- wer das verwechselt, baut den Public-Strang ab;
und Nautobot ist nicht nur eine Web-UI, sondern die Deploy-Pipeline, also
gehoert ein Job-Lauf zur Abnahme und nicht nur ein Browser-Aufruf.

TP14.4: Ist-Stand nachgesehen -- in mcp/cloudflare/.env stehen weder
CF_ACCESS_CLIENT_ID noch _SECRET, es ist also nichts halb erledigt. Das
Secret gibt es nur im Moment der Rotation, das steht jetzt als Warnung
davor. Abnahme braucht beide Faelle: mit Headern antwortet, ohne 403 --
sonst haette ein bypass-Hostname wie vw als Erfolg durchgehen koennen.

Kein CF-Write, kein Token rotiert. Beides bleibt Papier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:58:06 +02:00

5.9 KiB
Raw Blame History

TP16.3 — Probe: nautobot aus dem CF-Ingress nehmen (mesh-only)

Stand 2026-08-19 · vorbereitet, nicht ausgeführt. Die Recherche zu TP16.3 ist seit 2026-08-17 durch; offen war nur die Umsetzung. Dieses Runbook macht daraus einen ausführbaren, in einer Minute zurücknehmbaren Schnitt.


1. Worum es geht (in drei Sätzen)

Der private Datenpfad läuft seit TP16.1 über natives WireGuard auf dem Core (cf-mesh), nicht über Container — belegt, nicht vermutet: im TP5-Log-Lauf standen 137 Zeilen in:cf-mesh. Für Dienste, die niemand ohne WARP im Browser aufrufen muss, ist cloudflared damit überflüssiger Aufwand: eine Ingress-Zeile, ein Connector-Paar, eine HA-Frage. Diese Probe nimmt einen solchen Dienst heraus und schaut eine Woche zu.

Warum ausgerechnet nautobot

Kriterium nautobot
Wer nutzt es nur Christoph — kein Fremdgerät, kein Gast
Braucht es einen Client ohne Access-Login? nein (das ist das TP16.2-Kriterium, an dem vw hängt)
Wie oft schon per Mesh angefasst 62× im TP5-Log — der Spitzenreiter
Was kostet ein Fehlschlag nichts Produktives; im Zweifel greift man per IP zu

2. 🔴 Die Verwechslungsfalle, die den ganzen TP kippen kann

Mesh-Hostname-Routes sind Egress, nicht Publishing. Cloudflare kennt seit 2026-07-02 auch Hostname-Routes auf dem Mesh — die klingen so, als könnten sie den Ingress ersetzen. Sie können es nicht: sie leiten ausgehenden Verkehr zu diesem Hostname über den Node und egressen mit dessen öffentlicher IP. Sie veröffentlichen nichts.

Wer das verwechselt, baut den öffentlichen Strang ab und wundert sich, warum von außen nichts mehr geht. → Diese Probe ersetzt nichts. Sie entfernt einen Dienst, der öffentlich gar nicht gebraucht wird.


3. Vorbedingung — VOR dem Schnitt prüfen (read-only)

Alle drei Punkte müssen erfüllt sein, sonst wird nicht geschnitten:

  1. Die Mesh-Route steht. Auf dem Core: die vnet-Route 10.40.0.0/16 zeigt auf bf-core-mesh (TP16.1 §4.4, „Weg A"). Ohne sie ist Mesh-Zugriff auf 10.40.20.30 gar nicht möglich.
  2. Der Dienst antwortet über die private IP, mit aktivem WARP — von einem Client, der nicht im BF-LAN steht (das ist der einzige Test, der etwas beweist; im LAN geht es ohnehin):
    http://10.40.20.30:8080
    
  3. ⚠️ ICMP nicht als Beweis nehmen, aber auch nicht als Gegenbeweis. Der Mesh kann ICMP (das war der Gewinn von TP16.1). Wenn Ping scheitert, TCP aber geht, ist zuerst zu prüfen, ob lokal noch ein WARP-Client läuft — s. Memory ref_warp_local_icmp_trap. Umgekehrt ist ein erfolgreicher Ping kein Beleg, dass der HTTP-Dienst erreichbar ist.

4. Der Schnitt

Was: die nautobot-Zeile aus der Ingress-Config des Tunnels bf-nas entfernen. Die DNS-CNAME-Zeile bleibt zunächst stehen (Rollback bleibt so eine reine Ingress-Operation).

Womit: die Cloudflare-API mit CF_API_TOKEN.

🔴 Nicht über den Cloudflare-MCP. Der ist strikt read-only — Writes gehen ausschließlich über die API mit dem Token (Memory ref_cf_mcp_readonly_token_writes). Das Token ist account-owned, nutzt also einen anderen verify-Endpoint als ein User-Token, und läuft am 2027-01-09 ab.

Wo die Werte stehen: mcp/cloudflare/.env (chmod 600, gitignored) — CF_API_TOKEN, CF_ACCOUNT_ID, CF_BF_TUNNEL_ID.

Ablauf:

  1. Ist-Config sichern (das ist der Rollback): GET /accounts/{account_id}/cfd_tunnel/{tunnel_id}/configurations → JSON wegschreiben, mit Datum.
  2. Aus dem ingress-Array die nautobot-Zeile entfernen. ⚠️ Die abschließende Catch-all-Regel (service: http_status:404 ohne hostname) muss die letzte bleiben — sonst greift der Ingress für alle übrigen Hostnames nicht mehr.
  3. Zurückschreiben: PUT derselben Route mit dem gekürzten Array.
  4. Gegenprobe am Gerät, nicht am Statuscode: ein GET der Config liest zurück, was wirklich steht. (Dieselbe Regel wie in TP22/TP23: ein „success" der API ist kein Wirksamkeitsnachweis.)

5. Abnahme

Prüfung Erwartung
Öffentlicher FQDN nautobot.… ohne WARP nicht mehr erreichbar (das ist der Zweck)
http://10.40.20.30:8080 mit WARP, von außerhalb des LAN erreichbar
Die übrigen Hostnames auf bf-nas (gitea, grafana, pve-mcp, vw, ds-bf) unverändert erreichbar
Golden-Config-Deploys (Netmiko aus Nautobot) laufen weiter

🔴 Der letzte Punkt ist der, den man übersieht: Nautobot ist nicht nur eine Web-UI, sondern die Deploy-Pipeline. Der Netmiko-Deploy kommt von 10.40.20.31 (nautobot-worker), nicht von .20.30 — das war einer der vier TP5-Funde. Der Schnitt betrifft nur den eingehenden öffentlichen Weg, aber nach dem Schnitt gehört ein Job-Lauf zur Abnahme, nicht nur ein Browser-Aufruf.


6. Betriebsfenster und Rollback

  • Eine Woche fahren, dann entscheiden: bleibt es so, oder kommt es zurück.
  • Rollback = die gesicherte Ingress-Config aus Schritt 1 zurückschreiben. Eine Zeile, eine Minute.
  • Danach ist zu entscheiden, ob weitere Dienste der rechten Spalte folgen (pve, portainer, grafana, pve-mcp, ha-mcp, gitea-mcp, ds-bf, ccu, iobroker, z2m25).

Was in dieser Probe ausdrücklich NICHT entschieden wird

  • vw, hass, n8n bleiben öffentlich — harte Kriterien: Bitwarden-Clients (TP16.2-Constraint), die HA-Companion-App (das 400-Muster), eingehende Webhooks von Dritten.
  • gitea ist offen und wird hier nicht mitentschieden: Git-Clients/CI von außen können keinen interaktiven Access-Login. Braucht eine eigene Prüfung, ob es solche Zugriffe real gibt.

7. Nebeneffekt, der den Fall stärkt

Die TP16-HA-Degradierung (bf-nas und bf-pve haben je nur einen Connector, Befund 2026-08-16) verliert an Gewicht, je weniger Dienste an cloudflared hängen. Das ersetzt die Reparatur nicht — aber es verkleinert, was der SPOF trifft.