30 Jan 2021

Offsite-Backup mit DSL-Anschluss selbstbauen

Wenn man seine wichtigen Daten zuhause auf einem Server oder NAS liegen hat, bietet sich für den Katastrophenfall, wie einen Hausbrand, eine Datensicherung an einem anderen Ort an. Eine solche extern gelagerte Sicherung nennt sich Offsite-Backup. Im professionellen Bereich kommen dabei teure Installationen mit Bandlaufwerke an anderen Standorten zum Einsatz, was im Privatbereich jedoch nicht praktikabel ist.

Privat bietet sich jedoch beispielsweise eine Zweitwohnung, eine Studentenbude oder die Wohung eines Freundes oder Familienmitglieds an. Da in der genannten Situation aber beide Punkte hinter einem (vermutlich relativ langsamen) DSL-Anschluss mit wechselnden IP-Adressen liegen, ergeben sich hier Probleme mit der langen Übertragungszeit und daraus resultierenden Verbindungsabbrüchen. Hier zeige ich, wie ich mein Offsite-Backup konzepiert und das Problem gelöst habe.

Annahmen und Konzept

Es sollten folgende Annahmen gegeben sein. Die Domain- und Ordnernamen sind natürlich beispielhaft und müssen an eure Situation anpassen werden.

Bei mir laufen beide Server mit Debian 10, andere Linux-Distributionen sind natürlich genauso möglich. Zur Sicherheit sollte der SSH-Server auf origin so konfiguriert werden, dass nur Anmeldung per Public-Key-Verfahren erlaubt. Hierzu müssen unter /etc/ssh/sshd_config folgende Zeilen ergänzt werden:

PasswordAuthentication no
PubkeyAuthentication yes

Alle anderen Zeilen, die Authentication enthalten, sollten auf no gesetzt oder mit einer Raute am Zeilenanfang auskommentiert werden. Bitte achtet bei dem Schritt darauf, dass ihr euch nicht ausschließt und hinterlegt beispielsweise vorher einen SSH-Key.

Verbindung zwischen backup und origin herstellen

Um das Backup anlegen zu können, muss backup auf die Daten auf origin zugreifen können. Dies soll hier verschlüsselt mithilfe von SSH erfolgen. Dafür muss auf backup unter /root/.ssh/config folgendes eingetragen bzw. ergänzt werden. Der HostName (und ggf. Port) muss natürlich an den eigenen Hostnamen angepasst werden. Der Ordner /root/.ssh muss gegebenfalls angelegt werden.

Host origin
	HostName example.net
	Port 22
	User root
	IdentityFile /root/.ssh/backup

Ferner muss ein Public-Private-Key-Paar erzeugt werden und der Public-Key auf origin übertragen werden. Das passiert mit folgenden Befehlen im Terminal:

root@backup $ ssh-keygen -N '' -f /root/.ssh/backup
root@backup $ cat /root/.ssh/backup.pub
MYKEY

An der Stelle vom MYKEY steht der öffentliche Schlüssel. Bitte beachtet, dass das Schlüsselpaar kein Passwort hat, damit sich der Backup-Server automatisch verbinden kann. Mit folgenden Befehlen auf origin kann öffentliche Schlüssel eingetragen werden:

root@origin $ mkdir -p /root/.ssh
root@origin $ echo 'MYKEY' >> /root/.ssh/authorized_keys

Bevor die Verbinding getestet werden kann, sollten die Fingerabdrücke vom SSH-Server auf origin mit folgendem Befehl ermittelt und notiert werden:

root@origin $ ls -1 /etc/ssh/ssh_host_*_key.pub | xargs -L 1 ssh-keygen -l -f

Nun kann die Verbindung getestet werden. Dafür muss auf backup einfach folgendes eingegeben werden:

root@backup $ ssh origin
The authenticity of host 'origin' cant be established.
ECDSA key fingerprint is XYZ.
Are you sure you want to continue connecting (yes/no)?

Statt XYZ steht dort einer der notierten Fingerabdrücke (in diesem Fall der des ECDSA-Schlüssels). Falls der Fingerabdruck mit der entsprechenden Zeile von vorher übereinstimmt, kann yes eingegeben und mit Enter bestätigt werden. Wenn ein Terminal auf origin erscheit, hat alles funktioniert. Falls die Fingerabdrücke nicht übereinstimmen, muss no eingegeben werden. In dem Fall habt ihr euch mit dem falschen Server verbunden, was beispielsweise an veralteten DNS-Einträgen liegen kann.

Bei dieser Vorgehensweise bekommt man mit dem SSH-Key vollen Zugriff auf origin. Aus Sicherheitsgründen kann man erzwingen, dass mit dem SSH-Key nur einen bestimmten Befehl ausfürhen und somit beispielsweise das spezifische Verzeichnis sichern und nichts weiteres tun kann. Ebenso kann man das Schlüsselpaar mit einem Passwort ausstatten und mit einem SSH-Agent sicherstellen, dass backup den Schlüssel trotzdem verwenden kann. Jedoch übersteigt beides den Umfang dieses Beitrags.

Daten kopieren trotz Verbindungsabbrüchen

Das Kopieren der Daten in das Backup soll mit rsync erfolgen, was sich wie folgt auf backup installieren lässt.

root@backup $ apt-get install -y rsync

Falls noch nicht geschehen, muss das Paket auf dieselbe Art auch auf origin installiert werden. Prinzipiell lässt sich mit den Vorbereitungen bereits ein Backup realisieren. Der Befehl hierzu wäre wie folgt:

root@backup $ rsync -aHv origin:/storage/ /backup/current/

Bei größeren Datenmengen dauert dies eine längere Zeit. Gerade hinter DSL-Anschlüssen kann es hierbei zu Abbrüchen kommen, was rsync mit einem Fehlercode quittiert. Wenn man rsync neu startet, kann es mit dem Prozess fortfahren und muss höchstens eine Datei pro Verbindungsabbruch zusätzlich übertragen. Um das zu automatisieren, habe ich folgendes Skript erstellt, das einfach unter /usr/local/bin/breakfreersync abgelegt werden kann. Es wartet bei jedem Fehlversuch 2 Minuten, damit in der Zeit das Netzwerk sich stabilisieren kann (Router, die sich neu einwählen, IP-Adressen, die sich ändern und ähnliche unschöne Dinge).

#!/bin/bash
RC=1
while [[ RC -ne 0 ]]
do
	rsync "$@"
	RC=$?
	if [[ RC -ne 0 ]]; then
		sleep 120
	fi
done

Das Skript muss als ausführbar markiert werden und kann dann anstelle des originalen rsync-Befehls verwendet werden. Zum Setzen der Berechtigungen genügt folgender Befehl:

root@backup $ chmod 755 /usr/local/bin/breakfreersync

Der Kopierbefehl von oben sieht dann wie folgt aus. Bevor ihr ihn zeitaufwendig durchlaufen lasst, fahrt aber lieber mit dem nächsten Abschnitt fort.

root@backup $ /usr/local/bin/breakfreersync -aHv origin:/storage/ /backup/current/

Backup mit dirvish

Das Paket dirvish ist ein Backup-System, das auf rsync aufbaut und die Verwaltung übernimmt. Damit kann man beispielsweise mehrere Snapshots vorhalten und neben dem aktuellen auch auf ältere Datenbestände zugreifen. Installiert werden kann es aus den Paketquellen:

root@backup $ apt-get install -y dirvish

Für unser Beispiel müssen zwei Konfigurationen vorgenommen werden. Unter /etc/dirvish/master.conf muss folgendes angegeben werden:

bank:
	/backup
xdev: 1
log: gzip
index: gzip
image-default: %Y-%m-%d
exclude:
	lost+found/
Runall:
	origin
expire-default: +30 days
expire-rule:
 * * * * 1 +6 months
rsync: /usr/local/bin/breakfreersync

Die Konfiguration legt fest, dass Backups unter /backup liegen (bank), keine Dateisystemgrenzen überschritten werden (xdev), logs und indizies komprimiert werden, wie die einzelnen Snapshots heißen (image-default) und wie lange sie aufbewahrt werden sollen (hier: normalerweise 30 Tage, Sonntags 6 Monate). Unter Runall wird festgelegt, wie die konkrete Instanz des Backups heißen soll, was Vault genannt wird. Der Name kann frei gewählt werden und muss nicht wie der Server heißen, jedoch bietet sich ein sprechender Name an, um bei mehreren Vaults den Überblick zu behalten. Mehrere Vaults können untereinander geschrieben werden. Die letzte Zeile legt fest, dass dirvish nicht das normale rsync, sondern das Skript von eben zur Umgehung von Verbindungsabbrüchen verwendet. Trotz des Skriptes wird das erste Backup lange dauern, es stellt aber sicher, dass das Backup schlussendlich fertiggestellt wird. Bei allen weiteren werden nur die geänderten Daten übertragen, wodurch das Backup entsprechend schneller läuft. Die Snapshots liegen in Ordnern auf dem Dateisystem und werden mit Hardlinks verbunden, sodass jedes neue Backup nur soviel Speicher belegt, wie die geänderten Daten und die Verwaltungsdaten des Backups benötigen.

Neben der globalen Konfiguration muss noch das Verzeichnis für das Vault angelegt (hier: /backup/origin/) und in der Datei /backup/origin/dirvish/default.conf folgendes beschrieben werden:

client: origin
tree: /storage/

Unter client steht der Name, wie er in der SSH-Config festgelegt wurde und unter tree das zu sichernde Verzeichnis auf dem Server. In der Konfiguration können auch für das einzelne Vault Konfigurationen der master.conf überschrieben werden. Zum Schluss muss das erste Backup mit folgendem Befehl manuell angestoßen werden. Wegen der Laufzeit empfehle ich, das in einer tmux- oder screen-Sitzung zu tun.

root@backup $ dirvish --vault origin --init

Fertig! Damit wird der Heimserver jetzt täglich extern gesichert. Einzelne Backups können fehlen, wenn eine Sicherung länger als 24 Stunden gedauert hat oder der Heimserver mal nicht erreichbar war. Mindestens eine Sicherung wird aber immer vorgehalten. Die Daten befinden sich auf backup im Ordner /backup/origin/YYYY-MM-DD/tree Standardmäßig beginnt die Sicherung (in der von Debian ausgelieferten Version von rsync) um 22:04 Uhr am späten Abend. Die Uhrzeit kann einfach im Cronjob in der Datei /etc/cron.d/dirvish geändert werden. Bitte kontrolliert regelmäßig, ob die Sicherung erfolgreich war (in jedem Snapshot-Ordner wird eine Datei summary angelegt). Ein Backup ist nur dann etwas wert, wenn es sich auch wiederherstellen lässt.