Files
archivmail/docs/BACKUP_RESTORE_RUNBOOK.md
T
sysops 4eba165250 docs(PROJ-66): Backup & Restore Runbook schreiben
docs/BACKUP_RESTORE_RUNBOOK.md deckt beide Sicherungsebenen ab: App-eigenes
CLI-Backup (archivmail backup/restore, PROJ-66) und Infrastruktur-Ebene
(PBS + Sync auf Zweitserver, pct restore). Enthaelt Bitwarden-Keyfile-
Escrow-Anleitung, Pflicht-Verifikationsschritte (reconcile/reindex/
Stichprobe), Rotation-vs-DSGVO-Hinweis und den offenen Punkt "noch kein
Restore-Test durchgefuehrt" als groesste verbleibende Luecke.

AC 8 aus PROJ-66 damit erfuellt; AC 6 (Restore-Test) und AC 7 (Alerting)
bleiben offen.
2026-07-05 21:11:39 +02:00

171 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Backup & Restore Runbook archivmail
Bezug: `features/PROJ-66-backup-strategie.md` (Spec + Entscheidungsverlauf),
`docs/GOBD_DSGVO_CHECKLIST.md` Punkt 7 (Löschsperre) und 15 (Mandantentrennung).
Ziel: belegen können, dass ein Totalausfall von Store, Keyfile oder
PostgreSQL nicht zu unwiederbringlichem Mail-Verlust führt — und dass ein
Restore im Ernstfall tatsächlich funktioniert, nicht nur theoretisch existiert.
Gilt für: `archivmail backup`/`archivmail restore` (PROJ-66, App-eigenes
CLI-Backup) und ergänzend die Proxmox Backup Server (PBS) + Sync-auf-
Zweitserver-Sicherung auf Infrastruktur-Ebene.
## Grundsatz
Store, Keyfile und PostgreSQL-Metadaten sind **nur gemeinsam** nutzbar:
- Store ohne DB: Dateien vorhanden, aber keine Zuordnung zu Mail/Tenant.
- Keyfile ohne Store: irrelevant, nichts zu entschlüsseln.
- DB ohne Keyfile: Metadaten da, Mail-Inhalte nicht mehr lesbar (GoBD-Verstoß).
Ein Backup, das nur eine dieser drei Komponenten sichert, ist wertlos. Ein
Backup, das nie zurückgespielt wurde, ist nicht verifiziert — siehe
"Regelmäßiger Restore-Test" unten.
## Zwei unabhängige Sicherungsebenen
1. **Infrastruktur-Ebene (PBS + Sync auf Zweitserver)** — läuft vom
Proxmox-Host aus, sichert den kompletten Container (Store+Keyfile+
Config+PostgreSQL-Datendir+Audit-Log in einem Snapshot). Von innerhalb
des Containers nicht sichtbar/steuerbar. Siehe Memory
`project_backup_infra_pbs` für CLI-Befehle (`vzdump`, `pct restore`).
2. **App-eigenes Backup (`archivmail backup`/`restore`)** — ergänzt Ebene 1
um einen anwendungskonsistenten `pg_dump` (statt reinem Crash-Consistency-
Snapshot) und einen selektiven, von PBS unabhängigen Restore-Weg.
Keine der beiden Ebenen ersetzt die andere. Ein vollständiger Restore-Test
sollte mindestens einmal **beide** Wege durchlaufen haben (siehe unten).
## Backup erstellen
```bash
archivmail backup --config /etc/archivmail/config.yml --dest <ziel> --keep 14
```
- `<ziel>` MUSS auf einem vom Produktivsystem physisch getrennten Ziel
liegen (zweiter Host, NAS, o.ä.) — siehe PROJ-66-Spec, Abschnitt
"Backup-Ziel: On-Site vs. Off-Site". Ein Backup auf derselben Platte
schützt nicht vor Hardware-Ausfall.
- Schreibt `<ziel>/<timestamp>/`: `postgres.dump` (`pg_dump -Fc`), `store/`
(Hardlink-erhaltende Kopie, PROJ-65-Tenant-Ordner bleiben ohne
Speicherplatz-Verdopplung erhalten), `keyfile`, `config.yml`, `audit.log`
(best-effort).
- `--keep N` behält die letzten N Backup-Verzeichnisse, löscht ältere —
**nur nach erfolgreichem Lauf**. Ein fehlgeschlagener Lauf lässt den
partiellen Ordner stehen und rotiert nichts weg (Diagnose-Möglichkeit,
kein Verlust eines guten alten Backups).
- Cron-Aktivierung: `deploy/cron.d/archivmail` enthält eine auskommentierte
Beispielzeile. Erst aktivieren, wenn ein konkretes `--dest`-Ziel feststeht.
## Keyfile-Escrow (Bitwarden)
Zusätzlich zum Backup: das Keyfile als unabhängige Kopie in Bitwarden
hinterlegen (Secure Note, eigene Collection mit eingeschränktem Zugriff —
das Keyfile entschlüsselt das **gesamte Archiv aller Mandanten**).
```bash
cat /etc/archivmail/keyfile
# → Wert 1:1 in eine neue Bitwarden Secure Note kopieren, Metadaten
# ergänzen (Server/Installation, Datum, wer hinterlegt hat).
```
Zweck: unabhängiger Wiederherstellungsweg, falls PBS/Snapshot-Infrastruktur
selbst nicht verfügbar ist. Ersetzt nicht das App-Backup — beide parallel
pflegen. Bei künftiger Keyfile-Rotation (aktuell nicht vorgesehen) den
Bitwarden-Eintrag im selben Schritt aktualisieren.
## Restore durchführen
**Vorbereitung:**
1. Zielsystem: frischer Server/Container oder vorhandenes System im
Wartungsmodus. `archivmail`/`archivmail-web` müssen gestoppt sein —
`archivmail restore` stoppt/startet die Dienste NICHT selbst.
2. Backup-Verzeichnis identifizieren: `<ziel>/<timestamp>/`.
**Durchführung:**
```bash
systemctl stop archivmail archivmail-web
archivmail restore --config /etc/archivmail/config.yml \
--source <ziel>/<timestamp> [--force]
```
- Ohne `--force`: bricht ab, wenn `store_path`/Keyfile bereits Inhalt haben
— Schutz gegen versehentliches Überschreiben eines laufenden Systems.
`--force` nur auf einem bewusst freigeräumten/frischen Zielsystem nutzen.
- `--skip-db`: überspringt `pg_restore`, falls die Datenbank bereits separat
wiederhergestellt wurde (z.B. via PBS-Snapshot der DB-Ebene).
- Stellt Store (Hardlinks erhalten), Keyfile, Config und PostgreSQL
(`pg_restore --clean --if-exists`) wieder her. Gibt am Ende die
Pflicht-Verifikationsschritte aus (siehe unten).
**Verifikation (Pflicht, nicht optional):**
```bash
systemctl start archivmail archivmail-web
# Health-Check wie im Standard-Deploy-Workflow (Backend ✓, Frontend ✓)
archivmail reconcile --days 7 # PROJ-52: Zählvergleich Store vs. DB muss aufgehen
archivmail reindex # Manticore aus Store+DB neu aufbauen
# Stichprobe: 3-5 zufällige Mails über die UI öffnen und lesbar entschlüsseln
# lassen — beweist, dass Keyfile+Store+DB zueinander passen.
```
Restore-Ergebnis (Mail-Zahl, Zeitstempel, Dauer, welche Verifikationsschritte
liefen) dokumentieren — Prinzip "Zählen, Prüfen, Belegen" wie im
Migrations-Runbook.
## Restore aus einem PBS-Snapshot (Infrastruktur-Ebene)
Auf dem Proxmox-**Host** (nicht im Container):
```bash
pct restore <neue-id> <pbs-storage>:backup/ct/<quell-id>/<timestamp> --storage <ziel-storage>
```
Restored als neuer Container mit `<neue-id>` — der Quell-Container bleibt
unangetastet. Danach dieselbe Verifikation wie oben (`reconcile`, `reindex`,
Stichprobe) im neuen Container durchführen. PostgreSQL kam dabei aus einem
Crash-Consistency-Snapshot, nicht aus einem `pg_dump` — WAL-Replay beim
Start ist der Normalfall, sollte aber beim Test explizit beobachtet werden
(`journalctl -u postgresql` auf Recovery-Meldungen prüfen).
## Regelmäßiger Restore-Test
Ein Backup, das nie zurückgespielt wurde, ist nicht verifiziert. Empfehlung:
mindestens vierteljährlich einen vollständigen Restore auf einen isolierten
Test-Container durchführen (**nicht auf 131/132!**) — einmal über
`archivmail restore` (App-Backup) und mindestens einmal über `pct restore`
(PBS-Snapshot), jeweils mit vollständiger Verifikation. Bislang (Stand
2026-07-05) wurde noch kein Restore-Test durchgeführt — das ist die
kritischste offene Lücke in der Backup-Strategie, nicht das Fehlen eines
Backup-Ziels.
## Rotation vs. DSGVO-Löschung
Backup-Rotation (`--keep N`, bzw. PBS-Retention) ist unabhängig von der
GoBD-Aufbewahrungsfrist der Mails selbst (PROJ-51). Eine in Produktion
bereits DSGVO-gelöschte Mail (PROJ-50) kann in einem älteren Backup noch
enthalten sein. Rotation muss kurz genug sein, dass gelöschte Daten nach
spätestens N Zyklen auch aus Backups verschwinden — Zeitraum mit
Datenschutzbeauftragtem/Nutzer abstimmen, kein rein technisches Thema.
## Monitoring / Alerting (noch offen)
Größtes Risiko bei Cron-Backups: der Job schlägt still fehl, niemand merkt
es bis zum Ernstfall (Lehre aus PROJ-58: Cron-Zeilen fehlten wochenlang
trotz aktivem Code). Aktuell **nicht gebaut**: ein sichtbarer Alarm, wenn
das letzte erfolgreiche Backup älter als ein Schwellenwert ist. Bis dahin:
Log-Datei des Backup-Cron-Jobs (`/var/log/archivmail/backup.log`, sobald der
Cron aktiviert ist) manuell im Rahmen der regulären Betriebs-Checks prüfen.
## Verweis
- `features/PROJ-66-backup-strategie.md` — vollständige Spec, Optionsabwägung,
QA-Ergebnisse.
- `docs/MIGRATION_RUNBOOK.md` — Vorbild für den "Zählen, Prüfen, Belegen"-Stil.
- Memory `project_backup_infra_pbs` — PBS/Sync-Infrastruktur-Details,
`vzdump`/`pct restore`-Befehle.
- Memory `project_132_teilproduktiv` — 132 ist kein reiner Testserver,
Backup-Sorgfalt gilt dort genauso wie auf 131.