Verschlüsseltes NAS selber aufsetzen (Ubuntu, LUKS, ZFS, RAID)

14. Februar 2013 | 12 Kommentare

Festplatte

Unser File-Server ist an seine Grenzen gestoßen und wir mussten uns auf die Suche nach einer neuen Lösung machen. Klar war: es muss ein NAS werden, das verschlüsselt ist. Doch der Markt gab nix Passendes oder Bezahlbares her.

Deswegen haben wir uns für die Do-It-Yourself-Version entschieden: ein Ubuntu-NAS mit LUKS-Verschlüsselung, ZFS-Dateisystem und RAIDZ. Nachfolgend will ich Euch erklären, wie man das aufsetzt.

Folgende Features waren für uns beim Bau des NAS wichtig:

  • Stromsparend
  • Windows-Freigabe möglich
  • Voll verschlüsselt
  • Ausfallsicher
  • Performance
  • Einfache Pflege
  • Linux basiert (kein Solaris/BSD)
  • Erweiterbarkeit (Webserver, VPN, etc)

Wir haben uns daher für folgendes Setup entschieden:

  • Betriebssystem: ubuntu-server-12.10
  • Dateisystem: zfs
  • RAID: RAIDZ
  • Freigabe: Samba
  • Verschlüsselung: ecryptfs oder LUKS

Die Hardware sollte möglichst stromsparend und kostengünstig sein, da wir keine High-Performance Lösung benötigen. Sprich 1Gbit LAN zu 100% auslasten wäre zwar schön, ist aber nicht unbedingt nötig, 80% reichen auch ;-)

Hardware: Asus Mini ITX

  • 1 MBP ASUS E35M1-I – Mini-ITX
  • 1 2.5″ OCZ 60GB Vertex 3 Series
  • 1 GEH Sharkoon Rebel 9 Pro Economy schwarz o.NT
  • 1 SPE 8GB CORSAIR CL9 Vengeance CMZ8GX3M2A1600C
  • 2 HI3 3.5″ WD 2000GB Caviar Green WD20EARX 6GB/
  • 2 HI3 3.5″ SEAGATE 2000GB Barracuda Green ST200
  • 1 NEZ 400W Seasonic X-Fanless X-400FL 80plus Go

Gesamtpreis: 905,91 € (Stand Anfang 2012)

Immer daran denken: Ein ZetaFileSystem (ZFS) ist speicherhungrig.

Betriebssystem: OpenSolaris vs. BSD vs. Ubuntu

Hier haben wir es uns einfach gemacht und das System gewählt mit dem sich alle (hier) am besten auskennen. Sonst wäre sicherlich OpenSolaris oder BSD wegen des ZFS Supports die bessere Wahl gewesen.
Die Entscheidung für ubuntu-server-12.10 lag hauptsächlich daran, das ab der Version 12.10 die LVM Verschlüsselung wieder mit im Installer ist und man nicht mehr alles per Hand machen muss, aber ältere Versionen und das aktuelle LTS gehen natürlich auch. Später bin ich auch über ein paar Probleme gestolpert, die 12.10 spezifisch sind. Doch dazu später mehr.

Installiert wird das System auf eine 60GB SSD.

Dateisystem: ZFS

Die Entscheidung zugunsten von ZFS war eigentlich von vornherein klar. Ein Hardware RAID schied aus, da es bei Controller-Fehlern zu Dateiverlust kommen kann und Write Hole Probleme vorhanden sind. ZFS vereinigt einen Logical Volume Manager und ein Software RAID und kann dabei noch viel mehr.

Doch der Artikel soll sich aber nicht um ZFS an sich drehen, sondern ist an die gerichtet die schon von ZFS überzeugt sind und es einsetzen möchten.
Alle die nicht wissen was ZFS ist und was es kann empfehle ich diesen Podcast: http://cre.fm/cre049

Installation

Zunächst müssen wir sicher stellen, das de Befehl add-apt-repository vorhanden ist.
sudo apt-get install python-software-properties

Für 12.10 reicht dies aber nicht (zum Bugreport). Deswegen muss noch Folgendes installiert werden
sudo apt-get install software-properties-common

Jetzt können wir ZFS installieren. Wir entscheiden uns hier für das Kernelmodul und nicht die FUSE-Variante, da das Kernelmodul performanter ist.

Server vorbereiten:
sudo apt-get -y -q update && sudo apt-get -y -q upgrade

Benötigte Programme installieren:
sudo apt-get -y install build-essential gawk zlib1g-dev uuid-dev vim-nox

Das PPA hinzufügen:
sudo add-apt-repository ppa:zfs-native/stable

und ZFS installieren:
sudo apt-get install ubuntu-zfs

Zum Zeitpunkt dieses Artikel gab es noch kein Release für 12.10 also müsste ich die Sourcen manuell hinzufügen:
sudo nano /etc/apt/sources.list
---
deb http://ppa.launchpad.net/zfs-native/stable/ubuntu precise main
deb-src http://ppa.launchpad.net/zfs-native/stable/ubuntu precise main

Danach noch ein Update:
sudo apt-get -y -q update

und es kann installiert werden:
sudo apt-get install ubuntu-zfs

Jetzt müssen noch die nötigen Module aktiviert werden
sudo nano /etc/modules
---
spl
zavl
znvpair
zunicode
zcommon
zfs

und intramfs aktualisieren:
sudo update-initramfs -u

Nach dem Neustart sollte ZFS zur Verfügung stehen.

Verschlüsselung mit LUKS

Bei LUKS wird die Verschlüsselung „unterhalb“ von ZFS gemacht und nicht wir bei ecryptfs (siehe unten) auf ZFS.
Dazu muss zunächst LUKS installiert werden.
sudo apt-get install cryptsetup

dann sollte auf jeder Platte eine leere Partition angelegt werden:
sudo fdisk /dev/sdaX
Befehl (m für Hilfe): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p):
Using default response p
Partitionsnummer (1-4, Vorgabe: 2):
Benutze den Standardwert 2
Es sind keine freien Sektoren verfügbar
Befehl (m für Hilfe): w

Jetzt wird der LUKS-Container für jede Festplatte angelegt:
sudo cryptsetup --verify-passphrase luksFormat /dev/sdX1 -c aes -s 256 -h sha256

Danach werden alle Container geöffnet:
sudo cryptsetup luksOpen /dev/sdX1 encryptedX

Um die Platten nach den Neustart automatisch gemountet werden muss die /etc/crypttab angepasst werden:
encrypted1 UUID=e8795884-1549-41f2-9aad-705d66716678 none luks

Die UUID der jeweiligen Partition findet man folgendermaßen heraus:
sudo blkid /dev/sdX1

Jetzt kann das ZRAID erstellt werden:
sudo zpool create storage raidz /dev/mapper/encrypted1 /dev/mapper/encrypted2 /dev/mapper/encrypted3 /dev/mapper/encrypted4

In Storage können wir jetzt verschiedene Dateisysteme erstellen. Wir erstellen mal ein einfaches share
sudo zfs create storage/share

Jetzt erstellen wir noch einen Mountpoint für share:
sudo mkdir /media/share

Dieser muss noch in ZFS gesetzt werden:
zfs set mountpoint=/media/share storage/share

Sollte hier share nach dem Neustart nicht gemountet werden könnte es sich um dieses Problem handeln (ich hatte das zumindest.)

Meistens reicht ein Versionswechsel von mountall:
sudo apt-get install mountall=2.36.1-zfs1

Sollte es dann immer noch nicht gehen, mal folgendes Problem prüfen.

ZFS versucht die mapper zu mounten, die aber zu diesem Zeitpunkt noch nicht existieren. Dies konnte ich mit folgen den Änderungen beheben:
/etc/default/zfs:
ZFS_MOUNT='yes'

Schlüssel Authentifizierung

Beim Neustarten muss jetzt jedes mal für jede Festplatte das LUKS Password eingegeben werden. Das ist nervig (ein ZRAID kann auch aus 20+ Platten bestehen ). Es ist daher sinnvoll einen Schlüssel auf der verschlüsselten Systemplatte zu hinterlegen, mit dem sich die RAID Platten öffnen lassen.

Eine weitere Lösung ist es, diesen Schlüssel für alle Platten auf einen USB-Stick zu legen, dann lässt sich das System nur hochfahren und die Platten öffnen wenn der USB-Stick mit dem Schlüssel „eingesteckt“ ist.

Ich bevorzuge jedoch Lösung eins, weil ich sie für sicherer halte. Und dies geht so.

Erstellen des Schlüssels:sudo dd if=/dev/urandom of=/root/.key/key bs=512 seek=1 count=60
sudo chmod 0400 /root/.key/key

Jetzt muss ich LUKS noch mitteilen, das die Platten sich auch durch diesen Schlüssel öffnen lassen (für jede Platte):
sudo cryptsetup luksAddKey /dev/sdX1 /root/.key/key

Es ist zu beachten, das sich die Platten bei Verlust der Schlüsseldatei auch noch durch das Passwort öffnen lassen. Ferner lassen sich nur die RAID Platten mit dem Schlüssel öffnen, nicht die Systemplatte. Dadurch kann System nicht in Betrieb genommen werden von jemanden, der die Schlüsseldatei gestohlen hat, es muss ebenfalls das Passwort bekannt sein.

Damit die Schlüsseldatei auch beim Booten berücksichtigt wird, muss die /etc/crypttab angepasst werden (für jede Platte):encryptedX UUID=9e1923b6-97c7-4769-8139-18ecf2c7ebf7 /root/.key/key luks

Alternative zu LUKS: Verschlüsselung mit ecryptfs

Achtung: ecryptfs unterstützt nur 255 lange Dateinamen (https://bugs.launchpad.net/ecryptfs/+bug/344878) sollte das ein Problem sein empfiehlt es sich die LUKS Variante zu benutzen, siehe weiter unten.
Bei ecrypfs ist es notwendig, das wir zunächst die Festplatten mit ZFS einrichten und dann erst die Verschlüsselung aktivieren.

Ich erstelle ein RAIDZ Pool über 4 Festplatten mit dem Namen storage:sudo zpool create storage raidz /dev/sda /dev/sdb /dev/sdc /dev/sde

In Storage können wir jetzt verschiedene Dateisysteme erstellen. Wir erstellen mal ein einfaches sharesudo zfs create storage/share

Jetzt erstellen wir noch einen Mountpoint für share:sudo mkdir /media/share

Sollen share nach dem Neustart nicht gemountet werden könnte es sich um dieses Problem handeln (ich hatte das zumindest.)

Meistens reicht ein Versionswechsel von mountall
sudo apt-get install mountall=2.36.1-zfs1

Jetzt müssen wir ecryptfs installieren.
sudo apt-get install ecryptfs-utils

Jetzt wollen wir share verschlüsselt mounten. Dabei ist zu beachten, das share schon unter /storage/share unverschlüsselt gemountet ist.
sudo mkdir /media/share
sudo mount -t ecryptfs /storage/share /media/share

Das ganze mit mit Enter bestätigen. Ich hab aber zusätzlich noch die filename encryption aktiviert:

Passphrase:
Select cipher:
1) aes: blocksize = 16; min keysize = 16; max keysize = 32
2) blowfish: blocksize = 8; min keysize = 16; max keysize = 56
3) des3_ede: blocksize = 8; min keysize = 24; max keysize = 24
4) twofish: blocksize = 16; min keysize = 16; max keysize = 32
5) cast6: blocksize = 16; min keysize = 16; max keysize = 32
6) cast5: blocksize = 8; min keysize = 5; max keysize = 16
Selection [aes]:
Select key bytes:
1) 16
2) 32
3) 24
Selection [16]:
Enable plaintext passthrough (y/n) [n]:
Enable filename encryption (y/n) [n]: y

Jetzt können in /media/share Dateien gespeichert werden diese werden dann verschlüsselt.
In /storage/share sieht man nun nur verschlüsselte Dateien.

Performance

Im Anschluss ein paar Daten was das System so kann (gemessen mit bonnie++ und dd):

Performance ohne Verschlüsselung

ZFS Benchmark ohne Verschlüsselung

ZFS Benchmark ohne Verschlüsselung

Schreiben:
dd if=/dev/zero of=tempfile bs=1G count=1 oflag=dsync
1+0 Datensätze ein
1+0 Datensätze aus
1073741824 Bytes (1,1 GB) kopiert, 13,796 s, 77,8 MB/s

Performance mit Verschlüsselung

ecryptfs

ZFS Bechchmark mit encryptfs

ZFS Bechchmark mit encryptfs

Schreiben:
dd if=/dev/zero of=tempfile bs=1G count=1 oflag=dsync
1+0 Datensätze ein
1+0 Datensätze aus
1073741824 Bytes (1,1 GB) kopiert, 40,5001 s, 26,5 MB/s

Lesen:
dd if=tempfile of=/dev/null
2097152+0 Datensätze ein
2097152+0 Datensätze aus
1073741824 Bytes (1,1 GB) kopiert, 3,29727 s, 36 MB/s

LUKS

ZFS Benchmark auf LUKS

ZFS Benchmark auf LUKS

Schreiben:
dd if=/dev/zero of=tempfile bs=1G count=1 oflag=dsync
1+0 Datensätze ein
1+0 Datensätze aus
1073741824 Bytes (1,1 GB) kopiert, 31,1532 s, 34,5 MB/s

Lesen:
dd if=tempfile of=/dev/null
2097152+0 Datensätze ein
2097152+0 Datensätze aus
1073741824 Bytes (1,1 GB) kopiert, 19,0477 s, 56,4 MB/s

Weiterführende Links:

Titelbild: Festplatte von Wikimedia

Ähnliche Artikel:

Meta-Daten



12 Kommentare

Auch mal Kommentieren:

Kommentar