Das Programm »Restic« ist ein modernes Backup-Programm, welches als Speicherort sowohl lokale Verzeichnisse als auch per Netzwerk erreichbare Speicher (Online-Speicher) nutzen kann. Der Autor von »Restic« zeigt in anschaulicher Weise in zwei Videos viele Details zur Arbeitsweise seines Programms: »FOSDEM 2015« (2015-01-28) und »CCCCologne« (2016-01-29).
Im Folgenden soll gezeigt werden, wie man unter Linux automatische Backups mit »Restic« einrichten kann. Als Speicherort wird per WebDAV-Protokoll erreichbarer Online-Speicher genutzt. Sinngemäß können die Hinweise aber auch auf andere Speicherorte übertragen werden. Getestet wurde unter »openSUSE« und »Linux Mint« (»Ubuntu«), wobei aber auch alle anderen systemd-basierten Linux-Distributionen in derselben Art oder mit geringfügigen Änderungen geeignet sind.
| openSUSE | Ubuntu, Linux Mint | |
|---|---|---|
sudo zypper up |
sudo apt update |
|
sudo zypper in restic fuse |
sudo apt install restic fuse |
Ab Version »0.9.3« kann man »Restic« auch unabhängig vom Paketmanager der Linux-Distribution per
sudo restic self-updateauf den aktuellen Stand bringen.
»Restic« unterstützt nicht selbst den Zugriff auf Online-Speicher per WebDAV-Protokoll, kann aber die Fähigkeiten des Programms »Rclone« dafür nutzen. »Rclone« bietet sehr einfach die Möglichkeit, auf eine Vielzahl von Online-Speicher zuzugreifen.
| openSUSE | Ubuntu, Linux Mint | |
|---|---|---|
sudo zypper in rclone |
sudo apt install rclone |
Um regelmäßig über das Ergebnis der Backup-Abläufe informiert zu werden, muss ein geeignetes Programm zum Verschicken von E-Mails installiert werden.
| openSUSE | Ubuntu, Linux Mint | |
|---|---|---|
sudo zypper in mailx |
sudo apt install s-nail |
Es muss sich um eine mailx-kompatible Programmversion, die die Option -S unterstützt, handeln.
»Rclone« geeignet zu konfigurieren:
rclone config
e/n/d/r/c/s/q> n
name> GMX
Storage> 31
url> https://mediacenter.gmx.net
vendor> 4
user> [email protected]
y/g/n> y
password: XXXXXXXXXXXXXX
Confirm the password: XXXXXXXXXXXXXX
bearer_token>
y/n> n
y/e/d> y
e/n/d/r/c/s/q> q
Die zu beantwortenden Fragen sind weitgehend selbsterklärend. Als Name wurde hier »GMX« gewählt; andere Namen sind ebenso möglich. Als Ergebnis der Rclone-Konfiguration entsteht die Konfigurationsdatei ~/.config/rclone/rclone.conf. Weitere allgemeine Hinweise zur Rclone-Nutzung finden sich hier.
-
~/.config/backup/backup-env.txtRESTIC_REPOSITORY='rclone:GMX:backup' RESTIC_PASSWORD='???????????' RCLONE_TPSLIMIT=4 MAIL_TO='[email protected]'
Erklärung: Die hier definierte Umgebungsvariable
RESTIC_REPOSITORYlegt fest, wie »Restic« das Verzeichnis zum Speichern der Backups erreichen kann. Es ist das Verzeichnisbackupauf dem von »Rclone« erreichbaren Online-Speicher mit Namen »GMX«.RESTIC_PASSWORDlegt das zum Ver- und Entschlüsseln zu benutzende Passwort fest. Dieses Passwort sollte möglichst kompliziert sein und zusätzlich an einem sicheren Ort aufbewahrt werden.Tests hatten ergeben, dass der Server des Online-Speichers gelegentlich Fehler der Art
CLIENT_USER has exceeded the limit of 15000.0 requests per Hours for this client.: 429 Too Many Requestsmeldete. Das Rclone-Flag
--tmplimit=xxxlässt sich verwenden, um diesen Fehler zu unterdrücken. Die UmgebungsvariableRCLONE_TPSLIMITist äquivalent zu diesem Flag. Der Wert »4« ergibt sich aus 15000 / 1h = 15000 / 3600s ≈ 4/s.Mit
chmod go-rw ~/.config/backup/backup-env.txtsollte die Konfigurationsdatei als nur für ihren Eigentümer lesbar gekennzeichnet werden.
-
~/.config/backup/backup-include.txt/home/mustermannErklärung: Angabe der Verzeichnisse (eins pro Zeile), die von »Restic« gesichert werden sollen. In diesem Beispiel wird als einzige Angabe das gesamte HOME-Verzeichnis ausgewählt.
-
~/.config/backup/backup-exclude.txt/home/mustermann/.cache /home/mustermann/Download "/home/mustermann/VirtualBox VMs"Erklärung: Angabe der Verzeichnisse (eins pro Zeile), die von »Restic« von der Sicherung ausgenommen werden sollen.
-
~/.config/systemd/user/backup.timer[Unit] Description=Backup (Timer) [Timer] OnCalendar=19:30 Persistent=false [Install] WantedBy=default.targetErklärung: Es wird angenommen, dass einmal täglich von »Restic« ein Backup-Lauf gestartet werden soll.
OnCalendarbestimmt den Zeitpunkt (siehe auch: »Time and date specifications«). Die AngabePersistent=falsesorgt dafür, dass ein versäumter Aufruf vonbackup.servicenach Wiedereinschalten des Rechners nicht nachgeholt wird. -
~/.config/systemd/user/backup.service[Unit] Description=Backup on %H Documentation=https://restic.readthedocs.io/en/latest/ [Service] Type=oneshot Nice=15 EnvironmentFile=-/etc/environment EnvironmentFile=%h/.config/backup/backup-env.txt ExecStartPre=/bin/bash -lc "restic unlock --remove-all" ExecStart=/bin/bash -lc "restic backup \ --files-from %h/.config/backup/backup-include.txt \ --exclude-file %h/.config/backup/backup-exclude.txt \ --one-file-system --exclude-caches" ExecStopPost=/bin/bash -lc '%h/.config/systemd/user/backup-email.sh "%N"' ExecStopPost=/bin/bash -lc "restic unlock --remove-all"
Erklärung:
backup.servicebeinhaltet die Abläufe, die vonbackup.timerzeitgesteuert gestartet werden. MitNice=15wird deren Priorität auf einen unterdurchschnittlichen Wert gesenkt (siehe auch:man nice). Der eigentliche Backup-Aufruf geschieht inExecStart. InExecStopPostwird die Benachrichtigungs-E-Mail versendet. -
~/.config/systemd/user/backup-forget-prune.timer[Unit] Description=Purge backup snapshots (Timer) [Timer] OnCalendar=Mon 20:00:00 Persistent=true [Install] WantedBy=default.targetErklärung: Es wird angenommen, dass einmal wöchentlich die von »Restic« gespeicherten Backups bereinigt werden sollen. Die Angabe
Persistent=truesorgt dafür, dass ein versäumter Aufruf vonbackup-forget-prune.servicenach Wiedereinschalten des Rechners nachgeholt wird. -
~/.config/systemd/user/backup-forget-prune.service[Unit] Description=Forget/Prune/Check Snapshots (%H) Documentation=https://restic.readthedocs.io/en/latest/ [Service] Type=oneshot Nice=15 EnvironmentFile=-/etc/environment EnvironmentFile=%h/.config/backup/backup-env.txt ExecStart=/bin/bash -lc "restic unlock --remove-all" ExecStart=/bin/bash -lc "restic forget --prune \ --keep-daily 7 --keep-weekly 4 --keep-monthly 12" ExecStart=/bin/bash -lc "restic unlock --remove-all" ExecStart=/bin/bash -lc "restic check" ExecStopPost=/bin/bash -lc '%h/.config/systemd/user/backup-forget-prune-email.sh "%N"' ExecStopPost=/bin/bash -lc "restic unlock --remove-all"
Erklärung:
backup-forget-prune.servicebeinhaltet die Abläufe, die vonbackup-forget-prune.timerzeitgesteuert gestartet werden. Es werden ältere Backups nach einer sinnvollen Strategie gelöscht. Die Angaben--keep-daily 7,--keep-weekly 4und--keep-monthly 12haben folgende Bedeutung: Hebe monatlich ein Backup 12 Monate rückwirkend auf und hebe wöchentlich ein Backup 4 Wochen rückwirkend auf und hebe täglich ein Backup 7 Tage rückwirkend auf. -
~/.mailrcaccount "backup" { localopts yes set from="Backup Daemon <[email protected]>" set smtp-auth=login set ssl-verify=ignore set smtp-use-starttls set smtp-auth-user="[email protected]" set smtp-auth-password="???????????" set smtp="smtps://mail.gmx.de:465" }
Erklärung: Enthält Angaben zu dem E-Mail-Account, der unter dem Namen »backup« in den Skripten
backup-email.shundbackup-forget-prune-email.shverwendet wird. -
~/.config/systemd/user/backup-email.sh#!/bin/bash # $1 = Unit (short) if [ -z "${MAIL_TO}" ]; then exit 0; fi MAILX=$(which s-nail 2>/dev/null || which mailx) || exit $? HOST=$(hostname) LAST=$(restic snapshots --host $HOST --compact | tail -3 | head -1 | awk '{print $1}') PREV=$(restic snapshots --host $HOST --compact | tail -4 | head -1 | awk '{print $1}') if [[ ${PREV:0:1} == '-' ]]; then PREV=${LAST}; fi MESSAGE1=$(systemctl --user status -l -n 30 $1.service) MESSAGE2=$(restic diff "$PREV" "$LAST" | grep -ve '^.*\/\..*$') # ignore */.*/* SUBJECT="$SERVICE_RESULT: $1 ($HOST)" cat <<EOF | $MAILX > /dev/null \ -s "$SUBJECT" \ -A backup \ -S sendwait \ "$MAIL_TO" $MESSAGE1 ------------------------------------------------------------------------ $MESSAGE2 EOF # '-A backup': defined in ~/.mailrc exit 0
Zusätzlich muss das Skript ausführbar gemacht werden:
chmod ugo+x ~/.config/systemd/user/backup-email.shErklärung: Wird von
backup.servicegenutzt, um im Erfolgsfall wie auch im Fehlerfall eine E-Mail mit einem Bericht zu verschicken. -
~/.config/systemd/user/backup-forget-prune-email.sh#!/bin/bash # $1 = Unit (short) if [ -z "${MAIL_TO}" ]; then exit 0; fi MAILX=$(which s-nail 2>/dev/null || which mailx) || exit $? HOST=$(hostname) MESSAGE=$(systemctl --user status -l -n 30 $1.service) SUBJECT="$SERVICE_RESULT: $1 ($HOST)" cat <<EOF | $MAILX > /dev/null \ -s "$SUBJECT" \ -A backup \ -S sendwait \ "$MAIL_TO" "$MESSAGE" EOF # '-A backup': defined in ~/.mailrc exit 0
Erklärung: Wird von
backup-forget-prune.servicegenutzt, um im Erfolgsfall wie auch im Fehlerfall eine E-Mail mit einem Bericht zu verschicken.Mit
eval $(cat $HOME/.config/backup/backup-env-vaclab.txt) \ ./backup-email.sh backup eval $(cat $HOME/.config/backup/ ./backup-env-vaclab.txt) \ ./backup-forget-prune-email.sh backup-forget-prune
lässt sich das Funktionieren der E-Mail-Benachrichtigungen testen. Misslingt das E-Mail-Verschicken, müssen ggf. die Angaben in
~/.mailrcangepasst werden. Soll das Verschicken von E-Mails verhindert werden, muss in~/.config/backup/backup-env.txtder VariablemMAIL_TOein Leerstring zugewiesen oder die Zeile ganz gelöscht werden.
rclone mkdir GMX:backupDer folgende Aufruf
eval $(cat $HOME/.config/backup/backup-env.txt) restic initist einmalig nötig, um die Dateistruktur zur Aufnahme der Backups anzulegen.
Die folgenden Aufrufe starten die Systemd-Timer und legen fest, dass bei jedem Einloggen automatisch gestartet wird:
systemctl --user enable backup.timer
systemctl --user start backup.timer
systemctl --user enable backup-forget-prune.timer
systemctl --user start backup-forget-prune.timer
Mit
systemctl --user list-timers kann überprüft werden, ob und wann die neu gestarteten Timer ihre nächste Aktion ausführen werden.
Unabhängig von dem automatischen Ablauf, kann ein einzelner Backup-Lauf folgendermaßen gestartet werden:
systemctl --user start backup.serviceDies empfiehlt sich insbesondere beim ersten Backup, welches naturgemäß relativ lange dauert. In einem zweiten Terminal-Fenster kann per
journalctl -f --user-unit backup.serviceder Ablauf beobachtet werden. Ein erfolgreicher Backup-Lauf beginnt mit »Starting Backup on ...« und endet mit »Started Backup on ...«. Die beiden Hinweise
ERROR : index: error listing: directory not found
ERROR : snapshots: error listing: directory not found
beim ersten Backup-Lauf können ignoriert werden, da die Datei-Struktur unterhalb des Zielverzeichnisses noch unvollständig ist.
Der Aufruf
eval $(cat $HOME/.config/backup/backup-env.txt) restic snapshots zeigt eine Liste der Einzel-Backups (auch »snapshots« genannt).
Mit Anlegen der Datei ~/.config/systemd/user/backup-mount.service folgenden Inhalts
[Unit]
Description=Mount the backup
Documentation=https://restic.readthedocs.io/en/latest/
[Service]
Type=simple
Environment=mp="%h/mnt/backup"
EnvironmentFile=%h/.config/backup/backup-env.txt
ExecStartPre=/bin/bash -c 'mkdir -p "$mp"'
ExecStart=/bin/bash -lc 'if $(mountpoint -q "$mp"); then true; else \
restic mount "$mp"; fi'
ExecStop=/bin/bash -c 'if ! $(mountpoint -q "$mp"); then true; else \
fusermount -zu "$mp"; fi'
[Install]
WantedBy=default.targetund durch die Aufrufe
systemctl --user enable backup-mount.service
systemctl --user start backup-mount.service
werden die entschlüsselten Backups über ~/mnt/backup sofort und nach jedem neuen Einloggen automatisch zugänglich.
Sollen nur einzelne Dateien aus dem letzten oder einem früheren Backup wiederhergestellt werden, ist der Zugang über ~/mnt/backup gut geeignet. Will man dagegen den gesamten Inhalt wiederherstellen, weil z.B. die Festplatte mit dem HOME-Verzeichnis defekt ist, geht man folgendermaßen vor:
eval $(cat $HOME/.config/backup/backup-env.txt) restic restore latest --target /Es wird davon ausgegangen, dass das HOME-Verzeichnis auf einer neuen Festplatten nahezu leer neu angelegt wurde und komplett durch die im zuletzt erzeugten Backup gespeicherten Daten ersetzt werden soll. Der gezeigte Aufruf setzt natürlich voraus, dass die genutzte Datei backup-env.txt bereits vorhanden ist. Es ist daher nötig, sie oder besser gleich das gesamte Verzeichnis ~/.config unabhängig von den Backups an einem sicheren Ort zu speichern und vor dem Restore-Aufruf wiederherzustellen.
Soll, anders als hier gezeigt, die System-Installation des Rechners als Backups gesichert werden, müssen die gezeigten Abläufe unter Root-Rechten ablaufen, d.h. --user muss bei den systemctl-Aufrufen entfallen und die Systemd-Dateien müssen an andere Plätze kopiert werden.
Weitergehende Hinweise zu »Restic« findet man hier.
Ein Artikel im »Fedora Magazine« unter dem Titel »Automate backups with restic and systemd« behandelt das hier dargestellte Thema in sehr ähnlicher Weise.
Rolf Niepraschk (Neufassung, 11/2019 ff.)