Dieser Artikel ist ein Step-by-step Howto für die Einrichtung von dav-sync mit aktivierter Verschlüsselung.
1. Repository konfigurieren
Zuerst erstellen wir ein Repository mit Hilfe des add-repository
Befehls von dav. Wichtig ist, dass wir dabei auch Benutzername und Passwort angeben, da dav-sync Authentifizierungsinformationen benötigt und diese nicht zur Laufzeit vom Benutzer abfragt.
$ dav add-repository
Each repository must have an unique name.
name: myfirstrepo
Specify the repository base url.
url: https://mynas.local/webdav
User for HTTP authentication.
user (optional): mywebuser
password (optional):
2. Key erstellen und konfigurieren
Als nächstes benötigt man einen AES-Key. Diesen erstellen wir aus zufälligen Daten mit Hilfe von dd:
mkdir -p ~/.dav/keys
dd if=/dev/random of=~.dav/keys/mykey bs=32 count=1
Dann muss in der Datei $HOME/.dav/config.xml
nur noch ein Eintrag für den Key hinzugefügt werden.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
...
<key>
<name>mykey</name>
<type>aes256</type>
<file>keys/mykey</file>
</key>
</configuration>
3. Verschlüsselung für das Repository aktivieren
Wärend man mit dem Tool dav die Verschlüsselung per Kommandozeilenoption an- und abschalten kann, benutzt dav-sync immer die Default-Einstellungen des Repositories. Daher muss für das Repository die Verschlüsselung standardmäßig aktiviert sein und ein Default-Key muss angegeben werden. Hierfür fügt man innerhalb des <repository>
-Elements das <full-encryption>
und <default-key>
-Element hinzu:
<repository>
...
<full-encryption>true</full-encryption>
<default-key>mykey</default-key>
</repository>
3. Sync-Directory erstellen
Letztendlich benötigt man noch die eigentliche Konfiguriation für dav-sync. Mit dem Befehl add-directory
von dav-sync erstellen wir die Konfiguration für ein Sync-Directory. Dabei gibt man dann das Repository mit aktivierter Verschlüsselung an:
$ dav-sync add-directory
Each sync directory must have an unique name.
name: mysyncdir
Enter local directory path.
path: $HOME/important_files
Specify webdav repository.
0) myfirstrepo
1) anotherrepo
repository: 0
Enter collection relative to the repository base url.
collection (default: /): /important_files
Fertig. Für den Benutzer ändert sich an der Bedienung von dav-sync dann nichts. Man kann ganz wie gewohnt mit pull/push seine Dateien synchronisieren, nur dass sie dann verschlüsselt auf dem Server liegen.
Teil des dav Pakets ist das separate Tool dav-sync, das lokale Verzeichnisse mit WebDAV-Collections synchronisieren kann.
Features
- Verwendet die selbe Repository-Konfiguration von dav, womit Dinge wie Verschlüsselung oder Proxies zur Verfügung stehen
- Separate Befehle um die Änderungen vom Servers zu downloaden und um die lokalen Änderungen auf den Server zu übertragen
- Konflikterkennung
- Trash-Verzeichnis, in dem Dateien, die gelöscht oder überschrieben werden sollen, abgelegt werden können
- Regex-Filter, um bestimmte Dateien einzubeziehen und/oder auszuschließen
Funktionsweise
Jedes Sync-Directory hat eine Datenbank (in Wahrheit nur eine billige XML-Datei), in der Zustandsinformationen jeder Datei gespeichert sind. Im Detail sind das der Etag, die Dateigröße und das Datum der letzten Änderung. Diese Informationen werden genutzt um Änderungen zu erkennen. Um Änderungen auf dem Server zu erkennen, wird der Etag jeder Datei verglichen und um lokale Änderungen zu erkennen wird das Änderungsdatum und die Dateigröße mit den Werten in der Datenbank verglichen.
Konfiguration
Zunächst einmal muss ein Repository für den Server konfiguriert werden. Am einfachsten geht dies mit dem Befehl dav add-repository
. Siehe meinen Artikel zu dem Thema.
Als nächstes muss noch das lokale Verzeichnis in der Datei $HOME/.dav/sync.xml
konfiguriert werden. Eine einfache Basiskonfiguration kann mit dem Befehl dav-sync add-directory
angelegt werden.
Dies fragt zuerst nach einem frei wählbaren Identifier für das Verzeichnis, der dann auch mit den anderen dav-sync Befehlen genutzt wird. Danach muss der lokale Pfad angegeben werden, wobei man im Pfad auch Umgebungsvariablen wie $HOME verwenden kann. Danach folgt noch das Repository und die Collection des Repositories, in welche die Dateien dann synchronisiert werden sollen. Die volle URL ist der angegebene Collection-Pfad angehängt an die Basis-URL des Repositories.
$ dav-sync add-directory
Each sync directory must have an unique name.
name: mysyncdir
Enter local directory path.
path: $HOME/important_files
Specify webdav repository.
0) myfirstrepo
1) anotherrepo
repository: 0
Enter collection relative to the repository base url.
collection (default: /): /important_files
Danach kann man seine Daten mit den Befehlen pull
und push
synchronisieren. Es werden von dav-sync alle Einstellungen des Repositories verwendet, also Authentication-Informationen, TLS-Einstellungen und AES-Verschlüsslung. Zu beachten ist auch, dass dav-sync keinen Authentication-Prompt anzeigt, daher müssen Authentication-Daten im Repository konfiguriert sein.
Anwendung
Für die Synchronisation gibt es primär zwei Befehle: pull, um Dateien, die auf dem Server geändert wurden, zu downloaden und push, um lokale Änderungen auf den Server zu uploaden. Man gibt dabei nur den Identifier des Verzeichnisses an, z.B. um Änderungen zu downloaden:
dav-sync pull mysyncdir
Änderungen uploaden geht mit:
dav-sync push mysyncdir
Wer komplett das Verzeichnis mit dem Server synchronisieren will, damit sie den gleichen Zustand haben, sollte zunächst pull und danach push aufrufen:
$ dav-sync pull mysyncdir
...
$ dav-sync push mysyncdir
...
Im besten Fall werden dabei einfach nur Dateien gedownloadet bzw geuploadet. Wenn jedoch Dateien lokal und auf dem Server geändert wurden, führt dies zu einem Konflikt. Der push-Befehl ignoriert solche Dateien einfach. Beim pull-Befehl wird die entsprechende Datei umbenannt und die Version des Servers wird unter dem originalen Namen gespeichert. Der Anwender muss dann selber die Dateien vergleichen und entscheiden welche er behalten will. Die umbenannten Dateien der Form orig.$number.$name werden im übrigen von push ignoriert, da sie als Konflikt markiert sind. Wer sie trotzdem uploaden will, kann sie einfach umbenennen oder mit dav-sync resolve-conflicts <syncdir>
die Konfliktmarkierung entfernen, wonach sie für dav-sync ganz normale Dateien sind. Mit dav-sync delete-conflicts <syncdir>
können auch alle diese Dateien entfernt werden.
Gelöschte und überschriebene Dateien wiederherstellen
Wie anfangs erwähnt unterstützt dav-sync ein Trash-Verzeichnis, in das es alle Dateien verschiebt, anstatt sie zu löschen. Wenn mit dav-sync add-directory
das Sync-Directory angelegt wurde, ist das Trash-Verzeichnis auch standardmäßig aktiviert und ist das .trash Unterverzeichnis des Sync-Directory.
Wann immer pull also eine Datei löschen will, wird diese dann in das Trash-Verzeichnis verschoben. Das schützt schon mal vor unbeabsichtigten Löschen. Es gibt zusätzlich noch die Möglichkeit, dass auch Dateien, bevor sie durch den pull-Befehl überschrieben werden, in das Trash-Verzeichnis verschoben werden. Hierfür muss in der sync.xml innerhalb des entsprechenden <directory>
-Elements folgendes eingefügt werden:
<directory>
...
<backup-on-pull>true</backup-on-pull>
</directory>
Diese Datensicherheit hat natürlich den Preis, dass viele Kopien einer Datei irgendwann rumliegen. Mit dav-sync trash-info <directory>
erhält man einen Überblick darüber, wie viele Dateien im Trash sind, und wie viel Platz sie verbrauchen. Wer das Trash-Verzeichnis leeren will, kann hierfür dav-sync empty-trash <directory>
benutzen.
Es ist an der Zeit für ein dav Minor-Update. Dieses beinhalt hauptsächlich kleine neue Features sowie ein paar Detailänderungen und einen kritischen Bugfix.
Neu bei dav-sync ist, dass der Synchronisationsvorgang mit SIGINT (Ctrl+C) sauber abgebrochen werden kann. Die aktuelle Datei wird noch zuende gedownloadet bzw geuploadet und danach das Programm beendet. Beim nächsten pull/push wird dann der Rest synchronisiert.
Desweiteren gibt es jetzt für dav-sync das archive Kommando, was nur geänderte oder neue Dateien auf den Server uploadet, jedoch keine Dateien auf dem Server löscht.
Neu bei dav ist das remove-property Kommando. Um den Umgang mit Properties zu erleichtern können nun auch XML-Namespaces in der config.xml Datei mit dem neuen <namespace>
-Element konfiguriert werden, so dass man bei den Befehlen nur noch einen benutzerdefinierten Prefix angeben muss.
Sowohl dav als auch dav-sync können jetzt auch WebDAV-Locks mit Timeout erstellen.
Eine vollstände Liste der Änderung gibt es in der CHANGELOG-Datei.
Downloads gibt es hier oder auf Sourceforge. Die Dokumentation liegt dem Quellcode bei und ist auch online verfügbar.
In Zeiten von Cloud-Computing und NSA-Spionage sollte man seine Daten lieber verschlüsselt auf fremden Servern speichern. Daher habe ich in dav (und dav-sync) eine optionale client-seitige Verschlüsselung integriert, die Dateien on-the-fly beim Uploaden mit AES verschlüsselt.
Jede Datei wird dabei einzeln mit AES-CBC verschlüsselt. Es kann sowohl der Dateiinhalt als auch der Dateiname verschlüsselt werden. Desweiteren wird auch ein SHA256-Hash des Contents verschlüsselt in den Properties einer Resource gespeichert. Dieser wird beim Download automatisch zur Verifizierung des Inhalts benutzt.
Soll der Name verschlüsselt werden, wird eine Datei zunächst mit zufälligen Namen geuploadet. Der Name, den der Client benutzen möchte, wird verschlüsselt in einer WebDAV-Property gespeichert. Dateipfade werden von dav beim Zugriff automatisch übersetzt, indem Ressourcen mit dem entsprechenden verschlüsselten Namen gesucht werden.
Der Nachteil dieses Systems ist, dass die Verzeichnisstruktur und Dateigrößen für den Angreifer, in dem Fall der böse Cloudprovider, sichtbar sind. Desweiteren hat die Verschlüsselung der Dateinamen einiges an Overhead, da zusätzliche HTTP-Requests verschickt werden müssen.
Es gibt aber auch ein paar Vorteile:
- Dateien mit gleichen Klartext-Namen haben auf dem Server unterschiedliche Namen
- Für unterschiedliche Dateien können unterschiedliche Keys verwendet werden
- Einfaches System, das sich auch notfalls mit curl und openssl nachbauen lässt
- Der Name und Inhalt einer Datei sind kompromisslos sicher verschlüsselt (solange AES im CBC Mode sicher ist)
- Funktionsweise von WebDAV wird nicht kompromitiert und es stehen weiterhin Locking, Properties oder andere WebDAV-Features zur Verfügung
Voraussetzung
Der Server muss das Speichern von Deadproperties unterstützen. Mit Apache oder Owncloud/Nextcloud lässt sich das Verschlüsselungsfeature problemlos nutzen. Wer sich nicht sicher ist, ob sein Server Deadproperties unterstützt, kann folgenden Test durchführen:
$ dav set-property myserver testprop testvalue
$ dav get-property myserver testprop
testvalue
$ dav remove-property myserver testprop
Konfiguration
Zunächst benötigt man einen Schlüssel. Aktuell können keine Keys aus Passwörtern generiert werden, daher muss der Inhalt des Keys in einer Datei gespeichert werden. Für einen AES256-Key benötigt man daher eine 32 bytes große Datei (16 bytes für AES128). Den Key generiert man am besten, indem man mit dd 32 zufällige Bytes aus /dev/random liest.
$ mkdir ~/.dav/keys
$ dd if=/dev/random of=~/.dav/keys/mykey bs=32 count=1
Als nächstes fügt man einen key-Eintrag in der config.xml hinzu:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
...
<key>
<name>mykey</name>
<type>aes256</type>
<file>keys/mykey</file>
</key>
</configuration>
Der Name ist frei wählbar, er muss jedoch auf jedem System, von dem man aus auf verschlüsselte Dateien zugreifen will, gleich sein. type
muss entweder aes256 oder aes128 sein. file
ist der Pfad zu der key-Datei, relativ zu dem Verzeichnis $HOME/.dav/
.
Als nächstes muss die Verschlüsselung für ein Repository aktiviert werden. Man hat die Wahl, ob nur der Content oder auch noch die Dateinamen verschlüsselt werden sollen. Um nur den Content zu verschlüsseln fügt man innerhalb des <repository>
-Elements <content-encryption>true</content-encryption>
ein. Für eine vollständige Verschlüsselung von Dateiinhalten und Dateinamen fügt man <full-encryption>true</full-encryption>
ein. Desweiteren muss auch mit dem <default-key>
-Element der Key angegeben werden, der standardmäßig zum Verschlüsseln verwendet werden soll.
<repository>
...
<full-encryption>true</full-encryption>
<default-key>mykey</default-key>
</repository>
Man kann auch ganz ohne Repositorykonfiguration die Verschlüsselung nutzen, in dem man bei dav mit der -c
Option die full-encryption aktiviert und mit -k <key>
den Key angibt.
Anwendung
Ist die Verschlüsselung erstmal für ein Repository aktiviert, werden Dateien automatisch ver- und entschlüsselt. Auch die Pfade, die man den dav-Kommandos übergibt, werden automatisch übersetzt. Beispielsweise führt mit aktivierter Verschlüsselung dav put myrepo/myfile.txt mylocalfile.txt
dazu, dass die Datei mylocalfile.txt auf dem Server mit einem zufälligen Resource-Namen gespeichert wird. Die eigentliche URL wäre dann beispielsweise http://myserver/rDcz2L0MW2cxSEIHtH2qsqBs, wobei der letzte Teil nur ein bedeutungsloser zufälliger String ist. Der Name, den der Client benutzt, wird in den Properties verschlüsselt gespeichert. Greift man mit dav get myrepo/myfile.txt
darauf zu, sucht dav automatisch die passende Resource.
Möchte man die echte URL einer verschlüsselten Resource haben, kann man hierfür dav info
nutzen. Dies listet einige Informationen über eine Resource, unter anderem die URL.
Wer einen anderen Key zum Verschlüsseln nutzen möchte, als den konfigurierten default-key, kann mit der -k <key>
Option einen anderen Key angeben. Dieser muss natürlich in der config.xml konfiguriert sein.
Nach Teil 1 hier die Fortsetzung:
#include <stdio.h>
int main(int argc, const char* argv[printf("Hello, World!\n")]) {}
Gefunden hab ich das Beispiel hier.