diff --git a/docs/handoff-20260831-tp16.3-vorort-session.md b/docs/handoff-20260831-tp16.3-vorort-session.md new file mode 100644 index 0000000..b954b04 --- /dev/null +++ b/docs/handoff-20260831-tp16.3-vorort-session.md @@ -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@ "/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) diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index b331f1e..fdbd37f 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -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 diff --git a/docs/tp16.3-bf-public-ap-connector-runbook.md b/docs/tp16.3-bf-public-ap-connector-runbook.md index eb1c408..4018b25 100644 --- a/docs/tp16.3-bf-public-ap-connector-runbook.md +++ b/docs/tp16.3-bf-public-ap-connector-runbook.md @@ -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 —