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>
This commit is contained in:
2026-08-19 15:58:06 +02:00
parent 8b7ca8ddef
commit 914ff980b5
3 changed files with 205 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
# 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.