TP16 HA repariert; TP25 5-GHz-Scan + Empfehlung; TP17.2-Stub weg

TP16 -- Ursache war NICHT das erwartete QUIC-Flap: die beiden
macmini-Connectoren standen auf Exited(0), beide finishedAt auf
derselben Sekunde 2026-07-21T13:00:53, bei korrektem
restart=unless-stopped und http2. Also ein docker stop / compose down.
Fix = docker start. Abnahme: alle drei bf-Tunnel je 2 Connectoren /
8 conns, 36 Anfragen ueber 6 FQDNs beider Tunnel mit 530er=0.
- Datierung korrigiert: degradiert seit 07-21, nicht seit 08-16
  (der 08-16 war der Tag der Entdeckung) -- vier Wochen unbemerkt
- Nachweisluecke festgehalten: 1 von 2 Connectoren meldet healthy,
  nur die Connector-ANZAHL zeigt die Degradation -> Check nach TP11
- openclaw-Warnung korrigiert: welcher Tunnel einen Hostname bedient,
  entscheidet das DNS; kein CNAME zeigt auf die vier toten Tunnel,
  n8n zeigt korrekt auf bf-mm. Loeschen bleibt richtig als Hygiene
- Doku-Drift: bf-nas ist live 220c9958, nicht 70d6a4cf
- cf-tunnel-mapping.md Paragraph 15 als As-Built

TP25 -- 5-GHz-Umfeldscan am Manager: je EIN Fremdnetz pro AP, -86 bzw
-89 dBm. Band leer, Bloecke ueberlappungsfrei => beide ueblichen Gruende
fuer 20 MHz treffen nicht zu. Empfehlung: 20/40 behalten; der echte
Ausloeser ist die AP-Zahl (Band A = genau 2x40 MHz, mit zwei APs voll),
dann lautet die Wahl 20 MHz flottenweit gegen DFS akzeptieren.

TP30 -- neues Leak-Ereignis dokumentiert: list_wifi_interfaces gibt alle
Passphrasen im Klartext aus, damit sind fuenf WLAN-PSKs exponiert.
Als Falle aufgenommen. TP17.2-Stub entfernt (Verweise erklaeren den
Merge, ein Wegweiser ist nicht mehr noetig).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-24 07:22:44 +02:00
parent 93c32a2ad7
commit da199be925
2 changed files with 139 additions and 14 deletions

View File

@@ -346,3 +346,58 @@ Letzte in §9.2/§8 als „bleibt `.41`" geführte Origin-Klasse (`pve .41.100`,
- vnet-Route `5546dcb6…` von `bf-pve` auf den Mesh-Tunnel umhängen (Rollback = PATCH zurück; bf-pve bleibt Fallback).
- Team-Domain gemessen: `emsenhuber.cloudflareaccess.com` → Node-Identität `warp_connector@emsenhuber.cloudflareaccess.com`. Noch kein `warp_connector`-Tunnel im Account.
- Governance „Config nur via Nautobot" (TP21): CRS326-WG-Zeilen regulär via Golden Config, sobald das Device dort adoptiert ist — die alte ap1-Ausnahme gilt hierfür **nicht**.
## 15. Incident 2026-07-21 → ✅ GEFIXT 2026-08-24 — macmini-Connectoren gestoppt, HA fünf Wochen degradiert
**Symptom (erhoben 2026-08-16, gefixt 2026-08-24):** `bf-nas` und `bf-pve` liefen auf **je einem**
Connector statt zwei. Kein `530`, kein Round-Robin — reiner **Redundanzverlust**: die Dienste hinter
diesen Tunneln hingen an einem einzigen cloudflared-Prozess.
**Ursache — nicht das erwartete QUIC-Flap.** Die beiden macmini-Container standen auf
`Exited (0)`, `finishedAt` **beide auf `2026-07-21T13:00:53`** (gleiche Sekunde, Exit 0,
`restart=unless-stopped`, `TUNNEL_TRANSPORT_PROTOCOL=http2` korrekt gesetzt). Ein Absturz sieht anders
aus: gleiche Sekunde + Exit 0 + kein Neustart trotz `unless-stopped` = **ein `docker stop` bzw.
`compose down` auf genau diese zwei**. Die übrigen macmini-Container liefen die ganze Zeit, der Daemon
ist seither auch neu gestartet — Docker hat die zwei also als „vom Benutzer gestoppt" geführt.
⇒ **Die Datierung in TP16 war falsch: degradiert seit 2026-07-21, nicht seit dem 08-16.** Der 08-16 war
nur der Tag, an dem es *aufgefallen* ist. Zwischen Eintritt und Entdeckung lagen **vier Wochen**.
**Fix:** `docker start cloudflared-bfnas cloudflared-bfpve` auf dem macmini. Sonst nichts —
Tokens, Transport und Restart-Policy waren korrekt.
**Abnahme (2026-08-24):**
- CF-API: `bf-mm` / `bf-nas` / `bf-pve` je **2 Connectoren / 8 conns**, alle `healthy`.
- Connector-Log: `Registered tunnel connection … protocol=http2` (Konvention aus §13 gehalten).
- **Smoke-Test gegen das Round-Robin-Muster: 6 FQDNs über beide betroffenen Tunnel
(`gitea`/`nautobot`/`grafana` = bf-nas, `portainer`/`hass`/`vw` = bf-pve), je 6 Läufe = 36 Anfragen,
`530er = 0`.** Das reziproke Design hält: macmini hostet weder NAS- noch pve-Origins, die
macvlan-Host-Isolation aus §9 kann dort also nicht zuschlagen.
🔴 **Die eigentliche Lehre ist nicht der Fix, sondern die Nachweislücke.** Ein Tunnel mit einem von
zwei Connectoren meldet `healthy` — die Degradation ist über den Tunnel-Status **nicht sichtbar**, nur
über die **Connector-Anzahl**. Genau deshalb blieb sie vier Wochen unbemerkt und wurde beim
Doku-Aufräumen zufällig gefunden. **Ein HA-Design ohne Zähler auf die Redundanz ist kein HA-Design.**
⇒ Gehört als Check nach **TP11** (Monitoring): `connectoren < 2` je bf-Tunnel = Alarm.
### Korrektur: die vier toten Alt-Tunnel sind harmloser als notiert
Stand 2026-08-24, live erhoben: `openclaw`, `coolify`, `johnny2`, `TeilzeitCharlie` sind `down`,
0 Connectoren. Ihre **Ingress-Configs beanspruchen weiterhin Hostnames** — `openclaw` unter anderem
`n8n.emsenhuber.net` → `10.40.41.147:5678` (toter VLAN1-Origin), dazu `oc`, `dashboard`, `drawio`;
`coolify` → `10.40.41.133`; `johnny2` → `jc`; `TeilzeitCharlie` → `charlie`.
🔵 **Aber: kein einziger CNAME zeigt auf einen dieser vier Tunnel.** Alle 23 Tunnel-CNAMEs der Zone
zeigen auf `bf-mm`/`bf-nas`/`bf-pve`/`fm`/`terpene-db`; **`n8n.emsenhuber.net` zeigt korrekt auf
`bf-mm`**. ⇒ Die in TP16 notierte Sorge, ein wiederbelebter `openclaw` würde „exakt das alte
Round-Robin-Muster auf diesem Hostname" erzeugen, ist **so nicht richtig**: **welcher Tunnel einen
Hostname bedient, entscheidet das DNS**, nicht die Ingress-Config. Ein hochkommender `openclaw` wäre
inert, solange niemand `cloudflared tunnel route dns` dafür ausführt (was den CNAME umschreiben
*würde* — das ist der reale, aber aktive Angriffspfad). Das Round-Robin aus §9 war ein Problem
**mehrerer Connectoren auf EINEM Tunnel**, nicht mehrerer Tunnel auf einem Namen.
⇒ **Löschen bleibt richtig — als Hygiene und um die `route dns`-Falle zu entfernen, nicht als
Störungsbehebung.** Weiterhin user-gated (Löschen ist nicht umkehrbar).
📌 **Doku-Drift mitkorrigiert:** §10 führt `bf-nas` als `70d6a4cf`; live ist die Tunnel-ID
**`220c9958`** (Tunnel am 2026-07-12 neu angelegt, s. §11). §10 gilt sonst unverändert.
ℹ️ **Nicht Teil des BF-HA-Designs** (und daher kein Defekt, obwohl sie 1 Connector haben):
`fm.emsenhuber.net` (Standort FM) und `terpene-db` (eigenes Projekt).

View File

@@ -278,12 +278,30 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
erneut rotieren. Abnahme = ein Aufruf **mit** den Headern (antwortet) **und** einer **ohne** (403) —
der Erfolgsfall allein beweist nichts, der Hostname könnte auf `bypass` stehen.
### TP16 — CF-Tunnel: Round-Robin killen + reziprokes HA ▸ ✅ KERN UMGESETZT (2026-07-10) — ⚠️ **HA aktuell degradiert (Live-Befund 2026-08-16)** — `docs/cf-tunnel-mapping.md §10`, #1033
- 🟠 **BEFUND 2026-08-16 (beim Doku-Aufräumen live über die CF-API erhoben, kein Eingriff): das reziproke HA läuft nur noch auf einem von drei Tunneln.**
### TP16 — CF-Tunnel: Round-Robin killen + reziprokes HA ▸ ✅ **HA WIEDER VOLL (2026-08-24)** — Kern 2026-07-10 — `docs/cf-tunnel-mapping.md §10 + §15`, #1033
- ✅ **GEFIXT 2026-08-24 — Ursache war ein `docker stop`, kein QUIC-Flap.** Die beiden macmini-Connectoren
(`cloudflared-bfnas`, `cloudflared-bfpve`) standen auf `Exited (0)`, **beide `finishedAt` auf derselben
Sekunde `2026-07-21T13:00:53`**, bei korrekt gesetztem `restart=unless-stopped` und `http2`. Fix =
`docker start` der zwei, sonst nichts. **Abnahme: alle drei bf-Tunnel je 2 Connectoren / 8 conns,
und 36 Anfragen über 6 FQDNs beider betroffener Tunnel mit `530er = 0`.** Details `§15`.
- 🔴 **Die Datierung im Befund unten war falsch:** degradiert **seit 2026-07-21**, nicht seit dem 08-16 —
der 08-16 war der Tag der *Entdeckung*. **Vier Wochen unbemerkt.**
- 🔴 **Die eigentliche Lehre ist die Nachweislücke:** ein Tunnel mit 1 von 2 Connectoren meldet
`healthy`. Über den Tunnel-Status ist die Degradation **unsichtbar**, nur die **Connector-Anzahl**
zeigt sie. ⇒ Check nach **TP11**: `connectoren < 2` je bf-Tunnel = Alarm. **Ein HA-Design ohne
Zähler auf die Redundanz ist kein HA-Design.**
- 📜 **Ursprünglicher Befund 2026-08-16 (Historie, Ursache s.o.):**
- `bf-mm` = **2 Connectoren** (je 4 conns) ✅ · `bf-nas` = **1 Connector** (3 conns) 🟠 · `bf-pve` = **1 Connector** (4 conns) 🟠.
- **Bedeutung:** die Dienste hinter `bf-nas` (gitea, grafana, pve-mcp, **vw**, ds-bf, nautobot) und `bf-pve` (pve, ccu, iobroker, z2m25, portainer, **hass**, ha-mcp) hängen jeweils an **einem einzigen** cloudflared-Prozess. Fällt dessen Host aus, sind sie weg — genau der Zustand, den TP16 beseitigt hat. **Kein `530`/Round-Robin-Problem** (das bleibt strukturell gelöst), sondern **Redundanzverlust**.
- **Bekanntes Muster:** identisch zum Incident vom 2026-07-16 (macmini-Connectoren flappten unter QUIC → Fix `TUNNEL_TRANSPORT_PROTOCOL=http2`). Diesmal sind die *macmini*-Connectoren oben (bf-mm hat 2), es fehlt je **ein** Gegenstück auf NAS/pve. **Nächster Schritt (eigene Session):** auf NAS und pve nachsehen, welcher der beiden cloudflared-Container nicht läuft, und ob es der `http2`-Konventionsfall ist.
- 🧹 **Nebenbefund beim selben Sweep — Alt-Tunnel mit VLAN1-Origins (alle `down`, 0 Connectoren, daher aktuell harmlos):** `openclaw` (→ `10.40.41.147/.148/.139`), `coolify` (→ `10.40.41.133`), `johnny2`, `TeilzeitCharlie`. ⚠️ **`openclaw` beansprucht `n8n.emsenhuber.net`, das produktiv auf `bf-mm` läuft** — käme der Tunnel je wieder hoch, entstünde exakt das alte Round-Robin-Muster auf diesem Hostname. **Empfehlung: die vier toten Tunnel löschen** (user-gated, Löschen ist nicht umkehrbar) — gehört fachlich zu **TP19** (VLAN1-Retirement: `.41.133` war eines der „unidentifizierten VLAN1-Geräte" aus TP19 B1.2 — hiermit als coolify-Origin identifiziert).
- ~~**Bekanntes Muster:** identisch zum Incident vom 2026-07-16~~ 🔴 **war es NICHT** — s. Fix oben. Ursprungstext:
**Bekanntes Muster:** identisch zum Incident vom 2026-07-16 (macmini-Connectoren flappten unter QUIC → Fix `TUNNEL_TRANSPORT_PROTOCOL=http2`). Diesmal sind die *macmini*-Connectoren oben (bf-mm hat 2), es fehlt je **ein** Gegenstück auf NAS/pve. **Nächster Schritt (eigene Session):** auf NAS und pve nachsehen, welcher der beiden cloudflared-Container nicht läuft, und ob es der `http2`-Konventionsfall ist.
- 🧹 **Nebenbefund beim selben Sweep — Alt-Tunnel mit VLAN1-Origins (alle `down`, 0 Connectoren, daher aktuell harmlos):** `openclaw` (→ `10.40.41.147/.148/.139`), `coolify` (→ `10.40.41.133`), `johnny2`, `TeilzeitCharlie`. ⚠️ **`openclaw` beansprucht `n8n.emsenhuber.net`, das produktiv auf `bf-mm` läuft** — käme der Tunnel je wieder hoch, entstünde exakt das alte Round-Robin-Muster auf diesem Hostname. **Empfehlung: die vier toten Tunnel löschen** (user-gated, Löschen ist nicht umkehrbar)
🔵 **Begründung korrigiert 2026-08-24:** die Sorge „käme der Tunnel wieder hoch, entstünde das alte
Round-Robin auf diesem Hostname" ist **so nicht richtig** — **welcher Tunnel einen Hostname bedient,
entscheidet das DNS**, und live zeigt **kein einziger CNAME** auf die vier (`n8n` zeigt korrekt auf
`bf-mm`). Ein hochkommender `openclaw` wäre inert. Der reale Pfad ist ein *aktives*
`cloudflared tunnel route dns`, das den CNAME umschreibt. ⇒ **Löschen bleibt richtig — als Hygiene
und um genau diese Falle zu entfernen, nicht als Störungsbehebung.** — gehört fachlich zu **TP19** (VLAN1-Retirement: `.41.133` war eines der „unidentifizierten VLAN1-Geräte" aus TP19 B1.2 — hiermit als coolify-Origin identifiziert).
> **✅ Umgesetzt (2026-07-10, eigene Session):** reziprokes **3-Tunnel-HA** live (bf-nas `70d6a4cf` / bf-pve `f7fdf3a6` / bf-mm `7a322261`), 6 Connectoren (2/Host, je Fremdhost), 19 FQDNs Loop-Smoke **0×530**, HA per Host-Ausfall-Sim bewiesen. Round-Robin-#1033 **strukturell weg**. As-Built = `docs/cf-tunnel-mapping.md §10`. **Schritt 5 Access-Strang: ~~`vw` bypass→geschützt via WARP~~ — 🔴 GESTRICHEN (User-Constraint 2026-08-14, s. TP16.2). Verbleibend offen: `hass`/`ha-mcp` 400/403; `gateway-dw` (WG→404) klären.**
- **Symptom (User):** FQDNs über CF werden **sporadisch / „sehr unsicher"** aufgelöst = #1033-Muster zurück („jeden 3. Schuss eine Niete"). User hat alle 3 cloudflared-Images + Container aktualisiert/neu gestartet.
- **✅ Root-Cause endgültig (User-Diagnose bestätigt): macvlan/ipvlan-Host-Isolation.** Ein cloudflared-Connector ist **blind für macvlan/ipvlan-Container auf seinem EIGENEN Host** (Linux-Kernel-Regel), erreicht aber Fremdhost-L2 + co-lokierte Bridge-Container. Mehrere Connectoren auf EINEM Tunnel = geteilter Ingress + CF-**Round-Robin** → jede Origin, die auf dem Host *eines* Connectors liegt, fällt bei ~**1/N** aus. **Strukturell**, nicht durch „Origins fixen" heilbar. Bsp: `omada .20.175`/`pve-mcp .20.173`/`gitea .20.157`/`grafana .20.109` = NAS-macvlan → vom NAS-Connector NICHT erreichbar.
@@ -533,12 +551,6 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
</details>
### TP17.2 — einheitliches Geräte-Passwort (Shelly `SetAuth`) ▸ ➡️ **NACH [TP30](#tp30) VERSCHOBEN (2026-08-24)**
> **User-Entscheid:** TP30 ist das Sammelbecken für Credentials, die neu gesetzt oder rotiert werden
> müssen — TP17.2 ist genau das (Erstvergabe) und teilt sich mit der PSK-Rotation den Geräte-Durchgang.
> Der vollständige Text steht dort als **Posten #3**. Diese Zeile bleibt nur, damit die Nummer nicht
> ins Leere zeigt; **TP17.2 ist kein eigenes TP mehr.**
### TP17.3 — Shelly-Regression nach der VLAN30-Migration ▸ ✅ **ERLEDIGT (2026-08-23, Folge-Session): beide Geräte repariert, Ursache `eco_mode` bewiesen** — offen nur noch der Flotten-Entscheid (gehört TP17.1) — aus TP17 herausgelöst, User-Meldung
> **User-Meldung 2026-08-23:** „vor einiger zeit hast du an den shellys änderungen vorgenommen. das
> hatte bei einigen einen bösen seiteneffekt: **lüfter-shelly musste ich doppelt drücken**. der übelste
@@ -815,11 +827,49 @@ begründet** — er kaufte Redundanz, keine Abdeckung. Das ist eine andere Frage
(c) das Gerät selbst mit 5-min-Duty-Cycle → dann bleibt es unverändert.
🚫 **Nicht die alte Power-Save-Merkregel wiederbeleben** — die ist am 2026-08-13 als Fehldiagnose
zurückgezogen (`ref_wifi_powersave_multicast`).
2. ⚖️ **Entscheidung 5 GHz auf 20 MHz** (statt heute 20/40): **+3 dB Link-Budget**, für einen
1,2-Mbit-Call an Durchsatz irrelevant. Ein-Wort-Change im Template. Steht seit dem Terrassen-Fix
ohne Dringlichkeit da — **Christophs Entscheidung**, keine Empfehlung mehr.
2. ⚖️ **Entscheidung 5 GHz auf 20 MHz** (statt heute 20/40) — **✅ 5-GHz-Umfeldscan durchgeführt
2026-08-24, Empfehlung: NICHT verschmälern, Entscheidung an einen Auslöser hängen.**
⚠️ **2,4 GHz NICHT vorschnell drosseln** — dort hängen ~20 IoT-Geräte.
**Messung** (`/interface wifi scan` **am Manager**, cap-wifi3 = ap1 / cap-wifi1 = ap2, 10–12 s):
| vom Radio auf | fremdes 5-GHz-Netz | Kanal | Signal | Abstand zum eigenen AP |
|---|---|---|---|---|
| **ap1** (5180/Ce) | `Drei_H288A_5G_acHG` | 5745/ac/**80 MHz** | **−86 dBm** | 19 dB darunter |
| **ap2** (5220/Ce) | `LiwestBB93-5G` | 5200/ac/**80 MHz** (Block 5180–5240) | **−89 dBm** | 24 dB darunter |
⇒ **Das 5-GHz-Band ist an beiden Standorten praktisch leer.** Genau **ein** Fremdnetz je AP, beide
rund 20 dB unter dem eigenen Pegel. Der Nachbar `LiwestBB93-5G` liegt mit 80 MHz zwar formal über
**beiden** unserer Blöcke — bei −89 dBm ist das ohne Wirkung.
🎯 **Warum das gegen 20 MHz spricht — die zwei üblichen Gründe treffen hier nicht zu:**
- **Fremdinterferenz:** existiert nicht (−86/−89). Ein schmalerer Kanal hätte nichts abzuwehren.
- **Selbstüberlappung:** existiert nicht. ap1 `5180/Ce` = ch36+40, ap2 `5220/Ce` = ch44+48 —
überlappungsfrei (Fund C, 08-17).
- **Bleibt allein das +3 dB Link-Budget** — und das ist zum guten Teil **schon vorhanden**: in einem
40-MHz-BSS sendet die Ratenanpassung an schwache Clients ohnehin auf dem Primärkanal in 20 MHz.
Den Ceiling zahlen aber **alle** Clients dauerhaft. **Der Nutzen geht an die, die ihn schon haben.**
- **Und es löst das gemessene Problem nicht:** die offenen Schwachstellen sind die
Redundanz-Lücken (Schlafzimmer −84,6 / 38 %, Bad −82,3 / 24 %) **am Gegen-AP**. +3 dB macht aus
38 % Verlust keine 0 % — das ist eine Platzierungs-/AP-Zahl-Frage, keine Kanalbreiten-Frage.
🔑 **Der echte Auslöser ist die AP-Zahl, nicht die Interferenz** — und das ist der Grund, die
Entscheidung *jetzt* zu treffen statt sie offenzulassen. Beide Kanäle stehen hart in **Band A**
(`ch-5g-ap1`=5180, `ch-5g-ap2`=5220, kein `skip-dfs-channels`), und Band A hat unter ETSI genau
**4 × 20 MHz = 2 × 40 MHz**. Mit zwei APs ist es damit **exakt aufgebraucht**:
| Szenario | bei 40 MHz | bei 20 MHz |
|---|---|---|
| 2 APs (heute) | ✅ passt genau, überlappungsfrei | ✅ passt, +3 dB, halber Ceiling |
| **3.–4. AP** | ❌ Band A voll ⇒ **nur mit DFS** (Band B ch52–64: Radar-Events, 60 s CAC) | ✅ 4 saubere Kanäle, **kein DFS** |
⇒ **Empfehlung: 20/40 MHz beibehalten.** Die Verschmälerung ist heute ein Preis ohne Gegenwert.
Sie wird **fällig, sobald ein dritter AP dazukommt** — dann lautet die Wahl nicht mehr „20 gegen 40",
sondern **„20 MHz flottenweit" gegen „DFS akzeptieren"**, und dafür ist 20 MHz die ruhigere Antwort.
Ein Zwischenweg existiert (ap1 behält 40 MHz, AP 2+3 fahren 20 MHz auf 5220/5240) und braucht
ebenfalls kein DFS.
📌 **Damit ist dieser Punkt entscheidungsreif und an einen Auslöser gebunden statt offen.**
**Fund E (`signal-range`-Boden am Manager) — abgestuft, NICHT umsetzen.** Der Sticky-Client vom 08-20
reproduzierte sich am 08-22 nicht (Treppe: sauberer Wechsel ap2→ap1, 0 % über 57 s). Und auf der
Terrasse würde ein Boden **schaden**, weil es dort keinen besseren AP gibt, auf den gesteuert werden
@@ -844,7 +894,12 @@ Kanalarbeit **Breite VOR Frequenz** ändern, sonst erzeugt man auf dem Weg eine
⚠️ `steering=`/Channel-Änderungen **re-applien alle VAPs und werfen jeden Client kurz raus** — nicht
während eines Calls deployen, `/system backup` je AP vorher.
🔬 **Messwerkzeug — drei Regeln, jede aus einem Fehlbefund geboren:**
🔬 **Messwerkzeug — vier Regeln, jede aus einem Fehlbefund geboren:**
- 🔴 **Für einen Kanal-/Umfeldscan NICHT `list_wifi_interfaces` benutzen** (Fund 2026-08-24): das Tool
gibt `security.passphrase` **aller** Profile im Klartext aus — ein Read für die Kanalbreite hat so
fünf WLAN-Passphrasen in ein Transkript geschrieben, den IoT-PSK inklusive. Für Kanäle reicht
`/interface wifi channel print detail`; für die `cap-wifiN`-Zuordnung `… print where master=yes`
mit Feldauswahl. **Der Scan selbst (`/interface wifi scan`) ist unbedenklich.**
- 🔴 **Die `cap-wifiN`-Nummern sind NICHT stabil.** Der Manager vergibt sie in der Reihenfolge, in der
sich die CAPs anmelden — nach dem ap1-Rückbau sind `cap-wifi1/2` = **ap2** und `cap-wifi3/4` = **ap1**,
umgekehrt zur früher fest verdrahteten Tabelle. ⇒ **Die Zuordnung gehört zum Messlauf**, nicht zur
@@ -1086,7 +1141,22 @@ Es ist **ein** Passwort für alle vier Geräte — die „Überlebensversicherun
</details>
#### 🔴 Neues Leak-Ereignis 2026-08-24 — der IoT-PSK ist erneut exponiert
Beim 5-GHz-Umfeldscan für TP25 wurde `mcp__mikromcp__list_wifi_interfaces` gegen den Manager gefahren,
um die `cap-wifiN`-Zuordnung zu bestimmen. **Das Tool gibt `security.passphrase` aller Profile im
Klartext zurück** — damit stehen **alle fünf WLAN-Passphrasen** (`main`, `iot`, `media`, `untrusted`,
`guest`) in einem Sitzungstranskript. Kein Werkzeug hat versagt; es war das falsche Werkzeug für eine
Kanalabfrage. **Betrifft Posten #2 (IoT-PSK) und zusätzlich vier bisher unverbrannte Passphrasen.**
⚖️ **Nach der „harten Ausnahme" oben ist das ein Vorziehgrund** — Entscheidung gehört Christoph.
Gegenargument, das dieselbe Rechnung wie am 08-23 ergibt: der IoT-PSK lag ohnehin schon im Klartext
in der Git-Historie, neu exponiert sind vor allem `main`/`media`/`untrusted`/`guest` — und die kosten
beim Rotieren **wenige** Clients, nicht 26. ⇒ **`main` und `guest` wären billig und einzeln machbar,
unabhängig vom gebündelten Durchgang.**
#### Fallen, die für jedes Setzen/Rotieren gelten (nicht neu erheben)
- 🔴 **Kein Read auf `/interface/wifi`, wenn nur Kanäle/Interfaces gebraucht werden** —
`list_wifi_interfaces` liefert alle Passphrasen im Klartext mit (Leak vom 2026-08-24, s.o.).
Feldauswahl benutzen oder `/interface wifi channel print detail`.
- 🔴 **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`.