ROS 7.24.1 auf allen fuenf nachgezogen + Handover fuer TP16.3 §2/§3

Nautobot: ap1 stand als einziges Geraet noch auf SoftwareVersion 7.24 (ap2,
ap3, core, branch waren bereits richtig) -> auf 7.24.1 gesetzt. Danach
Backup/Intended/Compliance.

Folge fuers Runbook: aus zwei container.npk wird EINE. Die Zwei-Dateien-Regel
vom 08-30 war rein versionsbedingt, nicht modellbedingt - cAP ax und hAP ax^2
teilen sich die arm64-Pakete. §0, §2.1, §3.1 und Falle 1 umgeschrieben.
Die Regel dahinter bleibt: npk muss exakt zur ROS-Version passen, sonst ist
das Paket nach dem Reboot inaktiv - ohne Fehlermeldung.

Neue Compliance-Drift, NICHT von dieser Session und bewusst offen gelassen:
crs326-core / wifi-security - sec-main hat am Geraet ft-over-ds=no, Soll ist
yes (ft=yes ist korrekt). Kam mit dem Upgrade. 134/135 compliant. Braucht eine
Entscheidung (Geraet korrigieren oder neuen Wert zum Soll erklaeren) plus
Re-Provisionierung der CAPs; ein Re-Baseline ohne Entscheid wuerde die
Drift-Erkennung wertlos machen.

Handover docs/handoff-20260831-tp16.3-vorort-session.md fuer die Folgesession
(§2/§3: npk, device-mode, Container). Enthaelt u.a. den Hinweis, dass ein
fehlschlagendes /tool fetch vom AP auf Caddy KEIN Fehler ist, sondern die
SNI-Abweisung - und dass der TLS-Alert sogar beweist, dass die Freigabe traegt.

Offen notiert, nicht angelegt: TP-Vorschlag "dedizierter untagged-VLAN99-Port
je Switch" (Out-of-Band-Mgmt) - Auslöser war, dass crs326-branch beim
Core-Neustart nicht erreichbar war. Wartet auf Christophs Okay.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-31 14:57:35 +02:00
parent badf715f5a
commit 452ea53576
3 changed files with 167 additions and 25 deletions

View File

@@ -0,0 +1,126 @@
# Handover — TP16.3 §2/§3: Container-Bootstrap auf ap1 / ap2 / ap3
> **Erstellt 2026-08-31.** Zielsession: **§2 + §3** des Runbooks
> [`tp16.3-bf-public-ap-connector-runbook.md`](tp16.3-bf-public-ap-connector-runbook.md) — also
> `container.npk`, `device-mode`, Container. **Vor Ort**, weil jeder AP eine physische Bestätigung braucht.
> **Nicht** Teil dieser Session: der CNAME-Flip (§5) und der Abbau (§6).
---
## 1. Was vor dir schon erledigt ist — nicht nochmal machen
| Punkt | Stand | Nachweis |
|---|---|---|
| **§1 Blocker A** — Redirect-Schleife | ✅ 08-31 | `bf-public`-Ingress → `https://10.40.20.40:443`, `originServerName` je Regel, zurückgelesen |
| **§1 Blocker B** — Firewall `vlan99→vlan20:443` | ✅ 08-31 | via **Nautobot GC** (Plan `Completed`), Position vor `TP5: log-only` geprüft, funktional gegen Caddy nachgewiesen |
| **§1 Blocker C** — `ROUTER_AP3_PASS` | ✅ 08-31 | in `~/.secrets/credentials.env`, REST-Auth ap3 = **200** |
| Rollback-Snapshots | ✅ 08-30 | `docs/cf-backup/*-20260830-vor-tp16.3-schnitt.json` |
| ROS-Upgrade auf **7.24.1** | ✅ 08-31 (User) | alle fünf Geräte, RouterBOOT mitgezogen |
**⇒ Die Session startet bei §2.** Wer §1 nochmal anfasst, arbeitet doppelt.
---
## 2. Die eine Änderung gegenüber dem Runbook-Stand vom 08-30
🎉 **Aus zwei `container.npk` ist eine geworden.** Christoph hat am 08-31 alle fünf MikroTik auf
**7.24.1** gehoben. Damit gilt:
```
container-7.24.1-arm64.npk → ap1, ap2 UND ap3
```
Die frühere Zwei-Dateien-Regel war **rein versionsbedingt**, nicht modellbedingt — `cAP ax` und
`hAP ax²` teilen sich die `arm64`-Pakete. Das Runbook ist entsprechend umgeschrieben (§0, §2.1, §3.1,
Falle 1).
⚠️ **Die Regel dahinter bleibt:** `container.npk` muss **exakt** zur ROS-Version passen. Vor dem Upload
`/system resource print` lesen. Falsche Datei ⇒ Paket ist nach dem Reboot **inaktiv, ohne Fehlermeldung**.
---
## 3. Ablauf in einem Satz
Je AP, **einzeln und vollständig, Reihenfolge ap3 → ap2 → ap1**:
`.npk` hoch → Reboot (SSH, **nicht** MikroMCP) → `/system package print` prüfen →
`device-mode update container=yes` → **physisch bestätigen** → `veth` + `masquerade` →
`.tar` hoch → `/container add file=` → starten → `.tar` löschen → Log prüfen.
**Details, Befehle und Abnahmekriterien: Runbook §2 und §3.** Hier nur die Punkte, die man
erfahrungsgemäß falsch macht:
- 🔴 **Reboot geht NICHT über MikroMCP** (ROS kennt den `delay`-Parameter nicht, `run_command` ist für
`/system reboot*` gesperrt) → `SSHPASS="$PW" sshpass -e ssh admin@<ip> "/system reboot"`.
**Niemals `sshpass -p`** — das schreibt das Passwort in `ps`.
- 🔴 **`~/.secrets/credentials.env` in zsh sourcen schlägt still fehl** (rohe WireGuard-Zeilen ab ~Z. 69).
Variablen bleiben **leer**, und der Fehler sieht aus wie ein ungültiger Token. **Immer `bash -c`.**
- 🔴 **Kein PoE an den CRS326** (beide haben gar kein PoE-Menü) ⇒ kein Remote-Power-Cycle. Die
Bestätigung ist wirklich physisch: **Stecker ziehen/stecken** (Weg A, eindeutig) oder Reset-Knopf am
*laufenden* Gerät kurz drücken (Weg B). Weg B **nie während des Bootens** — das wäre ein Werksreset.
- 🔴 **Ein Container pro AP.** Nach dem Import bleiben ~39 MB. Kein Caddy, kein AGH dazu.
- ⚠️ **Jeder AP rebootet zweimal** → WLAN dieses APs ist je ~1–2 min weg. Die CAPs holen ihre Config
per L2-Discovery vom Core. **Nicht ungeduldig nachprovisionieren.**
- ⚠️ **WLAN-Abnahme ist eine frische DHCP-Lease je SSID, nicht die Registration-Table.**
**Erwartetes Ergebnis am Ende:** `bf-public` meldet `healthy` mit Connectoren (Richtung 12 = 3 APs × 4
CF-Edge). 🔴 **`healthy` heißt nur „Connector redet mit Cloudflare", nicht „Origin antwortet"** — der
Beweis für die Strecke bis Caddy ist §5.1, und der gehört in die **Folge**session.
---
## 4. Was du unterwegs sehen wirst und **nicht** als Fehler behandeln darfst
**`/tool fetch` von einem AP auf `https://10.40.20.40` schlägt mit einem TLS-Alert fehl.**
Das ist **korrekt und erwartet**: Caddy weist Handshakes ohne passenden SNI ab (gemessen: ohne SNI
`000`, mit korrektem SNI `200`). Der Alert **beweist sogar**, dass das Paket ankommt — ein TLS-Alert
kann nur vom Server kommen, die Firewall-Freigabe trägt also. cloudflared schickt den richtigen SNI
über `originServerName`. **Nicht „reparieren".**
---
## 5. Offene Punkte, die NICHT in diese Session gehören
1. 🔴 **Compliance-Drift `crs326-core` / `wifi-security` (134/135).** `sec-main` hat am Gerät
`ft-over-ds=no`, Soll `yes` (`ft=yes` ist korrekt). **Kam mit dem 7.24.1-Upgrade.** Braucht eine
Entscheidung — Gerät korrigieren *oder* neuen Wert zum Soll erklären — plus Re-Provisionierung der
CAPs. ⚠️ **Kein Re-Baseline ohne Entscheid**, das macht die Drift-Erkennung wertlos.
2. 🆕 **TP-Vorschlag (Christoph 2026-08-31, noch nicht angelegt): dedizierter untagged-VLAN99-Port
auf beiden Switches.** Auslöser ist eine reale Beobachtung: **beim Core-Neustart war `crs326-branch`
nicht mehr erreichbar**, weil das Management über den Core läuft. Ein Out-of-Band-Zugang je Switch
(ein Port, untagged VLAN99, Laptop direkt) macht den Branch unabhängig vom Core.
**Bewusst nicht eigenmächtig angelegt** (TP-Management-Konvention: vorschlagen, abstimmen, dann
anlegen). ⇒ Nummer vergeben und Abschnitt schreiben, sobald Christoph zustimmt.
💡 Berührt TP16.3 direkt: die Vor-Ort-Session rebootet dreimal Geräte, deren Mgmt am Core hängt.
3. 🟡 **`mcp/mikromcp/config/routers.yaml` hält `rosVersion: "7.24"`** für alle fünf — jetzt `7.24.1`.
⚠️ **Die Datei liegt auf `main`, nicht auf diesem Branch** (der Worktree hat eine ältere Kopie
**ohne** ap3). Der Fix gehört auf `main`, nicht hierher — sonst gibt es einen Konflikt.
4. **CNAME-Flip (§5) und Abbau (§6)** — eigene Session, §6 frühestens 7 Tage nach dem Flip.
---
## 6. Zugänge und Werkzeuge
| Was | Wie |
|---|---|
| APs | MikroMCP `ap1`/`ap2`/`ap3` (Reads), SSH `admin@10.40.99.11/.12/.13`, Creds `ROUTER_AP{1,2,3}_PASS` in `~/.secrets` |
| Reboot | `bash -c 'set -a; . ~/.secrets/credentials.env; set +a; SSHPASS="$ROUTER_AP3_PASS" sshpass -e ssh admin@10.40.99.13 "/system reboot"'` |
| Config-Änderungen an MikroTik | **ausschließlich Nautobot GC** (`nautobot/gc-manual-plan.py`), Token aus `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored, **nur im Haupt-Checkout**) |
| Cloudflare | `CF_API_TOKEN` / `CF_ACCOUNT_ID` in `~/.secrets`, Zone `1b5bc02fdf61b6b989afde543f3f4134` |
| Caddy | `caddy-bf1`, LXC 130 auf pve, `10.40.20.40`; Logs `ssh root@10.40.20.100 'pct exec 130 -- journalctl -u caddy -n 50'` |
⚠️ **`device-mode`- und Container-Schritte sind KEINE Golden-Config-Sache** — sie sind Bootstrapping am
Gerät (wie die genehmigte Ausnahme #2 beim CRS326-Bring-up). Die GC-Pflicht gilt für
`/ip firewall`, `/interface` & Co. **Wenn die Session eine Firewall- oder Interface-Zeile braucht:
über `gc-manual-plan.py`, nicht per Direkt-Write.**
---
## 7. Abnahme dieser Session
- [ ] `/system package print` zeigt auf **allen drei** APs `container` in **7.24.1**, nicht disabled
- [ ] `/system device-mode print` zeigt `container: yes` auf allen dreien
- [ ] `/container print` zeigt je AP **einen** Container `running`
- [ ] `.tar` je AP gelöscht (Flash zurück)
- [ ] `bf-public` meldet `healthy` mit Connectoren > 0
- [ ] WLAN je AP zurück — **frische DHCP-Lease pro SSID**, nicht Registration-Table
- [ ] Compliance nicht schlechter als **134/135** (die `wifi-security`-Drift aus Punkt 5.1 bleibt bestehen)

View File

@@ -40,6 +40,13 @@ liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur d
unterstellte einen Registry-Pull (`fetch: no` auf ap1/ap2) und enthielt eine **falsche**
Firewall-Freigabe-Behauptung. **CF-Stand:** `bf-public` `inactive` / 0 Connectoren; die vier
öffentlichen Namen laufen noch über bf-mm/bf-nas/bf-pve **an Caddy vorbei** direkt aufs Backend.
- 🆕 **ROS-Upgrade 7.24.1 auf allen fünf (2026-08-31, User).** In Nautobot nachgezogen: **ap1** stand
als einziges Gerät noch auf `7.24` (die anderen vier waren schon richtig) ⇒ auf `7.24.1` gesetzt.
🔴 **Eine Drift kam mit dem Upgrade: `crs326-core` / `wifi-security`** — `sec-main` hat am Gerät
`ft-over-ds=no`, Soll ist `yes` (`ft=yes` steht korrekt). **134/135 compliant.** Bewusst **nicht**
angefasst: das ist eine Roaming-Einstellung und braucht eine Entscheidung (Gerät korrigieren **oder**
den neuen Wert zum Soll erklären) plus Re-Provisionierung der CAPs — **nicht nebenbei**.
⚠️ Ein Re-Baseline ohne Entscheid würde die Drift-Erkennung wertlos machen.
- 🆕 **TP16.3 §1-Blocker remote erledigt (2026-08-31):** Ingress von `bf-public` auf
`https://10.40.20.40:443` + `originServerName`; Firewall-Freigabe `vlan99 → vlan20:443` **über
Nautobot GC** (Plan `Completed`, Re-Baseline `ingest-core-firewall.py --apply`, danach
@@ -47,11 +54,12 @@ liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur d
Vor-Ort-Session** (§2/§3: `container.npk`, `device-mode`, Container) und danach Flip + Abbau.
- 🆕 **Globale Verhaltensregeln konsolidiert (2026-08-29, TP35 Schicht 3):** `~/.config/opencode/AGENTS.md` ist jetzt die **SSoT** für globale Verhaltensregeln (Secrets, VLAN-Schema, 5 Lessons, SoC, Übergabe-Mechanik, Mid-Action-Checkpoint, Commit-Hinweis, Backup-Guard). `~/.claude/CLAUDE.md` hält denselben Block als Claude-Code-Spiegelung mit Verweis auf die SSoT. opencode liest AGENTS.md mit Vorrang vor `~/.claude/CLAUDE.md`.
- **Fünf MikroTik seit 2026-08-30** — neu dazu **`ap3`** (cAP ax `cAPGi-5HaxD2HaxD`, **`10.40.99.13`**,
Uplink core `ether21`, in der MikroMCP-Registry). ⚠️ **ap3 läuft `7.24.1`, die anderen vier `7.24`**
(live gelesen 08-30) — für versionsgebundene Pakete (`container.npk`) sind das **zwei** Dateien,
nicht eine. RouterBOOT jeweils = `upgrade-firmware`.
*(Hier stand bis 08-29 „Alle vier MikroTik laufen auf RouterOS 7.24" — mit ap3 überholt.)*
- **Fünf MikroTik, alle auf RouterOS `7.24.1`** (User-Upgrade 2026-08-31, live gegengelesen;
RouterBOOT jeweils = `upgrade-firmware` = `7.24.1`). Neu dabei **`ap3`** (cAP ax `cAPGi-5HaxD2HaxD`,
**`10.40.99.13`**, Uplink core `ether21`).
✅ **Folge für TP16.3:** die versionsgebundene `container.npk` ist damit **eine** Datei für alle drei
APs (alle `arm64`) — die Zwei-Dateien-Regel vom 08-30 war rein versionsbedingt und ist erledigt.
*(Hier stand bis 08-29 „Alle vier MikroTik … 7.24" — durch ap3 und das Upgrade zweifach überholt.)*
- **L3 + WAN-Edge = `crs326-core`** (CRS326-24G-2S+, Technik UG): Routing, DHCP (7 Server,
54 Reservierungen), DNS, NAT, **NTP-Server für den Standort** und der WG-Hub (TP10, Peers `fm`/`dw`)
laufen hier. Mgmt-SVI **`10.40.99.1`** (vlan99), Gateway `.1` je VLAN. **WAN = `vlan100`** — DHCP-Client

View File

@@ -17,15 +17,21 @@
| AP | IP | Modell | Arch | ROS **live** | Flash frei | RAM frei | `device-mode` | `container` | `fetch` |
|---|---|---|---|---|---|---|---|---|---|
| **ap1** | 10.40.99.11 | hAP ax² (`C52iG`) | arm64 | **7.24** | 95 MB / 128 | 686 MB | `home` | ❌ `no` | ❌ `no` |
| **ap2** | 10.40.99.12 | hAP ax² (`C52iG`) | arm64 | **7.24** | 95 MB / 128 | 694 MB | `home` | ❌ `no` | ❌ `no` |
| **ap1** | 10.40.99.11 | hAP ax² (`C52iG`) | arm64 | **7.24.1** | 95 MB / 128 | 712 MB | `home` | ❌ `no` | ❌ `no` |
| **ap2** | 10.40.99.12 | hAP ax² (`C52iG`) | arm64 | **7.24.1** | 95 MB / 128 | 699 MB | `home` | ❌ `no` | ❌ `no` |
| **ap3** | 10.40.99.13 | **cAP ax** (`cAPGi`) | arm64 | **7.24.1** | 96 MB / 128 | 689 MB | **`basic`** | ❌ `no` | ✅ `yes` |
🔴 **Zwei Unterschiede, die je einen eigenen Arbeitsschritt kosten:**
1. **ap3 läuft 7.24.1, ap1/ap2 laufen 7.24.** Ein `container.npk` **muss exakt zur RouterOS-Version
passen** — sonst bleibt es nach dem Reboot schlicht deaktiviert. ⇒ **zwei verschiedene Downloads**,
nicht einer. Nicht aus Bequemlichkeit dieselbe Datei auf alle drei schieben.
2. **ap3 steht auf `device-mode=basic`**, nicht `home` — dort sind `fetch`/`scheduler` bereits erlaubt.
*(Versionsspalte am **2026-08-31** nachgelesen: Christoph hat alle fünf MikroTik auf **7.24.1** gehoben,
RouterBOOT mitgezogen. Bis 08-30 liefen ap1/ap2 auf 7.24 — daher stand hier vorher eine Zwei-Dateien-Regel.)*
✅ **Seit dem Upgrade auf 7.24.1 (2026-08-31) reicht EINE `.npk` für alle drei APs** — alle sind `arm64`
und alle auf derselben Version. Die frühere Zwei-Dateien-Regel war **rein versionsbedingt**, nicht
modellbedingt: `cAP ax` und `hAP ax²` teilen sich die `arm64`-Pakete.
🔴 **Die Regel dahinter gilt weiter:** ein `container.npk` **muss exakt zur RouterOS-Version passen** —
sonst bleibt es nach dem Reboot deaktiviert. Wer künftig einen AP einzeln hebt, hat wieder zwei Dateien.
🟡 **Ein Unterschied bleibt:**
- **ap3 steht auf `device-mode=basic`**, nicht `home` — dort sind `fetch`/`scheduler` bereits erlaubt.
Das ändert am `container`-Flag nichts (auch dort `no`, auch dort physische Bestätigung), macht ap3
aber zum einzigen AP, der theoretisch aus der Registry ziehen könnte. **Wir nutzen das bewusst
nicht** — gleicher `.tar`-Weg auf allen dreien, damit alle drei dasselbe Image fahren.
@@ -201,19 +207,18 @@ in `bash -c '…'`. **Wer das übersieht, jagt einen „ungültigen Token", der
## §2 Vorbereitung am Schreibtisch (vor der Fahrt, mit Internet)
### 2.1 Die **zwei** `container.npk` holen — Versionen nicht mischen
### 2.1 Die `container.npk` holen — **eine Datei für alle drei APs**
```bash
mkdir -p ~/tp16.3 && cd ~/tp16.3
# ap1 + ap2 (7.24)
curl -fLO https://download.mikrotik.com/routeros/7.24/all_packages-arm64-7.24.zip
unzip -o -j all_packages-arm64-7.24.zip 'container-7.24-arm64.npk'
# ap3 (7.24.1)
curl -fLO https://download.mikrotik.com/routeros/7.24.1/all_packages-arm64-7.24.1.zip
unzip -o -j all_packages-arm64-7.24.1.zip 'container-7.24.1-arm64.npk'
ls -la container-*.npk
ls -la container-7.24.1-arm64.npk
```
*(Beide URLs am 2026-08-30 mit `HTTP 200` verifiziert.)*
*(URL am 2026-08-30 mit `HTTP 200` verifiziert.)*
⚠️ **Vor dem Upload gegenprüfen, dass das Gerät wirklich auf 7.24.1 steht** (`/system resource print`).
Stimmt die Version nicht, ist die Datei die falsche — und das merkt man erst nach dem Reboot.
### 2.2 cloudflared als `.tar` bauen — **Registry-Pull ist auf ap1/ap2 gesperrt** (`fetch: no`)
@@ -265,13 +270,15 @@ printf "%s" "$T" > ~/tp16.3/bf-public.token; chmod 600 ~/tp16.3/bf-public.token'
> sich ihre Config nach dem Boot vom Manager (`crs326-core`) per **L2-Discovery auf `vlan99`** —
> das kommt von selbst zurück, braucht aber ~1–2 min. **Nicht ungeduldig nachprovisionieren.**
### 3.1 `.npk` hochladen — **die richtige Datei zum richtigen AP**
### 3.1 `.npk` hochladen
| AP | Datei |
|---|---|
| ap1 (`.99.11`) | `container-7.24-arm64.npk` |
| ap2 (`.99.12`) | `container-7.24-arm64.npk` |
| **ap3 (`.99.13`)** | **`container-7.24.1-arm64.npk`** |
| ap1 (`.99.11`) | `container-7.24.1-arm64.npk` |
| ap2 (`.99.12`) | `container-7.24.1-arm64.npk` |
| ap3 (`.99.13`) | `container-7.24.1-arm64.npk` |
✅ **Seit 2026-08-31 dieselbe Datei überall** (alle drei `arm64` + 7.24.1).
```bash
cd ~/tp16.3
@@ -554,8 +561,9 @@ physischem Gang. Es schadet nicht — ohne laufenden Container ist es ein gesetz
## §8 Fallen
1. **Zwei ROS-Versionen, zwei `.npk`.** ap1/ap2 = 7.24, ap3 = **7.24.1**. Falsche Datei ⇒ Paket bleibt
nach dem Reboot inaktiv. **Nach jedem Reboot `/system package print` lesen**, nicht annehmen.
1. **`container.npk` ist versionsgebunden.** Seit 08-31 sind alle drei APs auf 7.24.1 ⇒ **eine** Datei.
Weicht ein Gerät später ab, braucht es wieder seine eigene. Falsche Datei ⇒ Paket bleibt nach dem
Reboot **inaktiv, ohne Fehler**. **Nach jedem Reboot `/system package print` lesen**, nicht annehmen.
2. **Die Freigabe `vlan99 → vlan20:443` existiert nicht** — entgegen der Behauptung im
Vorgänger-Runbook. Ohne §1.2 landet der Connector im `TP5-WOULD-DROP`-Log. **Erst dort nachsehen.**
3. **Caddy antwortet auf `:80` mit 308.** Ein Ingress auf `:80` erzeugt eine Redirect-Schleife —