Kommt ein Rechner abhanden, wiegt der Umstand, dass die Daten in fremde Hände gelangen, oft schwerer als der Verlust der Hardware. Der folgende Workshop erklärt anhand einer Gentoo-Installation, wie man mit Luks und ZFS ein System als Ganzes verschlüsselt.
Der Dummheit sind zwar sprichwörtlich keine Grenzen gesetzt. Aber niemand käme auf die Idee, den nächsten Businessplan der eigenen Firma auf Facebook zu posten. Auf Laptops jedoch tragen viele ihn spazieren. Bei einer Studie [1] gaben 86 Prozent der befragten IT-Sicherheitsfachkräfte an, dass in ihrem Unternehmen mindestens ein Laptop gestohlen oder verloren wurde. In 56 Prozent der Fälle kam es dabei zur Verletzung der Datensicherheit. 61 Prozent der deutschen IT-ler sagten, der Datenverlust wiege schwerer als der materielle Schaden, nur 13 Prozent grämten sich mehr über die abgängige Hardware.
Was tun? Herkömmliche Linux-Laptops verwenden zwar moderne Dateisysteme wie Ext 4 oder XFS, die für Validität der Dateien sorgen, legen die Daten aber unverschlüsselt ab – keine Hürde für einen Datendieb, der in den Besitz des Geräts gelangt ist. Techniken wie Truecrypt speichern Daten dagegen in verschlüsselten Containern, in Kombination mit einer starken Passphrase gilt das als sicher. Truecrypt kann jedoch Linux-Systeme nicht als Ganzes verschlüsseln.
Dieser Artikel stellt ein nahezu komplett verschlüsseltes System vor, das auf einer stark verschlüsselten Hauptpartition läuft. Nur die kleine »/boot« -Partition mit Kernel und Initram-FS bleibt unverschlüsselt. Als Filesystem kommt das Feature-reiche ZFS on Linux (ZoL, [2]) zum Einsatz. Damit ist der Speicherplatz zwischen allen ZFS-Dateisystemen dynamisch verteilbar. ZFS sorgt durch Block-Prüfsummen zudem für Datenintegrität und kann Dateien wenn nötig transparent komprimieren.
Ausgehend von einem Howto von Matthew Thode [3] beschreibt der folgende Workshop den nicht immer intuitiven Weg von der Installations-DVD bis zum verschlüsselten Produktivsystems. Als Betriebssystem kommt die 64-Bit-Variante von Gentoo Linux zu Ehren. 64 Bit, weil das 128-Bit-Filesystem ZFS aus der enterpreisigen Welt von Solaris kommt. Auch wenn viele es bereits täglich einsetzen, stufen seine Entwickler ZFS on Linux als Release Candidate ein. Für den Produktivbetrieb gilt die übliche Mahnung im erhöhten Maß: Ohne regelmäßige Backups lebt jeder Datenbestand gefährlich.
DELUG-DVD
Der Autor dieses Beitrags hat für die Delug-DVD die virtuelle Maschine bereitgestellt, anhand derer er diesen Artikel verfasst hat. Die Passphrase des Setup lautet »LinuxMag12« .
Das System vorbereiten
Die Installation von Gentoo erfolgt manuell per Live-CD und Shell. Der Vorgang ist, wie üblich bei dieser Distribution, gut dokumentiert [4]. Die folgende Anleitung beschränkt sich daher aufs Wesentliche. Nach dem Booten von der Live-DVD [5] legt der Admin die Partitionen an, am einfachsten ohne GPT: eine kleine Bootpartition (»/dev/sda1« ), dann »/dev/sda2« für den Rest.
Listing 1 zeigt die nächsten Schritte. Zeile 1 formatiert »/boot« als Ext 2. Zeile 2 erzeugt auf der anderen Partition ein Luks-verschlüsseltes Device. Die bei diesem Schritt erfragte Passphrase sollte stark gewählt sein, da von ihr die Sicherheit des künftigen Systems abhängt. Der Rechner wird beim Booten die Passphrase abfragen und nur dann, wenn sie korrekt ist, den ZFS-Pool öffnen.
Luks bietet übrigens die Möglichkeit, mehrere Passphrasen zu hinterlegen – beispielsweise eine Master-Passphrase für den Administrator und eine weitere für den täglichen Betrieb.
Im nächsten Schritt öffnet Luks mit der Passphrase das verschlüsselte Device. Zeile 4 legt nun auf dem Blockdevice einen ZFS-Pool an. Die verwendeten Optionen setzen die Sector Size [6], deaktivieren das Cachefile und mounten den neuen »rpool« -Pool Gentoo-konform vorläufig unter »/mnt/gentoo« . Der nächste Teil in Listing 1 legt auf dem ZFS-Pool ein Bündel einzelner Dateisysteme mit teils unterschiedlichen Eigenschaften an [7]. Das funktioniert mit ZFS-Funktionen.
Listing 1
System vorbereiten
01 mkfs.ext2 /dev/sda1 02 cryptsetup luksFormat -l 512 -c aes-xts-plain64 -h sha512 /dev/sda2 03 cryptsetup luksOpen /dev/sda2 cryptroot 04 zpool create -f -o ashift=12 -o cachefile= -m none -R /mnt/gentoo rpool /dev/mapper/cryptroot 05 06 zfs create -o mountpoint=none -o compression=on rpool/ROOT 07 # Rootfilesystem 08 zfs create -o mountpoint=/ rpool/ROOT/rootfs 09 zfs create -o mountpoint=/opt rpool/ROOT/rootfs/OPT 10 zfs create -o mountpoint=/usr rpool/ROOT/rootfs/USR 11 zfs create -o mountpoint=/var rpool/ROOT/rootfs/VAR 12 # Portage 13 zfs create -o mountpoint=none rpool/GENTOO 14 zfs create -o mountpoint=/usr/portage rpool/GENTOO/portage 15 zfs create -o mountpoint=/usr/portage/distfiles -o compression=off rpool/GENTOO/distfiles 16 zfs create -o mountpoint=/usr/portage/packages -o compression=off rpool/GENTOO/packages 17 # Home-Directorys 18 zfs create -o mountpoint=/home rpool/HOME 19 zfs create -o mountpoint=/root rpool/HOME/root 20 21 wget ftp://gentoo.osuosl.org/pub/gentoo/releases/amd64/autobuilds/current-stage3-amd64-hardened/stage3-amd64-hardened-*.tar.bz2 22 tar -xf /mnt/gentoo/stage3-amd64-hardened-*.tar.bz2 -C /mnt/gentoo 23 24 mkdir -p /mnt/gentoo/etc/zfs 25 cp /etc/zfs/zpool.cache /mnt/gentoo/etc/zfs/zpool.cache 26 cp /etc/zfs/zdev.conf /mnt/gentoo/etc/zfs/zdev.conf 27 mount -t proc none /mnt/gentoo/proc 28 mount --rbind /dev /mnt/gentoo/dev 29 chroot /mnt/gentoo /bin/bash 30 env-update 31 source /etc/profile 32 export PS1="(chroot) $PS1"
Tausendsassa ZFS
Statt die vorhandene Platte in Partitionen fixer Größe zu zerteilen, nutzt das Setup die Funktionalität von ZFS, den Speicherplatz als Pool zu verwalten. Der vorhandene Platz auf »/dev/sda2« stellt auch die Größe des ZFS-Pools namens »rpool« dar. Darin legt der Admin einzelne Dateisysteme für die verschiedenen Verzeichnisse von Gentoo Linux an, zum Teil mit abweichenden Eigenschaften (Properties), zum Beispiel mit transparenter Kompression. Dateien, die jemand dort hineinschreibt, komprimiert ZFS automatisch und transparent.
Die Gestaltung und Aufteilung in besagte Dateisysteme ist ein Vorschlag, den jeder Admin an eigene Gegebenheiten anpassen sollte. Dabei geht es darum, welche Features von ZFS in Form von Properties er für einzelne Bereiche anwenden möchte. Es ist möglich, Speicherplatz für den User Root zu reservieren (Property Reservation) oder für normal berechtigte User den maximalen Speicher zu beschränken (Property Quota). Für manche Bereiche wie die ohnehin komprimierten Tarballs der Gentoo-Packages in »/usr/portage/distfiles« ergibt es keinen Sinn, Rechenleistung auf Kompression zu verschwenden, daher steht die Property Compression hier auf »off« .
Weitere Properties sind das Freigeben von Dateisystemen per NFS und das platzsparende Deduplizieren von Blöcken – das benötigt allerdings RAM und andere Ressourcen, ist also für schwächere Maschinen nicht empfehlenswert. Besonders kritische Daten lassen sich mit der Property »copies« extra gut verwahren: ZFS speichert dann jeden Block mehrere Male. Sollte ein Block beim Lesen nicht mehr die ursprünglich errechnete Checksumme aufweisen, stehen die Kopien zur Verfügung, von denen sehr wahrscheinlich zumindest eine korrekt geblieben ist. Mit dem erhöhtem Speicherbedarf erkauft man sich Redundanz, ohne mehrere physische Datenträger verwenden zu müssen. (Die ZFS-Raid-Funktionalität benutzt dieser Artikel nicht.)
ZFS ist nicht nur Dateisystem, sondern auch Volume-Manager ähnlich wie LVM 2. Der Vorteil für den Anwender: Er muss nicht im Voraus genau planen, welche Directories wie viel Platz belegen, da er die Zuordnungen ohne Neupartitionierung nachträglich ändern kann.
ZFS-Pakete freischalten
Die nächsten Schritte sind Gentoo-üblich: Die Wget- und Tar-Befehle (Listing 1, Zeilen 21 und 22) entpacken ein so genanntes Stage3-Archiv ins neue System. Für die weiteren ist eine Chroot-Umgebung erforderlich. Der Bereich ab Zeile 24 sorgt für passende ZFS-Meta-Informationen und der Admin wechselt mit Chroot ins neue System. In dieser Umgebung installiert und konfiguriert er die weitere Software.
Die Gentoo-Entwickler stufen ZFS on Linux noch nicht als stabil ein. Daher muss man etliche Pakete gezielt erlauben (in Gentoo-Sprech: “unmasken”). Das betrifft auch SPL, den Solaris Porting Layer [8], eine Sammlung von Kernelmodulen, die Solaris-APIs unter Linux nachbilden, damit der unter Solaris entstandene ZFS-Code eine gewohnte Umgebung vorfindet. Daher umgeht ZFS on Linux einige Kernelfunktionen, die native Linux-Dateisysteme normalerweise nutzen. Das Unmasken der nötigen RC-Pakete gelingt durch die in Listing 2 genannten Einträge in der Datei »/etc/portage/package.accept_keywords« .
Beim Bootvorgang muss der Kernel selbstständig das Luks-Device öffnen. Dazu braucht er ein statisch kompiliertes Cryptsetup-Binary in seinem Initram-FS. Daher setzt Listing 3 in der »/etc/portage/package.use« -Datei für das Paket »sys-fs/cryptsetup« das Use-Flag »static« und noch ein paar weitere Flags für Pakete, von denen Cryptsetup abhängt.
Listing 2
package.accept_keywords
01 =sys-apps/openrc-0.11.1 ~amd64 02 =sys-kernel/genkernel-3.4.44.2 ~amd64 03 =sys-kernel/spl-0.6.0_rc11-r1 ~amd64 04 =sys-fs/zfs-kmod-0.6.0_rc11-r1 ~amd64 05 =sys-fs/zfs-0.6.0_rc11 ~amd64
Listing 3
package.use
01 #required by sys-fs/cryptsetup-1.4.1[static], required by sys-fs/cryptsetup (argument) 02 >=dev-libs/libgcrypt-1.5.0-r2 static-libs 03 #required by sys-fs/cryptsetup-1.4.1[static], required by sys-fs/cryptsetup (argument) 04 >=dev-libs/popt-1.16-r1 static-libs 05 #required by sys-fs/cryptsetup-1.4.1[static], required by sys-fs/cryptsetup (argument) 06 =sys-apps/util-linux-2.21.2 static-libs 07 #required by sys-fs/cryptsetup-1.4.1[static], required by sys-fs/cryptsetup (argument) 08 =dev-libs/libgpg-error-1.10 static-libs 09 10 sys-fs/cryptsetup static
Der Befehl in Zeile 1 von Listing 4 kompiliert und installiert Cryptsetup. Aktuell ist der Linux-Kernel 3.5.7 stabil, die Patches von Matthew Thode, die er für 3.5.0 gefertigt hat, lassen sich nach wie vor anwenden (Zeilen 2 bis 6).
An dieser Stelle ist es möglich, den Kernel an die eigene Hardware anzupassen.
Listing 4
Kernel installieren
01 emerge cryptsetup 02 emerge sys-kernel/genkernel 03 emerge sys-kernel/gentoo-sources 04 wget http://dev.gentoo.org/~prometheanfire/dist/kernel-patches/linux-3.5.0-gfp-vmalloc.patch -O - | patch -p1 -d /usr/src/linux 05 wget http://dev.gentoo.org/~ryao/dist/linux-3.5.0-zfs.patch -O - | patch -p1 -d /usr/src/linux 06 wget http://dev.gentoo.org/~prometheanfire/dist/kernel-patches/linux-3.5.0-zfs-builtin.patch -O - | patch -p1 -d /usr/src/linux 07 08 cd /usr/src/linux 09 zcat /proc/config.gz > .config 10 make oldconfig
Universal-Kernel zu Beginn
Doch im ersten Anlauf empfiehlt sich ein Kernel mit vielen Features, um ein garantiert lauffähiges System zu bekommen. (Einen generischen Kernel vorzuhalten lohnt auch, um bei Defekten auf anderer Hardware booten zu können.) Verlaufen erste Tests des künftigen Produktivsystems positiv, entfernt man nicht benötigte Treiber aus dem Kernel.
Dieser Artikel ist bei der Arbeit an einer virtuelle Maschine entstanden. (Sie ist zu finden auf der Delug-DVD dieser Ausgabe.) Um sie möglichst vielseitig einsetzen zu können, übernehmen die Zeilen 8 bis 10 (Listing 4) die Config des Kernels der Live-DVD. Jetzt geht es ans Konfigurieren des Kernels, etwa per »make menuconfig« . Wichtig ist, SPL und ZFS zu aktivieren (Abbildung 1).
Das Kompilieren und Linken dauert ein bisschen. Erfahrene Gentoo-User verkürzen die Zeit, indem sie zuvor die Variable »MAKEOPTS« in die »/etc/genkernel.conf« vorhandener CPU-Kerne setzen:
MAKEOPTS="-j3" # für zwei Cores
Ein »genkernel all« stößt nun den Compilerlauf an. Ebenso essenziell ist auch das Bauen des Initram-FS:
genkernel --luks --zfs --disklabel initramfs
Mit dessen Hilfe kann der Kernel beim Booten das Luks-Device öffnen und in der Folge den ZFS-Pool und die darin befindlichen Dateisysteme wie »/« , »/usr« , »/var« und so weiter.
Der folgende Befehl installiert das Paket »sys-fs/zfs« :
emerge sys-fs/zfs
Infolge der definierten Abhängigkeiten weiß das Gentoo-Portage-System, dass ZFS »sys-kernel/spl« benötigt, und installiert es automatisch mit. Die nächsten Zeilen sorgen dafür, dass der Service »zfs« in den relevanten Runlevels aktiv wird – der erste bewirkt den Start beim Booten, der zweite exportiert den Pool beim Shutdown:
rc-update add zfs boot rc-update add zfs-shutdown shutdown
Der Admin darf nicht vergessen das Root-Passwort mit »passwd« zu setzen. (Das Passwort der virtuellen Maschine auf der Delug-DVD lautet »gentoo« .)
Systemsetup abschließen
Die weitere Installation folgt dem Weg eines klassischen Gentoo-Setup, setzt also die Systemparameter und installiert die Basisservices wie Cron und Syslog-ng. Als Bootloader eignet sich die moderne Grub-Version 2.00 genauso wie die traditionelle. Der Einfachheit halber soll hier Grub 0.97 zum Einsatz kommen:
emerge grub mount /dev/sda1 /boot grub-install /dev/sda
Die Konfigurationsdatei »/boot/grub/grub.conf« in Listing 5 beinhaltet Kerneloptionen, die den verschlüsselten ZFS-on-Linux-Pool korrekt öffnen.
Um das System fertig für den ersten eigenständigen Bootvorgang zu machen, editiert der Admin die »/etc/fstab« . Entgegen üblichen Konventionen kommentiert er hier die Zeilen für »BOOT« , »ROOT« und »SWAP« aus, da der ZFS-Pool die Zuweisung erledigen wird. Die Befehle
exit cd zfs umount -a
verlassen die Chroot-Umgebung und hängen die Dateisysteme aus.
Listing 5
grub.conf
01 default 1 02 timeout 2 03 04 title Gentoo Linux 3.5.7 05 root (hd0,0) 06 kernel /kernel-genkernel-x86_64-3.5.7-gentoo real_root=ZFS=rpool/ROOT/rootfs crypt_root=/dev/sda2 dozfs=force ro 07 initrd /initramfs-genkernel-x86_64-3.5.7-gentoo
Mountpoint präparieren
Der letzte Schritt der recht umfangreichen Anleitung passt die Eigenschaft des Pool-Mountpoints an. In der Installationsumgebung war der Pool ja an »/mnt/gentoo« gemountet, in dem Produktivsystem soll dies natürlich an »/« geschehen:
zfs set mountpoint=/ rpool
Zum Schluss: die restlichen Dateisysteme aushängen, den ZFS-Pool exportieren:
umount -l /mnt/gentoo/dev{/shm,/pts}
umount -l /mnt/gentoo{/boot,/proc}
zpool export rpool
Ein Neustart des PC oder Notebooks ohne die Live-CD zeigt den Erfolg der Mühen. Ist alles korrekt verlaufen, fragt das bootende Gentoo nach der Passphrase des Luks-Device. Bei korrekter Angabe startet der Rechner vom entschlüsselten ZFS-Pool. Wer mag, kann nun mit »zfs list« die neue Umgebung anschauen.
Troubleshooting und der Umgang mit Updates
Bei einer komplexen Installation wie dieser passieren Fehler. Das Reparieren eines verschlüsselten Systems per Live-Medium gestaltet sich etwas komplizierter als bei einem gängigen Linux. Zuerst bootet der Admin von der Gentoo-Live-DVD oder einem anderen 64-Bit-Live-Medium, das ZFS mitbringt. Dann öffnet er per Cryptsetup das Luks-Device:
cryptsetup luksOpen /dev/sda2 cryptroot
Das Öffnen des ZFS-Pools heißt in der ZFS-Terminologie »import« . Gleich passiert dies mit den Optionen »-fN« , was einerseits die Host-ID ignoriert und andererseits den Automount unterbindet:
zpool import -fN rpool
Die folgenden Kommandos mounten das System wie bei der Installation an »/mnt/gentoo« und hängen die restlichen ZFS-Filesysteme unter dieser Hierarchie ein:
zfs set mountpoint=/mnt/gentoo rpool zfs mount rpool/ROOT zfs mount -a
Ab hier vollführt der Admin die bekannte Chroot-Prozedur und kann dann das System reparieren. Vor einem neuerlichen Bootversuch darf er das Anpassen des Mountpoints per »zfs set mountpoint=/ rpool« nicht versäumen.
Wegen der teils irregulären SPL- und ZFS-Kernelpatches erfordern künftige Updates oder Upgrades etwas Aufmerksamkeit. Beim Eintreffen neuer Kernelversionen passiert das Patchen und Kompilieren einfach im laufenden System. Wie bei anderen Distributionen auch empfiehlt es sich, einen gut funktionierenden Kernel im System zu behalten, bis der neue keinen Anlass zu Klagen mehr bietet.
Performance und Fazit
Anwender von Truecrypt & Co. wissen, dass eine durchgängige Verschlüsselung beim Lesen und Schreiben vieler kleiner Dateien die Performance beeinträchtigen kann. Darum lohnt es sich, die Datenübertragungsraten des Testsystems für diesen Artikel zu betrachten. Analog zu früheren Performancetests im Linux-Magazin [9] lautet der Benchmark-Aufruf auch hier:
iozone -r 4k -s 4g -i0 -i1
Die Gesamtgröße 4 GByte ist der Größe der Testumgebung in der virtuellen Maschine angepasst. Abbildung 2 zeigt den direkten Vergleich zwischen einer mit Ext 4 aufgesetzten Gentoo-Installation und dem gezeigten ZoL-Luks-Setup.
Die gemessenen Performance-Vor- und -Nachteile in einzelnen Disziplinen sollte man nicht überinterpretieren: Zum einen neigen Messungen in virtuellen Maschinen zu Fehlern. Zum zweiten arbeiten in modernen Laptops vielfach performante SSDs und drittens ist der Desktopbetrieb von deutlich mehr Lese- als von Schreibvorgängen gekennzeichnet.
Unterm Strich legen die Erfahrungen aus diesem Artikel nahe, dass sich vom Verlust bedrohte Rechner mit etwas Aufwand im Ganzen gut verschlüsseln lassen. Das sehr moderne Setup arbeitet für den Anwender und den zuständigen Admin transparent. Ob man den Arbeitsaufwand investieren will, lässt sich daran messen, was die eigenen Daten in den Händen Fremder bedeuten.
Infos
- Ponemon Institute, “Business Risk of a Lost Laptop: A Study of IT Practitioners in the US, UK, Germany, France, Mexico and Brazil”, April 2009: http://www.ponemon.org/local/upload/fckjail/generalcontent/18/file/The%20Business%20Risk%20of%20a%20Lost%20Laptop%20(Global)%20Final%204.pdf
- ZFN on Linux: http://zfsonlinux.org
- Matthew Thode, “Gentoo Hardened ZFS rootfs with dm-crypt/luks”: http://blog.mthode.org/gentoo-hardened-zfs-rootfs-with-dm-cryptluks/
- Anleitung zum Installieren von Gentoo: http://www.gentoo.org/doc/de/handbook/handbook-amd64.xml
- Gentoo Live-DVD: http://www.gentoo.org/news/20120401-livedvd.xml, http://bouncer.gentoo.org/fetch/gentoo-12.1-livedvd/amd64/
- “How does ZFS on Linux handles Advanced Format disks?”: http://zfsonlinux.org/faq.html#HowDoes-ZFSonLinuxHandlesAdvacedFormatDrives
- Anleitung für Gentoo-Installation direkt in ein ZFS-Root-Filesystem: https://github.com/pendor/gentoo-zfs-install/blob/master/install/GentooInstall.mdown
- Solaris Porting Layer: https://github.com/zfsonlinux/spl
- Hans-Peter Merkel, Markus Feilner, “Erste Begegnung zwischen dem Linux-Kernel und ZFS”: Linux-Magazin 02/11, S. 86







