Anleitung v0.9 (März 2017). Work in Progress. Keine Haftung für nichts.
Da auf meinen Uberspaces inzwischen doch recht viele wichtige Daten liegen, würde ich gerne vollständige Backups auf meine eigenen Platten legen. Meine WordPress-Installationen backupe ich schon via Plugins und habe auch Sicherungen der statischen Seiten, aber z.B. die Mails fehlen mir. (Da gibt’s inzwischen ja auch Aufbewahrungspflichten und sowas.)
Im Uberspace-Wiki gibt es einen Artikel zur Backup-Systematik. Meine Idee ist, das einfach wöchentlich von einem rsync-Skript per SSH auf eine externe Festplatte zu packen. Leisten soll das mein Raspberry Pi, damit das auch nachts läuft.
Contents
- 1 Anforderungen
- 2 Fallstricke …
- 3 Das Backup-System
- 4 Festplatte dauerhaft einbinden und konfigurieren
- 5 SSH-Zugang automatisieren
- 6 Datenbank-Dumps automatisieren
- 7 Das eigentliche Backup-Skript
- 8 Skript ausführen
- 9 Backup überprüfen
- 10 Übertragung auf weitere Uberspaces
- 11 Automatisierung per Cron
- 12 Fertig! Naja, fast…
Anforderungen
Die Anforderungen an diese Backup-Lösung sind eher schmal:
- das Backup soll wöchentlich automatisiert alle relevanten Daten sichern, die auf dem Uberspace liegen. Als da wären:
- /var/www/virtual/username
- insbesondere der Webroot (also /var/www/virtual/username/html)
- das /home-Verzeichnis (also /home/username)
- Datenbank-Dumps (folgt in v0.9)
- die Sicherung soll inkrementell passieren und minimale Versionierung beinhalten, damit a) der Speicher nicht überläuft und b) nicht jede Woche der ganze Uberspace kopiert wird. Mein Sicherheitsempfinden sagt mit, dass eine Version pro Monat reicht. Theoretisch kann man nach einigen Monaten auch mal alte Backups löschen
- wir brauchen keine Verschlüsselung der Daten auf dem Zielsystem. Wer die Daten auf einem LUKS-Speicher ablegen will, sollte sich ein paar Gedanken machen, wie er die Platten ent- und wieder verschlüsselt, ohne dass jemand mit physischem Zugriff an die Daten kommt
Und nun ans Werk!
Fallstricke …

Nun gibt es dafür leider noch nirgends eine Anleitung oder „Ideensammlung“, um die wichtigsten Fallstricke zu umgehen: Symlinks richtig auflösen, Datenbank-Dumps automatisieren etc. Da macht man ja gerne mal was falsch, und der Grund, diesen Artikel zu schreiben, ist meine Annahme, dass ich bestimmt nicht der einzige bin, der bei rsync prinzipiell den einen essentiellen Parameter vergisst …
Das Backup-System
Voraussetzungen:
- Rechner, der die Backups durchführen soll. In meinem Fall ein Raspberry Pi, der über LAN am Internet hängt und per USB an einer 500GB-Festplatte. Das sollte genügen. Geht aber natürlich auch mit jedem anderen Rechner, der regelmäßig läuft
- Betriebssystem: Irgend ein Linux, in meinem Fall läuft einfach Raspbian
- rsync
- SSH-Zugriff auf den Uberspace (und am besten auch ein Zugang zum Pi, damit man ihn headless einrichten kann)
Festplatte dauerhaft einbinden und konfigurieren
Um die Festplatte dauerhaft einzubinden, orientieren wir uns an dieser Anleitung bei Jan Karres. In Kurzform:
Mit
sudo blkid -o list -w /dev/null
holen wir uns die Infos zu unserer externen Platte. Wenn uns nicht gefällt, wo sie eingebunden ist, liefert das Tutorial die nötigen Schritte.
Ein Wort zum Dateisystem: Idealerweise sollte hier ein System laufen, das Rechteverwaltung unterstützt (ext4 o.ä.). Ansonsten wird das Zurückspielen eine Qual …
SSH-Zugang automatisieren
Der erste Schritt: Wir automatisieren den Zugriff vom Pi auf den Uberspace per SSH Public Key. Das Ubuntu-Wiki erklärt den Vorgang sehr gut. Wir machen also
ssh-keygen -t rsa -b 4096
und vergeben eine sinnvolle Passphrase. Danach erleichtern wir uns die Arbeit, indem wir den Zugang zum Uberspace in der Datei /home/pi/.ssh/config eintragen. Wir legen diese Datei an:
nano /home/pi/.ssh/config
und fügen den folgenden Datensatz ein (natürlich mit den korrekten Daten ersetzen):
Host meinuberspace HostName [knoten].uberspace.de User meinusername
Ab jetzt können wir uns per
ssh meinuberspace
einloggen, oder eben auch den Key übermitteln:
ssh-copy-id -i ~/.ssh/id_rsa.pub meinuberspace
Wenn wir uns nun per ssh dd einloggen, werden wir erst nach dem normalen SSH-Login zu unserem Uberspace gefragt – einfach das normale SSH-Passwort eingeben. Danach müssen wir den Key entsperren, indem wir die gerade festgelegte Passphrase eingeben. Und schon sind wir drin.
Damit bei folgenden Login-Versuchen keine Passphrase mehr abgefragt wird – wir wollen ja automatisieren – fügen wir diese per ssh-add hinzu:
pi@rasp:~/.ssh $ ssh-add Enter passphrase for /home/pi/.ssh/id_rsa:
Datenbank-Dumps automatisieren
Wir wollen ja nicht nur HTML und Mails, sondern auch die Inhalte unserer Datenbanken ins Backup packen.
Update 0.9 (März 2017): Bei gehaxelt findet sich eine kurze, noch immer gültige Anleitung, mit deren Hilfe man sich seine Datenbanken ins Userverzeichnis packen kann. Das muss allerdings direkt auf dem Uberspace integriert werden und beruht auf dieser Zeile Code:
mysqldump --user=$USER --password=$MYSQLPW --compact --comments --dump-date --quick --all-databases | gzip > "/var/www/virtual/"$USER"/database.sql.gz"
Das eigentliche Backup-Skript
Wir haben nun also alle Voraussetzungen erfüllt. Der Raspberry Pi kann sich eigenständig mit dem Uberspace via SSH verbinden und hat die Backups-Festplatte eingebunden. Nun kommt das Herzstück dieser Anleitung, das einfache, aber wirkungsvolle Skript, das die Daten vom Uberspace auf die Platte schaufelt. Das Beispiel bezieht sich auf meine Website digital-danach.de.
Erst das Skript, dann die Erklärung:
#!/bin/bash DATE=$(date +%y-%m) #Wir machen jeden Monat ein neues Backup, das wir dann für den Rest des Monats aktualisieren. Hier steuern wir also, wie oft ein neues Backup angelegt werden soll! USER="digidann" #Unser Name für das Backup, falls es vom Servernamen abweichen soll SERVER="dd" #Unser Server. Der Eintrag muss mit dem in der SSH config übereinstimmen QUELLE="/home/$USER" ZIEL="/media/pi/Backupplatte/Backups-$SERVER/$SERVER-full-$DATE" mkdir -p $ZIEL #Falls das Zielverzeichnis noch nicht existiert, legen wir es an. Das passier natürlich monatlich erneut. rsync --delete -azcvLP -e ssh "$SERVER":"$QUELLE" "$ZIEL"
Ausgeschrieben würde der einmalige rsync-Befehle lauten:
rsync --delete -azcvLP -e ssh dd:/home/digidann /media/pi/Backupplatte
Die Variablen
s. Kommentare im Skript
Die Parameter
Wir nutzen folgende Parameter:
- delete:
- a: fasst einige andere Parameter zusammen, etwa -r für rekusriv und -p fürs Beibehalten der Rechte (permissions) der Quelldateien
- z: komprimiert die Dateien auf dem Weg, damit das Backup schneller durchläuft. Ich habe die Unterschiede allerdings nicht getestet!
- c: „aktiviert einen Dateivergleich basierend auf Checksumme und nicht auf Größe und Timestamp. Die eigentlich Checksummenbildung dauert deutlich länger als der Vergleich Größe und Timestamp; andererseits werden überflüssige Kopiervorgänge (z.B. bei nur geändertem Timestamp) vermieden.“ (Quelle) Ich habe die Unterschiede allerdings nicht getestet!
- v: zeigt während des Synchronisierens alle ausgeführten Schritte an. Für den laufenden Betrieb kann das natürlich auch raus
- L: symbolische Links werden nicht als solche kopiert, sondern die dahinter liegenden Dateien
- P: gibt – sofern wir das Skript manuell aufrufen – den Fortschritt der Übertragung an. Für den laufenden Betrieb kann das natürlich auch raus
- -e ssh: hiermit steuern wir das Quellenverzeichnis auf dem Uberspace an
Skript ausführen
Nun machen wir das Skript backup_us1.sh mit
chmod +x backups_us1.sh
ausführbar und testen es mit
./backups_us1.sh
Wenn alles sauber durchgelaufen ist, geht es ans
Backup überprüfen
Ein erstes (unzureichendes) Indiz, ob die Kopie funktioniert hat, liefert die Dateigröße und -anzahl.
Daher überprüfen wir zunächst, wie groß die Dateien des Backups sind (z.B. mit einem grafischen Dateimanager, den wir zu sftp://rasp/media/pi/pfad/zum/backup lotsen.
Das vergleichen wir mit der Ausgabe von
quota -gsl
auf dem Uberspace, den wir gebackupt haben. Wenn Größe und Dateizahl grob übereinstimmen, wissen wir zumindest, dass erfolgreich die Symlink-Dateien kopiert wurden.
Übertragung auf weitere Uberspaces
Das Schöne an dem Skript ist: Wir müssen für weitere Uberspaces lediglich die Datei kopieren
cp /pfad/zum/skript_1.sh /pfad/zum/skript_2.sh
und die Variablen austauschen. Natürlich müssen wir auch hier das Skript ausführbar machen und sicherstellen, dass wir automatisch per SSH auf den Server kommen.
Automatisierung per Cron
Keine Sorge, das muss nicht immer per Hand angestoßen werden. Auf dem Pi machen wir mit
crontab -e
unsere Crontab auf und fügen z.B. (im Falle meiner Skripte) hinzu:
10 1 * * 1 /home/pi/Scripts/uberspace_backup_dsde.sh 10 1 * * 2 /home/pi/Scripts/uberspace_backup_mg.sh 10 1 * * 3 /home/pi/Scripts/uberspace_backup_spiel.sh 10 1 * * 4 /home/pi/Scripts/uberspace_backup_1crm.sh 10 1 * * 5 /home/pi/Scripts/uberspace_backup_wirblei.sh 10 1 * * 6 /home/pi/Scripts/uberspace_backup_af.sh 10 1 * * 0 /home/pi/Scripts/uberspace_backup_dd.sh
Das bedeutet, dass an jedem Wochentag um 1:10 nachts eines der Skripte angestoßen wird. Genaueres zu Cron findet sich im Wiki-Eintrag.
Fertig! Naja, fast…
Der Nachteil dieser funktionalen Lösung ist: Wir kopieren die Symlinks als Dateien und können sie also nicht einfach zurückspielen. Außerdem gibt das Skript noch ein paar Fehler zurück, um die ich mich demnächst kümmere. Jedenfalls ist Feedback herzlich willkommen!
Frage dazu, wie hast du deinen raspberry 24/7 (Dauerbetrieb) tauglich bekommen? Hab es leider noch nicht geschafft. Nicht nach diversen Anleitungen.
Ansonsten, sehr nette Anleitung, kann ich sicherlich auch für andere Projekte verwenden 🙂
Hi Daniel,
danke für das Lob! An sich war für die 24/7-Tauglichkeit nichts besonderes von Nöten. Ich habe momentan einen Pi mit Pihole und Thunderbird laufen. Per Cron starte ich den Rechner jede Nacht um 2 Uhr neu und lasse danach ein Update-Skript laufen (Cron: @reboot, Inhalt apt update && apt upgrade). Das mache ich aber vor allem, um auch Thunderbird neu zu starten und eine eventuell aktualisierte training.dat einzulesen – der Pi dient quasi auch zum Mail-Backup und zum zentralen Spamfiltern.
Was macht dein Pi denn nach dem Dauerbetrieb bzw. woran hapert der?
Grüße!
Dennis
Vielen Dank für diesen hilfreichen Beitrag!
Die Datenbank kann man auch mit einem weiteren rsync-Befehl aus den uberspace-Backups holen. Zum Beispiel durch Ergänzung des Skripts so:
DB_QUELLE=“/mysqlbackup/latest/$USER“
DB_ZIEL=“/volume1/backups/backups-$SERVER/$SERVER-db-$DATE“
rsync –delete -azcvLP -e ssh „$SERVER“:“$DB_QUELLE“ „$DB_ZIEL“
Oh, meine einfachen Anführungszeichen wurden automatisch durch typografische ersetzt – das lässt sich also nicht einfach kopieren.
Danke für die Ergänzung, wird sofort eingebaut 🙂