TP30 angelegt: Credential-Rotation als Sammel-TP, gebuendelt gegen Projektende
Vier Rotationsposten (MikroTik-admin, IoT-PSK, Shelly-Geraetepasswort, CF-Access-Token) lagen als verstreute Follow-up-Zeilen herum. Der teure Teil jeder Rotation sind die Konsumenten (HA-Re-Auth x4, Nautobot-Stack- Redeploy), nicht das Setzen -- einzeln gemacht zahlt man den mehrfach. Deshalb ein Sammel-TP mit Ausloesekriterium statt Termin. - 100 Zeilen Radius-/Etappe-1-Detail aus den Follow-ups nach TP30 verschoben (nicht dupliziert), Follow-ups tragen jetzt einen Zeiger - Etappe 1 (Service-Accounts ha/nautobot) ist durch; admin ist NICHT rotiert - Stale: "nach TP17.1 sind es weniger Geraete" -- TP17.1 ist verworfen, die Geraete bleiben WLAN-Clients, die Rechnung gilt unveraendert - Handoff 08-24 + Naechster-Schritt-Block als ueberholt markiert Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,12 @@ Fünf Commits: `d245d10`, `e8f7f80`, `0a7f2e2`, `2f18319`, `e9a5b36`.
|
||||
|
||||
## 🔴 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).
|
||||
|
||||
@@ -91,10 +91,13 @@ ab jetzt bei jeder Änderung mitgezogen, nicht nur die TP-Abschnitte.)*
|
||||
> bleibt WLAN-Client; `s9` zurückgebaut) · ✅ **TP17.3 ERLEDIGT** (Ursache **`eco_mode`** bewiesen;
|
||||
> `s23` + `s26` repariert; **`eco_mode` flottenweit aus**, 22/22 außer `s24`) ·
|
||||
> 🔜 **TP17.2 aktiviert** (Shelly-Gerätepasswort, an die PSK-Rotation gekoppelt) ·
|
||||
> 🔑 **Rotation des MikroTik-Admin-Passworts** — seit 08-23 bewusst **hinter** TP17.1 eingereiht.
|
||||
> 🔑 **Alle Passwort-/Token-Rotationen sind seit 2026-08-24 TP30** (Sammel-TP) — **bewusst
|
||||
> gebündelt gegen Projektende**, User-Entscheid. Damit ist die ältere Einreihung „hinter TP17.1"
|
||||
> gegenstandslos (TP17.1 ist verworfen). **Etappe 1 — die Service-Accounts — ist durch;**
|
||||
> das `admin`-Passwort selbst ist **nicht rotiert** und bleibt es bis dahin bewusst.
|
||||
> 📌 **Einstieg für die nächste Session: [`handoff-20260824-session.md`](handoff-20260824-session.md)**
|
||||
> — Start bei der **Passwort-Rotation Etappe 2** (Nautobot + HA auf die neuen Service-Accounts
|
||||
> umhängen, dann `admin` rotieren). Ältere Sitzungsvorschläge:
|
||||
> — ⚠️ dessen Empfehlung „Start bei der Passwort-Rotation Etappe 2" ist durch den TP30-Entscheid
|
||||
> **überholt**; der Rest der Übergabe gilt. Ältere Sitzungsvorschläge:
|
||||
> [`handoff-20260822-naechste-schritte.md`](handoff-20260822-naechste-schritte.md).
|
||||
> ✅ **`crs326-core` ist transaktionsfrei** (seit 2026-08-22, geprüft): ein gemeldeter Drift ist ab
|
||||
> jetzt **echt**, nicht beabsichtigt — `python3 nautobot/gc-transaktion.py status`.
|
||||
@@ -925,6 +928,167 @@ die Redundanzfrage oben.
|
||||
- **Abh.:** keine harten. Profitiert von TP25 (Abdeckung/AP-Zuordnung) und TP11 (Monitoring), wenn es
|
||||
dahin kommt. **Kein Blocker für irgendetwas.**
|
||||
|
||||
<a id="tp30"></a>
|
||||
### TP30 — Credential-Rotation (Sammel-TP) ▸ 🔜 **ANGELEGT 2026-08-24, bewusst GEBÜNDELT gegen Projektende**
|
||||
> **User-Entscheid 2026-08-24:** „ich würde gerne daraus einen eigenen punkt machen. ich bin mir
|
||||
> sicher, dass es noch öfters passwörter zu rotieren geben wird. das machen wir dann alles gegen
|
||||
> projektende."
|
||||
>
|
||||
> **Warum ein eigener TP und nicht vier verstreute Follow-up-Zeilen:** die Rotationen teilen sich Werkzeug,
|
||||
> Fallen und vor allem den **teuren Teil — den Konsumenten** (HA, Nautobot, MikroMCP, `~/.secrets`).
|
||||
> Wer sie einzeln macht, zahlt den Re-Auth-Aufwand mehrfach. Gebündelt ist es **ein** Durchgang je
|
||||
> Gerät. Deshalb steht hier die Liste, nicht der Termin.
|
||||
|
||||
- **Auslösekriterium (statt Datum):** wenn die offenen TPs abgearbeitet sind bzw. Christoph das
|
||||
Projekt schließt. 🔴 **Harte Ausnahme, die den Termin vorzieht:** ein *neuer* Leak, ein
|
||||
fremdzugängliches Gerät oder ein Personenwechsel — dann sofort und einzeln, nicht gebündelt.
|
||||
|
||||
| # | Credential | Umfang | Anlass | Vorarbeit | Preis der Rotation |
|
||||
|---|---|---|---|---|---|
|
||||
| 1 | **MikroTik `admin`** | core · branch · ap1 · ap2 (**ein** geteilter Wert) | 🔴 **zweimal in ein Transkript geraten** (2026-08-22 via `sshpass -p`; 2026-08-23 durch einen Enumerationsfehler) | ✅ **Etappe 1 durch** (s.u.) | nach Etappe 2 nur noch `~/.secrets/credentials.env` + `~/.claude.json` + MikroMCP-Neustart |
|
||||
| 2 | **IoT-WLAN-PSK** (`sec-iot`) | `dirtyvader-iot`, 26 Clients | steht **im Klartext** im TP17-Text ⇒ auch in der **Git-Historie**; Redigieren holt ihn dort nicht raus | Hebel `multi-passphrase` am Core verifiziert vorhanden, Tabelle leer | 23 Shellys per Skript + **3 von Hand** (`.249` NSPanel Pro, `.244` Nuki Bridge, `.227` SwitchBot) |
|
||||
| 3 | **Shelly-Gerätepasswort** | 23 Shellys | Härtung (bisher **keine** Auth auf den Geräten) | ✅ Werkzeug fertig (`migrate.py cmd_auth` + Digest-Fallback) | **je Gerät ein HA-Re-Auth-Flow** — das ist der Aufwand, nicht `SetAuth` |
|
||||
| 4 | **CF-Access-Service-Token** (`CF_API_TOKEN`) | Cloudflare-Zugang, s. TP14.4 | ⏳ **läuft am 2027-01-09 ohnehin ab** — harter Termin, unabhängig vom Projektende | Runbook liegt (`tp14.4-cf-access-token-runbook.md`) | Token neu ausstellen + `~/.secrets` nachziehen; **account-owned**, anderer verify-Endpoint |
|
||||
|
||||
> ℹ️ **#3 ist TP17.2 und bleibt dort inhaltlich zu Hause** — hier steht es, weil es denselben
|
||||
> Geräte-Durchgang wie #2 benutzt (ein Reboot statt zwei), nicht als Duplikat.
|
||||
|
||||
#### Detail — Radius, Etappe 1 und Etappe 2 (am 2026-08-24 aus den Follow-ups hierher gezogen)
|
||||
|
||||
**Vorgeschichte des Entscheids** (Stand bis 2026-08-23, User: „machen wir, aber erst später"):
|
||||
⏭️ ~~**Nachgelagert seit 2026-08-23: erst TP17.1, dann rotieren.**~~
|
||||
**Revidiert noch am selben Tag (User): beides läuft PARALLEL.** Der Passphrase-Override je MAC
|
||||
(s.u.) macht den Flag-Day überflüssig, damit war die Reihenfolge nie technisch nötig — nur
|
||||
ökonomisch. Regel für die Parallelität: **ein Gerät, das ohnehin auf Thread/Zigbee wandert,
|
||||
bekommt den neuen PSK gar nicht**, sondern nur einen Übergangs-Eintrag in der `access-list`.
|
||||
⚠️ Der Entscheid betrifft **beide** Passwörter: der **IoT-WLAN-PSK** steht im Klartext im
|
||||
TP17-Text ([Archiv](teilprojekte-archiv.md#tp17)) und damit auch in der Git-Historie — **bleibt
|
||||
auf User-Entscheid 2026-08-23 vorerst unverändert**, weil Redigieren ihn nicht aus der Historie
|
||||
holt und Rotieren heute ~22 Shellys kostet. ~~Nach TP17.1 sind es deutlich weniger.~~
|
||||
🔴 **Hinfällig seit 2026-08-23: TP17.1 ist verworfen** — die Geräte bleiben WLAN-Clients, es
|
||||
werden also *nicht* weniger. Die Rechnung „~23 Shellys + 3 Fremdgeräte" gilt unverändert. Anlass: das Core-Passwort ist bei einer Debug-Ausgabe im Klartext in
|
||||
ein Sitzungstranskript geraten. Ursache war `sshpass -p`, das es in die **Kommandozeile**
|
||||
schreibt — sichtbar in `ps` und in jedem argv-Trace.
|
||||
#### 🔑 Radius-Befund 2026-08-23: das Admin-Konto teilen sich FÜNF Konsumenten
|
||||
Vor dem Rotieren erhoben — das ist deutlich mehr als „vier Geräte + eine Datei":
|
||||
|
||||
| Halter | Nachziehen |
|
||||
|---|---|
|
||||
| `~/.secrets/credentials.env` | Datei |
|
||||
| `~/.claude.json` (MikroMCP-Env, `ROUTER_*`/`CRS326_*`) | JSON + MCP-Neustart |
|
||||
| **Nautobot-Stack** `NAUTOBOT_ROUTEROS_USERNAME/PASSWORD` | Stack-Datei + **Portainer-Redeploy auf der DS923** |
|
||||
| **HA: VIER `mikrotik`-Integrationen** (`.99.1/.2/.11/.12`, 40 `device_tracker`) | 🔴 **`supports_reconfigure: false` — NICHT skriptbar**, 4× Re-Auth von Hand |
|
||||
| Repo-Skripte (`routeros/*.py`, `nautobot/*.py`, `docs/tp*.sh`) | ziehen aus `~/.secrets` → automatisch |
|
||||
|
||||
⇒ **User-Entscheid 2026-08-23: Konten trennen statt ein Passwort teilen.** Nicht das Rotieren ist
|
||||
das Problem, sondern dass ein einziges `admin` von fünf Stellen benutzt wird — jede Rotation kostet
|
||||
sonst wieder vier Re-Auths und einen Stack-Redeploy.
|
||||
|
||||
#### ✅ Etappe 1 DURCH (2026-08-23): dedizierte Service-Accounts auf allen vier Geräten
|
||||
Rein **additiv**, kein laufender Dienst berührt. Vorher existierte **nur** `admin` (Gruppe `full`).
|
||||
|
||||
| Gruppe | Policy | User | Zweck |
|
||||
|---|---|---|---|
|
||||
| `grp-ha` | `read,api,rest-api,test` | `ha` | HA-Mikrotik-Integration, **lesend** über API 8728 |
|
||||
| `grp-nautobot` | `ssh,read,write,test,sensitive` | `nautobot` | Golden Config über SSH/Netmiko (Backup **und** Deploy) |
|
||||
|
||||
Passwörter: `MIKROTIK_HA_PASS` / `MIKROTIK_NAUTOBOT_PASS` in `~/.secrets/credentials.env`
|
||||
(32 Zeichen, je Dienst eigen, geräteübergreifend gleich).
|
||||
🔒 **Angelegt über ein Skript, das die Werte aus der Datei liest** — bewusst *nicht* über
|
||||
`manage_user`, dessen `password`-Parameter im Sitzungstranskript landen würde.
|
||||
|
||||
**Abnahme, auf allen vier Geräten geprüft:**
|
||||
- `ha` liest (`identity`, `dhcp-lease` — am Core 59 Einträge, genau was das Device-Tracking braucht),
|
||||
**Schreibversuch wird abgewiesen**.
|
||||
- `nautobot` meldet sich per SSH an und exportiert; **kein REST** (bewusst kein `rest-api` in der Policy).
|
||||
- 🎯 **Der Export von `nautobot` ist byte-identisch zu dem von `admin`** (391/56/87/87 Zeilen je Gerät)
|
||||
⇒ **die GC-Compliance driftet beim Umstellen nicht.** Das war das Hauptrisiko dieser Etappe.
|
||||
- `/user` wird von **keiner** ComplianceRule abgedeckt ⇒ die neuen Konten erzeugen selbst keinen Drift.
|
||||
|
||||
#### ⏭️ Etappe 2 offen — die Konsumenten umhängen, DANN `admin` rotieren
|
||||
1. **Nautobot** auf `nautobot` umstellen (Stack-Env + Portainer-Redeploy), GC-Backup-Lauf als Abnahme.
|
||||
2. **HA**: die vier `mikrotik`-Einträge auf den `ha`-User bringen. ⚠️ Reconfigure ist nicht skriptbar;
|
||||
Entfernen-und-neu-Anlegen **wäre** skriptbar, riskiert aber die 40 `device_tracker`-Entity-IDs
|
||||
(sie leiten sich aus der MAC ab, kämen also gleich zurück — **aber erst nachdem** die alten
|
||||
Registry-Einträge 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` + `~/.claude.json`.
|
||||
|
||||
🔴 **Eigener Fehler, protokolliert:** beim Erheben des Radius hat ein `json.dumps`-Aufruf über
|
||||
`~/.claude.json` das **ap1-Passwort im Klartext ins Transkript geschrieben**. Da alle vier Geräte
|
||||
dasselbe `admin`-Passwort teilen, ist es **derselbe Wert, der am 2026-08-22 bereits verbrannt ist** —
|
||||
keine neue Expositionsklasse, aber ein zweiter Beleg dafür, dass die Rotation fällig ist.
|
||||
**Merkregel: Secrets-Enumeration gibt nur Schlüsselnamen aus, nie Werte** — auch nicht abgeschnitten.
|
||||
|
||||
✅ **Vorbedingung erfüllt, geprüft 2026-08-23:** alle vier
|
||||
Skripte laufen auf `sshpass -e` (`tp6-marker/server.py`, `tp6-monitor-core.sh`,
|
||||
`tp25-walk-messung.sh`, `tp25-pin-s22.sh`) — die frühere Notiz, zwei davon hätten die Schwäche
|
||||
noch, war veraltet. Übrig blieb nur **`CLAUDE.md`, das `sshpass -p` weiterhin aktiv als Reboot-Weg
|
||||
empfahl** — am 2026-08-23 auf `sshpass -e` korrigiert. **Damit ist die Rotation ohne Rückfallgefahr
|
||||
fahrbar.**
|
||||
Weg: `manage_user set-password` (⚠️ `/user set*` ist per Deny-Policy blockiert), danach
|
||||
`~/.secrets/credentials.env` (`ROUTER_*_PASS`/`CRS326_*_PASS`) und `~/.claude.json` nachziehen.
|
||||
Es ist **ein** Passwort für alle vier Geräte — die „Überlebensversicherung" aus CLAUDE.md.
|
||||
- 🔎 **Nachtrag 2026-08-23 (Recherche-Session, read-only — kein Eingriff): der PSK in der Doku ist
|
||||
noch der LIVE konfigurierte.** Gegengeprüft am Manager `crs326-core` (`/interface wifi security`,
|
||||
Profil `sec-iot` → `cfg-iot` → SSID `dirtyvader-iot`, `datapath.vlan-id=30`,
|
||||
`wpa2-psk,wpa3-psk`) — und zwar **per Fingerprint statt Klartext** (Länge + drei Zeichenpaare),
|
||||
damit der Wert nicht ein zweites Mal in ein Transkript wandert. **Diese Methode ist die Merkregel
|
||||
daraus:** einen Verdacht auf Übereinstimmung prüft man mit Stichproben, nicht durch Ausgeben.
|
||||
- ✅ **User-Entscheid 2026-08-23 zur Git-Historie: belassen, im Nachtrag dokumentieren** — **kein**
|
||||
`git filter-repo`. Begründung trägt: genau **eine** getrackte Fundstelle
|
||||
([Archiv](teilprojekte-archiv.md#tp17)), drei Commits (`e76289c` Ersteintrag 2026-07-11,
|
||||
`f0d1ff9` 08-08, `7ee64b5` Doku-Split 08-23), Remote **ausschließlich** `gitea.emsenhuber.net`,
|
||||
**ein** lokaler Klon. Eine History-Rewrite hätte hier also nichts gerettet, was nicht ohnehin nur
|
||||
auf der eigenen Infrastruktur liegt — und den Preis (alle Hashes neu) für nichts bezahlt.
|
||||
- 📊 **Warum die Rotation heute teuer ist — live gemessen 2026-08-23:** **26 der 27 WLAN-Clients des
|
||||
gesamten Netzes hängen auf `dirtyvader-iot`** (`dirtyvader-main` 1, MEDIA/UNTRUSTED/GUEST je 0).
|
||||
VLAN30 führt **41 Leases/Reservierungen** (5 aktuell `bound`, der Rest sind statische
|
||||
Reservierungen ausgeschalteter Geräte). Neben den ~26 Shellys hängen dort **P750W** (Drucker),
|
||||
**Airfryer** (`espressif`, `.180`), **SwitchBot floor-lamp**, **Twinkly** `.228`, **DTUBI** `.8`,
|
||||
**SONOFF-NSPanelPro** und ein **iPhone** `.177`. ⇒ Ein Passwortwechsel ist heute eine
|
||||
Batch-Aktion über ~26 Geräte, und **das ist genau die Rechnung, die TP17.1 verkleinert.**
|
||||
- 🔧 **Zwei Umsetzungshinweise fürs spätere Rotations-Paket:**
|
||||
**(a)** `mcp/shelly/migrate.py` hat **kein** Rotate-Kommando (nur `migrate`/`deanchor`/`auth`/
|
||||
`table`) — es bräuchte eine kleine Variante über denselben `set_sta`-Pfad.
|
||||
**(b) Ein Flag-Day ist vermeidbar:** RouterOS 7 kann in `/interface wifi access-list`
|
||||
**Passphrase-Overrides je MAC**. Also neuer PSK aufs Profil, Altgeräte übergangsweise per MAC mit
|
||||
dem alten weiter, danach die Liste leeren. 💡 Nebeneffekt: der TP25-Befund „keine `access-list`"
|
||||
bekäme damit endlich einen Zweck — und seit dem 08-23 gibt es die ComplianceRule
|
||||
`wifi-access-list`, die Einträge dort auch sichtbar macht.
|
||||
- **Mitzuziehen bei der Rotation** (legitime, gitignorete Ablagen desselben Werts):
|
||||
`~/.secrets/credentials.env` (+ `.bak-20260808`), `routeros/.secrets/wlan-psks.env`,
|
||||
`mcp/shelly/.env`.
|
||||
|
||||
- **CF-Access-Service-Token** — **Rotationsposten #4**, am 2026-08-24 aus den Follow-ups hierher
|
||||
gezogen (stand dort als „TP14.4 — CF-Access-Service-Token rotieren"). Sachlich gehört er zu
|
||||
**TP14.4** (CF-Access-Profil für Claude, Runbook `docs/tp14.4-cf-access-token-runbook.md`); hier
|
||||
steht er, damit die Rotationsliste vollständig ist. ⚠️ Der `CF_API_TOKEN` läuft ohnehin
|
||||
**2027-01-09** ab — spätestens dann ist dieser Posten fällig, unabhängig vom Projektende.
|
||||
|
||||
#### Fallen, die für jede künftige Rotation gelten (nicht neu erheben)
|
||||
- 🔴 **Niemals `sshpass -p`** — schreibt das Passwort in die Kommandozeile, sichtbar in `ps` und in
|
||||
jedem argv-Trace. **Genau so entstand Leak #1.** `-e` hält es in der Umgebung des Kindprozesses.
|
||||
Der Repo-Stand ist bereits durchgängig `-e`.
|
||||
- 🔴 **Passwörter nie per MCP-`password`-Parameter setzen**, sondern per Skript aus `~/.secrets`
|
||||
(`manage_user set-password`; `/user set*` ist per Deny-Policy blockiert).
|
||||
- 🔴 **Keine Secrets-Enumeration im Transkript** — das war Leak #2, ohne dass irgendein Werkzeug
|
||||
fehlerhaft war.
|
||||
- 🔒 **`wifi-security` ist als ComplianceRule grün, aber NICHT deploybar** (Passphrasen stehen als
|
||||
`<<REDACTED>>` im Template). Ist-Stand für #2 immer per REST vom Gerät lesen
|
||||
(`GET http://10.40.99.1/rest/interface/wifi/security`), **nie** aus `wlan-psks.env`.
|
||||
- ⚠️ **CAPsMAN, für #2:** eine Profiländerung wirkt erst nach `remote-cap provision` für **beide**
|
||||
APs — und die Abnahme ist eine **frische DHCP-Lease je SSID**, nicht die Registration-Table.
|
||||
- ⚠️ **Für #2 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.
|
||||
- ⚠️ **`s1`/`s2`/`s3` sind ausgesteckt** und kommen im Dezember mit dem **alten** PSK zurück — der
|
||||
Übergangs-Eintrag muss sie überleben oder sie werden bei Rückkehr von Hand nachgezogen.
|
||||
- 🔴 **HA- und Repo-Nummerierung der Shellys weichen ab** (`s10`, `s17`) — **immer über MAC/IP
|
||||
zuordnen, nie über die s-Nummer.**
|
||||
- **Abh.:** keine harten; #2 und #3 laufen sinnvollerweise in **einem** Geräte-Durchgang.
|
||||
**Blockiert nichts.** Die frühere Kopplung „erst TP17.1, dann rotieren" ist **gegenstandslos** —
|
||||
TP17.1 ist am 2026-08-23 verworfen, die Geräte bleiben WLAN-Clients.
|
||||
|
||||
---
|
||||
|
||||
## Abgeschlossene Teilprojekte ▸ [`teilprojekte-archiv.md`](teilprojekte-archiv.md)
|
||||
@@ -1046,109 +1210,10 @@ den Weg, über den man den Fehler zurücknehmen wollte.
|
||||
Re-Walk + Dead-Spot-Kartierung laufen als Schritt 5 von TP25 — und zwar erst **nach** den Funkparameter-Fixes,
|
||||
weil vorher gemessene Werte wertlos sind.
|
||||
- **TP10 —** DDNS-Auto-Updater für `bf4.emsenhuber.net` (auf dem Core möglich, `device-mode` erlaubt scheduler).
|
||||
- 🔑 **Admin-Passwort der vier MikroTik rotieren (offen seit 2026-08-22, User: „machen wir,
|
||||
aber erst später").** ⏭️ ~~**Nachgelagert seit 2026-08-23: erst TP17.1, dann rotieren.**~~
|
||||
**Revidiert noch am selben Tag (User): beides läuft PARALLEL.** Der Passphrase-Override je MAC
|
||||
(s.u.) macht den Flag-Day überflüssig, damit war die Reihenfolge nie technisch nötig — nur
|
||||
ökonomisch. Regel für die Parallelität: **ein Gerät, das ohnehin auf Thread/Zigbee wandert,
|
||||
bekommt den neuen PSK gar nicht**, sondern nur einen Übergangs-Eintrag in der `access-list`.
|
||||
⚠️ Der Entscheid betrifft **beide** Passwörter: der **IoT-WLAN-PSK** steht im Klartext im
|
||||
TP17-Text ([Archiv](teilprojekte-archiv.md#tp17)) und damit auch in der Git-Historie — **bleibt
|
||||
auf User-Entscheid 2026-08-23 vorerst unverändert**, weil Redigieren ihn nicht aus der Historie
|
||||
holt und Rotieren heute ~22 Shellys kostet. Nach TP17.1 sind es deutlich weniger. Anlass: das Core-Passwort ist bei einer Debug-Ausgabe im Klartext in
|
||||
ein Sitzungstranskript geraten. Ursache war `sshpass -p`, das es in die **Kommandozeile**
|
||||
schreibt — sichtbar in `ps` und in jedem argv-Trace.
|
||||
---
|
||||
#### 🔑 Radius-Befund 2026-08-23: das Admin-Konto teilen sich FÜNF Konsumenten
|
||||
Vor dem Rotieren erhoben — das ist deutlich mehr als „vier Geräte + eine Datei":
|
||||
|
||||
| Halter | Nachziehen |
|
||||
|---|---|
|
||||
| `~/.secrets/credentials.env` | Datei |
|
||||
| `~/.claude.json` (MikroMCP-Env, `ROUTER_*`/`CRS326_*`) | JSON + MCP-Neustart |
|
||||
| **Nautobot-Stack** `NAUTOBOT_ROUTEROS_USERNAME/PASSWORD` | Stack-Datei + **Portainer-Redeploy auf der DS923** |
|
||||
| **HA: VIER `mikrotik`-Integrationen** (`.99.1/.2/.11/.12`, 40 `device_tracker`) | 🔴 **`supports_reconfigure: false` — NICHT skriptbar**, 4× Re-Auth von Hand |
|
||||
| Repo-Skripte (`routeros/*.py`, `nautobot/*.py`, `docs/tp*.sh`) | ziehen aus `~/.secrets` → automatisch |
|
||||
|
||||
⇒ **User-Entscheid 2026-08-23: Konten trennen statt ein Passwort teilen.** Nicht das Rotieren ist
|
||||
das Problem, sondern dass ein einziges `admin` von fünf Stellen benutzt wird — jede Rotation kostet
|
||||
sonst wieder vier Re-Auths und einen Stack-Redeploy.
|
||||
|
||||
#### ✅ Etappe 1 DURCH (2026-08-23): dedizierte Service-Accounts auf allen vier Geräten
|
||||
Rein **additiv**, kein laufender Dienst berührt. Vorher existierte **nur** `admin` (Gruppe `full`).
|
||||
|
||||
| Gruppe | Policy | User | Zweck |
|
||||
|---|---|---|---|
|
||||
| `grp-ha` | `read,api,rest-api,test` | `ha` | HA-Mikrotik-Integration, **lesend** über API 8728 |
|
||||
| `grp-nautobot` | `ssh,read,write,test,sensitive` | `nautobot` | Golden Config über SSH/Netmiko (Backup **und** Deploy) |
|
||||
|
||||
Passwörter: `MIKROTIK_HA_PASS` / `MIKROTIK_NAUTOBOT_PASS` in `~/.secrets/credentials.env`
|
||||
(32 Zeichen, je Dienst eigen, geräteübergreifend gleich).
|
||||
🔒 **Angelegt über ein Skript, das die Werte aus der Datei liest** — bewusst *nicht* über
|
||||
`manage_user`, dessen `password`-Parameter im Sitzungstranskript landen würde.
|
||||
|
||||
**Abnahme, auf allen vier Geräten geprüft:**
|
||||
- `ha` liest (`identity`, `dhcp-lease` — am Core 59 Einträge, genau was das Device-Tracking braucht),
|
||||
**Schreibversuch wird abgewiesen**.
|
||||
- `nautobot` meldet sich per SSH an und exportiert; **kein REST** (bewusst kein `rest-api` in der Policy).
|
||||
- 🎯 **Der Export von `nautobot` ist byte-identisch zu dem von `admin`** (391/56/87/87 Zeilen je Gerät)
|
||||
⇒ **die GC-Compliance driftet beim Umstellen nicht.** Das war das Hauptrisiko dieser Etappe.
|
||||
- `/user` wird von **keiner** ComplianceRule abgedeckt ⇒ die neuen Konten erzeugen selbst keinen Drift.
|
||||
|
||||
#### ⏭️ Etappe 2 offen — die Konsumenten umhängen, DANN `admin` rotieren
|
||||
1. **Nautobot** auf `nautobot` umstellen (Stack-Env + Portainer-Redeploy), GC-Backup-Lauf als Abnahme.
|
||||
2. **HA**: die vier `mikrotik`-Einträge auf den `ha`-User bringen. ⚠️ Reconfigure ist nicht skriptbar;
|
||||
Entfernen-und-neu-Anlegen **wäre** skriptbar, riskiert aber die 40 `device_tracker`-Entity-IDs
|
||||
(sie leiten sich aus der MAC ab, kämen also gleich zurück — **aber erst nachdem** die alten
|
||||
Registry-Einträge 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` + `~/.claude.json`.
|
||||
|
||||
🔴 **Eigener Fehler, protokolliert:** beim Erheben des Radius hat ein `json.dumps`-Aufruf über
|
||||
`~/.claude.json` das **ap1-Passwort im Klartext ins Transkript geschrieben**. Da alle vier Geräte
|
||||
dasselbe `admin`-Passwort teilen, ist es **derselbe Wert, der am 2026-08-22 bereits verbrannt ist** —
|
||||
keine neue Expositionsklasse, aber ein zweiter Beleg dafür, dass die Rotation fällig ist.
|
||||
**Merkregel: Secrets-Enumeration gibt nur Schlüsselnamen aus, nie Werte** — auch nicht abgeschnitten.
|
||||
|
||||
✅ **Vorbedingung erfüllt, geprüft 2026-08-23:** alle vier
|
||||
Skripte laufen auf `sshpass -e` (`tp6-marker/server.py`, `tp6-monitor-core.sh`,
|
||||
`tp25-walk-messung.sh`, `tp25-pin-s22.sh`) — die frühere Notiz, zwei davon hätten die Schwäche
|
||||
noch, war veraltet. Übrig blieb nur **`CLAUDE.md`, das `sshpass -p` weiterhin aktiv als Reboot-Weg
|
||||
empfahl** — am 2026-08-23 auf `sshpass -e` korrigiert. **Damit ist die Rotation ohne Rückfallgefahr
|
||||
fahrbar.**
|
||||
Weg: `manage_user set-password` (⚠️ `/user set*` ist per Deny-Policy blockiert), danach
|
||||
`~/.secrets/credentials.env` (`ROUTER_*_PASS`/`CRS326_*_PASS`) und `~/.claude.json` nachziehen.
|
||||
Es ist **ein** Passwort für alle vier Geräte — die „Überlebensversicherung" aus CLAUDE.md.
|
||||
- 🔎 **Nachtrag 2026-08-23 (Recherche-Session, read-only — kein Eingriff): der PSK in der Doku ist
|
||||
noch der LIVE konfigurierte.** Gegengeprüft am Manager `crs326-core` (`/interface wifi security`,
|
||||
Profil `sec-iot` → `cfg-iot` → SSID `dirtyvader-iot`, `datapath.vlan-id=30`,
|
||||
`wpa2-psk,wpa3-psk`) — und zwar **per Fingerprint statt Klartext** (Länge + drei Zeichenpaare),
|
||||
damit der Wert nicht ein zweites Mal in ein Transkript wandert. **Diese Methode ist die Merkregel
|
||||
daraus:** einen Verdacht auf Übereinstimmung prüft man mit Stichproben, nicht durch Ausgeben.
|
||||
- ✅ **User-Entscheid 2026-08-23 zur Git-Historie: belassen, im Nachtrag dokumentieren** — **kein**
|
||||
`git filter-repo`. Begründung trägt: genau **eine** getrackte Fundstelle
|
||||
([Archiv](teilprojekte-archiv.md#tp17)), drei Commits (`e76289c` Ersteintrag 2026-07-11,
|
||||
`f0d1ff9` 08-08, `7ee64b5` Doku-Split 08-23), Remote **ausschließlich** `gitea.emsenhuber.net`,
|
||||
**ein** lokaler Klon. Eine History-Rewrite hätte hier also nichts gerettet, was nicht ohnehin nur
|
||||
auf der eigenen Infrastruktur liegt — und den Preis (alle Hashes neu) für nichts bezahlt.
|
||||
- 📊 **Warum die Rotation heute teuer ist — live gemessen 2026-08-23:** **26 der 27 WLAN-Clients des
|
||||
gesamten Netzes hängen auf `dirtyvader-iot`** (`dirtyvader-main` 1, MEDIA/UNTRUSTED/GUEST je 0).
|
||||
VLAN30 führt **41 Leases/Reservierungen** (5 aktuell `bound`, der Rest sind statische
|
||||
Reservierungen ausgeschalteter Geräte). Neben den ~26 Shellys hängen dort **P750W** (Drucker),
|
||||
**Airfryer** (`espressif`, `.180`), **SwitchBot floor-lamp**, **Twinkly** `.228`, **DTUBI** `.8`,
|
||||
**SONOFF-NSPanelPro** und ein **iPhone** `.177`. ⇒ Ein Passwortwechsel ist heute eine
|
||||
Batch-Aktion über ~26 Geräte, und **das ist genau die Rechnung, die TP17.1 verkleinert.**
|
||||
- 🔧 **Zwei Umsetzungshinweise fürs spätere Rotations-Paket:**
|
||||
**(a)** `mcp/shelly/migrate.py` hat **kein** Rotate-Kommando (nur `migrate`/`deanchor`/`auth`/
|
||||
`table`) — es bräuchte eine kleine Variante über denselben `set_sta`-Pfad.
|
||||
**(b) Ein Flag-Day ist vermeidbar:** RouterOS 7 kann in `/interface wifi access-list`
|
||||
**Passphrase-Overrides je MAC**. Also neuer PSK aufs Profil, Altgeräte übergangsweise per MAC mit
|
||||
dem alten weiter, danach die Liste leeren. 💡 Nebeneffekt: der TP25-Befund „keine `access-list`"
|
||||
bekäme damit endlich einen Zweck — und seit dem 08-23 gibt es die ComplianceRule
|
||||
`wifi-access-list`, die Einträge dort auch sichtbar macht.
|
||||
- **Mitzuziehen bei der Rotation** (legitime, gitignorete Ablagen desselben Werts):
|
||||
`~/.secrets/credentials.env` (+ `.bak-20260808`), `routeros/.secrets/wlan-psks.env`,
|
||||
`mcp/shelly/.env`.
|
||||
- **TP14.4 —** CF-Access-Service-Token rotieren.
|
||||
- 🔑 **Alle Passwort-/Token-Rotationen laufen seit 2026-08-24 unter [TP30](#tp30) — Sammel-TP,
|
||||
gebündelt gegen Projektende (User-Entscheid).** Dort steht die Rotationsliste (MikroTik `admin`,
|
||||
IoT-PSK, Shelly-Gerätepasswort, CF-Access-Token), der Radius der fünf Konsumenten, der
|
||||
Etappe-1-Abschluss und die Fallenliste. **Etappe 1 ist durch**, Etappe 2 wartet bewusst.
|
||||
- ~~**Doku-Aufräumen** (`docs/doku-cleanup-session.md`)~~ ✅ **abgeschlossen 2026-08-23.** Punkte A–D
|
||||
(08-16), E (08-18/19) und **F — der Split** (08-23) sind durch: abgeschlossene TPs liegen jetzt in
|
||||
[`teilprojekte-archiv.md`](teilprojekte-archiv.md), TP25 ist von 394 auf ~100 Zeilen kondensiert,
|
||||
@@ -1161,7 +1226,8 @@ den Weg, über den man den Fehler zurücknehmen wollte.
|
||||
|
||||
**TP8** (Identity/802.1X) · **TP11** (Monitoring) · **TP12** (IPv6) · **TP13** (Botschafts-WLANs) ·
|
||||
**TP16.2** (Härtung bypass-Dienste) · **TP18** (Garage-Objektspeicher) · **TP20.1** (Vaultwarden → Platform-PG) ·
|
||||
**TP23** (DNS-Policy, s. Regel oben).
|
||||
**TP23** (DNS-Policy, s. Regel oben) · **TP30** (Credential-Rotation — nicht research-, sondern
|
||||
**termin**-gated: gebündelt gegen Projektende, User-Entscheid 2026-08-24).
|
||||
*(**TP17.1** — Shelly Gen4 → Thread, aktiviert 2026-08-23 — läuft **nicht hier**, sondern im
|
||||
HA-Projekt `~/dev/ha-xstate`; netzseitig ist nichts zu bauen. Es blockt bewusst die PSK-Rotation.)*
|
||||
*(**TP16.1** stand hier bis 2026-08-17 fälschlich als offen — es ist seit demselben Tag ✅ abgeschlossen und
|
||||
|
||||
Reference in New Issue
Block a user