#!/usr/bin/env bash # SSHKeyVault sichern (#029). # # bash deploy/sichern.sh # nach /var/backups/sshkv # bash deploy/sichern.sh /mnt/sicherung/sshkv # anderes Ziel # # Sichert die Datenbank (pg_dump mit --clean, damit sie sich auch in eine nicht leere # Datenbank zurueckspielen laesst) und legt einen Pruefwert des Master-Keys daneben. # # Den MASTER-KEY selbst sichert dieses Skript absichtlich NICHT mit: Datenbank und Master-Key # zusammen geben alle Private Keys preis. Den Master-Key einmalig und GETRENNT aufbewahren # (Passwortmanager, Tresor, zweites Medium) – ohne ihn ist jede Sicherung wertlos. # Siehe docs/betrieb/sicherung.md. set -o errexit set -o nounset set -o pipefail VERZEICHNIS=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) cd "$VERZEICHNIS" gruen() { printf '\033[1;32m✓ %s\033[0m\n' "$*"; } gelb() { printf '\033[1;33m! %s\033[0m\n' "$*"; } fehler() { printf '\033[1;31m✗ %s\033[0m\n' "$*" >&2 exit 1 } ZIEL="${1:-/var/backups/sshkv}" BEHALTEN="${SSHKV_SICHERUNGEN_BEHALTEN:-14}" STAND=$(date +%Y%m%d-%H%M%S) mkdir -p "$ZIEL" chmod 0700 "$ZIEL" # Datenbank: als Klartext-SQL, gzip-komprimiert. Enthaelt nur verschluesselte Private Keys. # Nur das Schema public: Die Warteschlange (Schema pgboss) legt der Worker beim Start neu an, # und ihre partitionierten Tabellen lassen sich mit --clean nicht zurueckspielen (in der # Wiederherstellungsprobe aufgefallen). docker compose exec -T db pg_dump -U sshkv --clean --if-exists --no-owner --schema=public sshkv \ | gzip -9 > "${ZIEL}/datenbank-${STAND}.sql.gz" \ || fehler "pg_dump ist fehlgeschlagen. Läuft der Dienst db?" [ -s "${ZIEL}/datenbank-${STAND}.sql.gz" ] || fehler "Die Sicherung ist leer." chmod 0600 "${ZIEL}/datenbank-${STAND}.sql.gz" gruen "Datenbank gesichert: ${ZIEL}/datenbank-${STAND}.sql.gz" # Pruefwert des Master-Keys: verraet nichts ueber den Schluessel, zeigt beim Zurueckspielen # aber, ob der richtige Master-Key bereitliegt. ENV_DATEI="${SSHKV_ENV_DATEI:-.env}" SCHLUESSEL="$(grep -E '^SSHKV_MASTER_KEY_HOST_FILE=' "$ENV_DATEI" 2>/dev/null | cut -d= -f2- || true)" SCHLUESSEL="${SCHLUESSEL:-./geheim/master.key}" if [ -r "$SCHLUESSEL" ]; then sha256sum "$SCHLUESSEL" | cut -d' ' -f1 > "${ZIEL}/master-key-pruefwert-${STAND}.txt" chmod 0600 "${ZIEL}/master-key-pruefwert-${STAND}.txt" gruen "Prüfwert des Master-Keys abgelegt (nicht der Schlüssel selbst)." else gelb "Master-Key ${SCHLUESSEL} nicht lesbar – kein Prüfwert abgelegt (mit sudo ausführen?)." fi # Alte Sicherungen aufraeumen (samt Pruefwert). ls -1t "${ZIEL}"/datenbank-*.sql.gz 2>/dev/null | tail -n +"$((BEHALTEN + 1))" | while read -r alt; do alter_stand=$(basename "$alt" .sql.gz) alter_stand=${alter_stand#datenbank-} rm -f -- "$alt" "${ZIEL}/master-key-pruefwert-${alter_stand}.txt" done gelb "Den Master-Key getrennt aufbewahren – er gehört NICHT neben diese Sicherung."