Sicherungen mit dem Lizenzschluessel verschluesselt, optional per FTP (#530)
Eine Sicherung des Managers ist jetzt als Ganzes mit dem Lizenzschluessel verschluesselt. Beim Zurueckspielen wird der eigene Schluessel probiert; passt er nicht, fragt die Oberflaeche nach dem Lizenzschluessel der Quellinstallation. Der Lizenzschluessel ist der eine Wert, den jede Installation ohnehin hat, und er liegt im Manager, nicht neben den Archiven. Damit faellt der Grund weg, aus dem die taegliche Sicherung bisher keine Zugangsdaten enthielt: Eine Passphrase haette gespeichert werden muessen, und neben den Sicherungen waere sie wirkungslos gewesen. Jetzt reisen die Zugangsdaten mit, und eine Sicherung uebersteht den Maschinenwechsel ohne Passphrase. LicenseBackupCipher: eigener Behaelter .clawdbak. Kopf mit Schluesselprobe, das Manifest als eigener Abschnitt, das ZIP in 1-MiB-Stuecken mit AES-256-GCM und Endmarke. PBKDF2 aus Lizenzschluessel und festem Salt, der Schluessel normiert. Kein RAR (braucht das lizenzpflichtige Herstellerprogramm), kein ZIP mit Kennwort (kann .NET nicht schreiben, ZipCrypto ist gebrochen, und mit abgeleitetem Schluessel braechte 7-Zip-Vertraeglichkeit nichts). Zurueckspielen: Die Schluesselprobe laeuft VOR dem Anhalten der Instanz. Passt der Schluessel nicht, antwortet der Endpunkt mit 422 und dem Code fremde_lizenz, und ein Fenster verlangt den Schluessel der Quelle. ManagerBackups: Gefuehrte Instanzen sichern sich nicht mehr selbst, weil nur der Manager den Schluessel hat; er liest ihre Einstellungen aus InstanceSettings.json. Einmal am Tag auch ueber einen Neustart des Managers hinweg. Ohne Lizenzschluessel wird nichts gesichert, auch nicht ersatzweise unverschluesselt. FTP (FluentFTP, schon im Loesungsbaum): TLS wo angeboten, requireTls erzwingt es; Upload unter .part-Namen und danach umbenannt; Aufraeumen auf dem Server je Instanz; ein gescheiterter Upload laesst die lokale Sicherung stehen. Das Kennwort liegt verschluesselt in manager.json und geht nie an die Oberflaeche. Welche Datei zu welcher Instanz gehoert, entscheidet ein Zeitstempel nach dem Namen und nicht das Praefix - Test und Test_2 werden nicht mehr verwechselt. Grenze, bewusst und dokumentiert (Konzept 9.10): Wer Lizenzschluessel und Archiv hat, hat die Zugangsdaten. Der Schluessel ist dem Hersteller bekannt und gilt fuer alle Instanzen einer Installation. Nicht ueber die Oberflaeche abgenommen: Fenster fuer die fremde Lizenz und FTP gegen einen echten Server stehen als Block H in #537. 860 Tests gruen, 0 Warnungen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -269,10 +269,8 @@ Produktions- und eine Testinstanz nebeneinander betreiben.
|
||||
|
||||
## 7 — Noch zu klären
|
||||
|
||||
**Sicherungen im Manager — zurückgestellt** (2026-09-08, #530). Erst soll der Rest
|
||||
laufen. Die gemeinsame Aufbewahrung ist mit Stufe 1 ohnehin erledigt, der
|
||||
verbleibende Gewinn ist damit kleiner als anfangs gedacht: Es bliebe, auch von
|
||||
einer Instanz sichern zu können, die gerade nicht läuft.
|
||||
**Sicherungen im Manager — gebaut** (2026-09-11, #530): verschlüsselt mit dem
|
||||
Lizenzschlüssel, auf Wunsch per FTP hinaus. Siehe Abschnitt 9.10.
|
||||
|
||||
**Eine Sache ist daran aber schon entschieden:** Zurückspielen heißt, in ein
|
||||
Instanzverzeichnis zu schreiben, und das darf **ausschließlich bei inaktiver
|
||||
@@ -957,3 +955,79 @@ bestätigt:
|
||||
| `--managed` + gültige Unterschrift | Instanz kommt hoch, meldet ihren Named Pipe |
|
||||
| Unterschrift für ein anderes Verzeichnis | „Lizenz erforderlich" |
|
||||
| Gültige Unterschrift, Ablauf hochgedreht | „Lizenz erforderlich" |
|
||||
|
||||
### 9.10 Sicherungen: verschlüsselt mit dem Lizenzschlüssel
|
||||
|
||||
Entschieden am 2026-09-11, als bewusste Vereinfachung gegenüber dem Schlüsselbund aus #190.
|
||||
|
||||
**Die Vorgabe.** Eine Sicherung wird mit dem Lizenzschlüssel des Managers und einem festen
|
||||
Salt aus dem Code verschlüsselt. Beim Zurückspielen versucht der Manager den eigenen
|
||||
Schlüssel; passt er nicht, fragt ein Fenster nach dem Lizenzschlüssel der Quellinstallation.
|
||||
Die ganze Sicherung liegt als ein verschlüsseltes Archiv vor, auf Wunsch zusätzlich per FTP
|
||||
hinaus.
|
||||
|
||||
**Warum das trägt.** Der Lizenzschlüssel ist der eine Wert, den jede Installation ohnehin hat
|
||||
und den ihr Betreiber ohnehin kennt — und er liegt im Manager, nicht neben den Archiven.
|
||||
Damit fällt der Grund weg, aus dem die tägliche Sicherung bisher **keine** Zugangsdaten
|
||||
enthielt: Eine Passphrase hätte gespeichert werden müssen, und neben den Sicherungen
|
||||
abgelegt wäre sie wirkungslos gewesen. Jetzt reisen die Zugangsdaten mit, und eine Sicherung
|
||||
übersteht den Maschinenwechsel ohne Passphrase.
|
||||
|
||||
**Zwei Abweichungen von der Vorgabe, beide erzwungen:**
|
||||
|
||||
| Vorgabe | Umgesetzt | Warum |
|
||||
|---|---|---|
|
||||
| RAR | nicht möglich | RAR zu schreiben braucht das lizenzpflichtige Programm des Herstellers |
|
||||
| verschlüsseltes ZIP | eigener Behälter `.clawdbak` | .NET kann kein ZIP mit Kennwort schreiben, und das verbreitete ZipCrypto ist gebrochen. Weil der Schlüssel ohnehin abgeleitet wird, ließe sich ein solches ZIP auch mit 7-Zip nicht öffnen — die Verträglichkeit brächte nichts |
|
||||
|
||||
Der Behälter: Kopf mit Kennung, Fassung und einer **Schlüsselprobe**; das Manifest als eigener
|
||||
Abschnitt; das ZIP in Stücken zu 1 MiB, jedes mit AES-256-GCM und eigener Nonce, das letzte
|
||||
mit Endmarke. Die Stückelung, weil AES-GCM in einem Zug alles im Speicher bräuchte. Das
|
||||
Manifest vorn, damit die Übersicht nicht jedes Archiv ganz entschlüsseln muss. Die Endmarke,
|
||||
damit ein abgeschnittenes Archiv auffällt. Und die Schlüsselprobe, damit „fremder Schlüssel"
|
||||
von „beschädigt" zu unterscheiden ist, **bevor** etwas angehalten wird.
|
||||
|
||||
**Was das aushält und was nicht — ausdrücklich.** Wer Lizenzschlüssel und Archiv hat, hat
|
||||
alle Zugangsdaten darin. Der Schlüssel ist dem Hersteller bekannt, und er gilt für alle
|
||||
Instanzen einer Installation. Das ist die Abwägung, nicht ein Versehen: Ein Archiv auf einem
|
||||
FTP-Server oder einem USB-Stick soll niemandem nützen, der es nur findet — aufhalten soll es
|
||||
nicht jemanden, der Schlüssel und Absicht mitbringt.
|
||||
|
||||
**Die Reihenfolge beim Zurückspielen.** Erst die Schlüsselprobe, dann das Anhalten. Wer
|
||||
anhält und danach merkt, dass der Schlüssel nicht passt, hat eine laufende Instanz für nichts
|
||||
gestoppt. Passt er nicht, antwortet der Endpunkt mit **422** und dem Code `fremde_lizenz`,
|
||||
und die Oberfläche öffnet das Fenster für den Schlüssel der Quelle. Groß- und Kleinschreibung
|
||||
und Leerzeichen spielen dabei keine Rolle — dort tippt ein Mensch einen fremden Schlüssel ab.
|
||||
|
||||
**Geführte Instanzen sichern sich nicht mehr selbst.** Nur der Manager hat den
|
||||
Lizenzschlüssel. Liefen beide, lägen jeden Tag zwei Archive im Ordner, eines davon
|
||||
unverschlüsselt und ohne Zugangsdaten. Die Einstellungen — Schalter, Uhrzeit, Aufbewahrung,
|
||||
Zielordner — bleiben in der `InstanceSettings.json`; der Manager liest sie. Einmal am Tag
|
||||
heißt dabei auch über einen Neustart des Managers hinweg: Eine Datei von heute, die nach der
|
||||
eingestellten Uhrzeit entstanden ist, gilt als erledigt.
|
||||
|
||||
**Ohne Lizenzschlüssel im Manager wird nichts gesichert** — nicht ersatzweise unverschlüsselt.
|
||||
Das steht beim Start als Warnung im Protokoll.
|
||||
|
||||
**FTP.** Hochgeladen wird unter einem vorläufigen Namen und erst danach umbenannt: Eine halbe
|
||||
Datei unter richtigem Namen würde beim Aufräumen als gültige Sicherung mitgezählt, während
|
||||
eine vollständige dafür gelöscht wird. Auf dem Server wird je Instanz aufgeräumt, sonst füllt
|
||||
ein automatischer Upload ihn, bis ausgerechnet die jüngste Sicherung scheitert. TLS wird
|
||||
genommen, wo der Server es anbietet, und lässt sich mit `requireTls` erzwingen; Zertifikate
|
||||
werden nicht geprüft, weil eigene FTP-Server meist selbstsignierte haben. Ein gescheiterter
|
||||
Upload lässt die lokale Sicherung stehen und steht in der Meldung. Das FTP-Kennwort liegt
|
||||
verschlüsselt in `manager.json` und geht nie an die Oberfläche zurück.
|
||||
|
||||
**Ein Präfix ist keine Grenze.** Welche Datei zu welcher Instanz gehört, entscheidet ein
|
||||
Zeitstempel unmittelbar nach dem Namen, nicht der Anfang des Namens. Sonst zählte `Test` die
|
||||
Archive von `Test_2` mit und würfe beim Aufräumen fremde weg (siehe 1.2).
|
||||
|
||||
**Und der Schlüsselbund aus #190?** Er bleibt, verliert aber seine Rolle für Sicherungen:
|
||||
Dafür ist jetzt der Lizenzschlüssel da. Das Wiederherstellungsfach ist nur noch für den Fall
|
||||
nötig, dass eine laufende Installation ihr Maschinenfach verliert, ohne dass eine Sicherung
|
||||
im Spiel ist. Die Naht für #180 bleibt davon unberührt.
|
||||
|
||||
**Nicht über die Oberfläche abgenommen.** Behälter, Sicherungsdienst und der Rundlauf über
|
||||
einen Maschinenwechsel sind mit Tests belegt; der Weg durch die Weboberfläche — das Fenster
|
||||
für den fremden Schlüssel, der FTP-Upload gegen einen echten Server — noch nicht. Beides steht
|
||||
in #537.
|
||||
|
||||
Reference in New Issue
Block a user