syncova-backup/docs/recovery-runbook.md
Jerrit Fritzsche 610719c316
Some checks failed
CI / Backend (Go) (push) Failing after 3m7s
CI / Frontend (React/TypeScript) (push) Successful in 37s
CI / Sicherheitsprüfungen (push) Successful in 44s
Syncova Backups V1
Enterprise-Backup-, Recovery-, Verification-, Security- und
Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme.

Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als
vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit
nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem
tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes
geht in keine Bewertung als "gut" ein.

Umfang (Phasen 0-23):

- Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll,
  Katalogaufbau allein aus den Manifesten — ohne Datenbank
- Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz
  Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck
- Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell)
- Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive
- Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit
- Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center,
  Ransomware-Heuristik (meldet, handelt nie)
- Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing
- Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository
- Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64

Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup
Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs.

Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die
systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine
wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md
und docs/release-candidate.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 09:10:54 +02:00

299 lines
9.8 KiB
Markdown

# Wiederherstellung — Handbuch für den Ernstfall
Dieses Dokument ist für den Moment geschrieben, in dem etwas weg ist. Es
beschreibt **was zu tun ist**, nicht wie es gebaut wurde — das steht in
[recovery.md](recovery.md) und [disaster-recovery.md](disaster-recovery.md).
Vier Lagen, von der harmlosen zur schwersten. Suchen Sie die Ihre und
überspringen Sie den Rest.
| Lage | Abschnitt |
| --- | --- |
| Einzelne Dateien oder ein Ordner sind weg | [1](#1-dateien-und-ordner) |
| Ein Proxmox-Gast ist weg | [2](#2-ein-proxmox-gast) |
| Der Control-Server samt Datenbank ist weg, das Repository steht | [3](#3-control-server-und-datenbank) |
| Das Repository ist beschädigt | [4](#4-beschädigtes-repository) |
---
## 0. Zuerst: nichts überstürzen
Drei Fragen, jede kostet eine Minute und kann Stunden sparen.
**Gibt es einen brauchbaren Wiederherstellungspunkt?**
```bash
curl -s -H "Authorization: Bearer <token>" \
'https://<server>/api/v1/backups?classification=recoverable' | jq '.data[0]'
```
`recoverable` bedeutet: Dieses Backup wurde zurückgeschrieben und gegen das
Original verglichen. `verified` bedeutet nur, dass die Blöcke stimmen —
ein starkes Indiz, aber kein Nachweis. `unverified` heißt: ungeprüft.
**Lässt sich der Punkt überhaupt zurückspielen?**
```bash
curl -X POST https://<server>/api/v1/restores/validate \
-H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \
-d '{"backup_id":"<id>","target_type":"filesystem","target_path":"/pfad/zum/ziel"}'
```
Die Vorabprüfung schreibt nichts. Sie prüft, ob **jeder benötigte Block noch
da ist** — ein Manifest allein belegt nur, dass jemand einmal etwas gesichert
hat.
**Wohin soll es?** Schreiben Sie nach Möglichkeit **neben** das Original, nicht
darüber. Ein Vergleich ist danach immer noch möglich; ein überschriebenes
Original nicht mehr.
---
## 1. Dateien und Ordner
### Über die Oberfläche
Wiederherstellungspunkte → Punkt wählen → *Wiederherstellen* → Zielpfad angeben.
### Über die API
```bash
curl -X POST https://<server>/api/v1/restores \
-H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" -d '{
"backup_id": "<id>",
"target_type": "filesystem",
"target_path": "/srv/wiederhergestellt",
"path_prefix": "daten/projekte"
}'
```
`path_prefix` beschränkt auf einen Teilbaum. Ohne ihn kommt alles zurück.
Fortschritt:
```bash
curl -s -H "Authorization: Bearer <token>" \
https://<server>/api/v1/restores/<id> | jq '.data | {status, files_restored, bytes_restored}'
```
### Überschreiben
Drei Hürden, absichtlich:
1. `"overwrite_existing": true`
2. die Berechtigung `restores.overwrite` — sie steckt **nicht** in
`restores.execute`
3. `"confirm_overwrite": "/srv/daten"` — der Zielpfad **wörtlich wiederholt**
Ein versehentlich gesetztes Kennzeichen in einem Skript reicht damit nicht aus.
Läuft der Schalter ins Leere, weil am Ziel nichts liegt, entfällt die
Bestätigung — ein Ritual ohne Anlass gewöhnt das Wegklicken an.
### Wenn eine Wiederherstellung abbricht
Sie wird **nicht** selbsttätig wiederholt. Ein zweiter Lauf in ein halb
gefülltes Ziel kann Daten beschädigen, die der erste bereits am Platz hatte.
Stattdessen fortsetzen:
```bash
curl -X POST https://<server>/api/v1/restores/<id>/resume -H "Authorization: Bearer <token>"
```
Die Fortsetzung räumt zuerst die beim Abbruch angefangene Datei weg und
beginnt beim Prüfpunkt. Der Prüfpunkt entsteht erst, **nachdem** eine Datei
vollständig und umbenannt am Platz liegt.
### Ohne Control-Server
Geht der Server nicht, aber das Repository steht:
```bash
./bin/syncova-repo list --path /srv/syncova-repository
./bin/syncova-agent restore \
--repository /srv/syncova-repository \
--backup <backup-id> \
--target /srv/wiederhergestellt
```
Dafür wird `SYNCOVA_ENCRYPTION_KEYS` gebraucht — bei einem verschlüsselten
Repository liegt der Datenschlüssel unter `metadata/data-key.json` und ist mit
diesem Schlüssel versiegelt.
---
## 2. Ein Proxmox-Gast
> **Ungeprüft auf echter Hardware.** Der Weg läuft gegen einen Nachbau der API
> vollständig durch, aber **ob eine wiederhergestellte Maschine startet, ist
> nicht nachgewiesen** (siehe [proxmox.md](proxmox.md)). Rechnen Sie im
> Ernstfall mit Nacharbeit.
```bash
./bin/syncova-proxmox restore-guest \
--cluster <verbund-id> \
--repository /srv/syncova-repository \
--backup <backup-id> \
--target-guest qemu/900 \
--node pve-01
```
**`--target-guest` setzen.** Ohne ihn wird der Ursprungsgast überschrieben —
und wenn der noch läuft und nur Daten fehlen, vernichtet das genau den Stand,
den man retten wollte.
Der Ablauf: Archiv aus dem Repository lesen (entschlüsseln, entpacken, jeder
Block gegen seine Kennung geprüft) → über den Zugriffsweg auf einen
Proxmox-Speicher schreiben → `qmrestore` anstoßen → Archiv wieder abräumen.
Danach:
- **Der Gast startet nicht von selbst.** `--start` ist der ausdrückliche Weg.
Eine wiederhergestellte Maschine, die sich mit derselben Adresse ins Netz
meldet wie das noch laufende Original, richtet mehr Schaden an als der
Ausfall.
- **Die Plattenzuordnung wird nicht aus der gesicherten Konfiguration gesetzt.**
Sie verwiese auf den alten Ort. Das erscheint als Warnung und ist von Hand
zu prüfen.
- **Ausgenommene Platten** (`backup=0`) fehlen. Die Ausgabe nennt sie.
---
## 3. Control-Server und Datenbank
Der Fall, für den `syncova-dr` gebaut ist. Voraussetzung: Das Repository steht,
und Sie haben den **Verschlüsselungsschlüssel**.
> Ohne `SYNCOVA_ENCRYPTION_KEYS` sind die abgelegten Geheimnisse verloren. Die
> Backups selbst bleiben lesbar, sofern der Datenschlüssel des Repositorys mit
> demselben Schlüssel versiegelt war — ist er das nicht, sind auch sie weg.
> Deshalb gehört dieser Schlüssel außerhalb der Anlage aufbewahrt.
### 3.1 Ansehen, was da ist
```bash
./bin/syncova-dr inspect --repo /srv/syncova-repository
```
Braucht **keine Datenbank**. Nach einem Totalverlust will man zuerst sehen, was
vorhanden ist.
### 3.2 Schema anlegen
```bash
./bin/syncova-migrate up
```
### 3.3 Konfiguration einspielen
```bash
./bin/syncova-dr restore --repo /srv/syncova-repository --catalog
```
`--catalog` bringt zusätzlich die Wiederherstellungspunkte zurück.
**Das Einspielen ist eine Transaktion.** Alles oder nichts — eine halb
wiederhergestellte Anlage sieht arbeitsfähig aus und scheitert beim ersten
Lauf.
### 3.4 Was danach von Hand zu tun ist
Nichts läuft von selbst wieder an. Das ist Absicht: Ein Zeitplan, der nachts
anspringt, könnte auf eine halb wiederhergestellte Anlage schreiben.
```text
Aufträge angehalten → nach Prüfung einschalten
Repositories nicht erreichbar → nach Prüfung auf aktiv setzen
Konten deaktiviert → Passwörter neu vergeben
Benachrichtigungen abgeschaltet → neu einrichten
last_verified_at leer → Prüfung anstoßen
```
Im Sicherungssatz sind **nicht** enthalten: Passwörter, TOTP-Geheimnisse,
Zugangsdaten **und Konfiguration** der Benachrichtigungswege (dort steht die
Webhook-Adresse, und die trägt oft ein Token im Pfad), Betriebstokens der
Agenten und der Verschlüsselungsschlüssel selbst.
```bash
./bin/syncova-admin create-admin --username admin
```
### 3.5 Vor dem ersten neuen Lauf
**Eine Prüfung anstoßen.** Die Wiederherstellbarkeit der übernommenen Punkte
ist nach dem Einspielen nicht belegt — sie wurde nicht neu nachgewiesen, und
`last_verified_at` ist deshalb leer.
---
## 4. Beschädigtes Repository
### 4.1 Feststellen, was betroffen ist
```bash
./bin/syncova-repo scan --path /srv/syncova-repository --deep
```
Der vollständige Lauf liest jeden Block und prüft ihn gegen seine Prüfsumme.
Er braucht **keinen** Schlüssel: Geprüft wird gegen die Prüfsumme der
abgelegten Form.
Der Bericht nennt betroffene Backups namentlich. Ein Backup mit einem einzigen
beschädigten Block ist **nicht zu 70 % wiederherstellbar, sondern gar nicht** —
die Einstufung geht deshalb auf 0 %.
### 4.2 Katalog verloren
```bash
./bin/syncova-repo rebuild --path /srv/syncova-repository
```
Der Katalog ist nur ein Beschleuniger; verbindlich sind die Manifeste. Er wird
bei Verlust, Beschädigung oder fremder Repository-Kennung ohnehin still neu
gebaut.
### 4.3 Einzelnes Manifest beschädigt
Betroffen ist genau dieses eine Backup. Die Prüfung meldet es, die
Wiederherstellung bricht ab (**0 Dateien im Ziel**, kein halbes Ergebnis), und
der Katalog-Neuaufbau schließt es aus.
Dass der Katalog es zunächst weiter anzeigt, ist richtig — er ist ein
Beschleuniger, nicht die Wahrheit.
### 4.4 Blöcke fehlen
Fehlende Blöcke lassen sich nicht wiederherstellen; sie sind weg. Was bleibt:
1. Ein **anderer** Wiederherstellungspunkt derselben Kette. Da Syncova-Manifeste
vollständig sind, ist jeder Punkt für sich wiederherstellbar — eine
zerrissene Kette gibt es nicht.
2. Ein exportierter Container (`syncova-repo export`), sofern vorhanden.
### 4.5 Verweigerte Löschung im gehärteten Modus
Kein Fehler, sondern der Schutz. Zum Entfernen eines geschützten Backups:
```bash
curl -X DELETE https://<server>/api/v1/backups/<id> -H "Authorization: Bearer <token>"
```
Der Server prüft Aufbewahrungsfrist und Legal Hold. Eine abgewehrte Löschung
wird protokolliert wie eine erfolgreiche — wer wiederholt gegen den Schutz
läuft, tut entweder etwas Falsches oder etwas Böses.
Eine rekursive Aufhebungsfunktion für den gesamten Schutz gibt es
**ausdrücklich nicht**.
---
## Wie oft man das üben sollte
Einmal im Quartal, mit einem echten Ziel und einer Stoppuhr. Die gemessene
Dauer ist die einzige RTO-Angabe, die in einem Bericht etwas wert ist — alles
andere ist eine Hochrechnung aus Datenmenge und Durchsatz, auf die sich im
Ernstfall niemand verlassen kann.
Solange nicht gemessen wurde, steht in der RTO-Spalte der Berichte „nicht
gemessen". Das ist die richtige Angabe, aber keine gute.