Dm-crypt

Aus wiki.archlinux.de

Festplatte verschlüsseln

Eine komplett verschlüsselte Festplatte kann in vielen Fällen sinnvoll sein. Zum Beispiel kann es sehr schnell passieren, dass der private Laptop mit den privaten Daten irgendwo liegen gelassen oder geklaut wird. In solchen Fällen ist es immer besser, wenn niemand auf die Daten zugreifen kann.

Für alle folgenden Schritte wird keine Haftung übernommen! Es wird empfohlen, vorher ein komplettes Backup aller wichtigen Daten zu erstellen.


Partitionslayout festlegen

Die Festplatte (in meinem Fall /dev/sda) sollte für alle folgenden Schritte folgendermaßen partitioniert sein:

  /dev/sda1 -> /boot (32-64MB, bis zu 100MB)
  /dev/sda2 -> swap (je nach Größe des Arbeitsspeichers, 1,2 x Arbeitsspeicher)
  /dev/sda3 -> / (10-15GB, ggf. 20?)
  /dev/sda4 -> /home

Die Größe der einzelnen Partitionen kann variieren.


Crypto-Devices anlegen

Das Ver- und Entschlüsseln wird über das Kryptographie-Modul des Devicemappers des Kernels abgewickelt. Dieser stellt uns ein virtuelles Device zu Verfügung, über das auf die verschlüsselten Partitionen zugegriffen werden kann. Den Verschlüsselungsalgorithmus, die Größe des Schlüssels und viele weitere Dinge die die Verschlüsselung beeinflussen, können selber festgelegt werden. Nähere Informationen zu den verfügbaren Parametern gibt es hier auf der Seite von dm-crypt [1] Informationen über die Geschwindigkeit der einzelnen Algorithmen gibt es hier [2] übersichtlich dargestellt. Für die folgenden Verschlüsselung wurde der AES-Algorithmus mit SHA-256 als Hash und mit einer Schlüssellänge von 256 Bit gewählt.

Anlegen des Crypto-Devices:

  # cryptsetup luksFormat /dev/sda3 --cipher aes-cbc-essiv:sha256 --verify-passphrase --key-size 256
  -> Passwort zweimal eingeben. 
  ACHTUNG: Das Passwort sollte ausreichend lang sein, also mindestens 16 stellig.

Hinweis: Da das Passwort während des Bootvorgangs abgefragt wird steht noch keine deutsche Tastaturbelegung zur Verfügung. Es stehen also keine Umlaute (ä;ö;ü;ß) zur Verfügung und Sonderzeichen sowie y und z befinden sich auf anderen Tasten. Um Probleme zu vermeiden sollte das Passwort mit der amerikanischen Tastaturbelegung erstellt werden.

Öffnen des eben erstellten Crypto-Devices:

  # mkdir /mnt/root
  # cryptsetup luksOpen /dev/sda3 root
  -> Passwort eingeben

Formatieren und mounten der Partition:

  # mke2fs -j /dev/mapper/root (mit ext3)
  # mount /dev/mapper/root /mnt/root

Für die home-Partition wollen wir kein extra Passwort verwenden, sondern ein Keyfile, damit wir nicht bei jedem Start des Systems zwei Passwörter eingeben müssen. Das Keyfile für die Home-Partition legen wir in /crypto/home.key ab. Allerdings ist es sehr wichtig dieses Keyfile zu sichern. Sollte die Root-Partition einmal beschädigt und nicht wiederherstellbar sein, ist die Home-Partition mit allen Daten ebenfalls verloren. Eine andere Möglichkeit wäre es auch hier eine 16-stelliges Passwort zu benutzen, dieses in der /etc/crypttab anzugeben und es an einem sehr sicheren Ort aufzubewahren. So muss das Passwort nicht auf einem physikalischen Datenträger abgelegt werden. Man kann es sich entweder merken oder z.B. in einem Bankschließfach ablegen ;)

Das Keyfile erstellen wir uns zufällig, indem wir einen 2048 Byte großen Block aus /dev/urandom kopieren.

  # mkdir /mnt/root/crypto
  # dd if=/dev/urandom of=/mnt/root/crypto/home.key bs=1k count=2

Anlegen des Crypto-Devices:

  # cryptsetup luksFormat /dev/sda4 /mnt/root/crypto/home.key --cipher aes-cbc-essiv:sha256 --key-size 256
  # cryptsetup luksOpen /dev/sda4 home --key-file /mnt/root/crypto/home.key

Formatieren und mounten der Partition:

  # mke2fs -j /dev/mapper/home (mit ext3)
  # mkdir /mnt/root/home
  # mount /dev/mapper/home /mnt/root/home


ArchLinux installieren

Zuerst müssen wir noch unsere Boot-Partition erstellen und mounten.

  # mke2fs /dev/sda1
  # mkdir /mnt/root/boot
  # mount /dev/sda1 /mnt/root/boot

Um eine Verbindung zum Internet aufbauen zu können, muss eine IP-adresse beim Router angefragt werden.

  # dhcpcd eth0

Jetzt kopieren wir alle wichtigen Dateien für das System in unsere verschlüsselte root-Partition.

  # /arch/quickinst ftp /mnt/root ftp://ftp.archlinux.org/current/os/i686

bzw.

  # /arch/quickinst ftp /mnt/root ftp://ftp.archlinux.org/current/os/x86_64

Nun brauchen wir für das neue System auch noch einen Kernel.

  # /mnt/root/usr/bin/pacman.static -r /mnt/root --config /tmp/pacman.conf -S kernel26

Und damit wir das System nachher auch bequem starten können einen Bootloader, in diesem Fall nehmen wir Grub.

Zuerst mounten wir alle wichtigen Systemverzeichnisse,

  # mount -o bind /dev /mnt/root/dev
  # mount -o bind /proc /mnt/root/proc
  # mount -o bind /sys /mnt/root/sys

und wechseln mit chroot das Root-Verzeichnis.

  # chroot /mnt/root /bin/bash

Schnell Grub installieren.

  # install-grub /dev/sda /dev/sda1

Und /boot/grub/menu.lst anpassen:

  # (0) Arch Linux
  title  Arch Linux
  root   (hd0,0)
  kernel /vmlinuz26 root=/dev/sda3
  initrd /kernel26.img

Damit dürfte das System im Prinzip schon einsatzbereit sein. Das initrd-image erkennt automatisch die verschlüsselte Partition und fragt nach dem Passwort. Sollte das nicht der Fall sein, muss noch mit mkinitcpio ein neues initrd-image erstellt werden, welches den hook für "encrypt" enthält. Dieser hook sollte in jedem Fall vor "filesystem" stehen. Dazu die Konfigurationsdatei /etc/mkinitcpio.conf bearbeiten und mit dem Befehl mkinitcpio das neue Image erzeugen.

Den hook encrypt einfügen.

  # nano /etc/mkinitcpio.conf

und dann das Image neu schreiben.

  # mkinitcpio -g /boot/kernel26.img
  • ACHTUNG: Sollte der seltene Fall eintreten, dass sich während des Installationsprozesses die Kernel-Version im Repository ändert, z.B. weil der Kernel auf dem Installationsmedium älter ist (wie 2.6.24 anstatt 2.6.25) und man sich aber online die aktuellen Packages besorgt hat, kommt es zu Problemen beim Erstellen des neuen initrd-Images, weil nicht alle entsprechenden Treiber gefunden werden (wie die für die Verschlüsselung)! Abhilfe schafft ein
  # mkinitcpio -k 2.6.25-ARCH -p kernel26 -g /boot/kernel26.img

in der chroot-Umgebung: -k für den neuen Kernel (hier 2.6.25) und -p damit u.a. auch ein Fallback erstellt wird; nähere Infos siehe manpage.

Um später zum gewohnten

  # mkinitcpio -g /boot/kernel26.img

zurückzukommen, muss der Kernel irgendwann im laufenden System nochmal installiert werden.


Konfiguration anpassen

Zunächst tragen wir erstmal die Boot und die Root Partition in die /etc/fstab ein.

# <file system>         <dir>      <type>   <options>     <dump> <pass>
  /dev/sda1                    /boot      ext2        defaults      0       0
  /dev/mapper/root        /             ext3        defaults      0       0

Damit unser System auch die Home-Partition korrekt einbindet und die Swap-Partition bei jedem Start mit einem neuen zufälligen Schlüssel verschlüsselt, müssen wir noch folgendes machen.

Home-Partition

Zuerst öffnen wir /etc/crypttab und tragen unsere Home-Partition samt Schlüssel, der ja auf der Root-Partition in /crypto/home.key liegt, ein.

  # NAME        SOURCE DEVICE      PASSWORD          OPTIONS
  home          /dev/sda4          /crypto/home.key
  ....

Damit wird bei jedem Systemstart die Home-Partition automatisch geöffnet. Jetzt können wir /dev/mapper/home ganz normal in unsere fstab-Datei eintragen, damit /home auch korrekt gemountet wird.

  # <file system>         <dir>      <type>   <options>     <dump> <pass>
  /dev/mapper/home      /home      ext3     defaults      0       0

Swap Partition

Auch die Swap Partition tragen wir in die /etc/crypttab ein.

  • Achtung: unbedingt darauf achten, dass hier das richtige Device angegeben wird, da sonst Datenverlust droht!
# NAME          SOURCE DEVICE           PASSWORD                OPTIONS
swap               /dev/sda2                      SWAP                       -c aes-cbc-essiv:sha256 -s 256

Jetzt müssen wir nur noch /dev/mapper/swap in die fstab Datei eintragen.

# <file system>         <dir>      <type>   <options>     <dump> <pass>
/dev/mapper/swap        none       swap          sw                0       0


Aufräumen & Neustarten

Zum Schluss müssen wir nur noch chroot mit Strg+d verlassen alle Partitionen wieder unmounten und die Crypto-Container schließen.

  # umount /mnt/root/boot /mnt/root/home 
  # umount -l /mnt/root
  # cryptsetup luksClose root
  # cryptsetup luksClose home
  # rm -r /mnt/root

Jetzt braucht es nur noch einen Restart und es sollte ein komplett verschlüsseltes ArchLinux starten ;)

  # shutdown -r now


System per USB-Stick entschlüsseln

Wer nicht jedesmal beim Booten das LUKS Passwort für die root Partition eingeben will kann auch ein Keyfile auf einem USB-Stick speichern. Wenn der Stick beim Booten eingesteckt ist wird das System automatisch aufgeschlossen. Es gibt zwei Möglichkeiten den Key auf dem Stick zu speichern. Als einfache (sichtbare) klartext Datei, oder zwischen dem MBR und der ersten Partition des Sticks.

Vorbereitungen

Bei beiden Methoden muss zunächst erstmal eine Udev Regel für den Stick erstellt werden. Wie das geht wird hier beschrieben. Ab jetzt wird angenommen, dass die Udev Regel den Stick usbstick nennt und die erste Partition des Sticks usbstick1.

Jetzt erstellt man ein Keyfile und speichert es auf dem USB-Stick. Soll das Keyfile als klartext Datei gespeichert werden, darf der Name keine Sonderzeichen, Punkte (versteckte Dateien) etc. enthalten, da der encrypt HOOK die Datei sonst beim Booten nicht findet.

USB-Stick mounten

mkdir /mnt/usb-stick
mount /dev/usbstick1 /mnt/usb-stick

Keyfile erstellen und auf dem Stick speichern.

dd if=/dev/urandom of=/mnt/usb-stick/archkey bs=512 count=4

Jetzt kann das Keyfile zu den Schlüsseln für die root Partition (hier /dev/sda3) hinzugefügt werden. Das alte LUKS Passwort sollte man nicht löschen. Falls das Keyfile mal verloren geht, oder das Entschlüsseln per USB-Stick nicht auf Anhieb funktioniert, kommt man immer noch ins System.

cryptsetup LuksAddKey /dev/sda3 /home/user/archkey

/dev/sda3 gegebenen Falls anpassen...

Als nächstes wird die /etc/mkinitcpio.conf angepasst. Die Udev-Regel wird in die FILES="" Zeile eingetragen und zu den HOOKS usb hinzugefügt (vor encrypt).

FILES="/etc/udev/rules.d/50-myusb.rules"
HOOKS="... usb encrypt filesystems ..."

Soll das Keyfile als klartext Datei gespeichert werden, müssen noch zwei Module zur MODULES="" Zeile hinzugefügt werden. Eins für das Dateisystem des Sticks (hier vfat) und eins für die Codepage

MODULES="ata_generic ata_piix nls_cp437 vfat"

Die Module für das Dateisystem und die Codepage müssen durch die passenden ersetzt werden, falls der USB-Stick ein anderes Dateisystem hat (z.B. ext2). Benutzer des Arch-stock Kernels sollten die hier genannte Codepage verwenden.

Jetzt kann das neue initrd-image erstellt werden. (evtl. das alte vorher sichern)

mkinitcpio -p kernel26

Schlüssel als klartext Datei speichern

Da das Keyfile ja bereits auf dem Stick existiert, muss nur noch die kernel Zeile in der menu.lst (GRUB) angepasst werden.

kernel /vmlinuz26 root=/dev/sda3 ro vga=771 cryptkey=/dev/usbstick1:vfat:/archkey

/dev/usbstick1 ist dabei die FAT Partition mit dem Keyfile.

Wenn alles geklappt hat, sollte Das System beim nächsten Booten automatisch aufgeschlossen werden. Vorausgesetzt der USB-Stick ist eingesteckt. ;-)

Schlüssel zwischen MBR und erster Partition speichern

  • ACHTUNG: man sollte das hier nur machen wenn man weiss was man tut. Es kann zu Datenverlust kommen und die Partitionen oder der MBR des Sticks beschädigt werden.

Sollte auf dem Stick ein Bootloader installiert sein müssen einige Werte angepasst werden. GRUB braucht z. B. die ersten 16 Sektoren. Man müsste also seek=4 durch seek=16 ersetzen. Andernfalls würden Teile von GRUB überschrieben werden. Im Zweifelsfall kann man sich die ersten 64 Sektoren anschauen und nach einem genügend großen freien Bereich suchen.

dd if=/dev/usbstick of=64sectors bs=512 count=64   # kopiert die ersten 64 Sektoren
hexcurse 64sectors                                                      # freien Platz suchen

Den Schlüssel auf den Stick schreiben.

dd if=/mnt/usb-stick/archkey of=/dev/usbstick bs=512 seek=4

Wenn das geklappt hat kann das (klartext) Keyfile vom Stick gelöscht werden.

shred --remove --zero /mnt/usb-stick/archkey

Jetzt muss noch die kernel Zeile in der menu.lst (GRUB) Datei angepasst werden.

kernel /vmlinuz26 root=/dev/sda3 ro vga=771 cryptkey=cryptkey=/dev/usbstick:2048:2048

Das Format für die cryptkey Option sieht so aus:

cryptkey=BLOCKDEVICE:OFFSET:SIZE

Die Werte für OFFSET und SIZE passen für dieses Beispiel, da das Keyfile die Länge 2048 hat (bs=512 count=4), und ab OFFSET 2048 (bs=512 seek=4) auf dem Stick gespeichert ist. Gegebenen Falls müssen die Werte angepasst werden.

Das wars, wenn alles geklappt hat, sollte Das System beim nächsten Booten automatisch aufgeschlossen werden. Vorausgesetzt der USB-Stick ist eingesteckt. ;-)


Padlock Fehlermeldung

FATAL: Error inserting padlock_aes (/lib/modules/2.6.24-ARCH/kernel/drivers/crypto/padlock-aes.ko): No such device

Wenn diese Fehlermeldung beim Booten erscheint, ist das nicht weiter schlimm. Die padlock Module bedienen wohl Entschlüsselungs-Hardware (z.B. Fingerabdruck-Scanner o.ä.), was wohl die wenigsten zur Verfügung haben.

Versucht zu laden werden die Module an zwei Stellen:

a) in der initrd
b) durch udev

Um die Meldung weg zu bekommen kan mann folgendes machen:

a)
Der encrypt-Hook bewirkt beim Erstellen des initrd-Images das alle Module die in Verzeich- nissen namens crypto liegen eingebunden und versucht zu laden werden. Das kann man steuern durch den Parameter CRYPTO_MODULES in der /etc/mkinitcpio.conf ähnlich des MODULES Parameters dort. D.h., man muß alle Crypto-Module, die zum Aufschließen der verschlüsselten Root-Partition nötig sind, dort explizit aufführen da der encrypt-Hook diese nicht mehr automatisch einfügt. Die benötigten Module kann man durch lsmod im laufenden System finden. Wer seine crypto-Module anhand des Namens nicht eindeutig identifizieren kann findet sie auf diesem Weg:

cd /lib/modules/$(uname -r)
source /lib/initcpio/functions 
m="$(all_modules "/crypto/") "
echo $m

Diese Module würde der encrypt-Hook automatisch einbinden (darunter auch die padlock). Zum Abgleich mit den eigenen Modulen jetzt einfach lsmod mit dieser Liste vergleichen.

Der nötige Eintrag in der /etc/mkinitcpio.conf kann z.B. so aussehen:

CRYPTO_MODULES="blowfish sha256_generic aes_i586 aes_generic"

Jetzt noch das initrd-Image erstellen(als root):

mkinitcpio -g /boot/kernel26.img

b)
Damit das Modul durch udev nicht versucht wird zu laden. Es reicht nicht (bzw. hat keine Auswirkung) die Module in der rc.conf mit ! vom Laden ausschließen zu wollen. Erst das explizite Blacklisten bei udev führte bei mir zum Erfolg. AlsoDatei /etc/modprobe.conf editieren

blacklist padlock-aes
blacklist padlock-sha

Nachtrag: Durch das Update auf 2.6.27 hat sich bei den notwendigen CRYPTO_MODULES wieder einiges geändert. Ich konnte meinen Laptop erstmal nicht normal starten, da in meinen vorgegebenen Modulen welche fehlten. Um das (und das padlock-Problem zu umgehen) habe ich nun die CRYPTO_MODULES Zeile wieder rausgenommen und habe einfach die Module selbst in lib/modules/2.6.27-ARCH/kernel/drivers/crypto/padlock-* gelöscht. Dann das initrd neu erstellt. Somit taucht diese Meldung ebenfalls nicht mehr auf (ich verwende nie eine Hardware für das ich dieses padlock brauchen würde).

lrw-benbi

Wer wie im US-Arch-Wiki mit lrw-benbi verschlüsseln will, muss ebenso die /etc/mkinitcpio.conf anpassen:

CRYPTO_MODULES="blowfish lrw sha256_generic aes_i586 aes_generic"


Links

Verschlüsseltes Verzeichnis