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

233 lines
9.0 KiB
Markdown

# Sicherheitsleitfaden für den Betrieb
Wie eine Anlage einzurichten ist, damit sie einem Angriff standhält. Die
Bauweise dahinter steht in [security.md](security.md), die gefahrenen Angriffe
in [hardening.md](hardening.md).
## Das Angriffsziel ist nicht der Server
Wer eine Umgebung erpressen will, verschlüsselt nicht nur die Daten — er sucht
zuerst die **Backups**. Ein Angreifer mit Administratorrechten auf der
Backup-Anlage braucht keine Verschlüsselung mehr: Er löscht.
Daraus folgt die Reihenfolge dieses Leitfadens. Der Löschschutz steht vorn,
nicht die Verschlüsselung.
## 1. Löschschutz — das Wichtigste
```bash
syncova-repo create --path /srv/syncova-repository --name "Hauptziel" --hardened
```
Danach **messen**, nicht glauben:
```bash
curl -X POST https://<server>/api/v1/repositories/<id>/enforcement/measure \
-H "Authorization: Bearer <token>"
```
Die Messung legt Probedateien an und versucht sie zu löschen. Gemeldet wird
nur, was das Betriebssystem nachweislich verhindert:
| Stufe | Bedeutung |
| --- | --- |
| `none` | kein Schutz |
| `advisory` | Rechte gesetzt, Löschen aber nicht verhindert |
| `filesystem` | das Dateisystem verweigert das Löschen nachweislich |
| `storage` | WORM des Speichersystems — **existiert als Begriff und wird nie vergeben**, weil es nicht umgesetzt ist |
**`0400` verhindert kein Löschen.** Unter POSIX hängt das Entfernen am
Schreibrecht des *Verzeichnisses*, nicht der Datei. Wer Dateirechte für
Löschschutz hält, hat keinen.
Geschützt sind Manifeste, Blöcke, Schutzvermerke, Descriptor und Datenschlüssel.
Der Katalog bewusst nicht — er ist nur ein Beschleuniger.
> Zwei Angriffsversuche waren beim Bau zunächst erfolgreich und haben den
> Umfang bestimmt: Beim ersten überlebte das Manifest, aber nicht seine Blöcke
> — ein Backup, das sich für vollständig ausgibt und leer ist. Beim zweiten
> fehlten Descriptor und Datenschlüssel; die Daten waren da und trotzdem
> verloren.
## 2. Rechte trennen
Sieben Rollen. Die Trennung, auf die es ankommt:
**`backups.delete` und `immutability.manage` gehören nicht in dieselbe Hand.**
Wer aufräumen darf, darf keinen Schutz aufheben — das ist der Schritt, der
einem Angreifer den Weg öffnet.
Ebenso getrennt: `restores.execute` und `restores.overwrite`. Wiederherstellen
darf mehr Leute betreffen als Überschreiben.
Prüfen Sie regelmäßig, wer schreiben darf:
```bash
curl -s -H "Authorization: Bearer <token>" https://<server>/api/v1/users \
| jq '.data[] | select(.status=="active") | {username, roles}'
```
Der **letzte Administrator ist geschützt** gegen Löschung, Deaktivierung und
Rollenentzug. Das ist kein Ersatz für ein zweites Administratorkonto.
## 3. Zweiter Faktor
```bash
SYNCOVA_AUTH_REQUIRE_MFA_FOR_PRIVILEGED_USERS=true
```
Damit verlangen Konten mit Benutzer-, Rollen- oder Sicherheitsrechten einen
zweiten Faktor. **Richten Sie ihn zuerst ein, dann schalten Sie die Pflicht
ein** — sonst sperren Sie sich aus.
Für den Fall, dass es doch passiert:
```bash
syncova-admin reset-password --username <name>
```
Das Kommando läuft auf dem Server und verlangt Zugriff auf die Datenbank. Wer
den hat, ist ohnehin bereits im System — deshalb ist das kein zusätzliches
Risiko, sondern die bewusste Notfalltür.
Der Replay-Schutz verhindert, dass ein abgefangener Code im selben
30-Sekunden-Fenster ein zweites Mal gilt.
## 4. Transport
```bash
SYNCOVA_HTTP_TLS_CERT_FILE=/etc/syncova/tls/server.crt
SYNCOVA_HTTP_TLS_KEY_FILE=/etc/syncova/tls/server.key
```
**Nur eines von beiden zu setzen verweigert den Start.** Sonst liefe der Dienst
im Klartext, während der Betreiber Verschlüsselung eingerichtet zu haben glaubt.
Alternativ ein Reverse Proxy — dann aber `SYNCOVA_HTTP_LISTEN_ADDRESS` auf
`127.0.0.1` binden. Die gefährliche Kombination ist *kein TLS* **und** *an
allen Schnittstellen*; davor warnt der Start in Großbuchstaben.
**Weitergeleitete IP-Header werden ignoriert.** Sie sind fälschbar; im
Auditprotokoll stünde sonst eine beliebige Adresse. Hinter einem Proxy steht
dort dessen Adresse — das ist unbefriedigend, aber wahr.
## 5. Der Verschlüsselungsschlüssel
`SYNCOVA_ENCRYPTION_KEYS` schützt MFA-Geheimnisse, Zugangsdaten der
Virtualisierungsverbünde und die Datenschlüssel der Repositories.
- **Außerhalb der Anlage aufbewahren.** In einem Backup, das Syncova selbst
erzeugt, ist er nutzlos: Man bräuchte ihn, um an ihn heranzukommen.
- **Nicht in ein Skript, nicht in die Prozessliste.** Der Dienst liest ihn aus
seiner Umgebung; die `EnvironmentFile` gehört auf `0600` und root.
- **Schlüsselwechsel:** Neuen Schlüssel unter neuer Version ergänzen, alten
behalten. `SYNCOVA_ENCRYPTION_CURRENT_KEY` bestimmt, womit **neu**
verschlüsselt wird; bestehende Geheimnisse tragen ihre Version bei sich.
**Den alten Schlüssel niemals entfernen, solange noch etwas mit ihm
verschlüsselt ist** — es gibt keine Umschlüsselung.
## 6. Ziele nach außen
Zwei Stellen, an denen die Anlage selbst Verbindungen aufbaut: Webhooks und
SMTP.
Beide werden gegen interne Adressen gesperrt — Metadatendienste der Cloud
(`169.254.169.254`), Rückschleife, private Netze. Geprüft wird **zweimal**:
beim Anlegen und erneut unmittelbar vor dem Verbindungsaufbau. Ein Name kann
zwischenzeitlich auf eine andere Adresse zeigen; das ist der übliche Weg um
eine einmalige Prüfung herum.
`SYNCOVA_ALLOW_INTERNAL_NOTIFICATION_TARGETS=true` hebt das auf. Für eine
Testumgebung vertretbar, in der Produktion nicht.
Webhooks verlangen HTTPS. Einen Schalter „Zertifikat egal" gibt es nicht.
## 7. Wiederherstellungsziele begrenzen
```bash
SYNCOVA_RESTORE_ALLOWED_ROOTS=/srv/restore:/mnt/wiederherstellung
```
Ohne diese Grenze kann jeder mit `restores.execute` in jedes beschreibbare
Verzeichnis schreiben. Die Systemverzeichnisse des laufenden Systems sind
ohnehin gesperrt — der Angriff braucht keine Lücke, nur ein Recht: Wer Backups
zurückschreiben darf, schreibt nach `/etc/cron.d` oder in eine fremde
`authorized_keys`.
Der Agent prüft zusätzlich gegen die Systemverzeichnisse **seines** Systems.
Das kann der Server nicht — er kennt sie nicht; ein Windows-Agent hat andere
Systempfade als ein Linux-Server.
## 8. Nachsehen, ob es stimmt
```bash
curl -s -H "Authorization: Bearer <token>" https://<server>/api/v1/security \
| jq '.data.assessment | {score, maximum_score, grade}'
```
Zwei Zahlen, nicht eine: `maximum_score` sagt, wie viel überhaupt geprüft
werden konnte. Ein ungeprüfter Bereich geht **weder positiv noch negativ** ein.
Ab drei ungeprüften sagt die Zusammenfassung ausdrücklich: *„Die Zahl ist eine
Vermutung, keine Aussage."*
**Ein kritischer Befund deckelt die Einstufung auf `unzureichend`** — unabhängig
von der Prozentzahl. 88 von 100 Punkten mit einem kritischen Befund ergeben
`unzureichend`.
Zwei Bereiche sind grundsätzlich nicht prüfbar, weil es die Funktionen nicht
gibt: Kopie an einen zweiten Ort und Zertifikate der Agenten.
## 9. Auditprotokoll
Append-only **per Datenbank-Trigger**, nicht nur per Anwendungslogik. Auch ein
künftiger Codefehler kann daran nichts ändern.
Was regelmäßig anzusehen ist:
```bash
curl -s -H "Authorization: Bearer <token>" \
'https://<server>/api/v1/audit-events?action=BACKUP_DELETION_DENIED' | jq '.data'
```
- `BACKUP_DELETED` und `BACKUP_DELETION_DENIED` — die destruktivsten Handlungen
- `LEGAL_HOLD_RELEASED` — wiegt schwerer als die Anordnung
- `NOTIFICATION_CHANNEL_DELETED` — wer Benachrichtigungen umleitet, kann
erreichen, dass niemand mehr von einem Ausfall erfährt
- `PERMISSION_DENIED` in Häufung — jemand versucht etwas, das er nicht darf
## 10. Ransomware
Die Heuristik **meldet und handelt nie**. Kein Löschen, kein Sperren, kein
Anhalten. Der Grund ist nicht Vorsicht, sondern Erfahrung: Ein
Betriebssystem-Update sieht von außen aus wie ein Verschlüsselungsangriff, und
eine Heuristik, die selbsttätig handelt, macht aus jedem Fehlalarm einen
Schaden.
Die Meldung heißt **„Verdacht"**, nicht „erkannt". Was zu tun ist:
1. Den betroffenen Lauf ansehen — welche Endungen sind neu?
2. Die Quelle prüfen, nicht das Backup. Das Backup ist der Bote.
3. **Nichts löschen.** Ein verschlüsseltes Backup ist immer noch besser als
keines, und die Aufbewahrung schützt den Stand davor.
Ein über Wochen schleichender Angriff verschiebt den Basiswert mit sich.
Dagegen hilft nur die Unveränderlichkeit — nicht die Erkennung.
## Kurzliste
```text
[ ] Repository gehärtet angelegt und Durchsetzungsstufe gemessen
[ ] backups.delete und immutability.manage in verschiedenen Händen
[ ] Zweiter Faktor für alle Konten mit Löschrecht
[ ] TLS eingerichtet oder Dienst an 127.0.0.1 gebunden
[ ] Verschlüsselungsschlüssel außerhalb der Anlage hinterlegt
[ ] SYNCOVA_RESTORE_ALLOWED_ROOTS gesetzt
[ ] Benachrichtigungsweg eingerichtet und zugestellt geprüft
[ ] Aufbewahrungsregel angelegt, die das letzte Backup schützt
[ ] Security Score angesehen, kritische Befunde abgearbeitet
[ ] Eine Wiederherstellung durchgeführt — mit Stoppuhr
```
Der letzte Punkt ist der, der am häufigsten fehlt und im Ernstfall am meisten
kostet.