Zum Inhalt springen
vaultigen

Betrieb

Backups

Verschlüsselte, verifizierte Backups erstellen und dort aufbewahren, wo Ransomware sie nicht erreicht.

Das Wichtigste

Ein Backup allein bringt Vaultigen nicht zurück. Sie brauchen außerdem einige Schlüssel, die außerhalb der Datenbank und außerhalb des Backup-Verzeichnisses liegen. Das ist Absicht: Ein gestohlenes Backup ist ohne sie wertlos, und ein gestohlener Live-Schlüssel öffnet nicht jeden alten Wiederherstellungspunkt. Bewahren Sie Backups und Schlüssel an verschiedenen Orten auf, und üben Sie eine Wiederherstellung, bevor Sie sie brauchen.

Was Sie schützen

Element Ort Warum es wichtig ist
Backup-Sätze storage/app/private/backups/ Verschlüsselter Datenbank-Snapshot, verschlüsselte Dateien und ein Manifest.
Backup-Schlüsselbund storage/app/private/backup.json Entschlüsselt Backup-Sätze.
Installations-KEK storage/app/private/kek.json Entpackt die Tresorschlüssel im Snapshot.
Installationsidentität storage/app/private/installation.json Installations-ID, Audit-Schlüssel, Passkey-Geheimnis.
APP_KEY .env Schützt vom Framework gespeicherte Authentifizierungsdaten.

Bei einer Installation mit Docker Compose liegen Backup-Sätze in backups/, und die vier Schlüssel sind die Dateien in data/keys/ (APP_KEY ist data/keys/app.key). Siehe Docker Compose unten.

System → Operations → Keys listet jede Wiederherstellungsvoraussetzung mit Kennung und Vorhandensein. Werte werden nie angezeigt. Siehe Schlüsselverwaltung.

Vor dem ersten Backup

php artisan vaultigen:backup-key:generate --if-missing

Kopieren Sie backup.json, kek.json, installation.json und APP_KEY in Ihre Hinterlegung. Ein sinnvolles Minimum: drei Kopien an drei Orten (der Live-Host, eine versiegelte Offline-Kopie und ein Safe oder Passwortmanager, den eine zweite Person öffnen kann).

Öffnen Sie dann System → Operations → Backup. Jede Bereitschaftsprüfung muss grün sein: Backup-Schlüssel vorhanden, Backup-Speicher beschreibbar, Snapshot-Werkzeug der Datenbank verfügbar, keine andere Operation läuft.

Ein Backup erstellen

Im Browser: System → Operations → Run backup. Der Job läuft in der Queue. Erfolg wird erst gemeldet, nachdem jede geschriebene Datei erneut gelesen und jede Prüfsumme sowie der Manifest-MAC verifiziert wurden.

Auf der Kommandozeile (ohne Queue-Worker):

php artisan vaultigen:backup

Der Befehl endet bei Fehlern mit einem Exit-Code ungleich null und nennt das absolute Verzeichnis des verifizierten Satzes.

Zeitplan und lokale Aufbewahrung

Nutzen Sie den bestehenden Laravel-Scheduler und einen überwachten Worker mit dauerhafter Queue:

VAULTIGEN_BACKUP_SCHEDULE_ENABLED=true
VAULTIGEN_BACKUP_SCHEDULE="30 2 * * *"
VAULTIGEN_BACKUP_TIMEZONE=UTC
VAULTIGEN_BACKUP_MAX_AGE_HOURS=48
VAULTIGEN_BACKUP_RETENTION_ENABLED=false
VAULTIGEN_BACKUP_RETENTION_DAYS=30

Der Zeitplan ist standardmäßig deaktiviert. Entfernen Sie vor dem Aktivieren einen alten eigenen Backup-Cronjob; schedule:work oder das bestehende minütliche schedule:run muss weiterlaufen. Geplante Backups stellen denselben Job wie die Oberfläche in die Queue, ohne den Scheduler zu blockieren. Erforderlich ist eine Datenbank-, Redis-, Beanstalkd- oder SQS-Queue; sync/deferred/null werden abgelehnt. retry_after (bei der Datenbank-Queue standardmäßig 3660 Sekunden) muss über jedem Job-Timeout liegen; die Wartezeit beim Beenden über der längsten Jobdauer. Bei SQS gilt das entsprechend für das Sichtbarkeits-Timeout. Fehlgeschlagene oder übersprungene Versuche erscheinen in Operations und Aktivität; Operations warnt außerdem bei fehlenden oder zu alten erfolgreichen Backups (standardmäßig 48 Stunden).

Während des Backups erhalten schreibende Anfragen 503; Lesen bleibt möglich, Aufräumarbeiten warten. Normale Beendigung und abgefangene Fehler schließen ihr eigenes Wartungsfenster. Ein getöteter Worker oder Host-Ausfall kann es offen lassen: niemals allein aufgrund des Alters freigeben. Laravel mit artisan down offline nehmen, Web, Worker und Scheduler stoppen und php artisan vaultigen:backup:recover --services-stopped ausführen. Eine Host-Sperre verhindert die Freigabe eines noch laufenden Backups; der Befehl löscht auch verwaiste private Arbeitsdateien. Ein Worker-Timeout räumt seinen eigenen Lauf selbst auf.

Lokales Löschen ist separat freizuschalten: VAULTIGEN_BACKUP_RETENTION_ENABLED=true und eine positive Anzahl Tage setzen. vaultigen:backups:prune läuft um 05:00 in der konfigurierten Zeitzone, löscht nur abgelaufene verifizierte abgeschlossene Sätze und behält den neuesten verifizierten Satz, auch wenn er alt ist. Ausstehende, fehlgeschlagene und nicht verifizierbare Sätze bleiben bestehen; Backups und Schlüsselrotation werden koordiniert. Dies bestätigt keine externe Kopie.

Speicherorte

VAULTIGEN_BACKUP_ROOT steuert alle Backup-Operationen; Standard bleibt storage/app/private/backups. Bisherige Datenbankpfade backups/<run-id> werden als <konfigurierter-root>/<run-id> aufgelöst. Vor einem Wechsel Backup- und Rotationsarbeiten stoppen, alle aufbewahrten Laufverzeichnisse ohne zusätzliche backups/-Ebene verschieben, private Rechte beibehalten, Konfiguration erneuern und jeden Satz prüfen. VAULTIGEN_BACKUP_TEMPORARY_ROOT ist standardmäßig storage/app/private/backup-work: privat und auf einem Datenträger halten, mit Platz für Klartext- und verschlüsselte Snapshots. Kapazitätsprüfungen reservieren zusätzlich VAULTIGEN_MIN_FREE_BYTES; Schätzwerte ersetzen keine Überwachung des freien Speichers.

Normale Sätze enthalten keine .env, Schlüsseldateien, aufgelösten Konfigurations-Caches, Logs oder temporären Klartext. Tresorbilder und Website-Icons liegen in Datenbankzeilen; verschlüsselte Anhänge und aufbewahrte Importquellen werden als Objekte kopiert. Temporäre Uploads und Laufzeit-Caches sind keine Wiederherstellungsvoraussetzungen.

Docker Compose

Alles oben Gesagte gilt; nur Befehle und Pfade unterscheiden sich.

  • Backup-Schlüssel: Die Einrichtung erzeugt data/keys/backup.json. Sichern Sie den ganzen Ordner data/keys/ außerhalb des Servers, wie unter Installation beschrieben.
  • Zeitplan: Die Vorlage aktiviert das nächtliche Backup um 02:30 UTC. Ändern Sie VAULTIGEN_BACKUP_SCHEDULE und VAULTIGEN_BACKUP_TIMEZONE in .env oder setzen Sie VAULTIGEN_BACKUP_SCHEDULE_ENABLED=false, dann docker compose up -d --wait. Der mitgelieferte Worker und Scheduler erfüllen die Queue-Anforderungen oben bereits.
  • Bei Bedarf: docker compose exec web php artisan vaultigen:backup gibt den Satz aus, zum Beispiel /backups/<id>, also backups/<id> neben compose.yaml. Bei einem Fehler endet der Befehl mit einem Exit-Code ungleich null.
  • Satz prüfen: docker compose exec web php artisan vaultigen:backup:verify /backups/<id>.
  • Aufbewahrung: Setzen Sie VAULTIGEN_BACKUP_RETENTION_ENABLED=true und VAULTIGEN_BACKUP_RETENTION_DAYS in .env. Ohne das sammeln sich Sätze an; behalten Sie den Speicherplatz im Blick.
  • Vor jedem Update erstellt der Dienst migrate ein geprüftes Backup (Auslöser migration), wenn Migrationen anstehen.

Kopieren Sie die Sätze jede Nacht vom Server weg, deutlich nach dem Ende des Backups. Der Ordner gehört dem Container-Benutzer, führen Sie die Kopie daher aus der Crontab von root aus (sudo crontab -e):

# Jede Nacht um 04:15, nach dem Backup um 02:30.
15 4 * * * rsync -a /home/admin/vaultigen/backups/ backup-copy@backup-host:vaultigen-backups/

Wählen Sie möglichst ein Ziel, das dieser Server nicht löschen oder überschreiben kann, etwa ein restic-Repository oder Objektspeicher mit Object Lock. Eine Kopie, die während eines laufenden Backups startet, kann einen unvollständigen Satz enthalten; der nächste Lauf vervollständigt ihn, und nur Sätze, die sich prüfen lassen, sind wiederherstellbar.

Ein Backup-Satz enthält nie data/keys/. Bewahren Sie Schlüsselkopie und Backup-Kopien an verschiedenen Orten auf.

Unterbrochenes Backup. Hat ein abgebrochener Worker oder ein Host-Ausfall das Wartungsfenster eines Backups offen gelassen (Schreibzugriffe liefern weiter 503), stoppen Sie die Anwendungsdienste und räumen es mit dem Image des Stacks auf:

docker compose stop web worker scheduler
docker compose run --rm migrate artisan down
docker compose run --rm migrate artisan vaultigen:backup:recover --services-stopped
docker compose run --rm migrate artisan up
docker compose up -d --wait

Jeden Satz vom Host wegbringen

Ein Backup neben der Live-Datenbank geht mit dieser Datenbank verloren. Kopieren Sie nach jedem Lauf den neuen Satz auf einen Speicher, den der Vaultigen-Prozess nicht beschreiben kann:

  • eine Offline-Festplatte, die Sie rotieren, oder
  • Objektspeicher mit Object Lock oder mit Zugangsdaten, die die Anwendung nicht kennt.

Lassen Sie die Kopie von etwas anderem als Vaultigen anfertigen, zum Beispiel von einem Host-Konto, das das Backup-Verzeichnis lesen, aber nicht ändern kann.

Unmittelbar vor der Kopie über ein vom Betreiber kontrolliertes Konto prüfen:

php artisan vaultigen:backup:verify /path/to/completed-set && \
  rsync -a /path/to/completed-set/ backup-copy@backup-host:/protected/vaultigen/set-id/

Kopierzugangsdaten außerhalb der Anwendung halten und die Aufbewahrung am Ziel unabhängig schützen. Alte KEK- und Backup-Schlüssel so lange behalten, wie aufbewahrte oder externe Sätze sie benötigen; das Entfernen eines Schlüssels kann diese unabhängigen Kopien unlesbar machen.

Wenn ein Backup fehlschlägt

Fehler erscheinen auf der Operations-Seite und in der Aktivität mit einem kurzen Code:

Code Bedeutung Vorgehen
backup_key_missing Kein Backup-Schlüsselbund oder aktiver Schlüssel fehlt vaultigen:backup-key:generate --if-missing ausführen oder backup.json wiederherstellen.
snapshot_unreadable / snapshot_unwritable Snapshot-Werkzeug oder Backup-Verzeichnis fehlgeschlagen, oft volle Festplatte Freien Speicher und Berechtigungen prüfen.
object_missing Ein referenzierter Anhang oder eine Importdatei fehlt Ursache klären, bevor Sie dem Satz vertrauen.
object_unreadable / object_unwritable Ein Objekt konnte nicht kopiert werden Berechtigungen von Anhangspeicher und Backup-Verzeichnis prüfen.
integrity_failed Der Satz ließ sich nach dem Schreiben nicht verifizieren Der Satz wird gelöscht; der nächste Lauf beginnt sauber.

Ein fehlgeschlagener Lauf macht den vorherigen guten Satz nie ungültig.

Checkliste

  • Ein Backup-Schlüssel existiert und ist getrennt vom Live-Schlüsselbund hinterlegt.
  • KEK, APP_KEY, Installationsidentität und Audit-Schlüssel sind bei einer zweiten Person hinterlegt.
  • Backups laufen nach Plan und werden abgeschlossen.
  • Jeder Satz wird auf Speicher kopiert, den die Anwendung nicht überschreiben kann.
  • Mindestens eine Wiederherstellungsübung war erfolgreich, und die Notizen sind festgehalten.
  • Nach jeder Schlüsselrotation existiert ein frisches Backup, und alte Schlüssel stehen für aufbewahrte Sätze weiter bereit.

Einen Fehler gefunden? Schreiben Sie uns an [email protected].