sshpass -p repo-weit weg + vier TP15-Cutover-Skripte archiviert
sshpass -p schreibt das Passwort in argv, wo es in ps und jedem argv-Trace steht -- die Klasse, an der am 2026-08-22 das Core-Passwort verbrannt ist. Nach gc-transaktion.py (voriger Commit) jetzt auch die fuenf unter routeros/: SSHPASS-Env + sshpass -e. Nachweis, gemessen statt gelesen: - alle 13 subprocess.run mit sshpass tragen env= (per AST geprueft; ohne env waere SSHPASS leer und alles still kaputt) - Signaturen passen zu den Aufrufen (AST-Arity; py_compile findet das NICHT) - echter Lauf des gepatchten Codes gegen den lebenden Core: backup-core.py importiert, IP zur Laufzeit auf 10.40.99.1 -> "name: crs326-core", rc=0 - Passwort in argv? nein. In ps waehrend der Verbindung? nein, 40 Stichproben - Negativkontrolle: derselbe Test mit einem Dummy-Wert ueber die alte -p-Form -> 36 Treffer. Die Probe ist also nicht blind, das "nein" hat Aussagekraft Mitgefixt, weil es im umgebauten Code lag: apply-core-cutover-l3.py griff in run_silent auf ein pw zu, das dort gar nicht existierte -- jeder Fehlerfall endete in einem NameError statt in der gedachten Meldung. Fuer TP30 aendert das NICHTS: der Weg ist zu, der Wert bleibt verbrannt. Posten #1 (MikroTik-admin) bleibt faellig. Im TP so hingeschrieben, damit es niemand als erledigt liest. --- Archivierung (Christoph-Entscheid) --- Beim Fixen fiel auf, dass alle vier Cutover-Skripte auf tote Adressen zeigten: apply-core-cutover-l3.py 10.40.41.211 tot (VLAN41 seit 2026-08-27 weg) backup-core.py 10.40.41.211 tot restore-core.py 192.168.88.1 tot (Werks-Temp-Pfad) backup-ap1.py 10.40.10.1 ANTWORTET -- ist aber der CORE backup-ap1.py war der gefaehrliche: er waere nicht gescheitert, er haette den Core gesichert und die Datei ap1-pre-core-cutover-*.backup genannt. Wer das spaeter zurueckspielt, spielt Core-Config auf einen AP. Entscheid war archivieren, nicht reparieren -- der Cutover ist am 2026-08-08 durch, die Skripte haben ihre Aufgabe erfuellt. Sie liegen jetzt unter routeros/archiv-tp15-cutover/ mit README nach dem Muster von switch/. Die Pfad-Nebenwirkungen des Verschiebens sind ABSICHTLICH nicht repariert (backup-core.py schriebe jetzt ins Archivverzeichnis, apply-core-cutover-l3.py faende seine .rsc nicht mehr) -- sie zu reparieren hiesse, die Skripte wieder lauffaehig zu machen, und das ist gerade nicht die Absicht. Der sshpass-Fix wurde trotzdem VOR dem Verschieben gemacht: Archiv-Code wird abgeschrieben, also soll dort das richtige Muster stehen. import-core-rsc.py bleibt, wo es ist -- als einziges generisch nuetzlich. Sein Default-Host ist ebenfalls tot (--host mitgeben), und in --host steckt ein zweiter latenter Bug: sys.argv[1] wird als RSC-Pfad gelesen, bevor auf --host geprueft wird. NICHT gefixt, eigene Runde. Zeiger gesetzt in: CLAUDE.md (sshpass-Gotcha), teilprojekte.md (TP30), teilprojekte-archiv.md (TP15), Handoff 2026-08-31. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,24 +102,72 @@ Rollback-Weg (der Snapshot liegt bereit):
|
||||
`python3 nautobot/gc-transaktion.py rollback --change-id TP25-fund-e-ft-over-ds`
|
||||
— erzeugt einen **Vorschlag**, der gelesen werden will, und pusht bewusst nicht selbst.
|
||||
|
||||
## 🔧 Nebenbefund: `sshpass -p` in sechs Skripten
|
||||
## ✅ Nebenbefund erledigt: `sshpass -p` ist repo-weit weg (2026-08-31, zweiter Durchgang)
|
||||
|
||||
`nautobot/gc-transaktion.py` rief `sshpass -p <PW>` auf — das schreibt das Passwort in `argv`, wo es
|
||||
in `ps` und jedem argv-Trace steht. Das ist die Klasse, an der am 2026-08-22 das Core-Passwort
|
||||
verbrannt ist, und CLAUDE.md verbietet sie ausdrücklich. **In `gc-transaktion.py` behoben**
|
||||
(`SSHPASS`-Env + `-e`), weil das Skript für diese Aufgabe laufen musste.
|
||||
|
||||
🔴 **Fünf weitere Dateien haben dasselbe Muster und sind NICHT angefasst** (Stop-Bedingung —
|
||||
gehört in eine eigene Runde, sinnvollerweise mit TP30):
|
||||
`sshpass -p <PW>` schreibt das Passwort in `argv`, wo es in `ps` und jedem argv-Trace steht — die
|
||||
Klasse, an der am 2026-08-22 das Core-Passwort verbrannt ist. **Alle sechs betroffenen Skripte laufen
|
||||
jetzt über `SSHPASS`-Env + `sshpass -e`:**
|
||||
|
||||
```
|
||||
routeros/import-core-rsc.py Z. 50, 74
|
||||
routeros/apply-core-cutover-l3.py Z. 29, 55
|
||||
routeros/backup-core.py Z. 29, 41
|
||||
routeros/restore-core.py Z. 30, 42
|
||||
routeros/backup-ap1.py Z. 29, 41
|
||||
nautobot/gc-transaktion.py (im ersten Durchgang, weil es laufen musste)
|
||||
routeros/import-core-rsc.py
|
||||
routeros/archiv-tp15-cutover/apply-core-cutover-l3.py ┐
|
||||
routeros/archiv-tp15-cutover/backup-core.py │ am selben Tag archiviert,
|
||||
routeros/archiv-tp15-cutover/restore-core.py │ s. unten -- aber VOR dem
|
||||
routeros/archiv-tp15-cutover/backup-ap1.py ┘ Verschieben noch gefixt
|
||||
```
|
||||
|
||||
**Warum Archiv-Code trotzdem gefixt wurde:** Archiv wird abgeschrieben. Wer sich dort ein
|
||||
sshpass-Muster holt, soll das richtige finden.
|
||||
|
||||
**Nachweis — gemessen, nicht gelesen:**
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| Alle 13 `subprocess.run`, die sshpass starten, tragen `env=` | ✓ per AST geprüft (ohne `env` wäre `SSHPASS` leer und alles kaputt) |
|
||||
| Signaturen passen zu den Aufrufen | ✓ per AST, Arity-Abgleich — `py_compile` findet so etwas **nicht** |
|
||||
| Echter Lauf des gepatchten Codes gegen den lebenden Core | ✓ `backup-core.py` importiert, IP zur Laufzeit auf `10.40.99.1`, Antwort `name: crs326-core`, rc=0 |
|
||||
| Passwort in `argv`? | **nein** |
|
||||
| Passwort in `ps` während der Verbindung? | **nein**, 40 Stichproben |
|
||||
| **Negativkontrolle** — Dummy-Wert über die alte `-p`-Form | **36 Treffer** ⇒ die Probe ist nicht blind, das „nein" oben hat Aussagekraft |
|
||||
|
||||
🔴 **Für TP30 ändert das nichts.** Der Weg ist zu, der Wert bleibt verbrannt — ein Passwort, das
|
||||
einmal in einem Transkript stand, wird nicht dadurch sauber, dass die Leitung dicht ist.
|
||||
Rotation von Posten #1 bleibt fällig.
|
||||
|
||||
⚠️ **Mitgefixt, weil es in umgebautem Code lag:** `apply-core-cutover-l3.py` griff in `run_silent`
|
||||
auf ein `pw` zu, das dort gar nicht existierte — **jeder Fehlerfall endete in einem `NameError`
|
||||
statt in der gedachten Meldung.**
|
||||
|
||||
### 🔴 Und dabei aufgefallen: die IPs in diesen fünf Skripten sind Schrott
|
||||
|
||||
Live geprüft am 2026-08-31, **bewusst NICHT stillschweigend geändert** — nur je ein lauter Header
|
||||
in die Datei:
|
||||
|
||||
| Skript | Ziel-IP | Realität |
|
||||
|---|---|---|
|
||||
| `import-core-rsc.py`, `apply-core-cutover-l3.py`, `backup-core.py` | `10.40.41.211` | **tot** — VLAN41 gibt es seit 2026-08-27 nicht mehr |
|
||||
| `restore-core.py` | `192.168.88.1` | **tot** — Werks-Temp-Pfad; dazu ein hartkodierter Backup-Dateiname vom 2026-08-06 |
|
||||
| `backup-ap1.py` | `10.40.10.1` | 🔴 **antwortet — ist aber der CORE** (VLAN10-SVI, tcp/22 offen). ap1 ist `10.40.99.11`. |
|
||||
|
||||
**`backup-ap1.py` ist der gefährliche:** er scheitert nicht, er sichert das **falsche Gerät** und legt
|
||||
die Datei als `ap1-pre-core-cutover-*.backup` ab. Wer dieses Backup später zurückspielt, spielt eine
|
||||
Core-Config auf einen AP.
|
||||
|
||||
✅ **Entschieden (Christoph, 2026-08-31): archiviert, nicht repariert.** Die vier liegen jetzt unter
|
||||
[`routeros/archiv-tp15-cutover/`](../routeros/archiv-tp15-cutover/README.md) mit README nach dem
|
||||
Muster von [`switch/`](../switch/README.md) — der Cutover ist am 2026-08-08 durchgezogen, die Skripte
|
||||
haben ihre Aufgabe erfüllt.
|
||||
|
||||
⚠️ **Die Pfad-Nebenwirkungen des Verschiebens sind absichtlich NICHT repariert** (`backup-core.py`
|
||||
schriebe jetzt ins Archivverzeichnis, `apply-core-cutover-l3.py` fände seine `.rsc` nicht mehr).
|
||||
Sie zu reparieren hieße, die Skripte wieder lauffähig zu machen — das ist gerade nicht die Absicht.
|
||||
|
||||
**`import-core-rsc.py` bleibt**, wo es ist: als einziges generisch nützlich. Sein Default-Host ist
|
||||
aber ebenfalls tot ⇒ **`--host` mitgeben**. (Und in `--host` steckt ein zweiter latenter Bug:
|
||||
`sys.argv[1]` wird als RSC-Pfad gelesen, bevor auf `--host` geprüft wird — die Option kann so, wie
|
||||
sie dokumentiert ist, nie greifen. **Nicht gefixt**, gehört zu einer eigenen Runde.)
|
||||
|
||||
**Entwarnung zum Snapshot:** `/export` auf ROS 7.24 gibt WLAN-Passphrasen **gar nicht** aus
|
||||
(0 Vorkommen im Vollexport, live geprüft). Die Transaktionsakte im Git ist sauber.
|
||||
|
||||
|
||||
@@ -758,6 +758,12 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
|
||||
|
||||
<a id="tp15"></a>
|
||||
|
||||
> 📦 **Nachtrag 2026-08-31:** die vier Skripte, die den Cutover begleitet haben
|
||||
> (`apply-core-cutover-l3`, `backup-core`, `restore-core`, `backup-ap1`), liegen jetzt unter
|
||||
> [`routeros/archiv-tp15-cutover/`](../routeros/archiv-tp15-cutover/README.md). Sie zeigten alle
|
||||
> auf tote Adressen — `backup-ap1.py` allerdings auf eine **lebende falsche** (`10.40.10.1` ist die
|
||||
> VLAN10-SVI des Core, nicht ap1) und hätte still das falsche Gerät gesichert.
|
||||
>
|
||||
### TP15 — HW-Refresh: Switching + Router ▸ ✅ **ABGESCHLOSSEN (2026-08-08)** — Bring-up beider CRS326 + Branch-Tausch (2026-07-23) **und** Core-Tausch/L3-Umzug (2026-08-08, Durchführung s. TP21.1) sind durch — `docs/hw-refresh-requirements.md`, Memory `project_mikrotik_commit_nautobot_gc`
|
||||
> 🔌 **Scope-Änderung 2026-08-16 (User-Entscheid): die DC-USV ist aus diesem TP herausgelöst und heißt jetzt **TP24**.** Sie war der letzte offene Rest hier, hat mit Switching/Routing sachlich nichts zu tun und trägt eigene Entscheidungen (Elektrik, Batterie, Standort). TP15 ist damit inhaltlich zu.
|
||||
> *Vorherige Header-Fassung (Stand 2026-08-05, überholt): „🟢 CRS326-Bring-up + Branch-Tausch DURCH (2026-07-23); Core-Tausch/L3-Umzug **vorbereitet, Cutover-Config materialisiert (2026-08-05)**, Cutover = nächstes Wartungsfenster."*
|
||||
|
||||
@@ -1773,6 +1773,16 @@ Umzug **nebeneinander**, ein zweiter AP am selben Punkt bringt nichts und stört
|
||||
| 3 | **Shelly-Gerätepasswort** *(vormals TP17.2)* | 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 |
|
||||
|
||||
> ✅ **Der Leak-MECHANISMUS hinter #1 ist seit 2026-08-31 zu — der Wert bleibt trotzdem verbrannt.**
|
||||
> Alle sechs Skripte im Repo, die `sshpass -p <PW>` benutzten (`nautobot/gc-transaktion.py` und
|
||||
> `routeros/import-core-rsc.py` sowie die vier TP15-Cutover-Skripte, die am selben Tag nach
|
||||
> `routeros/archiv-tp15-cutover/` gewandert sind), laufen jetzt über `SSHPASS`-Env + `sshpass -e`
|
||||
> — **auch die archivierten**, denn Archiv-Code wird abgeschrieben. **Kontrolliert gemessen**, nicht behauptet: mit `-e` taucht
|
||||
> das Passwort in 40 `ps`-Stichproben während einer laufenden Verbindung **nicht** auf, und die
|
||||
> Negativkontrolle (ein Dummy-Wert über die alte `-p`-Form) wurde **36-mal** gesehen — die Probe ist
|
||||
> also nicht blind. 🔴 **Das ändert an #1 nichts:** ein Wert, der einmal in einem Transkript stand,
|
||||
> wird nicht dadurch sauber, dass der Weg dorthin geschlossen ist. Rotation bleibt fällig.
|
||||
>
|
||||
> ℹ️ **#3 war bis 2026-08-24 TP17.2** und ist jetzt vollständig hier (s. Detailabschnitt unten) —
|
||||
> es benutzt denselben Geräte-Durchgang wie #2, **ein Reboot statt zwei**. #4 gehört sachlich zu
|
||||
> **TP14.4**, das als TP bestehen bleibt (dort steckt das CF-Access-Profil, nicht nur der Token).
|
||||
|
||||
Reference in New Issue
Block a user