syncova-backup/docs/recovery.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

9.4 KiB

Recovery Engine

Status

Umgesetzt sind Vorabprüfung, Wiederherstellung von Dateien und Ordnern über die API, Sitzungen mit Prüfpunkt, Schutz gegen versehentliches Überschreiben und die Ausführungsschleife.

Nicht umgesetzt: Plattenwiederherstellung, vollständige Systemwiederherstellung und Proxmox-VM-Wiederherstellung. Für Proxmox fehlt der ArchiveTransport (siehe proxmox.md); ohne ihn kommt schon die Sicherung nicht zustande.

Die Vorabprüfung ist der Kern

Ein Backup gilt erst als vertrauenswürdig, wenn Integrität geprüft und Wiederherstellbarkeit nachgewiesen wurde.

Ein Nachweis, der erst im Ernstfall erbracht wird, ist keiner. POST /restores/validate prüft deshalb ohne etwas zu schreiben, ob eine Wiederherstellung gelingen kann:

Prüfung Gewicht bei Befund
Manifest lesbar verhindernd
Abschlussvermerk vorhanden verhindernd
Jeder benötigte Block vorhanden verhindernd
Datenschlüssel des Repositorys auffindbar verhindernd
Zielverzeichnis erreichbar, Elternverzeichnis vorhanden verhindernd
Freier Platz ausreichend (5 % Aufschlag) verhindernd
Ziel nicht leer, ohne Zustimmung verhindernd
Ziel wird überschrieben, mit Zustimmung Warnung
Backup unverschlüsselt Warnung
Schlüsselversion weicht ab Warnung
Blockprüfung übersprungen Hinweis

Die Blockprüfung ist der eigentliche Nachweis. Ein Manifest allein belegt nur, dass jemand einmal etwas gesichert hat — nicht, dass die Daten noch da sind. Ein versehentlich aufgeräumtes Verzeichnis, ein unvollständig kopiertes Repository, ein fehlgeschlagenes Prune: Alles das fällt hier auf und nicht erst, wenn man es braucht.

Real geprüft: Nach dem Entfernen eines einzigen Blocks meldet die Prüfung

can_proceed: False
NICHT WIEDERHERSTELLBAR: 1 Hindernisse, 1 fehlende Bloecke.
[blocking] 1 von 16 benoetigten Bloecken fehlen im Repository.
         betroffen: daten/datei-8.bin

Die betroffene Datei wird genannt, nicht nur eine Zahl. „Ein Block fehlt" hilft niemandem weiter; „daten/datei-8.bin lässt sich nicht wiederherstellen" schon.

Wird die Blockprüfung übersprungen (skip_deep_check), steht das als Hinweis im Bericht. Sonst hielte man einen halben Nachweis für einen ganzen.

Die Prüfung läuft zweimal: einmal beim Anlegen des Auftrags und erneut unmittelbar vor dem Schreiben. Der Bericht am Auftrag kann Minuten oder Tage alt sein; in der Zwischenzeit kann ein Block verschwunden oder das Ziel gefüllt worden sein. Der Bericht wird am Auftrag gespeichert — später muss belegbar sein, was vor dem Start bekannt war.

Drei Hürden vor dem Überschreiben

Eine Wiederherstellung an einen belegten Ort richtet sich gegen Daten, die es noch gibt — und die könnten genau die sein, die man eigentlich retten will.

  1. Ohne overwrite_existing wird ein nicht leeres Ziel abgelehnt.
  2. restores.overwrite ist eine eigene Berechtigung, nicht in restores.execute enthalten. Wer wiederherstellen darf, darf nicht automatisch überschreiben.
  3. confirm_overwrite muss den Zielpfad wörtlich wiederholen. Ein zweites Feld neben dem Kennzeichen ist keine Umständlichkeit: Ein versehentlich gesetztes Kennzeichen in einem Skript oder einer Vorlage reicht damit nicht aus, um Daten zu vernichten. Wer den Pfad abtippt, hat ihn gelesen.

Läuft der Schalter ins Leere — das Ziel ist leer —, entfällt die Bestätigung. Ein Ritual ohne Anlass gewöhnt nur das Wegklicken an.

Jede Wiederherstellung wird auditiert, das Überschreiben unter eigener Aktion (RESTORE_OVERWRITE_REQUESTED) und zusätzlich als Warnung im Protokoll.

Sitzungen und Prüfpunkte

Ein Abbruch bei 90 Prozent darf nicht bedeuten, dass alles von vorn beginnt — bei mehreren Terabyte wäre das der Unterschied zwischen Stunden und Tagen, und zwar in einer Lage, in der ohnehin schon etwas schiefging.

Jeder Auftrag bekommt eine Sitzung mit Prüfpunkt. Der Prüfpunkt hält einen einzigen Pfad: den zuletzt vollständig zurückgeschriebenen. Das genügt, weil die Objekte im Manifest fest sortiert sind — alles lexikographisch davor ist erledigt. Eine Liste wäre bei einer Million Dateien unbrauchbar groß.

Der Prüfpunkt entsteht erst, nachdem die Datei vollständig und unter ihrem endgültigen Namen am Platz liegt. Ein Prüfpunkt auf eine halb geschriebene Datei wäre schlimmer als keiner: Die Fortsetzung übersprünge sie als erledigt.

Geschrieben wird er nicht bei jeder Datei, sondern höchstens alle paar Sekunden — bei einer Million kleiner Dateien wären das sonst eine Million Schreibvorgänge in die Datenbank. Der Preis ist, dass eine Fortsetzung wenige Sekunden Arbeit wiederholt.

Bei einer Fortsetzung greift der Schutz gegen ein volles Zielverzeichnis nicht: Dort liegt notwendigerweise der bereits zurückgeschriebene Teil. Ihn über overwrite_existing auszuhebeln wäre falsch — das erlaubte zugleich das Überschreiben fremder Daten.

Die Endzahlen beschreiben den gesamten Vorgang, nicht nur den letzten Versuch: drei Objekte aus dem ersten Lauf plus zwei aus dem zweiten ergeben fünf.

Kein automatischer Wiederholungsversuch

Anders als eine Sicherung wird eine gescheiterte Wiederherstellung nicht automatisch erneut gestartet. Ein zweiter Lauf in ein halb gefülltes Zielverzeichnis kann Daten beschädigen, die der erste Versuch bereits am Platz hatte. Der Betreiber soll hinsehen, bevor erneut geschrieben wird — die Sitzung mit ihrem Prüfpunkt bleibt dafür offen.

Das gilt auch für verwaiste Aufträge: Stirbt ein Control-Server mitten in einer Wiederherstellung, wird der Auftrag nach fünf Minuten als SCHEDULER_LOST gescheitert vermerkt, aber nicht erneut eingereiht. Die Sitzung überlebt.

Nebenläufigkeit

Standard ist eine Wiederherstellung zur Zeit. Sie läuft im Ernstfall, und dann zählt die Geschwindigkeit einer Wiederherstellung, nicht der Durchsatz mehrerer: Wer zwei gleichzeitig laufen lässt, halbiert die Geschwindigkeit derjenigen, auf die alle warten.

Ein Teilindex verhindert zwei gleichzeitige Wiederherstellungen in dasselbe Ziel. Sie schrieben sich gegenseitig zu — und zwar ohne dass es auffiele, weil beide erfolgreich endeten.

Das Repository wird schreibgeschützt geöffnet. Eine Wiederherstellung liest nur und kann deshalb neben einer laufenden Sicherung stattfinden, statt auf deren Schreibsperre zu warten. Im Ernstfall wartet niemand gern.

Übergangene Objekte sind ein Teilfehler

Wie bei den Sicherungen: Eine Wiederherstellung, die zwei Dateien nicht zurückschreiben konnte, ist unvollständig. Sie darf nicht als Erfolg dastehen — der Anwender glaubte sonst, alles sei wieder da. Die Datenbank erzwingt das über ein CHECK.

API

POST   /api/v1/restores/validate      restores.read      prüft, schreibt nichts
POST   /api/v1/restores               restores.execute   202: reiht ein, auditiert
GET    /api/v1/restores               restores.read      Liste mit Pagination
GET    /api/v1/restores/{id}          restores.read      inkl. Prüfpunkt bei Abbruch
POST   /api/v1/restores/{id}/cancel   restores.execute   auditiert

Die Vorabprüfung braucht nur das Leserecht: Sie schreibt nichts und soll niedrigschwellig sein — wer den Zustand der Backups beurteilen soll, muss sie ausführen können.

{
  "backup_id": "…",
  "target_path": "/wiederhergestellt",
  "path_prefix": "dokumente/2026",
  "overwrite_existing": true,
  "confirm_overwrite": "/wiederhergestellt"
}

path_prefix beschränkt auf einen Teilbaum — der häufigste Fall im Betrieb ist nicht die vollständige Wiederherstellung, sondern eine einzelne versehentlich gelöschte Datei. Die Präfixgrenze achtet auf Verzeichnisse: dokumente trifft nicht auch dokumentation.

POST /restores antwortet mit 202, nicht 201: Der Auftrag ist eingereiht, die Daten sind noch nicht zurück. Beim Abbruch wird ausdrücklich gesagt, dass bereits zurückgeschriebene Daten am Ziel liegen bleiben — sonst hielte man das Ziel für unberührt.

Nachgewiesen

Gegen den laufenden Dienst, 11,4 MiB in 12 Objekten:

Schritt Ergebnis
Vorabprüfung „Wiederherstellbar: 9 Dateien, 11.4 MiB", 16 Blöcke geprüft, 0 fehlend
Quelle gelöscht, über die API wiederhergestellt succeeded, 12 Objekte in 0,11 s
Vergleich bitgenau identisch inkl. Rechten (600), Symlink, leerem Verzeichnis
Volles Ziel ohne Zustimmung abgelehnt
overwrite_existing ohne Bestätigung abgelehnt, nennt den zu wiederholenden Pfad
Falscher Bestätigungswert abgelehnt
Mit korrekter Bestätigung 202, überschrieben, im Protokoll als Warnung
Ein Block entfernt can_proceed: false, betroffene Datei benannt, Auftrag mit 422 abgelehnt

Offene Punkte

  • Keine Platten- und Systemwiederherstellung. Sie setzen Provider voraus, die noch nicht liefern.
  • Proxmox-VM-Wiederherstellung ist im Provider umgesetzt, aber ungeprüft und ohne ArchiveTransport nicht erreichbar.
  • Keine Fortsetzung über die API. Der Prüfpunkt liegt vor und die Schleife nutzt ihn, aber es gibt keinen Endpunkt, der einen gescheiterten Auftrag erneut einreiht — nur den Weg über die Datenbank.
  • Kein GET /restores/{id}/logs und /metrics (SYNCOVA_API.md §13).
  • Keine Wiederherstellung in der Oberfläche. Sie geht nur über die API.
  • Kein Wiederherstellungstest als eigener Auftrag. Das ist Phase 10 — und der Punkt, an dem aus „prüfbar" ein regelmäßiger Nachweis wird.