153 lines
9.5 KiB
Markdown
153 lines
9.5 KiB
Markdown
# Übergabe — Session 2026-08-23 (bis in den 24. hinein)
|
||
|
||
> **Einstieg:** diese Datei, dann [`teilprojekte.md`](teilprojekte.md).
|
||
> **Zustand am Netz: stabil und aufgeräumt.** Nichts steht halb offen, keine Config-Transaktion
|
||
> gelaufen, `s9` ist vollständig zurückgebaut, alle Shellys erreichbar.
|
||
|
||
## Was diese Session war
|
||
|
||
Begonnen mit TP17.3 (der Shelly-Regression), geendet bei einer Umstrukturierung der Router-Konten.
|
||
Fünf Commits: `d245d10`, `e8f7f80`, `0a7f2e2`, `2f18319`, `e9a5b36`.
|
||
|
||
| | |
|
||
|---|---|
|
||
| ✅ **TP17.3 gelöst** | Ursache **`eco_mode`** bewiesen, `s23` (Dimmer-Flackern) und `s26` (Doppeldruck) repariert. |
|
||
| ✅ **`eco_mode` flottenweit aus** | 13 Geräte umgestellt, null Fehler. **22/22 erreichbare Shellys auf `false`.** |
|
||
| ❌ **TP17.1 verworfen** | Der Zigbee-Weg wurde **vollständig bewiesen** — und damit auch, dass das Ziel mit ihm nicht erreichbar ist. |
|
||
| ✅ **Passwort-Rotation Etappe 1** | Dedizierte Service-Accounts `ha` + `nautobot` auf allen vier MikroTik. |
|
||
|
||
---
|
||
|
||
## 🔴 Womit die nächste Session anfangen sollte
|
||
|
||
> ⚠️ **ÜBERHOLT am 2026-08-24 (User-Entscheid):** die Rotation ist **nicht** der Sessionstart.
|
||
> Sie ist zu **[TP30 — Credential-Rotation](teilprojekte.md)** geworden, einem Sammel-TP, der
|
||
> **gegen Projektende gebündelt** abgearbeitet wird — Begründung: es kommen weitere Passwörter
|
||
> hinzu, und der teure Teil sind die Konsumenten (HA-Re-Auth, Stack-Redeploy), den man nicht
|
||
> mehrfach zahlen will. **Der Inhalt unten bleibt sachlich gültig** und steht jetzt in TP30.
|
||
|
||
**Passwort-Rotation, Etappe 2.** Die Vorarbeit steht komplett, der Rest ist die einzige Sache mit
|
||
echter Dringlichkeit — das `admin`-Passwort ist zweimal in ein Transkript geraten (22.08. und, durch
|
||
meinen eigenen Enumerationsfehler, nochmal am 23.08.; **derselbe Wert**, da alle vier Geräte ihn teilen).
|
||
|
||
**Was Etappe 2 verlangt, in dieser Reihenfolge:**
|
||
1. **Nautobot** auf den `nautobot`-User umstellen — `NAUTOBOT_ROUTEROS_USERNAME/PASSWORD` im Stack
|
||
`docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored), dann **Portainer-Redeploy** auf der DS923.
|
||
⚠️ Beim Redeploy die Healthcheck-/`mem_limit`-Zeilen nicht verlieren — siehe CLAUDE.md-Gotcha,
|
||
der Stack hat am 17.08. zweimal die DS923 abgeräumt.
|
||
**Abnahme:** ein GC-Backup-Lauf, der durchgeht.
|
||
2. **HA**: die vier `mikrotik`-Integrationen (`.99.1`, `.99.2`, `.99.11`, `.99.12`) auf `ha` bringen.
|
||
🔴 **`supports_reconfigure: false` — nicht skriptbar.** Entfernen-und-neu-Anlegen *wäre* skriptbar
|
||
(`ha_set_integration domain="mikrotik"`), riskiert aber die **40 `device_tracker`-Entities**.
|
||
Sie heißen nach MAC (`device_tracker.10_20_ba_fa_f5_40`), kämen also identisch zurück — **aber nur,
|
||
wenn die alten Registry-Einträge vorher weg sind**, sonst hängt HA ein `_2` an. Dieselbe Falle wie
|
||
beim Shelly-Rename.
|
||
3. **Erst danach `admin` rotieren.** Dann berührt es nur noch `~/.secrets/credentials.env` und
|
||
`~/.claude.json` (+ MikroMCP-Neustart) — die Repo-Skripte ziehen automatisch nach.
|
||
|
||
### Was dafür schon fertig ist
|
||
Auf **allen vier** Geräten angelegt und abgenommen (vorher existierte dort **nur** `admin`/`full`):
|
||
|
||
| Gruppe | Policy | User |
|
||
|---|---|---|
|
||
| `grp-ha` | `read,api,rest-api,test` | `ha` |
|
||
| `grp-nautobot` | `ssh,read,write,test,sensitive` | `nautobot` |
|
||
|
||
Passwörter: `MIKROTIK_HA_PASS` / `MIKROTIK_NAUTOBOT_PASS` in `~/.secrets/credentials.env`.
|
||
🎯 **Der Export von `nautobot` ist byte-identisch zu dem von `admin`** (391/56/87/87 Zeilen) —
|
||
**die GC-Compliance driftet beim Umstellen nicht.** Das war das Hauptrisiko und ist geprüft.
|
||
`/user` wird von keiner ComplianceRule abgedeckt, die Konten erzeugen selbst keinen Drift.
|
||
|
||
---
|
||
|
||
## Danach, mit Vorsicht
|
||
|
||
- **C2 — IoT-PSK rotieren.** Der Hebel ist `/interface wifi security multi-passphrase`
|
||
(`group`/`passphrase`/`vlan-id`/`expires`), auf dem Core verifiziert vorhanden, Tabelle noch leer.
|
||
🔴 **Zuerst `multi-passphrase` gegen WPA3/SAE testen — auf einer Wegwerf-SSID, nie an
|
||
`dirtyvader-iot`.** `sec-iot` fährt `wpa2-psk,wpa3-psk`; trägt multi-passphrase SAE nicht, sperrt
|
||
man **26 IoT-Geräte auf einmal** aus, inklusive Nuki und NSPanel.
|
||
Danach: 23 Shellys per Skript (der erprobte Anker-Pfad in `migrate.py._migrate_one`), **3 Geräte von
|
||
Hand** — `.249` SONOFF NSPanel Pro (Touchscreen), `.244` Nuki Bridge (App), `.227` SwitchBot Floor
|
||
Lamp (App). ⚠️ `s1`/`s2`/`s3` sind ausgesteckt und kommen im Dezember mit dem **alten** PSK zurück.
|
||
⚠️ CAPsMAN: eine Profiländerung wirkt erst nach `remote-cap provision` für **beide** APs.
|
||
- **D — TP17.2 Shelly-Gerätepasswort**, an C2 gekoppelt (ein Reboot statt zwei). Werkzeug ist fertig
|
||
(`migrate.py cmd_auth`, Digest-Fallback in `_rpc`). 🔴 **Der Aufwand ist HA, nicht `SetAuth`:** je
|
||
Gerät ein Re-Auth-Flow, 23-mal. **Erst an EINEM Gerät messen** (Vorschlag `s15 technik_pve`, −36 dBm).
|
||
- **TP25 Fund F** (5:05-Takt IoT) und die Entscheidung **5 GHz auf 20 MHz**.
|
||
- **5-GHz-Umfeldscan** vor dem Einbau der zwei neuen APs.
|
||
|
||
---
|
||
|
||
## Die Entscheidung des Tages: warum TP17.1 gestorben ist
|
||
|
||
Der Pilot hat den Zigbee-Weg **technisch vollständig bewiesen** — `s9` lief auf `PowerStripZB`, trat
|
||
ZHA bei, ein Zigbee-Befehl schaltete das physische Relais, kein Broadcast-Sturm.
|
||
|
||
Christophs Einwand hat ihn trotzdem gekippt: *„zigbee sollte die antwort auf die vielen radios auf
|
||
-iot geben. nutzt aber wenig wenn man das wifi nicht abdrehen kann bzw. es nicht mehr aktivieren kann
|
||
ohne reset."* Und die Messung stützt ihn:
|
||
|
||
- **Das Gerät bleibt WLAN-Client** — Zigbee kommt *zusätzlich*, nicht *statt*.
|
||
- **Der Funkgewinn ist klein:** die 12 Gen4 sind 12 von 26 IoT-Clients, bewegen aber je nur
|
||
~150–200 KB rx / 0,6–3 MB tx in sechs Stunden.
|
||
- **Der Preis wäre dauerhaft:** die Zigbee-Firmware hat **keinen AP**, Shelly macht **kein Zigbee-OTA**,
|
||
`Shelly.InstallAlt` braucht IP. WLAN aus = nie wieder Update, kein Rückweg, bei 10 Unterputz-Modulen.
|
||
|
||
**Der Weg ist nicht gescheitert, das Ziel war mit ihm nicht erreichbar.** Das Runbook bleibt als
|
||
Wissensspeicher; einziger Restposten ist der **Frühindikator** (`Shelly.CheckForUpdate` auf einen
|
||
`…MT`/Thread-`alt`-Eintrag beobachten).
|
||
|
||
---
|
||
|
||
## Zwei Messungen, die vorherige Annahmen widerlegen
|
||
|
||
**1. `eco_mode` aus hebt die Sendeleistung NICHT an.** Ich hatte das als Airtime-Risiko notiert, das
|
||
TP25 berührt. Gemessen am Manager, vorher/nachher: **13 geänderte Geräte im Mittel −0,9 dB**, bei einer
|
||
**Kontrollgruppe von 13 unveränderten mit +0,0 dB** und derselben Streuung (±2 dB). Rauschen.
|
||
⇒ Die TP17-Aussage, `eco_mode` senke „den CPU-Takt **und** die WLAN-Sendeleistung", stimmt nur zur
|
||
Hälfte. Der Takt-Teil ist durch das Dimmer-Flackern bewiesen; der Rest ist nicht messbar.
|
||
|
||
**2. `restart_required` auf 14 Shellys war ein Fehlalarm.** Der Reboot von `s26` mit Config-Vergleich
|
||
davor/danach ergab **identische Configs**. Das Bit ist *sticky* und stand für keine abweichende
|
||
Konfiguration. **Nicht erneut untersuchen** — drei Wege (169 RPC-Methoden, Config-Diff über die
|
||
Gruppengrenze, Gerätelog) sind zu Ende gegangen, alle negativ.
|
||
|
||
---
|
||
|
||
## Zahlen und Fallen, die man nicht neu erheben muss
|
||
|
||
- **`dirtyvader-iot`: 26–27 Clients, alle auf EINEM VAP** (`cap-wifi4-virtual1`, ap1). Davon 23 Shellys
|
||
und **3 Fremde**: `.249` NSPanel Pro, `.244` Nuki Bridge, `.227` SwitchBot Floor Lamp.
|
||
- **`s4 kueche_mikrowelle` ist wieder online** (war den ganzen Tag als offline geführt) — und ist
|
||
**Gen3**, war also nie TP17.1-Kandidat. Bleibt der Härtefall bei −96 dBm (Geräte-Sicht).
|
||
- 🔴 **HA- und Repo-Nummerierung der Shellys weichen ab** — HA: `s10 = schlafzi/teststecker`,
|
||
Inventory: `s10 = bad_sonos`; ebenso `s17`. **Immer über MAC/IP zuordnen, nie über die s-Nummer.**
|
||
- 🔴 **`migrate.py _resolve` fällt ohne Argument auf den alten VLAN1-Sweep `10.40.41.180-250` zurück.**
|
||
Explizite Bereiche übergeben oder `SHELLY_SWEEP` setzen.
|
||
- 🔵 **`inventory/bf.csv` führt `s12` noch auf `10.40.41.219`** (live `10.40.30.219`).
|
||
- ⚠️ **Nach jedem Shelly-Firmwarewechsel den AP prüfen** — der Rückflash von `s9` zog einen **offenen**
|
||
AP hoch (`ap.enable=true, is_open=true`). Abgeschaltet und mit dem IoT-PSK abgesichert.
|
||
- 🔒 **`wifi-security` ist als ComplianceRule grün, aber NICHT deploybar** — die Passphrasen stehen als
|
||
`<<REDACTED>>` im Template. Ist-Stand immer per REST vom Gerät lesen
|
||
(`GET http://10.40.99.1/rest/interface/wifi/security`), **nie** aus `wlan-psks.env`.
|
||
|
||
### Der Firmware-Mechanismus der Shelly Gen4 (falls er je wieder gebraucht wird)
|
||
Zwei-Slot-Modell über drei **undokumentierte** RPCs, aus dem UI-JavaScript des Geräts extrahiert:
|
||
`Shelly.InstallAlt {app, stage}` lädt in den inaktiven Slot und rebootet hinein · `Shelly.SetAlternative
|
||
{name}` schaltet um (auf unseren Modellen **nicht vorhanden**) · `Shelly.ListAlternatives` (404 auf
|
||
beiden Builds). Die Shelly-Support-Seite beschreibt einen **Modus-Umschalter mit 5-Sekunden-Knopf** —
|
||
**das gilt für unsere Modelle nicht.**
|
||
|
||
---
|
||
|
||
## Neue und geänderte Dokumente
|
||
|
||
- [`tp17.1-shelly-gen4-funkmigration-runbook.md`](tp17.1-shelly-gen4-funkmigration-runbook.md) —
|
||
Kopf trägt jetzt „VERWORFEN"; enthält den kartierten Mechanismus, das 2,4-GHz-Bild und die
|
||
ZHA-Sturmzähler mit Baseline
|
||
- [`teilprojekte.md`](teilprojekte.md) — TP17.1 verworfen, TP17.2 aktiviert, TP17.3 erledigt,
|
||
PSK-Follow-up um Radius-Befund und Etappe 1 ergänzt
|
||
- `CLAUDE.md` — 🔴 empfahl bis gestern aktiv `sshpass -p` als Reboot-Weg, jetzt `sshpass -e`
|
||
- `mcp/shelly/migrate.py` — neues `eco`-Kommando (mit Retry je Gerät und Fehlerliste)
|