CallMeTechie
EN Anmelden
Home Produkte Blog Über mich Kontakt

Backup & Restore

🔒 Sicherheit · Updated vor 1 Monat

Zielgruppe: Ops. Dieses Kapitel beschreibt was in einem Backup steckt, wie du manuelle und automatische Backups anstößt, wie Restore läuft und was das Backup nicht abfängt. Für erste Einrichtung siehe deployment.md, für Version-Upgrades upgrade.md.


1. Was enthält ein Backup

Ein GateControl-Backup ist eine einzelne JSON-Datei (Format-Version 3 seit v1.35). Inhalt:

  • peer_groups — Namen, Farben, Beschreibungen
  • peers — Name, Public-Key, verschlüsselte Private/Preshared-Keys, allowed_ips, DNS, Keepalive, enabled-Flag, Tags, expires_at, Gruppen-Referenz per Name
  • routes — Domain, Target-IP/Port, Peer-Referenz per Name, sämtliche Feature-Flags (HTTPS, Basic-Auth, ACL, Rate-Limit, Retry, Backends, Sticky-Sessions, Circuit-Breaker, Mirror, Debug, Bot-Blocker, Custom-Header), ACL-Peer-Liste per Name
  • settings — kompletter Key-Value-Store (SMTP, Security, Alerts, Branding, Monitoring, DNS-Override, Split-Tunnel, Auto-Backup-Config, …)
  • webhooks — URL, Events, Beschreibung, Enable-Flag
  • route_auth — Email-/TOTP-Auth-Konfigs pro Route (inkl. verschlüsseltem TOTP-Secret)

Was nicht drin steht:

  • Caddy-TLS-Storage (/data/caddy/) — Zertifikate werden nach Restore neu geholt. Bei Let's-Encrypt ist das OK, bleibt aber innerhalb der Rate-Limits (50 Cert/Woche pro Domain). Bei kurzem Auseinander-Nehmen kein Problem; bei Zerfall einer ganzen Domain-Liste in kurzer Folge droht Rate-Limit.
  • Access-Logs (/data/caddy/access.log), Audit-Log-Tabelle activity_log, Traffic-Snapshots, Login-Versuche, API-Token-Plaintext (werden nach Issue nur gehasht gespeichert), Session-Cookies.
  • SQLite-WAL-Dateien, Auto-Backup-Archiv unter /data/backups/ selbst.
  • WireGuard-Server-Keypair (/data/wireguard/wg0.conf). Das muss separat gesichert werden (siehe Abschnitt 6). Ohne Server-Key schlagen alle bestehenden Peer-Configs fehl, weil der Public-Key nicht mehr matcht.
  • Lizenz-Token (/data/.license-token). Wird bei Re-Validation neu geholt, sofern GC_LICENSE_KEY gesetzt bleibt.

2. Manuelles Backup

Via UI

EinstellungenBackupBackup jetzt erstellen. Der Browser lädt eine Datei gatecontrol-backup-YYYY-MM-DD.json herunter.

Via API

curl -u admin@token:<token> \
  https://gate.example.com/api/v1/settings/backup \
  -o backup-$(date -u +%F).json

-u admin@token:<token> benutzt einen API-Token mit Scope settings:read. Alternativ mit Session-Cookie siehe API.md. Die Antwort ist direkt das JSON-Backup.

Der Endpoint selbst (GET /api/v1/settings/backup) liefert das Backup-Objekt unabhängig vom Query-Parameter; ?format=download setzt zusätzlich den Content-Disposition-Header, ist für curl aber optional.


3. Auto-Backup-Jobs

Einrichtung in der UI

EinstellungenBackup → Sektion Automatische Backups:

  • Aktiviert (Toggle)
  • Intervall6h, 12h, daily, 3d, weekly
  • Aufbewahrung1 bis 100 Versionen. Ältere werden nach jedem Run automatisch gelöscht.

Die Backups landen im Container unter /data/backups/ als gatecontrol-YYYYMMDD-HHmmss.json. Über die UI kannst du dir die Liste anschauen, einzelne Dateien runterladen oder löschen.

API-Endpoints

# Aktuelle Job-Konfig abrufen
GET  /api/v1/settings/autobackup

# Konfig updaten (Body: { enabled, schedule, retention })
PUT  /api/v1/settings/autobackup

# Sofort manuell auslösen (nutzt die konfigurierte Retention)
POST /api/v1/settings/autobackup/run

# Verzeichnis-Listing
GET  /api/v1/settings/autobackup/list
# → [{ filename, size, created }]

# Einzeldatei runterladen / löschen
GET    /api/v1/settings/autobackup/download/:filename
DELETE /api/v1/settings/autobackup/:filename

Filename-Format ist strikt: gatecontrol-YYYYMMDD-HHmmss.json. Alles andere wird von der API abgelehnt (schützt gegen Path-Traversal).

Failure-Handling

Wenn autobackup_run fehlschlägt:

  1. Eintrag im activity_log mit severity=error.
  2. Wenn in Settings → Alerts eine Alert-Mail konfiguriert UND SMTP konfiguriert ist, geht eine Mail mit Betreff [GateControl] Automatic backup failed raus.
  3. Der Scheduler läuft weiter — beim nächsten Slot wird ein neuer Versuch unternommen.

Feature-Flag: Auto-Backup läuft nur mit scheduled_backups — Community-Build hat das an, Lizenz-Restriktionen siehe concepts/licensing.md.


4. Restore

Via UI

EinstellungenBackupRestore:

  1. JSON-Datei wählen.
  2. Preview — zeigt die Summary (Anzahl Peers/Routes/Settings/Webhooks/…). Die Preview-Route validiert, läuft aber read-only.
  3. Restore bestätigen. Der Modus ist immer replace — bestehende Peers, Routes, Settings, Webhooks und Route-Auth-Einträge werden komplett ersetzt. Ein "merge" existiert aktuell nicht.
  4. Nach erfolgreichem Restore rotiert der CSRF-Token und du wirst in der UI neu eingeloggt.

Via API

curl -u admin@token:<token> \
  -F "backup=@gatecontrol-backup-2026-04-20.json" \
  https://gate.example.com/api/v1/settings/restore

Optionaler Preview-Endpoint (ohne Side-Effects):

curl -u admin@token:<token> \
  -F "backup=@..." \
  https://gate.example.com/api/v1/settings/restore/preview

Antwort { ok: true, summary: { version, created_at, peers, routes, … } }.

Was serverseitig passiert

  1. Validierung — Struktur, Versions-Kompatibilität (2 oder 3), Peer-Namen, Domains, Ports, Webhook-URLs.

  2. Decrypt-Check — jeder verschlüsselte Private-/Preshared-Key wird mit dem aktuellen GC_ENCRYPTION_KEY probewise entschlüsselt. Schlägt das bei irgendeinem Peer fehl, wird der Restore mit klarer Fehlermeldung abgebrochen, bevor die DB angefasst wird:

    Peer "nas-home": cannot decrypt private key — the backup was created with a different GC_ENCRYPTION_KEY

  3. Transaction — ein einzelner SQLite-Transaktionsblock löscht route_peer_acl, route_auth_otp, route_auth_sessions, route_auth, routes, peers, peer_groups, settings, webhooks und schreibt sie neu. Bei Fehler: automatischer Rollback, der alte Zustand ist intakt.

  4. WireGuard — nach erfolgreichem Commit wird wg0.conf neu aus dem Peer-Set generiert und das Interface per wg syncconf reloaded.

  5. Caddy — neues Config-JSON wird gebaut und per Admin-API gepusht.


5. Special-Case: Gateway-Peers nach Restore

Home-Gateways registrieren sich gegen den Server über einen pro-Gateway ausgestellten JWT. Der Signing-Key dieser Tokens ist ein Derivat aus GC_SECRET.

  • Gleicher Server, gleiche VolumesGC_SECRET bleibt, Gateway-Tokens bleiben gültig. Kein Handeln nötig.

  • Restore auf frisch aufgesetzter Instanz → neuer GC_SECRET, Gateway-Tokens aus alten .env-Dateien auf den NAS werden abgelehnt. Dann:

    1. Peer in der UI öffnen → Gateway-Pairing neu generieren.
    2. Neue .env für den Gateway-Companion generieren lassen und auf die NAS/RPi deployen.
    3. Dort docker compose up -d --force-recreate gateway.

Alternativ: GC_SECRET aus dem alten Volume übernehmen — dann ist kein Re-Pairing nötig. Das ist der empfohlene Weg, wenn du einfach auf eine neue VPS umziehst: alte .env + /data/.session_secret + /data/.encryption_key mitnehmen, dann Restore auf neue Instanz.


6. Offsite- & Voll-Volume-Strategie

Das JSON-Backup ist eine logische Sicherung. Für vollständige Desaster-Recovery musst du zusätzlich die physischen Volumes sichern.

Empfohlenes Setup

Täglich (automatisch):

  • Auto-Backup-Job läuft, schreibt in /data/backups/.
  • Ein externes System (Uptime-Server, Monitoring-Host) fetcht jede Nacht per API-Token GET /api/v1/settings/backup und archiviert das JSON in Git oder Objekt-Storage.

Wöchentlich (manuell oder per Cron auf dem Host):

  • Snapshot des Docker-Volumes gatecontrol-data per tar:

    docker run --rm \
      -v gatecontrol-data:/data:ro \
      -v /var/backups/gatecontrol:/out \
      alpine \
      tar czf /out/gatecontrol-volume-$(date -u +%F).tar.gz /data
    
  • Rotation: 4 wöchentliche + 12 monatliche Snapshots.

S3 / B2 / Rsync-Ziel

Die UI bietet aktuell keinen direkten S3-Upload-Target für Auto-Backups — das ist als Roadmap-Feature im Backlog. Workaround:

# Cron auf dem Host, läuft nach dem Auto-Backup-Fenster
0 4 * * * aws s3 sync /var/lib/docker/volumes/gatecontrol-data/_data/backups/ \
            s3://company-backups/gatecontrol/

Oder per API-Token von außen fetchen und in S3 schieben:

curl -sS -H "Authorization: Bearer $GC_API_TOKEN" \
  https://gate.example.com/api/v1/settings/backup \
  | aws s3 cp - s3://company-backups/gatecontrol/backup-$(date -u +%F).json

7. Backup testen

Ein Backup, das du nicht regelmäßig getestet hast, ist kein Backup.

Minimal-Test-Rezept:

  1. Zweite leere VPS mit identischem Docker-Stack hochziehen (siehe deployment.md).
  2. Alte GC_ENCRYPTION_KEY und GC_SECRET aus dem Prod-Volume in das Test-.env eintragen (sonst scheitert der Decrypt-Check).
  3. Container starten.
  4. Backup-JSON hochladen über Settings → Backup → Restore.
  5. Peer-Liste, Routes, Settings prüfen.
  6. Einen existierenden Peer mit der Config verbinden und einen Handshake erzwingen — wenn das klappt, ist das Keymaterial okay.
  7. VPS wieder wegwerfen.

Empfehlung: alle 3–6 Monate machen oder wenn du am Backup-Format (Schema-Migration) was geändert hast.


8. Was Backup nicht abfängt

Szenario JSON-Backup Volume-Snapshot Fix
Admin löscht versehentlich alle Peers ja ja Restore aus letztem Auto-Backup
Disk-Failure / Volume-Corruption teilweise ja Volume-Snapshot restore, dann Caddy-Certs nachholen
Kompromittierter Admin-Account nein nein API-Tokens revoken, Passwort + 2FA, Audit-Log prüfen
Verlorener GC_ENCRYPTION_KEY NEIN nein Private-Keys verloren → alle Peers neu ausrollen
Docker-Image-Corruption nach Bad Push nein nein Image-Tag auf letzte bekannte Version pinnen
Zerstörtes Host-OS nein nein VPS neu bauen, Volume-Tarball einspielen
Compromised VPS (Host-Root) nein nein Komplett neu aufsetzen, Secrets rotieren, Audit

Merkregel: JSON-Backup sichert die Konfiguration. Volume-Snapshot sichert Secrets + TLS-Storage. Beides zusammen macht Desaster-Recovery realistisch.

Für Incident-Debugging beim Wiederherstellen siehe auch troubleshooting.md, Abschnitt "Datenbank".

Cookie Settings

Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Essentielle Cookies sind immer aktiv.

Datenschutzerklärung
ESC
↑↓ navigate open esc close