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>
275 lines
11 KiB
Markdown
275 lines
11 KiB
Markdown
# Störungen
|
|
|
|
Nach Symptom geordnet — danach sucht man, wenn etwas nicht geht.
|
|
|
|
## Zuerst: die drei Auskünfte
|
|
|
|
```bash
|
|
curl -s http://127.0.0.1:8080/health/ready | jq
|
|
journalctl -u syncova-api -n 50 --no-pager
|
|
./bin/syncova-api --version
|
|
```
|
|
|
|
`/health/live` bleibt auch dann `200`, wenn die Datenbank weg ist — sonst löste
|
|
eine kurz nicht erreichbare Datenbank einen Prozessneustart aus und
|
|
verschlimmerte den Ausfall. Nur `/health/ready` bewertet die Abhängigkeiten.
|
|
|
|
Jede Fehlermeldung der API trägt eine `request_id`. Damit findet sich die
|
|
Anfrage in den Protokollen:
|
|
|
|
```bash
|
|
journalctl -u syncova-api --no-pager | grep <request-id>
|
|
```
|
|
|
|
---
|
|
|
|
## Der Dienst startet nicht
|
|
|
|
**„SYNCOVA_… erforderlich"** — eine Pflichtvariable fehlt. Die Meldung nennt
|
|
sie. Bei `SYNCOVA_ENCRYPTION_KEYS` steht das erwartete Format dabei.
|
|
|
|
**„Das Schema passt nicht zur Programmversion"** — `syncova-migrate up` wurde
|
|
nach dem Austausch der Programme vergessen. Der Dienst ändert das Schema
|
|
niemals selbst; das ist Absicht.
|
|
|
|
**Start bricht ab, TLS erwähnt** — es ist nur `SYNCOVA_HTTP_TLS_CERT_FILE`
|
|
**oder** nur `_KEY_FILE` gesetzt. Eine halbe Konfiguration wird abgelehnt,
|
|
statt im Klartext zu lauschen.
|
|
|
|
**Nichts im Protokoll, Prozess weg** — meist die Datenbank. Der Start wartet 30
|
|
Sekunden auf sie und endet dann mit einer Meldung.
|
|
|
|
---
|
|
|
|
## Anmeldung schlägt fehl
|
|
|
|
**Alle Anmeldungen scheitern gleichzeitig** — sehr wahrscheinlich die Datenbank,
|
|
nicht die Anmeldung. Die Tokenprüfung braucht sie; fällt sie aus, scheitert
|
|
jede Prüfung. Der Dienst meldet dann ausdrücklich `SERVICE_UNAVAILABLE` mit dem
|
|
Zusatz *„Das ist kein Problem Ihrer Sitzung."* — genau, damit niemand den
|
|
Fehler bei der Anmeldung sucht.
|
|
|
|
**Ein Konto scheitert, andere nicht** — Sperre nach zu vielen Fehlversuchen.
|
|
Vorgabe: 5 Versuche, dann 15 Minuten. Abwarten oder:
|
|
|
|
```bash
|
|
./bin/syncova-admin reset-password --username <name>
|
|
```
|
|
|
|
**Zweiter Faktor wird abgelehnt** — die Uhr des Servers oder des Geräts geht
|
|
falsch. TOTP erlaubt ein Fenster von ±30 Sekunden. Prüfen: `timedatectl`.
|
|
|
|
Wurde derselbe Code eben schon verwendet, wird er abgelehnt — das ist der
|
|
Replay-Schutz. Eine halbe Minute warten.
|
|
|
|
**Ausgesperrt, niemand kommt mehr rein** — `syncova-admin reset-password` auf
|
|
dem Server. Es setzt auch den zweiten Faktor zurück.
|
|
|
|
---
|
|
|
|
## Sicherungen laufen nicht
|
|
|
|
**Der Auftrag steht auf „fällig", nichts passiert.**
|
|
|
|
```bash
|
|
curl -s -H "Authorization: Bearer <token>" https://<server>/api/v1/jobs/<id>/runs | jq '.data[0]'
|
|
```
|
|
|
|
Häufigste Ursachen, in dieser Reihenfolge:
|
|
|
|
1. Der Auftrag ist **angehalten** (`status: paused`).
|
|
2. Ein **Wartungsfenster** verhindert ihn. Er wird dann verschoben, nicht
|
|
übersprungen — dass ein Lauf verspätet ist, sieht man; dass er fehlt, nicht.
|
|
3. Ein **vorausgesetzter Auftrag** ist nicht erfolgreich gelaufen. Ein
|
|
Teilfehler erfüllt keine Abhängigkeit.
|
|
4. Die Ausführungsschleife läuft nicht — dann steht auch in den Protokollen
|
|
nichts von einem Übernahmeversuch.
|
|
|
|
**Ein Lauf hängt auf `running`.** Stirbt ein Server mitten im Lauf, blockiert
|
|
dessen Zeile den Auftrag. Nach fünf Minuten ohne Lebendmeldung wird sie
|
|
freigegeben und als `SCHEDULER_LOST` vermerkt — Klasse `transient`, damit die
|
|
Wiederholung greift. Warten Sie diese fünf Minuten ab, bevor Sie eingreifen.
|
|
|
|
**`EXECUTOR_NOT_CONFIGURED`** — es ist kein Schlüsselmaterial eingerichtet. Der
|
|
Executor verweigert den Dienst, statt unverschlüsselt zu sichern. Setzen Sie
|
|
`SYNCOVA_ENCRYPTION_KEYS`.
|
|
|
|
**`ALL_SOURCES_FAILED`** — keine einzige Quelle war erreichbar. Bei nur teilweise
|
|
gescheiterten Quellen läuft der Auftrag weiter und endet als Teilfehler.
|
|
|
|
---
|
|
|
|
## „PARTIAL FAILURE" — Teilfehler
|
|
|
|
Ein Teilfehler ist **kein** Erfolg und wird **nicht** wiederholt: Die
|
|
übergangenen Objekte wären beim nächsten Versuch dieselben. Er verlangt einen
|
|
Blick, keine Wiederholung.
|
|
|
|
```bash
|
|
curl -s -H "Authorization: Bearer <token>" \
|
|
https://<server>/api/v1/jobs/<id>/runs | jq '.data[0].skip_reasons'
|
|
```
|
|
|
|
| Grund | Bedeutung |
|
|
| --- | --- |
|
|
| Rechtefehler | das Dienstkonto darf die Datei nicht lesen — **echter Datenverlust** |
|
|
| Datei nicht lesbar | dort waren Daten, und sie fehlen |
|
|
| Platte in Proxmox ausgenommen | `backup=0`; die Maschine kommt unvollständig zurück |
|
|
|
|
**Sockets, benannte Pipes und Gerätedateien sind kein Teilfehler.** Sie werden
|
|
vermerkt und übergangen — sie *gehören* nicht ins Backup. Auf einem Linux-System
|
|
sind sie ein Dauerzustand; jeder Lauf über `/var` ergäbe sonst einen Teilfehler,
|
|
und nach einer Woche klickt niemand mehr einen an.
|
|
|
|
---
|
|
|
|
## Repository
|
|
|
|
**`REPOSITORY_FULL`** — der Datenträger ist voll. **Klasse `configuration`, wird
|
|
nicht wiederholt**: Jeder Wiederholungslauf legte weitere Blöcke ab und
|
|
verschärfte die Lage. Platz schaffen, dann von Hand anstoßen.
|
|
|
|
**„Gelöscht, aber nichts frei geworden"** — kein Fehler, sondern Deduplizierung:
|
|
Die Blöcke werden von einem anderen Backup noch gebraucht. `syncova-repo prune`
|
|
entfernt nur die tatsächlich verwaisten.
|
|
|
|
**`REPOSITORY_UNREACHABLE` bei einem Agenten** — der Agent schreibt selbst ins
|
|
Repository. Auf einem anderen Rechner muss es dort **eingehängt** sein, und das
|
|
Dienstkonto braucht Schreibrechte.
|
|
|
|
**Sperre bleibt liegen** — Sperren werden nie automatisch gelöst. Nach einem
|
|
Absturz:
|
|
|
|
```bash
|
|
./bin/syncova-repo break-lock --path /srv/syncova-repository
|
|
```
|
|
|
|
Das Kommando nennt zuerst, **wer** die Sperre hält — Prozess, Rechner und
|
|
Zeitpunkt — und verlangt dann eine ausdrückliche Bestätigung:
|
|
|
|
```bash
|
|
SYNCOVA_REPO_CONFIRM_BREAK_LOCK=ja ./bin/syncova-repo break-lock --path /srv/syncova-repository
|
|
```
|
|
|
|
Vergewissern Sie sich vorher, dass wirklich kein Vorgang mehr läuft. Bricht man
|
|
die Sperre eines **laufenden** Vorgangs, arbeiten zwei Schreiber gleichzeitig am
|
|
selben Repository — das Ergebnis ist keine Fehlermeldung, sondern ein
|
|
beschädigter Bestand, und der fällt erst bei einer Wiederherstellung auf.
|
|
|
|
**Löschen im gehärteten Repository schlägt fehl** — der Schutz greift. Auch für
|
|
root, auch für `rm -rf`. Das ist der Zweck.
|
|
|
|
---
|
|
|
|
## Wiederherstellung
|
|
|
|
**`ErrTargetNotEmpty`** — das Ziel ist nicht leer. Überschreiben verlangt drei
|
|
Dinge: das Kennzeichen, die Berechtigung `restores.overwrite` und
|
|
`confirm_overwrite` mit dem **wörtlich wiederholten** Zielpfad.
|
|
|
|
**`RESTORE_TARGET_FORBIDDEN`** — das Ziel liegt in einem Systemverzeichnis. Der
|
|
Agent prüft gegen die Systempfade **seines** Systems; der Server kennt sie
|
|
nicht.
|
|
|
|
**Wiederherstellung abgebrochen** — 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 `POST /restores/{id}/resume`.
|
|
|
|
**Vorabprüfung meldet fehlende Blöcke** — das Backup ist unvollständig. Die
|
|
Befunde nennen die betroffene Datei. Nehmen Sie einen anderen
|
|
Wiederherstellungspunkt; da Manifeste vollständig sind, ist jeder für sich
|
|
wiederherstellbar.
|
|
|
|
---
|
|
|
|
## Agenten
|
|
|
|
| Meldung | Ursache |
|
|
| --- | --- |
|
|
| Agent meldet sich nicht | Netzweg zum Server prüfen. Der Agent baut **ausgehend** auf; eine eingehende Freigabe ist nie nötig |
|
|
| `ENCRYPTION_KEY_MISSING` | der Auftrag verlangt Verschlüsselung, dem Agenten fehlt das Schlüsselmaterial. Er lehnt ab, statt unverschlüsselt zu sichern |
|
|
| `AGENT_LOST` | der Agent meldete sich während eines Auftrags nicht mehr. **Wird nicht wiederholt** — er könnte bereits Blöcke geschrieben haben |
|
|
| `UNKNOWN_TASK_TYPE` | der Server kennt eine Auftragsart, die dieser Agent nicht hat. Agent aktualisieren |
|
|
| Dienst startet und endet sofort | Zustandsdatei fehlt oder ist unlesbar. `syncova-agent register` erneut ausführen |
|
|
|
|
**Der Agent beendet sich bei abgelehntem Token.** Das behebt sich nicht durch
|
|
Warten — anders als eine Netzunterbrechung, bei der die Wartezeit von 5 Sekunden
|
|
auf höchstens 5 Minuten wächst.
|
|
|
|
---
|
|
|
|
## Proxmox
|
|
|
|
> Der Provider ist **nicht auf echter Hardware freigegeben**. Rechnen Sie mit
|
|
> Abweichungen (siehe [proxmox.md](proxmox.md)).
|
|
|
|
| Meldung | Ursache |
|
|
| --- | --- |
|
|
| „kein zugriffsweg auf die sicherungsarchive" | `archive_transport` fehlt oder die Speicherzuordnung ist leer. Proxmox gibt Archivdateien nicht über die REST-API heraus |
|
|
| „fuer den knoten ist kein fingerabdruck hinterlegt" | beim SSH-Weg gehört je Knoten der Wirtsschlüssel eingetragen. Einen Schalter „egal" gibt es nicht |
|
|
| „das zertifikat weicht vom hinterlegten fingerabdruck ab" | Proxmox hat ein neues Zertifikat. Fingerabdruck aktualisieren — **nicht** die Prüfung abschalten |
|
|
| „meldete erfolg, auf dem speicher liegt aber kein archiv" | vzdump lief, das Archiv fehlt. Speicherplatz auf dem Knoten prüfen |
|
|
| `ErrNotSupported` bei geänderten Blöcken | erwartet. Proxmox gibt sie nicht über REST heraus; es wird vollständig gelesen |
|
|
|
|
---
|
|
|
|
## Meldungen und Benachrichtigungen
|
|
|
|
**Keine Meldungen, obwohl etwas kaputt ist** — jeder Kanal hat eine Schwelle
|
|
(Vorgabe `high`). Ohne sie schaltet der Bereitschaftsdienst nach einer Woche
|
|
die Benachrichtigungen ab, und dann kommt auch die kritische nicht mehr an.
|
|
|
|
**Nur neue Meldungen werden zugestellt**, aktualisierte nicht. Der wiederholte
|
|
Befund erhöht einen Zähler — einmal ist ein Zwischenfall, zwanzigmal ein
|
|
Zustand.
|
|
|
|
**Meldung bleibt stehen, obwohl behoben** — Meldungen lösen sich selbst auf,
|
|
sobald die Regel den Befund nicht mehr liefert. Bleibt sie, besteht der Zustand
|
|
weiter. **Bestätigen ist nicht Erledigen**: Eine bestätigte Meldung bleibt
|
|
offen und in der Liste.
|
|
|
|
**Webhook wird abgelehnt** — HTTPS ist Pflicht, und interne Ziele sind gesperrt
|
|
(Metadatendienste, Rückschleife, private Netze). Für eine Testumgebung:
|
|
`SYNCOVA_ALLOW_INTERNAL_NOTIFICATION_TARGETS=true`.
|
|
|
|
---
|
|
|
|
## Oberfläche
|
|
|
|
**404 nach dem Neuladen einer Unterseite** — der SPA-Fallback fehlt im
|
|
Webserver: `try_files $uri /index.html`.
|
|
|
|
**„noch nicht verfügbar"** — die Seite ist bewusst gekennzeichnet. Sie sagt,
|
|
*was* fehlt und *wo dieselbe Auskunft heute steht*. Kein Fehler.
|
|
|
|
**Eine Kennzahl zeigt keine Zahl, sondern einen Satz** — sie hat keine
|
|
Datengrundlage. Eine `0` stünde für „geprüft und in Ordnung"; genau das wäre
|
|
falsch.
|
|
|
|
**Erfolgsquote meldet `warning` bei 100 %** — es gab keine Läufe in sieben
|
|
Tagen. Ohne Lauf gibt es keine Quote. Ein Dashboard, das bei ausgefallener
|
|
Sicherung grün zeigt, ist schlimmer als keines.
|
|
|
|
---
|
|
|
|
## Wenn nichts davon passt
|
|
|
|
```bash
|
|
# Was hat der Dienst zuletzt getan?
|
|
journalctl -u syncova-api -n 200 --no-pager | grep -v '"level":"DEBUG"'
|
|
|
|
# Stimmt der Schemastand?
|
|
./bin/syncova-migrate status
|
|
|
|
# Ist das Repository in Ordnung?
|
|
./bin/syncova-repo health --path /srv/syncova-repository
|
|
./bin/syncova-repo scan --path /srv/syncova-repository --deep
|
|
|
|
# Wie sieht die Anlage sich selbst?
|
|
curl -s -H "Authorization: Bearer <token>" https://<server>/api/v1/security | jq '.data.assessment'
|
|
```
|
|
|
|
Für eine Rückfrage nützlich: Version (`--version`), Schemastand, die
|
|
`request_id` der fehlgeschlagenen Anfrage und die Protokollzeilen dazu.
|
|
**Ohne die `request_id` bleibt „es hat nicht funktioniert".**
|