Das Programm »restic« ist ein modernes Backup-Programm,
welches als Ziel lokal gemountete Verzeichnisse verwenden kann. Darüber hinaus
unterstützt es einige ausgewählte Protokolle, um direkt auf Cloud-Speicher
zugreifen zu können (SFTP, S3, OpenStack Swift, Google Cloud Storage u.a.). Im
Folgenden soll gezeigt werden, wie man unter Linux automatische Backups
konfigurieren kann. Als Ziel wird in diesem Beispiel der S3-kompatible »Object
Storage Service« (TelekomCLOUD) benutzt. Sinngemäß lassen sich die folgenden
Angaben auch auf andere Backup-Ziele (z.B. NFS-Mounts) anwenden. Getestet wurde
unter openSUSE
, wobei aber auch alle anderen systemd-basierten
Linux-Distributionen in derselben Art oder mit geringfügigen Änderungen
geeignet sind.
Der Autor von »restic« zeigt in anschaulicher Weise in zwei Videos (»FOSDEM 2015« und »CCC Cologne«) viele Details zur Arbeitsweise des Programms.
Es hat sich als günstig herausgestellt, zwei verschiedene Zeitabläufe zu definieren.
Die Datei $HOME/.config/systemd/user/backup.timer
[Unit]
Description=Backup (Timer)
[Timer]
OnCalendar=22:00
Persistent=true
[Install]
WantedBy=default.target
legt fest, dass täglich um 22 Uhr ein Ablauf gestartet wird, der in der Datei
backup.service
definiert ist. Sollte der betreffende Nutzer zu diesem
Zeitpunkt nicht eingeloggt sein, wird beim nächsten Einloggen die
auszuführende Aktion sofort begonnen.
Die Datei $HOME/.config/systemd/user/backup-purge.timer
[Unit]
Description=Purge backup snapshots (Timer)
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=default.target
legt fest, dass einmal wöchentlich ein Ablauf gestartet wird, der in der
Datei backup-purge.service
definiert ist. Sollte der betreffende Nutzer zu
diesem Zeitpunkt nicht eingeloggt sein, wird beim nächsten Einloggen die
auszuführende Aktion sofort begonnen.
Für die Initialisierung des Backup-Repositoriums und auch für andere Aufrufe
des Programms »restic« ist es nützlich, die Adresse des Repositoriums sowie
alle Angaben zur Autorisierung in Form von Umgebungsvariablen
bereitzustellen. Dazu erhält die Datei $HOME/.config/backup/backup-env.txt
vorerst folgenden Inhalt:
AWS_ACCESS_KEY_ID=????????????????????
AWS_SECRET_ACCESS_KEY=????????????????????????????????????????
RESTIC_REPOSITORY='s3:obs.eu-de.otc.t-systems.com/ob3-3215/backup'
RESTIC_REPOSITORY
ermöglicht den S3-kompatiblen Zugriff auf einen Server,
der durch den »endpoint« obs.eu-de.otc.t-systems.com
definiert ist (hier:
»Object Storage Service« der Telekom). Dort wurde ein Speicherbereich
(»bucket«) mit dem Namen ob3-3215
definiert. Das Backup soll künftig darin
in einem Verzeichnis backup
untergebracht werden. Die Angaben zu
AWS_ACCESS_KEY_ID
und AWS_SECRET_ACCESS_KEY
erhält man per Web-Zugang zum
Server beim Anlegen des Buckets. Mit dem folgenden restic-Aufruf wird das
Backup-Repositorium initialisiert:
eval $(cat $HOME/.config/backup/backup-env.txt) restic init
Das dabei erfragte Passwort für die Verschlüsselung des späteren Backups muss
danach als weitere Zeile der Datei $HOME/.config/backup/backup-env.txt
hinzugefügt werden:
RESTIC_PASSWORD='????????????'
Es ist zu empfehlen, die Lese- und Schreibrechte der Datei auf ihren Eigentümer zu beschränken:
chmod 600 $HOME/.config/backup/backup-env.txt
Durch den in der Datei backup.timer
festgelegten Zeitablauf wird periodisch
ein neuer Snapshot entsprechend dem Inhalt der Datei
$HOME/.config/systemd/user/backup.service
erstellt:
[Unit]
Description=Backup %H
Documentation=https://restic.readthedocs.io/en/latest/
OnFailure=failure-email@%n.service
[Service]
Type=oneshot
EnvironmentFile=%h/.config/backup/backup-env.txt
#---Ubuntu---#EnvironmentFile=/etc/environment
#---Ubuntu---#Environment=HOME=%h
ExecStart=/bin/bash -lc "/usr/bin/nice -n 15 /usr/bin/ionice -c2 -n5 \
/usr/bin/restic backup --cleanup-cache \
--files-from %h/.config/backup/backup-include.txt \
--exclude-file %h/.config/backup/backup-exclude.txt \
--one-file-system --exclude-caches"
[Install]
WantedBy=default.target
Zur Erklärung: Der restic-Aufruf legt einen neuen Snapshot dessen an, was sich
seit dem vorigen geändert hat. Welche Verzeichnisse behandelt und welche
ignoriert werden sollen, ist in den Dateien backup-include.txt
und
backup-exclude.txt
enthalten. Das Ziel des Backups und alle nötigen Angaben
zur Autorisierung erhält das Programm über die Umgebungsvariablen, die in der
Datei $HOME/.config/backup/backup-env.txt
definiert sind (siehe oben). Nähere
Hinweise zu weiteren Angaben beim Anlegen eines Snapshots entält die
Dokumenation. Im
Falle dessen, dass dieser Ablauf mit einem Fehler endet, wird die Systemd-Unit
[email protected]
aufgerufen. Näheres zu [email protected]
siehe
weiter unten. Die mit #---Ubuntu---#
gekennzeichneten Zeilen sind nur unter
»Ubuntu« notwendig.
Mit
systemctl --user start backup.service
kann man einen neuen Snapshot unabhängig vom automatischen Timer-Aufruf erzeugen. Wenn man parallel dazu in einem anderen Terminal
journalctl -f --user-unit backup.service
aufruft, kann man die Ausgabe des restic-Aufrufs beobachten.
Mit dem folgenden Aufruf lässt sich die Integrität des Backups überprüfen:
eval $(cat $HOME/.config/backup/backup-env.txt) restic check
Eine erweiterte Überprüfung, bei der auch die Daten selbst mit einbezogen werden, erreicht man mit
eval $(cat $HOME/.config/backup/backup-env.txt) restic check --read-data
Diese Überprüfung kann relativ lange andauern.
Grundsätzlich wäre es möglich, nach der oben gezeigten Definition, unbegrenzt
über Jahre hinweg jeden Tag einen neuen Snapshot anzulegen. Ein solches
Vorgehen ist allerdings nicht unbedingt notwendig. Es ist ausreichend, wenn
man nur eine bestimmte Zahl der täglichen Snapshots aufbewahrt. Das Programm
»restic« unterstützt Regeln, nach denen als unnötig betrachtete Snapshots
gelöscht werden. Die Datei $HOME/.config/systemd/user/backup-purge-check.service
definiert dazu einen geeigneten Ablauf:
[Unit]
Description=Purge backup snapshots
Documentation=https://restic.readthedocs.io/en/latest/
OnFailure=failure-email@%n.service
[Service]
Type=oneshot
EnvironmentFile=%h/.config/backup/backup-env.txt
#---Ubuntu---#EnvironmentFile=/etc/environment
#---Ubuntu---#Environment=HOME=%h
ExecStartPre=/usr/local/bin/restic unlock --remove-all
ExecStart=/usr/local/bin/restic forget --prune \
--keep-daily 7 --keep-weekly 4 --keep-monthly 12
ExecStart=/usr/local/bin/restic check
[Install]
WantedBy=default.target
Zur Erklärung: Dieser restic-Aufruf löscht alle Snapshots, die älter als sieben Tage sind, wobei aber darauf geachtet wird, dass zusätzlich vier Wochen rückwirkend jeweils ein Snapshot pro Woche erhalten bleibt. Ebenso bleibt zusätzlich 12 Monate rückwirkend jeweils ein Snapshot pro Monat erhalten. Auf diese Weise hat man die Sicherheit, aktuelle Stände zur Verfügung zu haben. Darüber hinaus hat man aber auch die reale Chance, maximal ein Jahr rückwirkend Dateien wiederherstellen zu können.
Die besprochenen Systemd-Units (backup.service
und
backup-purge-check.service
) enthalten jeweils die Zeile
OnFailure=failure-email@%n.service
Im Falle eines Fehlers wird dadurch die Unit [email protected]
mit dem
Namen der ursprünglichen Unit als Parameter aufgerufen. Die Datei hat den
folgenden Inhalt:
[Unit]
Description=OnFailure email for %i
[Service]
Type=oneshot
KillMode=process
ExecStart=%h/.config/systemd/user/email-on-failure.sh %i
Zur Erklärung: Es wird das Shell-Script
$HOME/.config/systemd/user/email-on-failure.sh
mit einem Unit-Namen (z.B.
backup.service
) als Parameter aufgerufen. Das Shell-Script dient der
Benachrichtigung über den aufgetretenen Fehler per E-Mail. Es könnte folgenden
Inhalt haben (hier als Beispiel: E-Mail-Versand durch den E-Mail-Provider »GMX«):
#!/bin/bash
EMAIL="[email protected]"
SUBJECT="OnFailure ($1)"
SENDER="$EMAIL"
cat <<EOF | mailx -s "$SUBJECT" \
-S from=$SENDER \
-S ssl-verify=ignore \
-S smtp-auth=login \
-S smtp=smtps://mail.gmx.de:465 \
-S smtp-auth-user=$EMAIL \
-S smtp-auth-password='__GEHEIM__' \
$EMAIL
*** STATUS ***
$(systemctl --user status -l -n 30 "$1")
EOF
exit
Das Script muss ausführbar gemacht werden:
chmod u+x $HOME/.config/systemd/user/email-on-failure.sh
Im Betreff der E-Mail wird die mit Fehler beendete Unit genannt. Im Hauptteil der E-Mail werden die letzten 30 Zeilen von deren Status-Abfrage angegeben.
Um das Verhalten im Fehlerfalle zu testen, kann Folgendes getan werden.
Testweise wird in $HOME/.config/backup/backup-include.txt
ein
nichtexistierendes Verzeichnis wie z.B.
/Wrzlbrnft
eingetragen, was zu einem fehlerhaften restic-Aufruf nach
systemctl --user start ptb-backup.service
führt. Dies wiederum sollte zum Versenden einer E-Mail an
[email protected]
führen.
Das Programm »restic« erlaubt es, das gesamte Backup zu mounten. Dies ist
eine angemessene Methode, wenn es darum geht, nur einige ausgewählte Dateien
aus dem Backup wiederherzustellen. Die Datei
$HOME/.config/systemd/user/backup-mount.service
enthält den dazu nötigen
Aufruf:
[Unit]
Description=Mount the backup
Documentation=https://restic.readthedocs.io/en/latest/
[Service]
Type=simple
EnvironmentFile=%h/.config/backup/backup-env.txt
#---Ubuntu---#EnvironmentFile=/etc/environment
#---Ubuntu---#Environment=HOME=%h
ExecStart=/usr/bin/restic mount %h/backup
ExecStop=/usr/bin/fusermount -zu %h/backup
[Install]
WantedBy=default.target
Zur Erklärung: Der Aufruf systemctl --user start backup-mount.service
macht
den Inhalt des Backups über das Verzeichnis $HOME/backup
zugänglich. Mit
systemctl --user stop backup-mount.service
wird er wieder abgemeldet.
Die folgende Bash-Funktion vereinfacht das manuelle Mounten (man kann sie in
$HOME/.bashrc
eintragen):
function mountBackup () {
local mp="$HOME/backup"
if $(mountpoint -q $mp); then
systemctl --user stop backup-mount.service
echo "\"$mp\" unmounted"
else
systemctl --user start backup-mount.service
echo "\"$mp\" mounted"
fi
}
Der Aufruf von mountBackup
bindet den Inhalt des Backups als $HOME/backup
ein. Ist der Mount-Prozess bereits aktiv, bewirkt der Aufruf, dass er
stattdessen ausgehangen wird. Je nach Güte der Netzwerkverbindung zum
Cloud-Speicher kann es einige Zeit dauern, bis ein Zugriff möglich ist.
Da auch hier auf systemd zurückgeriffen wird, wäre es bei Bedarf leicht möglich, den Inhalt des Backups automatisch beim Einloggen zu mounten:
systemctl --user enable backup-mount.service
systemctl --user start backup-mount.service
Es ist möglich, mit einem einzelnen restic-Aufruf alle gesicherten Dateien eines bestimmten Snapshots an ihren ursprünglichen Platz zurückzuholen oder sie an anderer Stelle abzulegen. Zur zeitlichen Einordnung der Snapshots ist der folgende Aufruf geeignet:
eval $(cat $HOME/.config/backup/backup-env.txt) restic snapshots
Das Rückholen des kompletten Snapshots könnte so erfolgen:
eval $(cat $HOME/.config/backup/backup-env.txt) restic restore 6ae7c118 --target /home
Statt der konkreten Snapshot-Kennung (in diesem Beispiel 6ae7c118
) kann
bei Bedarf auch latest
angegeben werden.
Näheres dazu ist in der Dokumentation zu finden.
systemctl --user enable backup.timer # Timer beim Einloggen automatisch starten
systemctl --user start backup.timer # Timer jetzt starten
systemctl --user enable backup-purge.timer
systemctl --user start backup-purge.timer
systemctl --user status backup.timer
journalctl -f --user-unit backup.service
journalctl --since yesterday --user-unit backup.service
systemctl --user list-timers
Rolf (2018/04)