Stand vor Einführung des Nacht-Agenten
This commit is contained in:
commit
4763548bfb
168 changed files with 12726 additions and 0 deletions
77
docs/betrieb-backup-restore.md
Normal file
77
docs/betrieb-backup-restore.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# Betrieb: Backup und Wiederherstellung
|
||||
|
||||
## Neu: Passwort und Ziele in der Oberfläche
|
||||
Unter **Einstellungen → Backup** (nur Superadministratoren dürfen ändern):
|
||||
- **Backup-Passwort**: selbst wählbar, mindestens 11 Zeichen (länger als 10), mit Wiederholung und Bestätigung durch das Anmeldepasswort. Neue Sicherungen werden damit per **gpg (AES-256, Integritätsschutz)** verschlüsselt (`*.tar.gz.gpg`). Das Passwort liegt mit dem Master-Schlüssel verschlüsselt in der Datenbank, wird nie angezeigt oder protokolliert und lässt sich **nicht wiederherstellen**. Nach einer Änderung bleiben ältere Sicherungen mit dem alten Passwort verschlüsselt. Ohne Passwort und ohne age-Schlüssel wird nichts gesichert (nie unverschlüsselt).
|
||||
- **Externe Ziele**: SFTP (Passwort oder Schlüssel; Server-Schlüssel wird beim ersten Test gemerkt und angezeigt, ein anderer Server wird danach abgelehnt), FTP/FTPS, Google Drive (Token aus `rclone authorize`), Ordner/Netzlaufwerk (eingehängt, z. B. `/mnt/nas/...`). Zugangsdaten werden verschlüsselt gespeichert und nie wieder angezeigt. „Testen“ legt den Ordner an, schreibt und löscht eine Testdatei. Ziele lassen sich deaktivieren oder entfernen (bereits abgelegte Sicherungen bleiben).
|
||||
- Alte Sicherungen mit `.age` bleiben mit der Schlüsseldatei lesbar; der Wiederherstellungstest erkennt die Art an der Dateiendung.
|
||||
|
||||
**Entschlüsseln im Notfall (nur mit Standardwerkzeug):**
|
||||
```bash
|
||||
gpg -d -o archive.tar.gz kundencenter-DATUM-....tar.gz.gpg # fragt nach dem Backup-Passwort
|
||||
```
|
||||
|
||||
## Überblick
|
||||
- **Was wird gesichert:** Datenbank `kundencenter` (Dump) + Konfiguration mit dem Master-Schlüssel (`app.env`, `db.env`, `discord.env`). Ohne `KC_SECRET_KEY` wären 2FA- und Verbindungs-Geheimnisse in einem Backup unlesbar, deshalb ist er enthalten. **Nicht** enthalten: der private Backup-Schlüssel, Plane-Zugang, das Lizenzsystem (eigenes System, eigenes Backup).
|
||||
- **Verschlüsselung:** `age` (öffentlicher Schlüssel `BACKUP_AGE_RECIPIENT`). Ziele (NAS, FTP, Google Drive) sehen nur verschlüsselte Dateien.
|
||||
- **Zeitplan:** täglich ca. 02:30 (`kc-backup.timer`), Wiederherstellungstest sonntags ca. 04:30 (`kc-restore-test.timer`). Verpasste Läufe werden nachgeholt (`Persistent`).
|
||||
- **Aufbewahrung** (lokal und auf jedem Ziel): 14 tägliche, 8 wöchentliche, 12 monatliche Sicherungen; immer mindestens 3 bleiben erhalten. Fremde Dateien werden nie gelöscht.
|
||||
- **Ablage lokal:** `/var/backups/kundencenter/` (Rechte 700). Das ersetzt kein externes Ziel: bei Verlust des Servers ist es weg.
|
||||
- **Kontrolle:** Übersicht (Personal) zeigt letzten Lauf, Ziele und Wiederherstellungstest. Bei fehlgeschlagenem Lauf oder mehr als 26 h ohne Erfolg geht eine Meldung an Discord (ohne Nutzdaten, sobald der Bot eingerichtet ist). Status: `/var/lib/kundencenter/backup-status.json`, Logs: `journalctl -u kc-backup`.
|
||||
- **Wiederherstellungstest** (automatisch): entschlüsselt die neueste Sicherung, spielt sie in die Wegwerf-Datenbank `kundencenter_restoretest` ein und prüft Prüfsummen, Zeilenzahlen aller Kerntabellen, Migrationen, Audit-Hash-Kette und ob gesicherte Geheimnisse mit dem gesicherten Schlüssel lesbar sind. Produktivdaten bleiben unberührt.
|
||||
|
||||
## WICHTIG: privaten Schlüssel extern sichern
|
||||
Der private Schlüssel liegt in `/etc/kundencenter/backup-age-key.txt` (Rechte 600). **Ohne ihn sind alle Backups wertlos.** Bitte einmalig eine Kopie an einem sicheren Ort ablegen (Passwortmanager, Tresor), **nicht** im selben Cloud-Ziel wie die Backups:
|
||||
```bash
|
||||
cat /etc/kundencenter/backup-age-key.txt # Inhalt (zwei Kommentarzeilen + Schlüsselzeile AGE-SECRET-KEY-...) sicher kopieren
|
||||
```
|
||||
Der Schlüssel liegt auf dem Server, damit der automatische Wiederherstellungstest laufen kann. Wer den Server kontrolliert, hat ohnehin Zugriff auf die Datenbank.
|
||||
|
||||
## Backup-Ziele per Kommandozeile (Alternative zur Oberfläche)
|
||||
Zugangsdaten der Ziele stehen in `/var/lib/kundencenter/rclone.conf` (nur root). Alle Befehle mit `--config /var/lib/kundencenter/rclone.conf`.
|
||||
|
||||
**SFTP (empfohlen: Schlüssel statt Passwort)**
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -N "" -f /var/lib/kundencenter/backup_ed25519
|
||||
cat /var/lib/kundencenter/backup_ed25519.pub # auf dem Ziel in ~/.ssh/authorized_keys eintragen
|
||||
ssh-keyscan -H ZIELHOST > /var/lib/kundencenter/known_hosts
|
||||
rclone config create nas sftp host=ZIELHOST user=BENUTZER key_file=/var/lib/kundencenter/backup_ed25519 known_hosts_file=/var/lib/kundencenter/known_hosts --config /var/lib/kundencenter/rclone.conf
|
||||
rclone mkdir nas:kundencenter --config /var/lib/kundencenter/rclone.conf && rclone lsd nas: --config /var/lib/kundencenter/rclone.conf
|
||||
```
|
||||
**FTP/FTPS**
|
||||
```bash
|
||||
rclone config create ftpziel ftp host=ZIELHOST user=BENUTZER pass="$(rclone obscure 'PASSWORT')" explicit_tls=true --config /var/lib/kundencenter/rclone.conf
|
||||
```
|
||||
(Nur unverschlüsseltes FTP möglich? Dann `explicit_tls=false`; die Backups sind trotzdem verschlüsselt, Zugangsdaten gehen aber im Klartext über das Netz.)
|
||||
|
||||
**Google Drive** (OAuth, einmalig auf einem Rechner mit Browser)
|
||||
```bash
|
||||
# auf dem Rechner mit Browser (rclone dort installieren):
|
||||
rclone authorize "drive" "eyJzY29wZSI6ImRyaXZlLmZpbGUifQ" # Scope drive.file: nur von rclone angelegte Dateien
|
||||
# ausgegebenen Token kopieren, dann auf dem Server:
|
||||
rclone config create gdrive drive scope=drive.file token='{"access_token":...}' --config /var/lib/kundencenter/rclone.conf
|
||||
```
|
||||
Empfehlung: eigene OAuth-Client-ID (Google Cloud) verwenden (`client_id=`/`client_secret=`), sonst gelten geteilte Limits.
|
||||
|
||||
**Aktivieren und testen**
|
||||
```bash
|
||||
# in /etc/kundencenter/backup.env: BACKUP_REMOTES=nas:kundencenter,gdrive:Backups/kundencenter
|
||||
systemctl start kc-backup && journalctl -u kc-backup -n 30 --no-pager -o cat # Ziele müssen "ok": true zeigen
|
||||
```
|
||||
Ein ausgefallenes Ziel lässt den Lauf als Fehler zählen (Meldung), das lokale Backup bleibt erhalten.
|
||||
|
||||
## Wiederherstellung (Notfall)
|
||||
1. Neuer/repariertes Server mit MariaDB, Node und `age`; Kundencenter-Code nach `/srv/kundencenter` (Repo), `pnpm install && pnpm build`.
|
||||
2. Sicherungsdatei holen (lokal, Ziel) und den **privaten Schlüssel** bereitlegen.
|
||||
3. Entschlüsseln und entpacken:
|
||||
```bash
|
||||
age -d -i backup-age-key.txt -o archive.tar.gz kundencenter-DATUM-....tar.gz.age
|
||||
mkdir restore && tar -xzf archive.tar.gz -C restore # enthält db.sql, config/*.env, manifest.json
|
||||
```
|
||||
4. Konfiguration zurück: `cp restore/config/*.env /etc/kundencenter/` (chmod 600), Datenbank und Benutzer anlegen (nur Rechte auf `kundencenter`).
|
||||
5. Datenbank einspielen: `mysql -u… -p kundencenter < restore/db.sql`
|
||||
6. Dienste starten (`kc-api`, `kc-worker`, `kc-web`), prüfen: `/v1/ready`, Anmeldung, Übersicht, **Audit-Protokoll → „Integrität prüfen“**.
|
||||
7. Erwartung: Datenverlust höchstens bis zum letzten Backup (bis zu 24 h), Wiederherstellung ca. 30 Minuten.
|
||||
|
||||
## Vor größeren Änderungen
|
||||
Vor Migrationen oder Updates manuell sichern: `systemctl start kc-backup`. Rollback einer fehlerhaften Migration = Wiederherstellung (Abschnitt oben) in eine Wegwerf-Datenbank prüfen, dann produktiv einspielen.
|
||||
Loading…
Add table
Add a link
Reference in a new issue