Es gibt eine Vielzahl von guten Backup-Programmen, aber jedes legt den Schwerpunkt auf andere Aspekte. Für mich persönlich gibt es einige Kriterien, die eine Lösung erfüllen muss:
- Differenzielle Sicherungen/Deduplizierung: Sicherungen erfüllen ihren Zweck am besten, wenn sie regelmäßig und häufig durchgeführt werden. Selbstverständlich möchte ich aber nicht unveränderte Dateien doppelt und dreifach auf dem gleichen Ziel vorhalten. Auch wenn ich nur neue und veränderte Dateien sichere, teilen sich viele von ihnen gleiche Daten, die ich ebenfalls nicht mehrfach ablegen möchte.
- Komprimierung: Um den Speicherplatzbedarf zusätzlich zu senken, kommt ein Kompressionsverfahren zum Einsatz.
- Verschlüsselung: Auch wenn das Backup-Ziel gut gegen Angreifer geschützt ist, schadet eine zusätzliche Sicherheitsmaßnahme nicht.
- Aufbewahrungsrichtlinien: Sicherungen müssen in der Regel nicht ewig aufbewahrt werden und sollen nach festzulegenden Kriterien automatisch gelöscht werden.
- Wiederherstellungsmethoden: Die beste Sicherung nützt letztlich nichts, wenn verlorengegangene Daten nicht mehr zurückgespielt werden können.
- Kommandozeilenprogramm: Automatisierung ist das Ziel, und dafür muss eine Schnittstelle existieren.
Borg ist hier besonders interessant, weil es ein weitverbreitetes und stetig weiterentwickeltes Programm ist.
Installation und Konfiguration
Die Installation erfolgt zum Beispiel über den Paketmanager und kann daher natürlich variieren. Unter Ubuntu und seinen Derivaten wählt man das Paket borgbackup, unter Arch Linux und seinen Abkömmlingen das Paket borg. Danach geht es in der Konsole mit der Konfiguration weiter. Ich gehe davon aus, dass die Backups auf einem externen Datenträger gespeichert werden, der unter /mnt/backups/ eingebunden ist. Unter diesem Pfad richte ich das sogenannte Repository ein:
borg init --encryption=repokey /mnt/backups
Man wird nach einem Kennwort gefragt, mit dem die Sicherungen verschlüsselt werden und das bei der Wiederherstellung und beim Zugriff auf das Repository im Allgemeinen benötigt wird – also gut aufbewahren. Jetzt könnte man eine erste Sicherung mit dem Namen initial und dem Kompressionsverfahren zlib erstellen:
borg create --compression zlib,1 /mnt/backups::initial ~/Bilder ~/Dokumente
Nach der Eingabe des Kennworts wird die Sicherung im Repository erstellt. Je öfter man Backups erstellt, desto mehr Speicher wird verbraucht, und irgendwann erreichen Sicherungen auch ein Alter, ab dem sich eine Wiederherstellung wahrscheinlich nicht mehr lohnen würde. Darum lassen sich Anzahl und Zeiträume der vorzuhaltenen Backups konfigurieren und alle übrigen Backups löschen. So werden zum Beispiel nur Backups behalten, die an sieben unterschiedlichen Tagen erstellt wurden, außerdem noch ein zusätzliches wöchentliches und ein zusätzliches monatliches Backup:
borg prune --keep-daily 7 --keep-weekly 1 --keep-monthly /mnt/backups::initial
Systematisierung mit borgmatic
Diese Befehle könnte man nun in ein Skript einbetten. Übersichtlicher (besonders wenn man mehrere verschiedene Backup-Repositories anlegt) finde ich die Möglichkeit, die Parameter in eine YAML-Datei zu schreiben und den Vorgang später nur noch durch einen wesentlich simpleren Befehl zu starten, der die Konfigurationsdatei ausliest. Genau dies tut das Programm borgmatic, das natürlich ebenfalls über die Paketverwaltung zu installieren ist.
Anschließend kopiert man sich eine Beispiel-Konfigurationsdatei, aus deren auskommentierten Zeilen man sich nur noch die passenden aussuchen und abändern muss:
generate-borgmatic-config --destination ~/job-backups.yaml
Der obige Befehl speichert die Konfigurationsdatei im Benutzerverzeichnis ab, aber natürlich kann man jeden beliebigen Pfad verwenden. Mit einem Texteditor öffnet man die Datei und entfernt die #-Zeichen für jede Option, die man anpassen möchte. Eine minimale Konfigurationsdatei, welche den borg-Befehlen weiter oben entspricht, sähe so aus:
location:
source_directories:
- ~/Bilder
- ~/Dokumente
repositories:
- /mnt/backups
storage:
encryption_passphrase: "langesundkomplexeskenwort"
compression: zlib,1
retention:
keep_daily: 7
keep_weekly: 1
keep_monthly: 1
Das im Klartext in der Datei hinterlegte Kennwort für das Repository ist natürlich schlecht. Entweder man sichert die Datei so ab, dass nur der Besitzer der Datei lesend und schreibend auf sie zugreifen kann:
chmod 600 ~/job-backups.yaml
Oder man beschafft sich das Kennwort über ein externes Programm (Skript mit grafischer Passwortabfrage oder ein Kommandozeilen-Tool eines Passwort-Managers), indem man die Zeile mit encryption_passphrase
gegen diejenige mit encryption_passcommand
austauscht.
Ausführen könnte man die Aufgaben (Erstellen eines Backups und Löschen von alten Backups) nun mit einem Befehl:
borgmatic -c ~/job-backups.yaml
Geplante Aufgaben mit systemd
In einem Skript kann auch dieser vereinfachte Befehl nun schon zum Einsatz kommen. Aber ich möchte noch ein wenig mehr Kontrolle über die Ausführung. Unter Linux lässt sich glücklicherweise Gebrauch von der mächtigen Systemverwaltung systemd machen. So möchte ich die Sicherung jeden Tag zu einer bestimmten Uhrzeit und nur dann, wenn das Ziel /mnt/backups verfügbar ist, durchführen. Dazu erstellt man einfach zwei systemd-Units als Textdateien: einen Timer und einen Service, der von ihm gestartet wird. Gespeichert werden sie im systemd-Konfigurationsverzeichnis im Benutzerverzeichnis, da auch das Backup selbst keine administrativen Rechte erfordert.
Der Inhalt von ~/.config/systemd/user/backup-daily.timer:
[Unit]
Description=Run daily borgmatic backups
[Timer]
OnCalendar=*-*-* 20:00
Persistent=true
[Install]
WantedBy=default.target
[Unit]
ist der allgemeine Abschnitt, den jede systemd-Unit und eben auch Timer als spezielle Unit nutzt. Im Abschnitt [Timer]
wird ein Intervall angegeben (jedes Jahr, jeden Monat, jeden Tag um 20:00 Uhr) und festgelegt, dass ein verpasster Termin nachgeholt wird, wenn der Rechner ausgeschaltet war. Ein Timer, der vom systemd-User-Prozess ausgeführt wird, funktioniert als Abhängigkeit von default.target
, einem Standard-Zustand, den das System mit der Anmeldung des Benutzers erreicht.
Zu dem Timer gehört der anzustoßende Service ~/.config/systemd/user/backup-daily.service:
[Unit]
Description=borgmatic backup
ConditionACPower=true
ConditionPathIsMountPoint=/mnt/backups
[Service]
Type=oneshot
ExecStart=systemd-inhibit --who="%u" --why="Do not interrupt a running backup." /usr/bin/borgmatic -c %h/job-backups.yaml
Im Abschnitt [Unit]
wird verlangt, dass der Rechner über das Netzteil mit Stromversorgt wird. Darunter setze ich die Bedingung, dass die Unit nur ausgeführt wird, wenn das angegebene Verzeichnis existiert und ein Einhängepunkt ist. Im [ExecStart]
-Abschnitt nutze ich systemd-inhibit, um das System daran zu hindern, herunterzufahren, neuzustarten und so weiter, während die Sicherung noch nicht abgeschlossen ist. %u
ist dabei eine Variable, die mit dem ausführenden Benutzer aufgelöst wird. Im eigentlichen borgmatic-Befehl gleich dahinter kommt dann die %h
-Variable für das Benutzerverzeichnis zum Einsatz, da in den Unit-Dateien keine Tilde dafür verwendet werden kann.
Schließlich müssen beide Units noch aktiviert werden, damit sie automatisch bei der nächsten Anmeldung starten:
systemctl --user enable backup-daily.timer backup-daily.service
Damit ist das automatische und verschlüsselte Backup auf den externen Datenträger eingerichtet!
Nach einer erneuten Anmeldung lassen sich die aktiven, im Benutzerkontext laufenden Timer anzeigen:
systemctl --user list-timers --all
Überprüfen lässt sich die Ausführung zum Beispiel im Systemprotokoll mit journald:
journalctl --user -xe
Ob ein Backup angelegt wurde, sieht man natürlich auch direkt im Repository (Kennwort erforderlich):
borg list /mnt/backups
Zwar liegt ein Backup nun auf einem externen Datenträger. Wünschenswert wäre aber natürlich auch ein Backup auf einem Cloud-Speicher, der einem ja heute überall hinterhergeworfen wird. Das ist ein Fall für das Programm rclone und einen separaten Artikel.