# Handover — TP16.3 §2/§3: Container-Bootstrap auf ap1 / ap2 / ap3 > ✅ **ERLEDIGT am 2026-08-31.** Nachfolge-Dokument mit Ergebnis, drei korrigierten Runbook-Fehlern > und der einen offenen Entscheidung (Compliance 128/135): > [`handoff-20260831-tp16.3-paragraph2-3-durch.md`](handoff-20260831-tp16.3-paragraph2-3-durch.md). > Dieses Dokument bleibt als Ausgangslage stehen — **Abschnitt 3 und 7 sind inhaltlich überholt** > (Flash-Budget, `docker save`, `envs`-Parametername, Reihenfolge Paket/device-mode). > **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. 🆕 **[TP37](teilprojekte.md#tp37) — OOB-Management, angelegt 2026-08-31.** Je ein untagged-VLAN99-Port auf beiden Switches (Kandidat `ether23`, auf core **und** branch frei). Auslöser: beim Core-Neustart war `crs326-branch` nicht erreichbar, weil sein Mgmt **ausschließlich** über den Core läuft. 🔴 Nebenbefund mit eigenem Gewicht: **der Branch hat gar keine `input`-Firewallregeln** — sein Schutz ist heute allein die Erreichbarkeit über den gehärteten Core. 💡 **Berührt diese Session, ist aber keine Voraussetzung:** hier rebooten dreimal Geräte, deren Mgmt am Core hängt. Wer vor Ort ist, kann `ether23` schon mal beschriften — gebaut wird TP37 separat. 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)