In diesem Artikel möchte ich mal ein kleines How-To schreiben wie ich meine Festplatte über einen Schlüssel auf einem USB-Key während des Bootens entschlüssele. Den Schlüssel für die verschlüsselte Festplatte auf einem USB-Key zu haben hat natürlich Vor- und Nachteile. Natürlich ist es eine Gefährdung für die Sicherheit, da jeder, der an den Stick drankommt auch an den Schlüssel kommt. Wenn man es schafft diese Gefahr zu reduzieren, bietet der Schlüssel einige Vorteile in der Bequemlichkeit. Man muss kein Passwort eintippen und die Festplatte wird “automatisch” entsperrt. Außerdem kommt man über einen Hardware-Keylogger nicht an das Passwort heran (jedoch ist das eher theoretischer Natur).
Ich setze nun folgendes Voraus: Es ist bereits eine verschlüsselte Partition über Cryptsetup angelegt und einer der Keyslots ist mit einem in einer Datei gespeicherten Schlüssel gefüllt. Außerdem ist der Boot-Vorgang so eingerichtet, dass von einer verschlüsselten Root-Partition gestartet wird.
Nun sollte man als erstes den USB-Stick als ext2 formatieren. Das hat zwei Vorteile: 1. man braucht keine Treiber für fat in die initrd integrieren. 2. sollte jemand mal aus Versehen an den Stick kommen, funktioniert er nicht unter Windows 😉
An der Stelle könnte man sich auch gleich die UUID des USB-Keys ausgeben lassen.
So nun kommen wir zum Kernstück des ganzen Vorhabens. Wir schreiben ein Skript welches das Passwort aus einer Datei auf dem USB-Stick liest und Cryptsetup zuführt. Cryptsetup unterstützt einen solchen Mode: es kann ein Skript angegeben werden, welches das Passwort zufüttert. Dabei ist es wichtig, dass JEDE Ausgabe des Skripts an Cryptsetup weitergegeben wird. Deshalb muss man alle Ausgaben auf stderr umleiten.
Mein Skript:
#!/bin/sh
modprobe usb-storage 1>&2
sleep 5
mkdir /usb 1>2&
mount -t ext2 /dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /usb 1>2&
sleep 5
cat /usb/root.key
umount /usb 1>2&
Wir sehen, dass Skript lädt als erstes das Treiber-Modul für USB-Sticks. Danach geben wir über den sleep dem System Zeit den Stick zu erkennen. Nun erzeugen wir den Mountpoint und binden den Stick ein. Erneut geben wir dem System etwas Zeit (hier kann man natürlich etwas herumspielen und die Zeit verkürzen). Nun geben wir einfach den Inhalt des gespeicherten Schlüssels aus und unmounten den Stick wieder. Beim Starten wird uns das ganze dann durch eine Success-Meldung angezeigt. An dieser Stelle kann man den Stick auch ohne Probleme wieder abziehen.
Nun müssen wir noch dem Cryptsetup mitteilen, dass wir ein Skript verwenden wollen. Dazu bearbeiten wir /etc/crypttab:
# target name|source device|key file|options
root /dev/vg1/vol1 none luks,retry=1,cipher=aes-cbc-essiv:sha256,keyscript=/path/to/keyscript
Wir sehen, dass entscheidende ist, dass bei “key file” “none” angegeben ist und bei den Optionen ein “keyscript=/path/to/keyscript” hinzukommt. Wenn man nun eine neue initrd erstellt, wird das Skript mit eingearbeitet.
Nun fehlt noch eins: die initrd braucht auch sämtliche Module um den USB-Stick überhaupt einbinden zu können. Sonst hat man ein Henne-Ei Problem. Der Treiber für den USB-Stick liegt im verschlüsselten System und um das System zu entschlüsseln, braucht man den Treiber. Dazu bearbeitet man die Datei /etc/initramfs-tools/modules. Hier müssen alle Module aufgelistet werden, die man braucht um den USB-Stick einzubinden. Da ich jetzt nicht genau weiß, welche es zwingen sind, gib ich mal meine komplette Datei an:
aes-x86_64
dm-crypt
dm-mod
sha256
sd_mod
usb_storage
usb-storage
ehci_hcd
ohci_hcd
Wenn ich jetzt nichts wichtiges vergessen habe, sollte man nun die initrd neue erzeugen können. Dies macht man über:
update-initramfs -u
Wichtig: erst mal nur die initrd für den aktuellen Kernel bearbeiten. Falls etwas nicht klappt, möchte man ja zumindest noch mit einem alten Kernel ein startfähiges System haben 😉
Nun ist der Zeitpunkt das ganze auszuprobieren. Reboot 🙂