Auslöser (User 2026-08-31): beim Core-Neustart war crs326-branch nicht mehr erreichbar, weil sein Management ausschliesslich ueber den Core laeuft. Live nachgemessen: auf dem Branch ist vlan99 tagged=ether1,ether24,bridge mit untagged="" - es gibt also keinen Weg zu 10.40.99.2, der nicht durch den Core fuehrt. Wer den Core zerkonfiguriert, verliert den Branch gleich mit und damit die Moeglichkeit, es vom Branch aus zu reparieren. Zweiter, unangenehmerer Befund: crs326-branch hat GAR KEINE input-Regeln (Kette leer). Sein gesamter Schutz besteht heute darin, dass VLAN99 nur ueber den Core erreichbar ist und dessen forward-Kette deny-by-default faehrt - die Erreichbarkeitsbeschraenkung IST die Zugangskontrolle. Damit ist ein untagged MGMT-Port ein physischer Generalschluessel, und das TP traegt eine explizite Auflage: Port disabled im Normalbetrieb ODER input-Regeln auf beiden Switches ODER physische Sicherung. Empfehlung im Abschnitt: die input-Regeln, weil sie eine Luecke schliessen, die unabhaengig von diesem TP besteht. Kandidat ether23 - auf core und branch beide running=false, also frei, und auf beiden Geraeten dieselbe Nummer. Abnahme im Abschnitt so formuliert, dass sie den Zweck prueft: Laptop an branch ether23, Core-Trunk gezogen, 10.40.99.2 muss antworten. Alles andere misst nur den Normalfall. Quick-Index (nach TP36 einsortiert), TP-Abschnitt und Ist-Stand mitgezogen; Handover 20260831 auf den angelegten TP umgestellt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
127 lines
7.5 KiB
Markdown
127 lines
7.5 KiB
Markdown
# 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. 🆕 **[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)
|