TP16.3 §2/§3 durch: cloudflared auf ap1/ap2/ap3, bf-public healthy mit 12 Connectoren
Merge von claude/nervous-williams-acf000 (d5b3ce3) plus Ergebnis der
Vor-Ort-Session vom 2026-08-31.
Ergebnis
- je ein cloudflared 2026.6.1 auf ap1/ap2/ap3, bf-public healthy/12
(vorher 0 Connectoren), Flash je AP 54-55 MiB frei, WLAN zurueck.
Drei Runbook-Fehler aufgedeckt und korrigiert (§2.2, §3.3, §3.5, §8)
- Flash-Budget war Faktor 2,5 zu optimistisch: cloudflared entpackt
69,5 MiB (gemessen mit docker export), nicht 28 MB -- das offizielle
Image passt auf keinen der drei APs. Ersatz: eigenes FROM-scratch-Image
mit 35,3 MiB aus dem statisch gelinkten Binary, Binary-SHA e93824f6
gepinnt, Neubau byte-identisch. tools/build-cfd-image.py.
- docker save schreibt seit Docker 25 OCI statt docker-v1 -> RouterOS
meldet "no config found in manifest". tools/oci2docker.py als Konverter.
- /container/envs nimmt list=, nicht name= (auch MikroMCPs
manage_container_env ist dadurch fuer dieses Feld unbrauchbar).
Weitere Funde
- Der device-mode-Bestaetigungs-Boot installiert keine Pakete; erst
Paket-Reboot, dann device-mode.
- "A - AVAILABLE" in /system package print ist ein Download-Katalog,
kein Paket auf dem Geraet (Gegenprobe am Core: 2,9 MB frei, listet
10,1 MB wifi-qcom als verfuegbar).
- MikroMCPs export_config exportiert unvollstaendig (301 B statt 6,2 KiB).
Offen und entscheidungsbeduerftig
- Compliance 128/135: §3.4 verlangt Direkt-Writes fuer ip address/nat,
die unter GC-Kontrolle stehen -> sechs neue extra-Drifts, zwei je AP.
Inhaltlich richtig, gehoeren ins Soll -- kein Re-Baseline, kein Rueckbau.
- Zwei Nautobot-Tokens sind in dieser Session ins Transkript geraten
(unzureichende sed-Maskierung) -> Rotation noetig, TP30. Merkregel in
CLAUDE.md ergaenzt.
Merge-Konflikte aufgeloest
- Nummernkonflikt: beide Branches hatten ein TP37. main behaelt TP37
(Nautobot als Netzwerkdoku, User-Okay 08-30), OOB-Mgmt wird TP38.
Braucht noch Christophs Okay.
- Drei CF-Rollback-Snapshots hatten gleichen Namen bei verschiedenem
Inhalt -> aelterer Stand als *-vor-hostname-schnitt.json erhalten,
keiner verworfen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
139
docs/handoff-20260831-tp16.3-paragraph2-3-durch.md
Normal file
139
docs/handoff-20260831-tp16.3-paragraph2-3-durch.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Handoff — TP16.3 §2/§3 durch: drei Connectoren live, eine Entscheidung offen
|
||||
|
||||
> **2026-08-31, Vor-Ort-Session.** Nachfolger von
|
||||
> [`handoff-20260831-tp16.3-vorort-session.md`](handoff-20260831-tp16.3-vorort-session.md).
|
||||
> **Nicht** Teil dieser Session: §5 (CNAME-Flip) und §6 (Abbau).
|
||||
|
||||
---
|
||||
|
||||
## 1. Was jetzt steht
|
||||
|
||||
`bf-public` ist **healthy mit 12 Connectoren** (3 APs × 4 CF-Edges) — der Tunnel hatte vorher
|
||||
**null**. Je ein `cloudflared 2026.6.1` läuft auf ap1, ap2 und ap3.
|
||||
|
||||
| | ap1 | ap2 | ap3 |
|
||||
|---|---|---|---|
|
||||
| `container`-Paket | 7.24.1 ✅ | 7.24.1 ✅ | 7.24.1 ✅ |
|
||||
| `device-mode container` | `yes` ✅ | `yes` ✅ | `yes` ✅ |
|
||||
| Container | `R` running | `R` running | `R` running |
|
||||
| `.tar` gelöscht | ✅ | ✅ | ✅ |
|
||||
| Flash frei | 54,0 MiB | 54,6 MiB | 55,0 MiB |
|
||||
|
||||
WLAN auf allen drei zurück, CAPs `state=Ok` am Manager. Backups je AP liegen auf dem Gerät
|
||||
(`vor-tp16.3-apN.backup`) **und** lokal unter `~/tp16.3/backups/` — inklusive vollständigem
|
||||
`/export` (nicht der MCP-Export, s. Punkt 4).
|
||||
|
||||
---
|
||||
|
||||
## 2. 🔴 Die eine offene Entscheidung: Compliance steht auf 128/135
|
||||
|
||||
Nach vollem Refresh (Backup → Intended → Compliance, **nicht** die stale Zahl von vorher):
|
||||
|
||||
| Gerät | Regel | Inhalt |
|
||||
|---|---|---|
|
||||
| ap1 / ap2 / ap3 | `ip-address` | `/ip address add address=172.17.0.1/24 interface=veth-cf` |
|
||||
| ap1 / ap2 / ap3 | `ip-firewall-nat` | `masquerade`, Kommentar `TP31: cloudflared egress` |
|
||||
| crs326-core | `wifi-security` | `ft-over-ds` — **die bekannte, unverändert** |
|
||||
|
||||
**Ursache ist ein Widerspruch zwischen zwei Dokumenten**, kein Ausrutscher: Runbook §3.4 schreibt
|
||||
Direkt-Writes für `veth`/`ip address`/`nat` vor, die Governance stellt `/ip address` und
|
||||
`/ip firewall` unter GC-Pflicht. Ich bin dem Runbook gefolgt.
|
||||
|
||||
**Die sechs Drifts sind inhaltlich richtig** — die Config *soll* dort stehen, ohne sie läuft kein
|
||||
Container. Der saubere Weg ist, sie ins **Soll** zu heben (AP-Template bzw. ConfigContext
|
||||
`ap-common`), damit die Compliance sie als konform sieht.
|
||||
🔴 **Kein Re-Baseline** (macht die Drift-Erkennung wertlos) und **kein Rückbau** (killt die Tunnel).
|
||||
⚠️ `/interface veth` erzeugt **keine** Drift — dafür existiert keine ComplianceRule. Wenn das Soll
|
||||
angepasst wird, gehört die Frage dazu, ob `veth` überhaupt erfasst sein soll.
|
||||
|
||||
---
|
||||
|
||||
## 3. 🔴 Drei Runbook-Fehler, die diese Session aufgedeckt hat
|
||||
|
||||
**(a) Die Flash-Rechnung war um Faktor 2,5 zu optimistisch.** §3.5 rechnete mit „28 MB `.tar`
|
||||
+ ~28 MB entpackt ≈ 39 MB Rest". Die 28 MB sind die **komprimierte** Archivgrösse; entpackt misst
|
||||
`cloudflare/cloudflared:2026.6.1` **72.926.208 B = 69,5 MiB**. Der Import braucht Tar **und**
|
||||
entpacktes Abbild gleichzeitig ⇒ 95,7 MiB gegen ~90 MiB frei. **Das offizielle Image passt auf
|
||||
keinen der drei APs.**
|
||||
⚠️ **`docker image inspect .Size` führt in die Irre** (meldete 27.463.950). Für Flash-Budgets
|
||||
`docker export | wc -c` messen.
|
||||
|
||||
**Lösung, ausgerollt:** eigenes `FROM scratch`-Image aus dem — nachweislich **statisch gelinkten** —
|
||||
Binary (36,8 MB) plus CA-Bundle: **35,3 MiB**, Spitzenbedarf 70,6 MiB. Build-Skript liegt jetzt im
|
||||
Repo (`tools/build-cfd-image.py`), ein Neubau ist **byte-identisch** (`f818bf40…`).
|
||||
🔑 Der Pin ist die **Binary-SHA256 `e93824f6…`**, und cloudflared bestätigt sie beim Start selbst
|
||||
(`Version 2026.6.1 (Checksum e93824f6…)`) — im Log aller drei APs nachlesbar.
|
||||
|
||||
**(b) `docker save` taugt seit Docker 25 nicht mehr als Quelle.** Mit containerd-Image-Store schreibt
|
||||
es OCI-Layout (`blobs/sha256/`, gzip-Layer); RouterOS will docker-v1 und meldet
|
||||
**`no config found in manifest`** — klingt nach kaputtem Image, ist das Format.
|
||||
(Konverter für den Fall, dass man doch ein Docker-Image braucht: `tools/oci2docker.py`, prüft die
|
||||
Layer-Digests gegen `rootfs.diff_ids`.)
|
||||
|
||||
**(c) `/container/envs` heisst auf ROS 7.24.1 `list=`, nicht `name=`.** Mit `name=` kommt
|
||||
`bad parameter name` bzw. `unknown parameter name`. **Auch MikroMCPs `manage_container_env` benutzt
|
||||
`name=` und ist damit für dieses Feld unbrauchbar.**
|
||||
|
||||
---
|
||||
|
||||
## 4. Vier weitere Funde
|
||||
|
||||
- 🔴 **Der `device-mode`-Bestätigungs-Boot installiert KEINE Pakete.** Auf ap1 lag die `.npk` schon
|
||||
bereit, als `device-mode` gesetzt wurde — der Stromzyklus hat `container: yes` bestätigt und die
|
||||
Datei **verbraucht, ohne zu installieren**. **Reihenfolge ist Pflicht: erst Paket-Reboot, dann
|
||||
`device-mode`.** (Nachholen ging per SSH, ohne zweiten Gang zum Gerät.)
|
||||
- 🟡 **`A - AVAILABLE` in `/system package print` ist ein Download-Katalog, kein Paket auf dem Gerät.**
|
||||
Gegenprobe: `crs326-core` hat 2,9 MB frei von 16 MB, listet aber `wifi-qcom` (10,1 MB) und
|
||||
`rose-storage` (4,3 MB) als „available"; die Grössen sind arch-spezifisch. `enable` löste einen
|
||||
Internet-Fetch aus — auf ap1/ap2 per `device-mode=home` gesperrt. **Der `.npk`-Weg bleibt richtig.**
|
||||
- 🟡 **MikroMCPs `export_config` exportiert unvollständig:** 301 Bytes gegen 6,2 KiB bei direktem
|
||||
`/export`. Ein Rollback-Artefakt, das existiert und trotzdem fast leer ist — dieselbe Klasse wie
|
||||
„Lücke statt Fehlermeldung". Für Backups `/export file=…` per SSH.
|
||||
- ⚠️ **WLAN-Abnahme nur teilweise belegbar:** `main` (3 Clients) und `iot` (27) haben frische Leases;
|
||||
`media`/`untrusted`/`guest` hatten **schon vor** dem Umbau null Clients. Kein Rückschritt, aber
|
||||
auch kein Beleg — nicht als „grün" buchen.
|
||||
|
||||
---
|
||||
|
||||
## 5. 🔴 Sicherheitsvorfall in dieser Session — Rotation nötig
|
||||
|
||||
Beim Suchen des Nautobot-Tokens hat eine unzureichende `sed`-Maskierung
|
||||
(`grep -n … | sed 's/:.*TOKEN/…/' | cut -c1-60`) **zwei Werte im Klartext ins Transkript geschrieben**:
|
||||
|
||||
- `NAUTOBOT_SUPERUSER_API_TOKEN`
|
||||
- `NAUTOBOT_GITEA_TOKEN`
|
||||
|
||||
beide aus `docs/nas-vlan20/stacks/210-nautobot.yml`. **Als verbrannt behandeln → TP30.**
|
||||
Das ist exakt die Falle, die seit 2026-08-28 in der CLAUDE.md steht (der `SHELLY_DEVICE_PW`-Fall).
|
||||
**Merkregel, die offenbar noch nicht scharf genug formuliert war:** ein Maskierungs-Muster, das auf
|
||||
`:` ankert, matcht bei `grep -n` den **Zeilennummer-Präfix** statt den Wert. Sicher ist nur
|
||||
`sed -E 's/(TOKEN|PASSWORD|SECRET|KEY|PASS)=.*/\1=<redacted>/'` — auf den **Schlüsselnamen** ankern,
|
||||
nie auf ein Trennzeichen, das auch im Präfix vorkommt.
|
||||
|
||||
---
|
||||
|
||||
## 6. Repo-Zustand
|
||||
|
||||
- Branch `claude/nervous-williams-acf000` ist hier **hereingemergt**. Konflikte aufgelöst:
|
||||
- **Nummernkonflikt TP37**: `main` hatte TP37 = *Nautobot als Netzwerkdoku* (User-Okay 08-30),
|
||||
der Branch TP37 = *OOB-Mgmt*. Letzterer ist auf **TP38** umnummeriert. ⚠️ **Braucht dein Okay** —
|
||||
Nummernvergabe ist laut Konvention deine Entscheidung.
|
||||
- **Drei CF-Rollback-Snapshots hatten denselben Dateinamen bei verschiedenem Inhalt**
|
||||
(`bf-mm` v4/6 Regeln vs. v6/2 Regeln, analog `bf-nas`, `bf-pve`) — zwei Zeitpunkte, beide
|
||||
„vor-tp16.3-schnitt" genannt. **Keiner verworfen:** der ältere liegt jetzt als
|
||||
`*-vor-hostname-schnitt.json` daneben.
|
||||
- Neu: `tools/build-cfd-image.py`, `tools/oci2docker.py`.
|
||||
- `mcp/mikromcp/config/routers.yaml` meldet weiter `rosVersion: "7.24"` für alle fünf (live 7.24.1) —
|
||||
kosmetisch, unangetastet gelassen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Nächste Schritte
|
||||
|
||||
1. **Entscheidung zu Punkt 2** (sechs Drifts ins Soll heben) — vor dem Flip, sonst geht man mit
|
||||
erklärter, aber ungeklärter Drift in den Produktivpfad.
|
||||
2. **§5 CNAME-Flip**, einzeln mit Abnahme dazwischen, Testname zuerst (§5.1).
|
||||
🔴 `healthy` beweist nur, dass der Connector mit Cloudflare redet — **nicht**, dass das Origin
|
||||
antwortet. Der Streckenbeweis bis Caddy ist §5.1.
|
||||
3. **§6 Abbau** frühestens 7 Tage nach dem Flip.
|
||||
4. **TP30**: die zwei Tokens aus Punkt 5 rotieren.
|
||||
Reference in New Issue
Block a user