💡 Hinweis: Dieses Tutorial setzt voraus, dass du einen normalen Benutzer mit sudo-Rechten verwendest — wie im Tutorial Debian 13 Server absichern beschrieben.

Einleitung — Warum Backups? Warum restic?

Backups sind keine Option, sondern Pflicht. Ob Hardwaredefekt, versehentliches rm -rf, Ransomware oder ein fehlgeschlagenes Update — ohne Backup stehst du vor dem Nichts. Die 3-2-1-Regel fasst es zusammen: 3 Kopien deiner Daten, auf 2 verschiedenen Medien, davon 1 offsite.

restic ist ein modernes, in Go geschriebenes Backup-Programm, das sich in den letzten Jahren als echte Alternative zu klassischen Tools wie borgbackup, duplicity oder tar-Skripten etabliert hat. Die wichtigsten Vorteile:

  • Deduplizierung: Gleiche Datenblöcke werden nur einmal gespeichert — egal in welcher Datei
  • Verschlüsselung: Alle Daten werden clientseitig mit AES-256 verschlüsselt, bevor sie das System verlassen
  • Vielfältige Backends: Lokal, SFTP, S3, Backblaze B2, Azure, Google Cloud und mehr
  • Schnell: Inkrementelle Backups übertragen nur geänderte Blöcke
  • Cross-Plattform: Läuft auf Linux, macOS, Windows und BSD
  • Einfache CLI: Wenige, gut dokumentierte Befehle

In diesem Tutorial richten wir ein komplettes Backup-System ein: Von der Installation über automatische Backups mit systemd Timers bis hin zu Monitoring und Datenbank-Integration.


Voraussetzungen

Bevor wir loslegen, solltest du Folgendes mitbringen:

💡 Hinweis: Alle Befehle in diesem Tutorial werden als root ausgeführt. Falls du mit einem normalen User arbeitest, stelle jedem Befehl sudo voran.


restic installieren

In Debian 13 ist restic direkt in den offiziellen Repositories enthalten:

apt update
apt install restic

Prüfe die installierte Version:

restic version
# restic 0.17.3 compiled with go1.23.x on linux/amd64

Neueste Version manuell installieren (optional)

Die Debian-Pakete hinken manchmal etwas hinterher. Falls du die allerneueste Version benötigst, kannst du restic auch direkt von GitHub installieren:

# Neueste Version von GitHub herunterladen
RESTIC_VERSION=$(curl -s https://api.github.com/repos/restic/restic/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//')
wget https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2

# Entpacken und installieren
bzip2 -d restic_${RESTIC_VERSION}_linux_amd64.bz2
chmod +x restic_${RESTIC_VERSION}_linux_amd64
mv restic_${RESTIC_VERSION}_linux_amd64 /usr/local/bin/restic

# Version prüfen
restic version

Autovervollständigung einrichten

Restic kann Shell-Completions generieren, was die Arbeit auf der Kommandozeile deutlich erleichtert:

# Für Bash
restic generate --bash-completion /etc/bash_completion.d/restic
source /etc/bash_completion.d/restic

# Für Zsh
restic generate --zsh-completion /usr/local/share/zsh/site-functions/_restic

Backup-Repository erstellen

Bevor du das erste Backup erstellen kannst, brauchst du ein Repository — den Ort, an dem restic deine verschlüsselten Backup-Daten speichert. Restic unterstützt verschiedene Backends.

Variante 1: Lokales Repository

Am einfachsten für den Einstieg — zum Beispiel auf einer externen Festplatte oder einer separaten Partition:

# Verzeichnis erstellen
mkdir -p /mnt/backup/restic-repo

# Repository initialisieren
restic init --repo /mnt/backup/restic-repo

Du wirst nach einem Passwort gefragt. Dieses Passwort verschlüsselt dein Repository — vergiss es nicht! Ohne Passwort sind deine Backups nicht wiederherstellbar.

enter password for new repository:
enter password again:
created restic repository 8a7a5bcde0 at /mnt/backup/restic-repo

Variante 2: SFTP (Remote-Server)

Ideal für Offsite-Backups auf einen eigenen Server:

# SSH-Key einrichten (falls noch nicht vorhanden)
ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N ""
ssh-copy-id -i /root/.ssh/backup_key user@backup-server.example.com

# Repository über SFTP initialisieren
restic init --repo sftp:user@backup-server.example.com:/backups/mein-server

⚠️ Tipp: Verwende einen dedizierten SSH-Key ohne Passphrase für automatisierte Backups. Beschränke den Key auf dem Remote-Server ggf. mit command= in der authorized_keys.

Variante 3: Amazon S3 (oder S3-kompatibel)

Für Cloud-Backups mit S3-kompatiblen Diensten (AWS, Wasabi, MinIO etc.):

# Zugangsdaten setzen
export AWS_ACCESS_KEY_ID="dein-access-key"
export AWS_SECRET_ACCESS_KEY="dein-secret-key"

# Repository in S3-Bucket initialisieren
restic init --repo s3:s3.amazonaws.com/mein-backup-bucket/restic

# Für S3-kompatible Anbieter (z.B. Wasabi)
restic init --repo s3:https://s3.eu-central-1.wasabisys.com/mein-bucket/restic

Variante 4: Backblaze B2

Backblaze B2 ist eine günstige Alternative zu S3 (ca. $0.005/GB/Monat):

# B2-Zugangsdaten setzen
export B2_ACCOUNT_ID="deine-account-id"
export B2_ACCOUNT_KEY="dein-account-key"

# Repository initialisieren
restic init --repo b2:mein-backup-bucket:/restic

Umgebungsvariablen für den täglichen Gebrauch

Damit du nicht jedes Mal --repo und das Passwort angeben musst, speichere die Einstellungen in einer Datei:

# Konfigurationsdatei erstellen
mkdir -p /etc/restic
cat > /etc/restic/env.sh << 'EOF'
export RESTIC_REPOSITORY="/mnt/backup/restic-repo"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
# Für S3:
# export AWS_ACCESS_KEY_ID="..."
# export AWS_SECRET_ACCESS_KEY="..."
# Für B2:
# export B2_ACCOUNT_ID="..."
# export B2_ACCOUNT_KEY="..."
EOF

# Passwort-Datei erstellen
echo "dein-sicheres-passwort" > /etc/restic/password

# Dateien absichern
chmod 600 /etc/restic/password /etc/restic/env.sh
chmod 700 /etc/restic

Vor jedem restic-Befehl lädst du nun die Umgebung:

source /etc/restic/env.sh
restic snapshots

Erstes Backup erstellen & verstehen

Jetzt wird es ernst — wir erstellen das erste Backup:

source /etc/restic/env.sh

# Backup des /etc-Verzeichnisses
restic backup /etc

Die Ausgabe sieht ungefähr so aus:

repository 8a7a5bcd opened (version 2, compression level auto)
created new cache in /root/.cache/restic

Files:         312 new,     0 changed,     0 unmodified
Dirs:           47 new,     0 changed,     0 unmodified
Added to the repository: 2.146 MiB (876.345 KiB stored)

processed 312 files, 3.891 MiB in 0:02
snapshot 4c2fa8b3 saved

Was ist gerade passiert?

  1. Scanning: restic hat alle Dateien in /etc gelesen
  2. Chunking: Jede Datei wurde in variable Blöcke (Chunks) aufgeteilt
  3. Deduplizierung: Bereits bekannte Chunks werden übersprungen
  4. Kompression & Verschlüsselung: Neue Chunks werden komprimiert und verschlüsselt
  5. Snapshot: Ein Snapshot (Zeitstempel + Metadaten) wurde erstellt

Snapshots anzeigen

restic snapshots

# Ausgabe:
ID        Time                 Host        Tags        Paths
---------------------------------------------------------------
4c2fa8b3  2026-02-17 10:30:00  mein-server             /etc
---------------------------------------------------------------
1 snapshots

Deduplizierung in Aktion

Führe das gleiche Backup nochmal aus:

restic backup /etc

# Ausgabe:
Files:           0 new,     3 changed,   309 unmodified
Dirs:            0 new,     2 changed,    45 unmodified
Added to the repository: 1.234 KiB (567 B stored)

processed 312 files, 3.891 MiB in 0:01
snapshot 7d3e91af saved

Nur geänderte Blöcke wurden übertragen — das zweite Backup war praktisch sofort fertig und hat kaum Speicher belegt. Das ist die Magie der Deduplizierung.

Mehrere Pfade in einem Backup

restic backup /etc /home /var/www /root

Dateien & Ordner ein-/ausschließen

In der Praxis willst du nicht alles sichern. Cache-Dateien, temporäre Daten und Logs brauchen selten ein Backup.

Dateien ausschließen mit –exclude

restic backup /home \
  --exclude="*.tmp" \
  --exclude="*.cache" \
  --exclude=".thumbnails" \
  --exclude="node_modules" \
  --exclude=".local/share/Trash"

Exclude-Datei verwenden

Bei vielen Ausschlüssen ist eine Datei übersichtlicher:

cat > /etc/restic/excludes.txt << 'EOF'
# Cache und temporäre Dateien
*.tmp
*.cache
*.swp
*~

# Paketmanager-Caches
node_modules
__pycache__
.npm
.cache

# System-Caches
/var/cache
/var/tmp
/tmp

# Logs (optional — je nach Bedarf)
# /var/log

# Container-Daten
/var/lib/docker
/var/lib/containerd
EOF
restic backup /etc /home /var/www --exclude-file=/etc/restic/excludes.txt

Nur bestimmte Dateien sichern mit –files-from

Alternativ kannst du explizit angeben, was gesichert werden soll:

cat > /etc/restic/backup-paths.txt << 'EOF'
/etc
/home
/root
/var/www
/var/lib/mysql
/opt/app
/srv
EOF
restic backup --files-from=/etc/restic/backup-paths.txt --exclude-file=/etc/restic/excludes.txt

Tags verwenden

Tags helfen, Backups zu organisieren und später gezielt zu filtern:

restic backup /var/www --tag webserver --tag production
restic backup /home --tag userdata

# Snapshots nach Tag filtern
restic snapshots --tag webserver

Backups wiederherstellen

Ein Backup ist nur so gut wie seine Wiederherstellung. Teste regelmäßig!

Variante 1: Komplette Wiederherstellung mit restore

# Neuesten Snapshot wiederherstellen
restic restore latest --target /tmp/restore-test

# Bestimmten Snapshot wiederherstellen
restic restore 4c2fa8b3 --target /tmp/restore-test

# Nur bestimmte Dateien/Pfade wiederherstellen
restic restore latest --target /tmp/restore-test --include="/etc/nginx"
restic restore latest --target /tmp/restore-test --include="/home/user/.bashrc"

🔴 Achtung: restic restore mit --target / überschreibt vorhandene Dateien! Stelle bei einer echten Wiederherstellung sicher, dass du weißt, was du tust. Teste immer erst in ein temporäres Verzeichnis.

Variante 2: Backup mounten mit FUSE

Noch eleganter: Du kannst Snapshots als Dateisystem mounten und wie ein normales Verzeichnis durchsuchen:

# FUSE installieren (falls nicht vorhanden)
apt install fuse3

# Mount-Punkt erstellen
mkdir -p /mnt/restic

# Backup mounten
restic mount /mnt/restic

In einem zweiten Terminal kannst du jetzt durch deine Backups navigieren:

ls /mnt/restic/
# hosts  ids  latest  snapshots  tags

ls /mnt/restic/snapshots/
# 2026-02-17T10:30:00+01:00

ls /mnt/restic/latest/
# etc  home  var

# Einzelne Datei kopieren
cp /mnt/restic/latest/etc/nginx/nginx.conf /tmp/nginx.conf.restored

Zum Unmounten drücke Ctrl+C im ersten Terminal oder:

fusermount -u /mnt/restic

Variante 3: Einzelne Dateien mit dump extrahieren

# Eine einzelne Datei auf stdout ausgeben
restic dump latest /etc/hostname

# In eine Datei umleiten
restic dump latest /etc/nginx/nginx.conf > /tmp/nginx.conf.restored

Alte Backups aufräumen (forget + prune)

Ohne Aufräumen wächst dein Repository stetig. Restic trennt hier sauber zwischen zwei Schritten:

  1. forget — Markiert Snapshots zum Löschen (basierend auf Retention Policies)
  2. prune — Entfernt die tatsächlichen Daten, die von keinem Snapshot mehr referenziert werden

Retention Policies

Mit restic forget definierst du, welche Snapshots behalten werden:

# Beispiel: Behalte die letzten 7 täglichen, 4 wöchentlichen, 6 monatlichen und 2 jährlichen Snapshots
restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --keep-yearly 2 \
  --prune

Die wichtigsten Optionen:

OptionBedeutung
--keep-last nDie letzten n Snapshots behalten
--keep-daily nPro Tag den neuesten Snapshot der letzten n Tage
--keep-weekly nPro Woche den neuesten der letzten n Wochen
--keep-monthly nPro Monat den neuesten der letzten n Monate
--keep-yearly nPro Jahr den neuesten der letzten n Jahre
--keep-tag tagAlle Snapshots mit diesem Tag behalten

Trockentest

Mit --dry-run siehst du, was passieren würde, ohne tatsächlich zu löschen:

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run

Forget + Prune kombinieren

Der Parameter --prune bei forget führt automatisch den Prune-Schritt aus:

# In einem Schritt
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

# Oder getrennt (z.B. wenn mehrere Hosts ein Repository teilen)
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6
restic prune

Automatisierung mit systemd Timer

Jetzt bringen wir alles zusammen: Ein automatisches Backup, das täglich läuft, alte Snapshots aufräumt und den Status protokolliert.

Backup-Skript erstellen

cat > /usr/local/bin/restic-backup.sh << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail

# Konfiguration laden
source /etc/restic/env.sh

# Logfile
LOG="/var/log/restic-backup.log"
exec >>"$LOG" 2>&1

echo "========================================="
echo "Backup gestartet: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================================="

# Datenbank-Dumps erstellen (optional, siehe Abschnitt Datenbanken)
if [ -x /usr/local/bin/restic-db-dump.sh ]; then
    /usr/local/bin/restic-db-dump.sh
fi

# Backup durchführen
restic backup \
    --files-from=/etc/restic/backup-paths.txt \
    --exclude-file=/etc/restic/excludes.txt \
    --tag auto \
    --verbose

# Alte Snapshots aufräumen
restic forget \
    --keep-daily 7 \
    --keep-weekly 4 \
    --keep-monthly 6 \
    --keep-yearly 2 \
    --prune

echo "Backup beendet: $(date '+%Y-%m-%d %H:%M:%S')"
echo ""
SCRIPT

chmod +x /usr/local/bin/restic-backup.sh

systemd Service Unit

cat > /etc/systemd/system/restic-backup.service << 'EOF'
[Unit]
Description=Restic Backup
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
Nice=10
IOSchedulingClass=idle
# Sicherheitshärtung
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/log /mnt/backup /var/lib/mysql-backup /root/.cache/restic
EOF

systemd Timer Unit

cat > /etc/systemd/system/restic-backup.timer << 'EOF'
[Unit]
Description=Tägliches Restic Backup

[Timer]
# Jeden Tag um 03:00 Uhr
OnCalendar=*-*-* 03:00:00
# Verpasstes Backup nachholen
Persistent=true
# Zufällige Verzögerung bis 30 Min (verhindert gleichzeitige Backups mehrerer Server)
RandomizedDelaySec=1800

[Install]
WantedBy=timers.target
EOF

Timer aktivieren und starten

# systemd neu laden
systemctl daemon-reload

# Timer aktivieren (startet automatisch beim Boot)
systemctl enable restic-backup.timer

# Timer sofort starten
systemctl start restic-backup.timer

# Status prüfen
systemctl status restic-backup.timer
systemctl list-timers --all | grep restic

Ausgabe von list-timers:

NEXT                         LEFT     LAST  PASSED  UNIT                  ACTIVATES
Wed 2026-02-18 03:00:00 CET  16h left n/a   n/a     restic-backup.timer   restic-backup.service

Manuell testen

# Service einmal manuell ausführen
systemctl start restic-backup.service

# Ergebnis prüfen
systemctl status restic-backup.service
journalctl -u restic-backup.service --no-pager -n 50

Backup-Benachrichtigungen bei Fehler

Ein Backup, das still fehlschlägt, ist fast so schlimm wie kein Backup. Richte Benachrichtigungen ein!

Variante 1: E-Mail bei Fehler

Erweitere das Backup-Skript um eine Fehlerbehandlung:

cat > /usr/local/bin/restic-backup.sh << 'SCRIPT'
#!/usr/bin/env bash
set -uo pipefail

source /etc/restic/env.sh

LOG="/var/log/restic-backup.log"
MAILTO="admin@example.com"
HOSTNAME=$(hostname -f)
EXIT_CODE=0

exec >>"$LOG" 2>&1
echo "========================================="
echo "Backup gestartet: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================================="

# Datenbank-Dumps
if [ -x /usr/local/bin/restic-db-dump.sh ]; then
    /usr/local/bin/restic-db-dump.sh || EXIT_CODE=$?
fi

# Backup
restic backup \
    --files-from=/etc/restic/backup-paths.txt \
    --exclude-file=/etc/restic/excludes.txt \
    --tag auto \
    --verbose || EXIT_CODE=$?

# Aufräumen
restic forget \
    --keep-daily 7 \
    --keep-weekly 4 \
    --keep-monthly 6 \
    --keep-yearly 2 \
    --prune || EXIT_CODE=$?

echo "Backup beendet: $(date '+%Y-%m-%d %H:%M:%S') (Exit: $EXIT_CODE)"

# Bei Fehler: E-Mail senden
if [ "$EXIT_CODE" -ne 0 ]; then
    BODY="Backup FEHLGESCHLAGEN auf ${HOSTNAME}!\n\nExit Code: ${EXIT_CODE}\nZeit: $(date)\n\nLetzte 50 Zeilen:\n$(tail -50 "$LOG")"
    echo -e "$BODY" | mail -s "[BACKUP FEHLER] ${HOSTNAME}" "$MAILTO"
fi

exit $EXIT_CODE
SCRIPT

chmod +x /usr/local/bin/restic-backup.sh

💡 Voraussetzung: Für E-Mail-Versand benötigst du ein konfiguriertes Mail-System (z.B. msmtp oder postfix). Installiere sudo apt install msmtp msmtp-mta mailutils für eine einfache Lösung.

Variante 2: Webhook (Slack, Discord, Telegram etc.)

Füge am Ende des Skripts einen Webhook-Aufruf hinzu:

# Discord/Slack Webhook
WEBHOOK_URL="https://discord.com/api/webhooks/xxx/yyy"

if [ "$EXIT_CODE" -ne 0 ]; then
    curl -s -H "Content-Type: application/json" \
        -d "{\"content\":\"🔴 **Backup FEHLER** auf \`${HOSTNAME}\` — Exit Code: ${EXIT_CODE}\"}" \
        "$WEBHOOK_URL"
else
    curl -s -H "Content-Type: application/json" \
        -d "{\"content\":\"✅ Backup OK auf \`${HOSTNAME}\` — $(date '+%Y-%m-%d %H:%M')\"}" \
        "$WEBHOOK_URL"
fi

Variante 3: systemd OnFailure

Eleganter: Lass systemd selbst bei Fehlern benachrichtigen:

# Benachrichtigungs-Service erstellen
cat > /etc/systemd/system/restic-backup-notify@.service << 'EOF'
[Unit]
Description=Backup Fehler-Benachrichtigung für %i

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-notify.sh %i
EOF

# In der Backup-Service-Unit ergänzen:
# [Unit]
# OnFailure=restic-backup-notify@%n.service

Datenbank-Backups integrieren

Datenbankdateien direkt zu sichern ist keine gute Idee — die Daten könnten inkonsistent sein. Erstelle stattdessen Dumps.

MariaDB / MySQL

Falls du MariaDB nutzt (siehe Tutorial #5: MariaDB auf Debian 13), erstelle ein Dump-Skript:

cat > /usr/local/bin/restic-db-dump.sh << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail

DUMP_DIR="/var/lib/mysql-backup"
mkdir -p "$DUMP_DIR"

echo "Erstelle MariaDB-Dumps..."

# Alle Datenbanken einzeln dumpen
for DB in $(mariadb -N -e "SHOW DATABASES" | grep -Ev "^(information_schema|performance_schema|sys)$"); do
    mariadb-dump --single-transaction --routines --triggers --events "$DB" \
        | gzip > "${DUMP_DIR}/${DB}.sql.gz"
    echo "  → ${DB}.sql.gz"
done

# Alternativ: Alle Datenbanken in einer Datei
# mariadb-dump --all-databases --single-transaction --routines --triggers --events \
#     | gzip > "${DUMP_DIR}/all-databases.sql.gz"

echo "MariaDB-Dumps abgeschlossen."
SCRIPT

chmod +x /usr/local/bin/restic-db-dump.sh

💡 Tipp: Verwende --single-transaction für InnoDB-Tabellen, damit der Dump konsistent ist, ohne die Datenbank zu sperren.

PostgreSQL

# Ergänze in restic-db-dump.sh:

echo "Erstelle PostgreSQL-Dumps..."

PG_DUMP_DIR="/var/lib/pgsql-backup"
mkdir -p "$PG_DUMP_DIR"

# Alle Datenbanken dumpen
for DB in $(sudo -u postgres psql -t -c "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres'"); do
    DB=$(echo "$DB" | xargs)  # Whitespace entfernen
    sudo -u postgres pg_dump "$DB" | gzip > "${PG_DUMP_DIR}/${DB}.sql.gz"
    echo "  → ${DB}.sql.gz"
done

# Alternativ: Kompletter Cluster-Dump
# sudo -u postgres pg_dumpall | gzip > "${PG_DUMP_DIR}/all-databases.sql.gz"

echo "PostgreSQL-Dumps abgeschlossen."

Vergiss nicht, die Dump-Verzeichnisse in deine backup-paths.txt aufzunehmen:

echo "/var/lib/mysql-backup" >> /etc/restic/backup-paths.txt
echo "/var/lib/pgsql-backup" >> /etc/restic/backup-paths.txt

Verschlüsselung & Sicherheit

Restic verschlüsselt alle Daten im Repository automatisch mit AES-256 im CTR-Modus und authentifiziert sie mit Poly1305-AES. Der Schlüssel wird aus deinem Passwort abgeleitet (scrypt KDF).

Passwort-Management

Option 1: Passwort-Datei (einfachste Lösung)

echo "mein-sehr-langes-sicheres-passwort" > /etc/restic/password
chmod 600 /etc/restic/password
export RESTIC_PASSWORD_FILE="/etc/restic/password"

Option 2: Umgebungsvariable

export RESTIC_PASSWORD="mein-passwort"

Option 3: Passwort-Kommando (z.B. aus einem Passwort-Manager)

export RESTIC_PASSWORD_COMMAND="pass show backup/restic"
# oder
export RESTIC_PASSWORD_COMMAND="secret-tool lookup service restic"

Zusätzliche Sicherheitsmaßnahmen

  • Repository-Berechtigungen: Nur root sollte Zugriff auf /etc/restic/ haben
  • Separater Backup-User: Erstelle einen dedizierten User für Backups mit minimalen Rechten
  • Append-Only-Modus: Auf dem Remote-Server kann restic im Append-Only-Modus laufen — ein kompromittierter Client kann dann keine alten Backups löschen
# Auf dem Backup-Server: restic REST-Server im Append-Only-Modus
restic-rest-server --append-only --path /srv/restic-repos

Repository-Schlüssel verwalten

# Alle Schlüssel anzeigen
restic key list

# Neuen Schlüssel (Passwort) hinzufügen
restic key add

# Passwort ändern
restic key passwd

# Alten Schlüssel entfernen
restic key remove <key-id>

Monitoring: Backup-Status prüfen

Repository-Integrität prüfen

# Schneller Check (nur Metadaten)
restic check

# Vollständiger Check (liest alle Daten — dauert lange!)
restic check --read-data

# Stichproben-Check (liest einen Teil der Daten)
restic check --read-data-subset=5%

💡 Empfehlung: Führe restic check (ohne --read-data) wöchentlich aus und einen vollständigen Check monatlich. Integriere den Check in einen separaten systemd Timer.

Snapshots auflisten und analysieren

# Alle Snapshots anzeigen
restic snapshots

# Kompakte Ansicht
restic snapshots --compact

# Nach Host filtern
restic snapshots --host mein-server

# Nach Pfad filtern
restic snapshots --path /var/www

# Detaillierte Infos zu einem Snapshot
restic ls latest
restic ls latest /etc/nginx/

# Statistiken
restic stats
restic stats latest --mode raw-data

Automatischer Integritäts-Check per Timer

cat > /etc/systemd/system/restic-check.service << 'EOF'
[Unit]
Description=Restic Repository Check
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env.sh
ExecStart=/usr/bin/restic check
Nice=19
IOSchedulingClass=idle
EOF

cat > /etc/systemd/system/restic-check.timer << 'EOF'
[Unit]
Description=Wöchentlicher Restic Check

[Timer]
OnCalendar=Sun *-*-* 05:00:00
Persistent=true
RandomizedDelaySec=3600

[Install]
WantedBy=timers.target
EOF

systemctl daemon-reload
systemctl enable --now restic-check.timer

Zusammenfassung & Checkliste

Hier ist deine Checkliste für ein komplettes Backup-Setup mit restic:

✅ Backup-Checkliste

  • ☐ restic installiert und Version geprüft
  • ☐ Repository initialisiert (lokal und/oder remote)
  • ☐ Passwort sicher gespeichert (/etc/restic/password)
  • Passwort separat gesichert! (Passwort-Manager, Safe, etc.)
  • ☐ Backup-Pfade definiert (/etc/restic/backup-paths.txt)
  • ☐ Exclude-Regeln definiert (/etc/restic/excludes.txt)
  • ☐ Datenbank-Dump-Skript eingerichtet
  • ☐ Backup-Skript erstellt und getestet
  • ☐ systemd Timer konfiguriert und aktiviert
  • ☐ Fehler-Benachrichtigung eingerichtet (E-Mail/Webhook)
  • Wiederherstellung getestet!
  • ☐ Integritäts-Check per Timer eingerichtet
  • ☐ Dateiberechtigungen gehärtet (chmod 600/700)

Verzeichnisstruktur im Überblick

/etc/restic/
├── env.sh                # Umgebungsvariablen (Repo, Credentials)
├── password              # Repository-Passwort
├── excludes.txt          # Ausschluss-Regeln
└── backup-paths.txt      # Zu sichernde Pfade

/etc/systemd/system/
├── restic-backup.service # Backup-Service
├── restic-backup.timer   # Täglicher Timer
├── restic-check.service  # Integritäts-Check Service
└── restic-check.timer    # Wöchentlicher Check Timer

/usr/local/bin/
├── restic-backup.sh      # Backup-Hauptskript
└── restic-db-dump.sh     # Datenbank-Dump-Skript

/var/log/
└── restic-backup.log     # Backup-Log

Troubleshooting

Problem: Lock-Dateien blockieren das Backup

Wenn ein Backup-Prozess abgebrochen wurde, kann eine Lock-Datei zurückbleiben:

# Fehlermeldung:
# Fatal: unable to create lock in backend: repository is already locked by PID xxx

# Locks anzeigen
restic list locks

# Veraltete Locks entfernen (nur wenn sicher kein anderer Prozess läuft!)
restic unlock

# Hartnäckige Locks entfernen
restic unlock --remove-all

⚠️ Vorsicht: Stelle vor restic unlock sicher, dass wirklich kein anderer restic-Prozess läuft: ps aux | grep restic

Problem: Repository nimmt zu viel Speicherplatz ein

# Repository-Größe prüfen
restic stats --mode raw-data

# Aggressiveres Prune
restic forget --keep-daily 3 --keep-weekly 2 --keep-monthly 3 --prune

# Cache bereinigen
restic cache --cleanup

Problem: Backups sind sehr langsam

  • Netzwerk prüfen: Bei Remote-Repos ist oft die Upload-Geschwindigkeit der Flaschenhals
  • Cache nutzen: restic cached lokal in ~/.cache/restic/ — stelle sicher, dass genug Platz vorhanden ist
  • Exclude-Regeln: Schließe große, unnötige Dateien aus (Logs, Caches, temporäre Dateien)
  • Bandbreite limitieren: Mit --limit-upload und --limit-download (in KiB/s) kannst du verhindern, dass das Backup die Leitung blockiert
# Backup mit Bandbreitenbegrenzung (5 MiB/s Upload)
restic backup /home --limit-upload 5120

Problem: „ciphertext verification failed“

Dies deutet auf korrupte Daten im Repository hin:

# Problematische Packs identifizieren
restic check 2>&1 | grep -i error

# Repository reparieren
restic repair index
restic repair snapshots
restic prune

Problem: „not enough cache capacity“

# Cache-Verzeichnis prüfen
du -sh ~/.cache/restic/

# Cache für dieses Repository leeren
restic cache --cleanup

# Anderes Cache-Verzeichnis verwenden
restic --cache-dir /tmp/restic-cache backup /home

Nächste Schritte

Dein Backup-System läuft jetzt automatisch — aber es gibt immer noch Raum für Verbesserungen:

  • Mehrere Repositories: Nutze ein lokales UND ein Remote-Repository für echte 3-2-1-Backups
  • Monitoring-Dashboard: Integriere Backup-Metriken in Grafana oder Prometheus
  • Disaster Recovery testen: Simuliere regelmäßig eine komplette Wiederherstellung auf einem frischen System
  • restic REST-Server: Betreibe einen dedizierten Backup-Server mit dem offiziellen REST-Backend
  • Append-Only Backups: Schütze dich vor Ransomware durch ein Append-Only-Repository

Weiterführende Ressourcen: