Sent from Hauptstadt!

ein Blog für den geneigten Leser

Verschlüsseltes Backup mit Amazon S3

Tags: , , ,

Kategorie Software Engineering | 2 Kommentare »

Bisher kopiere ich meine Daten von Zeit zu Zeit mittels rsync auf eine externe Festplatte, die ich in einem anderen Raum meiner Wohnung lagere. Da dies nicht gegen Einbrüche oder Brand schützt, sichere ich meine Daten zusätzlich in der Wolke bei Amazon S3. Das Aufsetzen der Lösung samt Verschlüsselung war dann doch umständlicher als gedacht.

Argumente für ein Online Backup

Vor einigen Jahren waren die Gebühren für Onlinespeicher noch zu hoch und ich verwarf die Idee eines Onlinebackps. Inzwischen zahle ich für meine maximal 150GB Speichervolumen aber nur noch 4,50€ monatlich bei Amazon S3. Alternativ hätte ich mir einen feuersicheren Tresor für ca. 200€ kaufen können, was spätestens beim nächsten Umzug viel Freude gemacht hätte.

Ich könnte die monatlichen Kosten sogar auf ein Drittel eindampfen, wenn ich statt S3 den Glacier Dienst von Amazon nutzen würde. Dies würde die Lösung aber nur unnötig verkomplizieren, da Glacier keinen Dateibaum kennt, sondern jeder hochgeladenen Datei eine neue ID gibt. Ich würde also ein Mapping zwischen Glacier ID und meinem lokalen Dateipfad benötigen und müsste dieses Mapping ebenfalls, etwa bei S3, sichern. Das ist mir zu viel Aufwand und ich gönne mir deshalb den Luxus von S3!

Das Backup eines lokalen Dateibaums nach Amazon S3 ist trivial und es gibt diverse Werkzeuge dafür. Die meisten Werkzeuge unterstützen aber keine Verschlüsselung während der Synchronisation. Ohne Verschlüsselung könnte aber jeder, der Zugriff auf das entsprechende S3 Bucket erlangt, die Daten lesen. Deshalb kommt für mich nur ein Online Backup in Frage, wenn die Daten vor dem Upload lokal verschlüsselt werden.

Die meisten Werkzeuge synchronisieren die lokalen Dateien mit S3 anhand des MD5 Hash. Amazon S3 speichert den MD5 Hash automatisch für jede Datei in den Metadaten. Eine Datei wird nur hochgeladen, wenn die Hashes nicht übereinstimmen. Das spart Datenvolumen, denn auch mit einer 16.000er DSL Leitung ist der Upload gähnend langsam und dauert bei 150GB rund 10 Tage!

Lokale Verschlüsselung mit encfs

Um die vorhandenen Werkzeuge für die Synchronisation weiter nutzen zu können, müssen die Dateien bereits verschlüsselt sein, bevor das Werkzeug darauf zugreift. Bei der Synchronisation wird der MD5 der verschlüsselten Datei für den Abgleich genutzt.

Nach langer Recherche bin ich auf encfs gestoßen, einem virtuellen Dateisystem unter Linux. Normalerweise wird encfs genutzt, um verschlüsselte Dateien automatisch zu entschlüsseln, wenn jemand darauf zugreift. Ich wollte aber genau das Gegenteil: Dateien sollen verschlüsselt werden, wenn die Synchronisation läuft. Während es für das transparente Entschlüsseln mehrere Alternativen wie duplicity gibt, konnte ich nur bei encfs eine –reverse Option finden. Encfs ist nicht ganz unumstritten unter Kryptologen, ich glaube aber, für meine Zwecke ist es sicher genug.

Meine Bildersammlung kann ich folgendermaßen verschlüsseln:

encfs --reverse ~/bilder ~/bilder-encrypted

Das Verzeichnis „bilder-encrypted“ enthält genau die gleichen Dateien und Verzeichnisse wie in meinem Bildverzeichnis „bilder“. Der Inhalt der Dateien ist aber verschlüsselt.

Beim ersten Aufruf muss man die Verschlüsselungsparameter wie den verwendeten Algorithmus auswählen (zum Beispiel AES256) und ein Passwort eingeben. Die Parameter werden in der Datei .encfs6.xml abgelegt. Diese Datei muss man ebenfalls unbedingt im Klartext nach S3 sichern, da in dieser Datei auch der Salt steht, der bei der Erstellung des Schlüssels verwendet wurde. Der Schlüssel selbst ist ebenfalls in der Datei enthalten, allerdings verschlüsselt mit dem selbst gewählten Passwort. Dieses Passwort darf man natürlich nicht bei S3 sichern, da man sich sonst die ganze Verschlüsselung sparen kann :-) Meine momentane Lösung ist, dass ich dieses Passwort samt Ausdruck der „.encfs6.xml“ Datei bei Verwandten meines Vertrauens in einem Briefumschlag hinterlegt habe.

Greife ich auf die Dateien in „bilder-encrypted“ zu, sehe ich meinen gewohnten Dateibaum. Die Dateien selbst enthalten aber nur noch Datensalat. Diesen Datensalat kann ich jetzt mit gutem Gewissen nach Amazon S3 synchronisieren!

Ich nutze für die Synchronisation s3cmd. Eine gute Alternative ist das offizielle Kommandozeilenwerkzeug von Amazon. Mit s3cmd lautet das Kommando zur Synchronisation folgendermaßen:

s3cmd sync ~/bilder-encrypted s3://S3-BUCKET-ID/bilder/
--server-side-encryption --exclude ".encfs6.xml"

Bei der ersten Nutzung von s3cmd werden die Zugangsdaten wie Access und Secret Key abgefragt. Man kann auch angeben, dass nur Verbindungen per https:// zur Amazon API aufgebaut werden sollen. Die Einstellungen speichert s3cmd in der Datei „.s3cfg“ im Nutzerverzeichnis.

IAM Nutzer für S3 Bucket

Amazon proklamiert für seine Web Services das Prinzip der geteilten Verantwortung (engl.: shared responsibility). Amazon übernimmt die Verantwortung für den sicheren Betrieb der Rechenzentren und der angebotenen Dienste wie S3, IAM oder Glacier. Der Nutzer ist andererseits für die sichere Konfiguration zuständig. So liegt es natürlich in meiner Verantwortung, dass niemand Unbefugtes auf das S3 Bucket mit meinem Backup zugreifen kann.

Amazon empfiehlt nicht den eigenen Administrationsnutzer für den Zugriff auf einzelne Dienste zu verwenden. Stattdessen soll man sich mittels dem kostenlosen IAM Dienst eigene Nutzer anlegen. Ich habe dementsprechend einen IAM Nutzer angelegt. Dieser Nutzer kann sich nicht per Nutzername und Passwort bei Amazon Web Services anmelden, sondern verfügt lediglich über einen Access und Secret Key.

IAM unterstützt deklarative Sicherheit. Mittels selbst definierter Policies regelt man bestimmte Sicherheitsaspekte. Meinem Nutzer habe ich eine Policy zugewiesen, die es ihm nur erlaubt, auf mein S3 Bucket mit dem Backup zuzugreifen. Amazon bietet in der Management Console einen Policy Generator. Trotzdem hat es mehrere Versuche gebraucht, bis ich die gewünschte Policy erstellt hatte.

[gist id=c2a008562312f019477e]

Amazon prüft die Einhaltung dieser Policy bei jedem Zugriff des Nutzers auf die verschiedenen Dienste. Mein Backup Nutzer kann damit nur auf dem vorgegebenen S3 Bucket arbeiten. Wenn man das Beispiel nachvollziehen will, muss man natürlich S3-BUCKET-ID durch die tatsächliche ID ersetzen. Auch die Policy Statements selbst benötigen eindeutige IDs statt Stmt-GENERATED-ID, aber entsprechende IDs werden beim Erstellen einer Policy automatisch erzeugt.

S3 Bucket mittels Policies absichern

Neben der deklarativen Sicherheit gibt es noch eine ganz normale Rechtevergabe. Beides kann kombiniert werden. Durch die im vorherigen Abschnitt definierte Policy hat mein Backup Nutzer bereits Zugriff auf das S3 Bucket, obwohl ich ihm nicht explizit im Bucket die entsprechenden Rechte erteilt habe.

Man kann Policies auch verwenden, um Konventionen durchzusetzen. So habe ich eine Policy am S3 Bucket definiert, die verhindert, dass ein unverschlüsselter Zugriff auf das Bucket per http:// erfolgt. Entsprechende Verbindungsversuche werden abgelehnt. Damit kann ich Fehler in meinen lokalen Skripten entdecken und vermeiden.

Amazon S3 unterstützt eine serverseitige Verschlüsselung mittels AES256. Ziel ist, dass ein Techniker bei Amazon, der Zugriff auf die Hardware hat, ebenfalls nur Datensalat sieht, wenn er die Festplatte mit meinen Daten klaut. Amazon täte gut daran, dies eine Standardeinstellung zu machen, auch wenn es sicher auf Seiten von Amazon zusätzliche Rechenzeit kostet. So ist man als Nutzer gezwungen, bei jeder neu hochgeladenen Datei die Verschlüsselung explizit anzufordern.

Ich habe für mein S3 Bucket eine Policy definiert, die den Upload von Dateien ablehnt, wenn die serverseitige Verschlüsselung nicht aktiviert ist. Beide Bucket Policies zusammen sehen folgendermaßen aus:

[gist id=“bcc29d9c304ed4925e76″]

Ein weiteres Detail von S3 ist die so genannte Storage Class. Darüber steuert man, wie redundant ein Objekt gespeichert wird. Eine reduzierte Redundanz kostet bei Amazon weniger. Glücklicherweise ist dies nicht der Standardwert für neue S3 Objekte. Anscheinend gibt es momentan keine Möglichkeit per Policy zu verhindern, dass reduzierte Redundanz für ein S3 Objekt gewählt wird. Ich hoffe, dass Amazon dies noch nachbessert. Trotz dieser Einschränkung sind Policies und IAM Nutzer schon jetzt ein mächtiges Werkzeug, um die gröbsten Fehler zu vermeiden.

Fazit

Meine Lösung ist was für Bastler. Ich habe natürlich viel zu viel Zeit investiert. Wer nicht basteln will, findet diverse fertige Angebote. Allerdings muss man bei diesen Angeboten den Herstellern vertrauen, dass sie keine Hintertüren in die Verschlüsselung eingebaut haben. Überprüfen kann man es nicht.

Amazon macht es sich meiner Meinung mit seinem Shared Responsibility Prinzip zu leicht. Es macht wenig Sinn, dass Daten auf den Datenträgern im Amazon Rechenzentrum nicht verschlüsselt abgelegt werden. Auch das Erstellen von Policies könnte einfacher gelöst sein und überfordert den Bastler schnell. Interessant ist auch, dass Amazon zum Beispiel keinerlei öffentliche Aussage darüber trifft, ob der Datenverkehr zwischen seinen Rechenzentren (zum Beispiel während der redundanten Spiegelung des S3 Buckets) verschlüsselt ist. Dementsprechend muss man hier selbst Hand anlegen.

Im meinem Fall ist die Verschlüsselung relativ einfach umzusetzen, da ich immer noch einen lokalen Rechner habe, dem ich „vertraue“. Schwieriger wird es bei Angeboten, die vollständig auf Amazon laufen. In solch einem Szenario gibt es keine lokalen Rechner mehr, sondern alle Maschinen und Dienste laufen bei Amazon. Ob die Verschlüsselung der Daten auf einer EC2 Instanz vor dem Upload nach S3 überhaupt noch was bringt, ist fraglich.

Andererseits muss ich hier natürlich die Kirche im Dorf lassen, denn mir geht es erst mal nur um die Sicherung von meinen privaten Fotos und ein paar krautigen Emails. Mein Ziel mich vor einem Datenverlust durch Einbruch oder Wohnungsbrand zu schützen, dürfte ich auf alle Fälle erreicht haben.

Insgesamt ist die Lösung im täglichen Gebrauch sehr komfortabel. Sobald ich neue Fotos in meinen Archivordner gelegt habe, brauche ich nur ein Kommando auszuführen, um die Fotos auch nach S3 zu sichern. Das ist wesentlich bequemer als ein Backup auf eine externe Festplatte. Vielleicht gelingt es mir damit dann auch, regelmäßiger ein Backup zu machen :-)

Update: Auch nach über 5 Jahren nutze ich die Lösung. Inzwischen gibt es eine gute Lösung, um die Speicherkosten zu optimieren ohne eine Lösung mittels S3 Glacier bauen zu müssen. Alle Details dazu hier: Optimierung AWS S3 Kosten

2 Kommentare to “Verschlüsseltes Backup mit Amazon S3”

  1. Matthias sagt:

    Hallo Sebastian,

    das klingt schon ziemlich gut. Ohne Verschlüsselung würde ich meine gesammelten Daten nirgends hochladen.

    Allerdings sind die Metadaten doch auch schon recht spannend. Wenn die Ordnerstruktur bei s3 liegt, und die verschlüsselten Bilder aussagekräftige Titel haben, ist das für manche Organisation auch schon eine nützliche Information.
    Da klingt für mich die Glacier-ID Variante, ja mit dem Zusatzaufwand eines Mappings, sinnvoller.

    Kann man die Datei mir den Mappings aber nicht auch im Glacier hinterlegen? Die eine ID müßte dann bei der Konfiguration des Clients eingegeben werden können.

  2. Sebastian sagt:

    Ja, natürlich verraten die Metainformationen ziemlich viel. Spätestens seit den Berichten aus dem letzten Jahr wissen wir, dass viele Drohnenangriffe allein aufgrund von Metadatenanalysen befohlen werden.

    Allerdings darf hier nicht die primäre Intention vergessen werden, warum ich überhaupt ein Cloud Backup mache. Ich möchte mich primär gegen Datenverlust durch Wohnungseinbruch und Wohnungsbrand schützen. Weiterhin ist es mir wichtig, dass niemand den Inhalt der Dateien sehen kann, etwa von Fotos oder Schriftverkehr. Von daher ist es für mich ein akzeptabler Kompromiss.

    Es ist technisch kaum umsetzbar das Mapping zwischen ID und tatsächlichem Dateipfad selbst in einer Glacier Datei zu speichern. Amazon verwendet für Glacier vermutlich Bandlaufwerke oder ähnliche Systeme. Auf alle Fälle steht eine Datei erst einige Stunden nach Anforderung zum Download bereit. Für ein Backup ist dies prinzipiell akzeptabel, da man einige Stunden warten kann, um an seine Dateien zu kommen. Für das Laden und ändern der Mapping Datei hingegen geht das natürlich nicht. Deshalb müsste die Datei zum Beispiel in S3 gesichert werden. Weiterhin muss man die Mapping Datei selbst ebenfalls verschlüsseln, was die Lösung ebenfalls komplexer macht.

Schreiben sie ein Kommentar