{"id":375,"date":"2020-09-25T20:18:51","date_gmt":"2020-09-25T18:18:51","guid":{"rendered":"https:\/\/pascal-korz.de\/blog\/?p=375"},"modified":"2020-09-25T20:18:51","modified_gmt":"2020-09-25T18:18:51","slug":"automatische-backups-unter-linux-mit-borg-und-borgmatic","status":"publish","type":"post","link":"https:\/\/pascal-korz.de\/blog\/2020\/09\/25\/automatische-backups-unter-linux-mit-borg-und-borgmatic\/","title":{"rendered":"Automatische Backups unter Linux mit borg und borgmatic"},"content":{"rendered":"\n<p>Es gibt eine Vielzahl von guten Backup-Programmen, aber jedes legt den Schwerpunkt auf andere Aspekte. F\u00fcr mich pers\u00f6nlich gibt es einige Kriterien, die eine L\u00f6sung erf\u00fcllen muss:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Differenzielle Sicherungen\/Deduplizierung: Sicherungen erf\u00fcllen ihren Zweck am besten, wenn sie regelm\u00e4\u00dfig und h\u00e4ufig durchgef\u00fchrt werden. Selbstverst\u00e4ndlich m\u00f6chte ich aber nicht unver\u00e4nderte Dateien doppelt und dreifach auf dem gleichen Ziel vorhalten. Auch wenn ich nur neue und ver\u00e4nderte Dateien sichere, teilen sich viele von ihnen gleiche Daten, die ich ebenfalls nicht mehrfach ablegen m\u00f6chte.<\/li><li>Komprimierung: Um den Speicherplatzbedarf zus\u00e4tzlich zu senken, kommt ein Kompressionsverfahren zum Einsatz.<\/li><li>Verschl\u00fcsselung: Auch wenn das Backup-Ziel gut gegen Angreifer gesch\u00fctzt ist, schadet eine zus\u00e4tzliche Sicherheitsma\u00dfnahme nicht.<\/li><li>Aufbewahrungsrichtlinien: Sicherungen m\u00fcssen in der Regel nicht ewig aufbewahrt werden und sollen nach festzulegenden Kriterien automatisch gel\u00f6scht werden.<\/li><li>Wiederherstellungsmethoden: Die beste Sicherung n\u00fctzt letztlich nichts, wenn verlorengegangene Daten nicht mehr zur\u00fcckgespielt werden k\u00f6nnen.<\/li><li>Kommandozeilenprogramm: Automatisierung ist das Ziel, und daf\u00fcr muss eine Schnittstelle existieren.<\/li><\/ul>\n\n\n\n<p><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/borgbackup.readthedocs.io\/en\/stable\/\" data-type=\"URL\" data-id=\"https:\/\/borgbackup.readthedocs.io\/en\/stable\/\" target=\"_blank\">Borg<\/a><\/strong> ist hier besonders interessant, weil es ein weitverbreitetes und stetig weiterentwickeltes Programm ist.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installation und Konfiguration<\/h2>\n\n\n\n<p>Die Installation erfolgt zum Beispiel \u00fcber den Paketmanager und kann daher nat\u00fcrlich variieren. Unter Ubuntu und seinen Derivaten w\u00e4hlt man das Paket <strong>borgbackup,<\/strong> unter Arch Linux und seinen Abk\u00f6mmlingen das Paket <strong>borg<\/strong>. Danach geht es in der Konsole mit der Konfiguration weiter. Ich gehe davon aus, dass die Backups auf einem externen Datentr\u00e4ger gespeichert werden, der unter <strong>\/mnt\/backups\/<\/strong> eingebunden ist. Unter diesem Pfad richte ich das sogenannte Repository ein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>borg init --encryption=repokey \/mnt\/backups<\/code><\/pre>\n\n\n\n<p>Man wird nach einem Kennwort gefragt, mit dem die Sicherungen verschl\u00fcsselt werden und das bei der Wiederherstellung und beim Zugriff auf das Repository im Allgemeinen ben\u00f6tigt wird \u2013 also gut aufbewahren. Jetzt k\u00f6nnte man eine erste Sicherung mit dem Namen initial und dem Kompressionsverfahren zlib erstellen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>borg create --compression zlib,1 \/mnt\/backups::initial ~\/Bilder ~\/Dokumente<\/code><\/pre>\n\n\n\n<p>Nach der Eingabe des Kennworts wird die Sicherung im Repository erstellt. Je \u00f6fter 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\u00fcrde. Darum lassen sich Anzahl und Zeitr\u00e4ume der vorzuhaltenen Backups konfigurieren und alle \u00fcbrigen Backups l\u00f6schen. So werden zum Beispiel nur Backups behalten, die an sieben unterschiedlichen Tagen erstellt wurden, au\u00dferdem noch ein zus\u00e4tzliches w\u00f6chentliches und ein zus\u00e4tzliches monatliches Backup:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>borg prune --keep-daily 7 --keep-weekly 1 --keep-monthly \/mnt\/backups::initial<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Systematisierung mit borgmatic<\/h2>\n\n\n\n<p>Diese Befehle k\u00f6nnte man nun in ein Skript einbetten. \u00dcbersichtlicher (besonders wenn man mehrere verschiedene Backup-Repositories anlegt) finde ich die M\u00f6glichkeit, die Parameter in eine YAML-Datei zu schreiben und den Vorgang sp\u00e4ter nur noch durch einen wesentlich simpleren Befehl zu starten, der die Konfigurationsdatei ausliest. Genau dies tut das Programm <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/torsion.org\/borgmatic\/\" data-type=\"URL\" data-id=\"https:\/\/torsion.org\/borgmatic\/\" target=\"_blank\">borgmatic<\/a><\/strong>, das nat\u00fcrlich ebenfalls \u00fcber die Paketverwaltung zu installieren ist.<\/p>\n\n\n\n<p>Anschlie\u00dfend  kopiert man sich eine Beispiel-Konfigurationsdatei, aus deren auskommentierten Zeilen man sich nur noch die passenden aussuchen und ab\u00e4ndern muss:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>generate-borgmatic-config --destination ~\/job-backups.yaml<\/code><\/pre>\n\n\n\n<p>Der obige Befehl speichert die Konfigurationsdatei im Benutzerverzeichnis ab, aber nat\u00fcrlich kann man jeden beliebigen Pfad verwenden. Mit einem Texteditor \u00f6ffnet man die Datei und entfernt die #-Zeichen f\u00fcr jede Option, die man anpassen m\u00f6chte. Eine minimale Konfigurationsdatei, welche den borg-Befehlen weiter oben entspricht, s\u00e4he so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location:\n    source_directories:\n        - ~\/Bilder\n        - ~\/Dokumente\n    repositories:\n        - \/mnt\/backups\nstorage:\n    encryption_passphrase: \"langesundkomplexeskenwort\"\n    compression: zlib,1\nretention:\n    keep_daily: 7\n    keep_weekly: 1\n    keep_monthly: 1<\/code><\/pre>\n\n\n\n<p>Das im Klartext in der Datei hinterlegte Kennwort f\u00fcr das Repository ist nat\u00fcrlich schlecht. Entweder man sichert die Datei so ab, dass nur der Besitzer der Datei lesend und schreibend auf sie zugreifen kann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod 600 ~\/job-backups.yaml<\/code><\/pre>\n\n\n\n<p>Oder man beschafft sich das Kennwort \u00fcber ein externes Programm (Skript mit grafischer Passwortabfrage oder ein Kommandozeilen-Tool eines Passwort-Managers), indem man die Zeile mit <code>encryption_passphrase<\/code> gegen diejenige mit <code>encryption_passcommand<\/code> austauscht.<\/p>\n\n\n\n<p>Ausf\u00fchren k\u00f6nnte man die Aufgaben (Erstellen eines Backups und L\u00f6schen von alten Backups) nun mit einem Befehl:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>borgmatic -c ~\/job-backups.yaml<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Geplante Aufgaben mit systemd<\/h2>\n\n\n\n<p>In einem Skript kann auch dieser vereinfachte Befehl nun schon zum Einsatz kommen. Aber ich m\u00f6chte noch ein wenig mehr Kontrolle \u00fcber die Ausf\u00fchrung. Unter Linux l\u00e4sst sich gl\u00fccklicherweise Gebrauch von der m\u00e4chtigen Systemverwaltung systemd machen. So m\u00f6chte ich die Sicherung jeden Tag zu einer bestimmten Uhrzeit und nur dann, wenn das Ziel <strong>\/mnt\/backups<\/strong> verf\u00fcgbar ist, durchf\u00fchren. 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.<\/p>\n\n\n\n<p>Der Inhalt von <strong>~\/.config\/systemd\/user\/backup-daily.timer<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Run daily borgmatic backups\n\n&#91;Timer]\nOnCalendar=*-*-* 20:00\nPersistent=true\n\n&#91;Install]\nWantedBy=default.target<\/code><\/pre>\n\n\n\n<p><code>[Unit]<\/code> ist der allgemeine Abschnitt, den jede systemd-Unit und eben auch Timer als spezielle Unit nutzt. Im Abschnitt <code>[Timer]<\/code> 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\u00fchrt wird, funktioniert als Abh\u00e4ngigkeit von <code>default.target<\/code>, einem Standard-Zustand, den das System mit der Anmeldung des Benutzers erreicht.<\/p>\n\n\n\n<p>Zu dem Timer geh\u00f6rt der anzusto\u00dfende Service <strong>~\/.config\/systemd\/user\/backup-daily.service<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=borgmatic backup\nConditionACPower=true\nConditionPathIsMountPoint=\/mnt\/backups\n\n&#91;Service]\nType=oneshot\n\nExecStart=systemd-inhibit --who=\"%u\" --why=\"Do not interrupt a running backup.\" \/usr\/bin\/borgmatic -c %h\/job-backups.yaml<\/code><\/pre>\n\n\n\n<p>Im Abschnitt <code>[Unit]<\/code> wird verlangt, dass der Rechner \u00fcber das Netzteil mit Stromversorgt wird. Darunter setze ich die Bedingung, dass die Unit nur ausgef\u00fchrt wird, wenn das angegebene Verzeichnis existiert und ein Einh\u00e4ngepunkt ist. Im <code>[ExecStart]<\/code>-Abschnitt nutze ich systemd-inhibit, um das System daran zu hindern, herunterzufahren, neuzustarten und so weiter, w\u00e4hrend die Sicherung noch nicht abgeschlossen ist. <code>%u<\/code> ist dabei eine Variable, die mit dem ausf\u00fchrenden Benutzer aufgel\u00f6st wird. Im eigentlichen borgmatic-Befehl gleich dahinter kommt dann die <code>%h<\/code>-Variable f\u00fcr das Benutzerverzeichnis zum Einsatz, da in den Unit-Dateien keine Tilde daf\u00fcr verwendet werden kann.<\/p>\n\n\n\n<p>Schlie\u00dflich m\u00fcssen beide Units noch aktiviert werden, damit sie automatisch bei der n\u00e4chsten Anmeldung starten:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl --user enable backup-daily.timer backup-daily.service<\/code><\/pre>\n\n\n\n<p>Damit ist das automatische und verschl\u00fcsselte Backup auf den externen Datentr\u00e4ger eingerichtet!<\/p>\n\n\n\n<p>Nach einer erneuten Anmeldung lassen sich die aktiven, im Benutzerkontext laufenden Timer anzeigen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl --user list-timers --all<\/code><\/pre>\n\n\n\n<p>\u00dcberpr\u00fcfen l\u00e4sst sich die Ausf\u00fchrung zum Beispiel im Systemprotokoll mit journald:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>journalctl --user -xe<\/code><\/pre>\n\n\n\n<p>Ob ein Backup angelegt wurde, sieht man nat\u00fcrlich auch direkt im Repository (Kennwort erforderlich):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>borg list \/mnt\/backups<\/code><\/pre>\n\n\n\n<p>Zwar liegt ein Backup nun auf einem externen Datentr\u00e4ger. W\u00fcnschenswert w\u00e4re aber nat\u00fcrlich auch ein Backup auf einem Cloud-Speicher, der einem ja heute \u00fcberall hinterhergeworfen wird. Das ist ein Fall f\u00fcr das Programm rclone und einen separaten Artikel.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Es gibt eine Vielzahl von guten Backup-Programmen, aber jedes legt den Schwerpunkt auf andere Aspekte. F\u00fcr mich pers\u00f6nlich gibt es einige Kriterien, die eine L\u00f6sung erf\u00fcllen muss: Differenzielle Sicherungen\/Deduplizierung: Sicherungen erf\u00fcllen ihren Zweck am besten, wenn sie regelm\u00e4\u00dfig und h\u00e4ufig durchgef\u00fchrt werden. Selbstverst\u00e4ndlich m\u00f6chte ich aber nicht unver\u00e4nderte Dateien doppelt und dreifach auf dem gleichen&hellip; <a class=\"more-link\" href=\"https:\/\/pascal-korz.de\/blog\/2020\/09\/25\/automatische-backups-unter-linux-mit-borg-und-borgmatic\/\"><span class=\"screen-reader-text\">Automatische Backups unter Linux mit borg und borgmatic<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":6,"featured_media":71,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,8],"tags":[],"class_list":["post-375","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-backups","category-linux","entry"],"_links":{"self":[{"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/posts\/375","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/comments?post=375"}],"version-history":[{"count":4,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/posts\/375\/revisions"}],"predecessor-version":[{"id":379,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/posts\/375\/revisions\/379"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/media\/71"}],"wp:attachment":[{"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/media?parent=375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/categories?post=375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pascal-korz.de\/blog\/wp-json\/wp\/v2\/tags?post=375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}