Für das Backup meines Desktop benutze ich seit langem backintime. Dieses Tool erzeugt inkrementelle rsync-Backups, mit denen man im nachhinein den Stand zu jedem Backup-Zeitpunkt wiederherstellen kann - sehr übersichtlich und bequem.
Ziel von backintime ist mein NAS, auf das per ssh zugegriffen wird. Wenn einmal das Ursprungs-Backup mit etwa 20 GByte erzeugt wurde, kommen täglich - je nach Aktivität - nur einige MByte dazu. Die unverändert bestehenden Dateien werden nicht kopiert, sondern nur als hard links in die Backup-Verzeichnisse eingetragen.
Nun ist eine Backup-Generation besser als gar keine, aber um halbwegs seriös zu sein braucht man mindestens eine, besser zwei zusätzliche Backup-Generationen, die im Idealfall auch räumlich getrennt voneinander aufbewahrt werden.
Ziel der zweiten Generation soll das NAS an meiner Fritzbox sein. Leider ist die Fritzbox ausschließlich über SMB erreichbar (noch dazu das historische SMB1).
Versuch 1: tar
Ein tar-Archiv stellt an das Ziel-Dateisystem die geringsten Anforderungen. Auch wenn man hard links archiviert, muss das vom Ziel nicht unbedingt unterstützt werden. Also prüfen wir zunächst, ob ein Backup per tar sinnvoll machbar ist. Das Fritzbox-Share wird am NAS also per cifs gemountet und das Backup per tar vom NAS auf den Share kopiert.
Aber wie verhält sich tar bei hard links? Backintime macht davon sehr ausgiebig Gebrauch. Da mir das nicht ganz klar war, habe ich einige Versuche angestellt. zunächst mal die einfachste Variante: Ursprungsdatei und Link befinden sich im selben Archiv:
$ touch a
$ ln a b
$ tar cvf 1.tar a b
a
b
$ tar -tvf 1.tar
-rw-r--r-- joerg/joerg 0 2018-12-01 14:43 a
hrw-r--r-- joerg/joerg 0 2018-12-01 14:43 b Verknüpfung zu a
$
Wie wahrscheinlich von jedem erwartet, erzeugt tar für den Link b keine Datei, sondern trägt die Verlinkung auf a in das Archiv ein. Was passiert aber, wenn die Ursprungsdatei nicht ausdrücklich in das Archiv kopiert wird?
$ tar cvf 2.tar b
b
$ tar -tvf 2.tar
-rw-r--r-- joerg/joerg 0 2018-12-01 14:43 b
$
Auch das mach Sinn: der Link wird aufgelöst und als Datei in das Archiv kopiert. Jetzt überprüfen wir das Verhalten von inkrementellen tar-Archiven. Sie sollen nur Dateien kopieren, die nach dem letzten Backup erzeugt wurden. Was passiert aber, wenn das Inkrement einen Link auf eine ältere Datei enthält, die eigentlich nicht nochmals gesichert werden müsste?
mkdir files
$ touch files/a
$ tar cvf 1.tar -g timestamp.dat files
tar: Verzeichnis „files“ ist neu.
files/
files/a
$ touch files/b
$ tar cvf 2.tar -g timestamp.dat files
files/
files/b
joerg@ubuntu-desktop:/tmp/tar$ tar tvf 2.tar
drwxr-xr-x joerg/joerg 10 2018-12-01 15:08 files/
-rw-r--r-- joerg/joerg 0 2018-12-01 15:08 files/b
$
Bis hierhin ist alles wie erwartet: Im ersten Archiv wird Datei a angelegt, während sie im zweiten, inkrementellen Archiv fehlt. Die Informationen in timestamp.dat haben ergeben, dass sich die Datei seit dem letzten Backup nicht verändert hat und daher nicht erneut kopiert werden muss. Jetzt erzeugen wir aber einen Link auf Datei a:
$ ln files/a files/c
$ tar cvf 3.tar -g timestamp.dat files
files/
files/a
files/c
$ tar tvf 3.tar
drwxr-xr-x joerg/joerg 7 2018-12-01 15:06 files/
-rw-r--r-- joerg/joerg 0 2018-12-01 15:05 files/a
hrw-r--r-- joerg/joerg 0 2018-12-01 15:05 files/c Verknüpfung zu files/a
Obwohl sich Datei a seit dem ersten Backup nicht verändert hat, wird sie jetzt nochmals in das Archiv kopiert. Nur so bleibt das Archiv in sich selbst konsistent, denn anderenfalls wäre der Link c nicht auflösbar.
Im Falle von backintime ist dieses Verhalten aber fatal: hier stecken in jedem Backup tausende hard links auf Dateien, die sich nicht verändert haben, aber auf diese Weise trotzdem jedes mal mitkopiert werden müssen. So wächst die Größe eines inkrementellen Backups von den eigentlich nötigen wenigen MBytes auf mehrere GBytes.
Ich habe keinen Weg gefunden, tar beizubringen, bei der dereferenzierung von Links auch ein früheres Archiv mit heranzuziehen. Damit erzeugt tar für backintime-Archive immer Unmassen an überflüssigen Daten und ist deswegen leider komplett ungeeignet.
Versuch 2: rsync
In meiner Verzweiflung habe ich dann doch noch einmal ausprobiert, wie sich das cifs-Share bei links verhält. Zunächst einmal ein Listing des Quellverzeichnisses inklusive verlinkter inodes:
$ ls -links files
insgesamt 0
527274 0 -rw-r--r-- 2 1000 1000 0 Dez 1 15:05 a
527272 0 -rw-r--r-- 1 1000 1000 0 Dez 1 15:05 b
527274 0 -rw-r--r-- 2 1000 1000 0 Dez 1 15:08 c
$
Man sieht, dass die Dateien a und c auf die selbe inode zeigen. Jetzt kopieren wir das Verzeichnis mit rsync auf die Fritzbox, wobei die Option H für den Erhalt der hard links sorgen soll.
$ rsync -avdH files /media/fritzbox/USB-Drive/
sending incremental file list
files/
files/b
files/c
files/a => files/b
sent 206 bytes received 73 bytes 79.71 bytes/sec
total size is 0 speedup is 0.00
$ ls -links /media/fritzbox/USB-Drive/files
insgesamt 0
18874370 0 -rw-rw-rw- 2 1000 1000 0 Dez 1 15:05 a
18874371 0 -rw-rw-rw- 1 1000 1000 0 Dez 1 15:05 b
18874370 0 -rw-rw-rw- 2 1000 1000 0 Dez 1 15:08 c
$
Wer hätte das gedacht: auch auf der Fritzbox zeigen die Dateien a und c auf dieselbe inode, sind also hard links! Scheinbar ist ein Backup per rsync also im Hinblick auf die hard links doch sinnvoll möglich.
Nach dem Umstellen des Backup-Scripts auf rsync also der erste Versuch. Leider hatte ich nicht bedacht, dass cifs ohne Unix-Erweiterungen die Informationen über owner, group und permissions nicht speichern kann.
Obwohl nach dem Mounten das Dateisystem mit unix gelistet wird, scheinen die Unix-Erweiterungen bei der Fritzbox-Implementierung des SMB-Protokolls nicht oder zumindest nicht vollständig umgesetzt zu sein. Jeder Versuch, Eigentümer, Gruppe oder Permissions einer Datei zu ändern, endet mit einer Fehlernachricht über fehlende Rechte dafür.
Man kann rsync trotzdem einsetzten, wenn man statt des --archive Schalters, der implizit unter anderem auch --owner, --group und --perms setzt, nur --recursive, --times und --links angibt. Allerdings werden dann alle Dateien auf dem Share mit Standard-User, Group und -Permissions gespeichert.
Standard-User und -Gruppe können zwar ebenso wie die Standard-Permissions beim mounten des cifs-Shares angegeben werden, gelten dann aber für alle Dateien auf dem Share. Gibt man nichts an, stehen die Permissions übrigens auf 777, so dass jeder, der generell Zugriff auf das Share hat, alle Rechte an Dateien und Ordnern besitzt.
Statt des Standardwerts von 0:0 (root:root) für Nutzer- und Gruppen-ID meldet die Fritzbox übrigens 1031:0, erlaubt aber das Überschreiben per Mount-Parameter.
Viele Probleme würden sich wahrscheinlich erübrigen, hätte man es auf der Fritz-Seite mit einem ‘echten’ rsync-Server zu tun. Aber FRITZ!OS bietet keinen an und hat zudem die Möglichkeiten, selbst Software nachzuinstallieren, seit einiger Zeit stark beschnitten. So kann man seit Version 6.3 den Telnet-Zugang nicht mehr aktivieren, und mit folgenden Versionen wurde der Einsatz unsignierter Softwarepakete unterbunden.
Einzige Möglichkeit, an zusätzliche Software zu kommen, wäre wohl das freie System Freetz, dass FRITZ!OS mit zusätzlichen Paketen zu einer neuen OS-Version bündelt. Das Ganze müsste man aber selbst kompilieren und als OS-Update einspielen.
Neben dem Verlust der Garantie muss man auch damit rechnen, dass solche Aktionen mal schiefgehen können. Ich würde das nicht ohne eine funktionierende Ersatz-Fritzbox angehen.
Seit längerem ist zudem freetz.org, die Heimat des Projekts, sporadisch nicht erreichbar. So konnte ich zum Veröffentlichungszeitpunkt nicht feststellen, ob es überhaupt für die aktuelle FRITZ!OS-Version verfügbar ist.
Verschlüsseltes Dateisystem
Mit einem verschlüsselten Dateisystem wie ecryptfs lassen sich auch einzelne Ordner sichern. Eigentümer und Rechte innerhalb des Containers verwaltet dann das Dateisystem des Rechners, auf dem das verschlüsselte Dateisystem gemounted wird, nicht das der Fritzbox. So sollten sich die Rechteprobleme von rsync umgehen lassen. Fraglich ist nur, wie sich das auf die Performance auswirkt.
Das Dateisystem ecryptfs selbst ist zwar Bestandteil der meisten Linux-Distributionen, aber die Hilfsprogramme müssen üblicherweise noch installiert werden:
$ apt-get install ecryptfs-utils
Für die verschlüsselten und entschlüsselten Daten muss jeweils ein Verzeichnis angelegt werden.
$ mkdir /media/remote/.geheim
$ mkdir -p /media/fritzbox/geheim
$ chmod 700 /media/fritzbox/geheim
Dabei liegt /media/fritzbox, das Verzeichnis mit den verschlüsselten Daten, auf dem mit cifs gemounteten Share der Fritzbox, während sich /media/lokal auf dem NAS selbst befindet und die unverschlüsselten Daten aufnimmt. Für das lokale Verzeichnis verweigern wir allen außer dem Eigentümer den Zugriff; für das Verzeichnis auf der Fritzbox hätte das keine Wirkung (siehe oben).
Damit das spätere Mounten ohne Passwortabfrage erfolgen kann, muss das Passwort für die Verschlüsselten Daten in den Schlüsselring der root-Users eingetragen werden:
$ ecryptfs-add-passphrase
Passphrase:
Inserted auth tok with sig [a8dfcae0c76dea6c] into the user session keyring
$
Zur Sicherheit kann man sich den Inhalt des Schlüsselrings mit keyctl auch nochmals listen lassen:
$ keyctl list @u
1 key in keyring:
983685422: --alswrv 0 0 user: a8dfcae0c76dea6c
$
Mit diesem Schlüssel lässt sich jetzt das (noch leere) verschlüsselte Verzeichnis mounten:
$ mount -i -t ecryptfs -o ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=y,ecryptfs_sig=a8dfcae0c76dea6c,ecryptfs_fnek_sig=a8dfcae0c76dea6c,ecryptfs_unlink_sigs,ecryptfs_key_bytes=16,ecryptfs_cipher=aes /media/fritzbox/.geheim /media/lokal/geheim
$
Legt man jetzt im unverschlüsselten Verzeichnis eine Datei an, erscheint sie mit verschlüsseltem Dateinamen auch im verschlüsselten Verzeichnis:
$ echo "geheime Daten">/media/lokal/geheim/GeheimDatei
root@omv0:~# cat /media/lokal/geheim/GeheimDatei
geheime Daten
$ ls /media/fritzbox/.geheim
ECRYPTFS_FNEK_ENCRYPTED.FWbpHMqM4Zi.lUQM9ah.l1WRL8A1RhEhzz2F.Jv8o.RkqGyLKObHJSxfK---
$
In der verschlüsselten Datei findet man erwartungsgemäß keine lesbaren Daten. Als ersten Performance-Test kann man eine große Datei, hier ein Virtualbox-Image von 4,4 GByte, in das lokale Verzeichnis kopieren.
$ du -h image.vdi
4,4G image.vdi
$ date
So 2. Dez 15:32:29 CET 2018
$ cp image.vdi /media/fritz/geheim/
$ date
So 2. Dez 16:01:12 CET 2018
$
Am Ende ist die verschlüsselte Datei ebenfalls 4,4 GByte groß. Sie wächst auf der Fritzbox mit etwa 2,5…3 MByte/s. Die Gesamtdauer beträgt 28:43 Minuten oder 1723 Sekunden, das entspricht ebenfalls etwa 2,55 MByte/s. Die CPU des NAS zeigt dabei etwa 10% Last, die der Fritzbox 25%.
Hier der Vergleich zum unverschlüsselten Kopieren:
$ mkdir /media/fritzbox/offen
$ date
So 2. Dez 16:14:47 CET 2018
$ cp image.vdi /media/fritz/offen/
$ date
So 2. Dez 16:16:36 CET 2018
$
Das unverschlüsselte Kopieren dauert nur 1:49 Minuten oder 109 Sekunden, das entspricht 40,4 MByte/s. Das ist ernüchternd: der verschlüsselte Transfer erreicht nur etwa 1⁄16 der Übertragungsrate der unverschlüsselten Variante.
Kapitulation
Der fehlende rsync-Server, die nicht vorhandenen Unix-Erweiterungen des Samba-Servers und die ernüchternde Geschwindigkeit eines entfernt gemounteten verschlüsselten Dateisystems machen die Fritzbox als Ziel für Backups meines back-in-time-Archivs unattraktiv.
Ein RasPi erfüllt die Mindestanforderungen mit seinem offenen Linux wesentlich besser. Ein rsync-Server und eine aktuelle Samba-Implementierung ist immer mit an Bord. Der aktuelle 3B+ dürfte mit Gigabit-Ethernet und nochmals schnellerem Prozessor auch in Punkto Geschwindigkeit einige Vorteile gegenüber der Fritz-Box haben. Leider bedeutet das aber wieder einen weiteren Kistchen-Stapel mit RasPi, Netzteil und Laufwerk, der auch zusätzlich Strom schluckt.
Wohl oder übel muss ich wohl zunächst kapitulieren. Ein lokales Backup auf eine direkt am NAS angeschlossene USB3-Festplatte dauert statt Stunden nur wenige Minuten und sichert die Daten auch mit den korrekten Eigentümern und Zugriffsrechten. Mit zwei oder 3 separaten Laufwerken lässt sich sogar sehr einfach ein Mehrgenerationen-System aufbauen. Nach dem Backup lässt sich das Laufwerk abziehen und sicher verstauen.
Man darf nur nicht vergessen, die Backups auch regelmäßig durchzuführen.