"Backup zum Feierabend"

TL;DR

Backup zum festen Zeitpunkt funktioniert nicht regelmäßig? Eine Lösung dafür ist die automatische Datensicherung, wenn das System herunterfährt oder in den Ruhezustand (Hibernate) wechselt.

Über eine Systemd-Unit wird das Backup zum Feierabend einfach zum richtigen Zeitpunkt gestartet:

[Unit]
Description=Run backup before hibernate/poweroff
Before=systemd-hibernate.service
Before=systemd-poweroff.service
Before=systemd-halt.service

[Service]
Type=oneshot
ExecStart=<path to backup program>

[Install]
WantedBy=systemd-hibernate.service
WantedBy=systemd-poweroff.service
WantedBy=systemd-halt.service

Einleitung

Kernpunkt dieses kleinen Projekts ist nicht die Durchführung des Backups an sich, sondern die Wahl des richtigen Zeitpunkts für das Backup.

Aus meiner Erfahrung ist eine Datensicherung zu einem festen Zeitpunkt für PCs und Laptops unzuverlässig, da nicht sicher ist, dass das System zum entsprechenden Zeitpunkt aktiv ist.

Besser ist es die Daten zu sichern, wenn Daten verändert wurden und die Tätigkeit beendet ist - das "Backup zum Feierabend".

Dieses Dokument beschreibt einen alternativen Ansatz der Datensicherung beim Wechseln vom aktiven Zustand in einen Ruhemodus oder ausgeschalteten Zustand.

Dafür wird eine Systemd-Unit konfiguriert, die durch verschiedene Trigger automatisch gestartet wird und so alle Änderungen sichert, bevor das System in einen inaktiven Zustand wechselt.

Als Backupsoftware wird restic genutzt. Es kann auch jede andere Software genutzt werden, die die nachfolgenden Überlegungen unterstützt.

Das erste Vollbackup wird manuell durchgeführt. Alle nachfolgenden Backups sind inkrementelle Backups, die nur die Änderungen zur vorherigen Datensicherung aufzeichnen. Dieses Schema wird auch "Forever Incremental Backup" bezeichnet.

Aufgrund der Funktionsweise von restic und der eingebauten Deduplizierung, spiegelt jedes Backup den kompletten Stand wider.

Das Setup

Das erste Backup wird alle Daten lesen und in das Repository schreiben. In Abhängigkeit von der Datenmenge nimmt dieser Vorgang einige Zeit in Anspruch. Daher wird das erste Backup manuell ausgeführt und anschließend die Systemd-Unit aktiviert. Das verhindert ein scheinbares Hängen, während der PC herunterfährt oder in den Ruhezustand wechselt.

Bei größeren Änderungen ist ein manuelles Backup ebenfalls zu empfehlen.

Beim Aufruf durch Systemd führt das Backup-Skript lediglich ein Backup und keine weiteren Aktionen, wie zum Beispiel eine Prüfung des Repositories, durch. Das minimiert die Laufzeit des Backups und der PC wechselt schneller in den gewünschten Zustand.

Dagegen läuft restic.sh bei einem manuellen Start länger, da das Repository geprüft wird und dabei nicht mehr genutzte Daten wieder freigegeben d.h. gelöscht werden.

Eine Integritätsprüfung der Backupdaten ist im Skript vorgesehen aber nicht aktiviert, um die Laufzeit des Backups so kurz wie möglich zu halten.

Alte Backup-Stände werden ebenfalls nicht automatisch gelöscht. Eine entsprechende Prozedur ist durch den Nutzer selbst zu implementieren, zu testen und anschließend zu aktivieren. Im Skript gibt es Einstellungen, die diesen Vorgang unterstützen können.

Das Einrichten eines Repositories wird nicht in diesem Dokument beschrieben. Die Dokumentation von restic enthält eine ausführliche Beschreibung Preparing a new repository.

Anforderungen

  • aktuelle restic-Version
  • xargs und jq installiert und über den PATH erreichbar

Installation

  1. Annahmen für diese Installation

    • das Repository ist eingerichten und konfiguriert. Der Zugang wurde erfolgreich getestet
    • das Skript zur Steuerung des Backups ist ~/bin/restic.sh
    • eine Kopie von restic wird in ~/bin/ installiert
    • die Datei mit den zu sichernden Basisverzeichnissen ist ~/bin/backup.incl
    • die Datei zum Ausschluss von Dateien und Verzeichnissen von der Sicherung ist ~/bin/backup.excl

    Die Annahmen können an die eigenen Bedürfnisse angepasst werden.

  2. Eigene Kopie von restic anlegen

     # cp -p <path to restic installed by system> ~/bin
     # chmod 700 ~/bin/restic
    
  3. Capabilities setzen, um restic ohne Root-Rechte ausführen und dennoch alle Dateien lesen zu können

     # sudo setcap cap_dac_read_search=+ep ~/bin/restic
    
  4. Benötigte Konfigurationen und Skripte nach ~/bin kopieren

     # cp -p restic.sh ~/bin
     # chmod 700 ~/bin/restic.sh
     # cp -p backup.incl backup.excl ~/bin
     # chmod 600 ~/bin/backup.incl ~/bin/backup.excl
    
  5. Konfiguration in ~/bin/backup.incl und ~/bin/backup.excl anpassen, um Dateien und Verzeichnisse in das Backup ein- und auszuschließen

     # cp -p backup.incl backup.excl ~/bin
     # chmod 600 ~/bin/backup.incl ~/bin/backup.excl
     # $EDITOR ~/bin/backup.incl
     # $EDITOR ~/bin/backup.excl
    
  6. Backup-Skript ~/bin/restic.sh konfigurieren

     # $EDITOR ~/bin/restic.sh
    
  7. Erstes vollständiges Backup durchführen

     # ~/bin/restic
    
  8. Nutzer, Gruppe und Pfade in der Systemd-Unit anpassen

     # $EDITOR restic_before_shutdown.service
    
  9. Systemd-Unit installieren und aktivieren

     # sudo cp -p restic_before_shutdown.service /etc/systemd/system
     # sudo systemctl daemon-reload
     # sudo systemctl enable restic_before_shutdown
     # sudo systemctl status restic_before_shutdown
    
  10. Wechseln Sie in den Ruhezustand und zurück oder starten Sie neu, um restic.sh zu testen

Update

  1. Service-Unit restic_before_shutdown.service erneuern und aktivieren

  2. Backup-Skript restic.sh erneuern und konfigurieren

  3. restic aktualisieren und Capabilities setzen

  4. Backup testen: restic.sh --help und restic.sh --backup

Anwendung

Syntax

$ ./restic.sh --help
Usage: restic.sh <option>
Perform a backup with restic.

If this is started from Systemd, fewer actions are executed than if the
script is started from the command line. This is intended to shorten the
runtime for the backup during the suspend process.

Actions if the backup is triggered by Systemd:
 CHECK BACKUP SHOWDELTA SHOWSTATS
Actions if the backup is not triggered by Systemd:
 CHECK BACKUP SHOWDELTA PRUNE SHOWSTATS

Options
=======
  -b|--backup    perform a backup

  -a|--read-all  read all packs to verify the overall integrity of all
                 backup data
                 action: READALL
  -c|--check     do a check if the restic binary is available, has the
                 right capabilities and the repository is accessible
                 action: CHECK
  -f|--forget    remove old snapshots
                 settings to keep snapshots: --keep-tag forever
                 --keep-tag ewig --keep-within 30d --keep-daily 90
                 --keep-weekly 100 --keep-yearly 20 --prune
                 action: FORGET
  -p|--prune     removes data that is not referenced and therefore not
                 needed any more
                 action: PRUNE
  -s|--shell     open shell with restic settings for manual restic calls
  -u|--unlock    remove stale locks
  -h|--help      shows this message
  -v|--version   shows the version number of this script

Protokoll anzeigen

Das Protokoll der über Systemd gestarteten Backups lässt sich mit journalctl anzeigen:

# journalctl -u restic_before_shutdown.service

Okt 16 22:14:49 saturn systemd[1]: Starting "Backup zum Feuerabend" - Run backup before hibernate/poweroff/halt...
Okt 16 22:14:50 saturn bash[449786]: -= restic.sh - Backup with restic =-
Okt 16 22:14:50 saturn bash[449786]: -= Version 3, (c) 2023 Carsten Grohmann, Lizenz: MIT =-
Okt 16 22:14:50 saturn bash[449786]: Run script with these actions: CHECK BACKUP SHOWDELTA SHOWSTATS
Okt 16 22:14:50 saturn bash[449786]: Initial check ...
Okt 16 22:14:50 saturn bash[449786]: Restic binary /home/carsten/bin/restic found and executable
Okt 16 22:14:50 saturn bash[449786]: Correct file capabilities set on /home/carsten/bin/restic
Okt 16 22:14:50 saturn bash[449786]: Repository s3:https://<s3 host>/repo found and accessible
Okt 16 22:14:50 saturn bash[449786]: Start restic backup ...
Okt 16 22:14:50 saturn bash[449805]: open repository
Okt 16 22:14:51 saturn bash[449805]: lock repository
Okt 16 22:14:52 saturn bash[449805]: using parent snapshot 1fc4698e
Okt 16 22:14:52 saturn bash[449805]: load index files
Okt 16 22:14:52 saturn bash[449805]: start scan on [/home /etc /root]
Okt 16 22:14:52 saturn bash[449805]: start backup on [/home /etc /root]
[...]
Okt 16 22:15:19 saturn bash[449786]:   Added:   284.117 KiB
Okt 16 22:15:19 saturn bash[449786]:   Removed: 284.110 KiB
Okt 16 22:15:19 saturn bash[449786]: Show repository statistics ...
Okt 16 22:15:19 saturn bash[449786]: Current bucket size: 437.331 GiB
Okt 16 22:15:19 saturn systemd[1]: restic_before_shutdown.service: Deactivated successfully.
Okt 16 22:15:19 saturn systemd[1]: Finished "Backup zum Feuerabend" - Run backup before hibernate/poweroff/halt.
Okt 16 22:15:19 saturn systemd[1]: restic_before_shutdown.service: Consumed 41.847s CPU time.

Änderungsprotokoll

14. Dezember 2023 - Version 3

  • Kommandozeilenoptionen für den Zugriff auf einzelne Funktionen hinzugefügt
  • Ausschlussmuster erweitert
  • Regeln zum Aufbewahren der Snapshots erweitert

25. Oktober 2023 - Version 2

  • Versionsnummer zum Skript hinzugefügt
  • Skriptname, Copyright/Lizenz und Versionsnummer beim Start anzeigen

20. Oktober 2023 - Version 1

  • Initiale Version

Projektseite und Feedback

Die Projektseite ist unter https://www.carstengrohmann.de/backupzumfeierabend.html zu finden.

Der Quellcode befindet sich unter https://sr.ht/~carstengrohmann/BackupZumFeierabend.

Kommentare, Vorschläge und Patches sind willkommen und erwünscht. Bitte mailen Sie mir.

Lizenz

Diese Software unterliegt der MIT-Lizenz.

Copyright (c) 2023 Carsten Grohmann mail@carstengrohmann.de

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.