Posts Tagged “luks”

While installing gentoo on my laptop, I had to switch over and use initramfs as I want full disk encryption.
Dracut provides a module which can load gpg encrypted keys and open a LUKS encrypted disk. This is nice, but it requires manual setup.
As I always forget about such things, I went on and implemented a small but easy to use auto-detection for LUKS encrypted volumes.
The script checks /boot/.luks for key-files named <VOLUME UUID>[.gpg] for each LUKS Device found in fstab. if found, it adds a entry to /etc/cmdline.
The patch is simple and consistent with how dracut deals with UUIDS (which is rather odd, they use udev to get the UUID instead using blkid. No idea why).

Patch for the crypt-module in /usr/lib/dracut/modules/90crypt (if using gpg-encrypted files, you need add crypt-gpg to the modules list in /etc/dracut.conf or you won’t be able to open your key on boot!)

--- module-setup.sh.orig	2012-02-24 15:38:08.000000000 +0100
+++ module-setup.sh	2012-03-29 00:24:49.997233979 +0200
@@ -22,6 +22,23 @@
         [[ ${ID_FS_UUID} ]] || return 1
         if ! [[ $kernel_only ]]; then
             echo " rd.luks.uuid=luks-${ID_FS_UUID} " >> "${initdir}/etc/cmdline.d/90crypt.conf"
+	    # look for keyfiles in $luks_key_dir (default:/boot/.luks).
+	    # Keys must be named ${ID_FS_UUID} or {ID_FS_UUID}.gpg
+	    # you need add the crypt-gpg modules to the list of additional modules to have gpg keys work.
+	    local keydir=${luks_key_dir-/boot/.luks}
+	    local keyfile=${keydir}/${ID_FS_UUID}
+	    # check for keyfile. if none try add .gpg
+	    [[ -f ${keyfile} ]] || keyfile=${keyfile}.gpg
+	    [[ -f ${keyfile} ]] || return 1
+            ID_KEY_UUID=$(udevadm info --query=property --name=$(readlink -f "/dev/block/$(find_block_device "/boot")") \
+                | while read line; do
+                    [[ ${line#ID_FS_UUID} = $line ]] && continue
+                    eval "$line"
+                    echo $ID_FS_UUID
+                    break
+                    done)
+	    [[ ${ID_KEY_UUID} ]] || return 1
+            echo " rd.luks.key=${keyfile}:UUID=${ID_KEY_UUID}:UUID=${ID_FS_UUID} " >> "${initdir}/etc/cmdline.d/90crypt.conf"
         fi
         return 0
     }
@@ -29,7 +46,7 @@this
     [[ $hostonly ]] || [[ $mount_needs ]] && {
         for_each_host_dev_fs check_crypt || return 1
     }
-
+    ddebug < ${initdir}/etc/cmdline.d/90crypt.conf
     return 0
 }

The path to the key-directory can be configured in /etc/dracut.conf

# location of keys.
# keys must be named {FSUUID} or {FSUUID}.gpg where FSUUID is the luks-device (not the key device!)
# for example "5b1049c3-ae7c-4b4c-99e7-240ba4a76f94" or "5b1049c3-ae7c-4b4c-99e7-240ba4a76f94.gpg".
#luks_key_dir="/boot/.luks"

dracut-crypt-gpg-extension.patch

anyone knows how to disable that stupid file extension filter in wordpress? simply rename .patch to .patch.txt is enough. This is just stupid in a single user setup as mine.

To answer a question in the comments, if one is paranoid and does not trust the boot partition (which has to be world readable), there are 2 ways to solve this:

  1. Use external boot volumes. Just put everything on a USB-Stick or a SD-Card. Just keep this with you all the time (or hide it in a secure location)
  2. use SATA full decryption (requires BIOS support). This allows to encrypt the disk fully without any LUKS and alike. The BIOS/Disk is responsible for doing all the stuff. This is transparent to linux, it does not even know the disk is encrypted. However, this requires HArdware support, and you have to Trust your Harddisk Vendor to implement the encryption correct (and not insert any backdoors).

Flattr this!

Comments 1 Comment »

Auf meinem neuen rootserver wollte ich die Root-Partition LUKS-verschlüsseln.
Debian unterstützt dieses vorgehen fast ohne manuelle eingriffe, wobei ein paar Details zu beachten sind.

In meinem Fall sind die beiden 3TB Festplatten in 2 Partitionen unterteilt, einmal eine kleine (1GB) /boot partition und eine LUKS-verschlüsselte LVM für alles andere.
Das LVM erlaubt es mir, Partitionen einfach anzupassen wenn es irgendwo knapp wird (die betrifft vor allem die Home-partitionen).
Das setup habe ich vor dem installieren aus dem rescue-system meines ISPs eingerichtet, die Anleitung im Debian-Handbuch ist dabei hilfreich (suche nach debootstrap).

Das Problem mit LUKS ist, dass das Passwort/Keyfile im initramfs vorhanden sein muss, sonst kann die HD nicht entschlüsselt werden. Normalerweise fragt das initramfs beim booten nach dem Passwort, was aber bei einem headless rootserver im Rechenzentrum nicht geht.
Der Trick besteht darin, einen ssh-server ins initramfs einzubauen, und den key dann über ein keyscript an cryptsetup weiterzureichen. Der normale openssh ist dafür etwas zu gross, daher verwende ich den dropbear sshd. Dieser ist Bestandteil vieler busybox-installationen auf (zum Beispiel) Routern und das von debian verwendete update-initramfs-script benützt es automatisch wenn eine verschlüsselte root-partition gefunden wird (man kann es aber auch in /usr/share/initramfs-tools/conf-hooks/dropbear erzwingen).

Dann muss man noch die /etc/crypttab anpassen.

md1_crypt /dev/md1 none luks,tries=0,keyscript=/lib/cryptsetup/keyscript

Den Key auf “none” setzten; tries=0 erzwingt ewiges warten im initramfs bis das keyscript den korrekten Key liefert.
Das Keyscript prüft ob der key existiert, und falls ja gibt es ihn zurück

if [ -f /lib/cryptsetup/passfifo ]; then
    cat /lib/cryptsetup/passfifo
fi

Das Keyscript wird am einfachsten auf dem host in /lib/cryptsetup/ abgelegt, damit die initramfs-tools es automatisch finden.

Um einfach einzuloggen (ohne passwort) ist es ratsam, den eigenen public key in /etc/initramfs-tools/root/.ssh/authorized-keys anzugeben. Falls die Datei nicht existiert erzeugt initramfs ein eigenes Key-paar, und hinterlegt es im initramfs (schlechte Idee).

Damit ist man fast fertig. Erhält der Server seine IP per DHCP, kann man das interface einfach in /etc/initramfs-tools/initramfs.conf als DEVICE angeben. Will man eine statische öffentliche IP vergeben, so muss man die parameter als kernel-boot-parameter übergeben. In meinem Fall (Grub2, hetzner setup) füge ich also

GRUB_CMDLINE_LINUX="ip=88.198.59.12::88.198.59.1:255.255.255.224:::none"

zu /etc/default/grub hinzu. Die parameter kann man in der Linux-Dokumentation unter /usr/src/linux/Documentation/filesystems/nfs/nfsroot nachlesen (das ganze ist dafür gedacht nfs-Volumes als root einzubinden, aber es funktioniert auch für andere Dinge). Die leeren Parameter werden für nfs-boot gebraucht.
Falls dass nicht klappt, kann man auch ein simples script in /etc/initramfs-tools/scripts/init-premount/mount-boot hinterlegen:

PREREQ="udev devpts"
prereqs() {
    echo "$PREREQ"
}
case "$1" in
    prereqs)
        prereqs
        exit 0
    ;;
esac
. /scripts/functions
ifconfig eth0 inet pointopoint 88.198.59.1 88.198.59.12/32

Damit ist alles bereit und der Server hält beim booten an, bis in der Datei /lib/cryptsetup/passfifo der Korrekte Key hinterlegt wird.
Der Key muss nach dem booten nicht gelöscht werden da initramfs eh nur im RAM liegt und bald überschrieben sein sollte.

Um sich einzuloggen verwendet man dann etwas in der Art

# ssh -o "UserKnownHostsFile=~/.ssh/known_hosts.initramfs" \
	-i "~/id_rsa.initramfs" root@initramfshost.example.com \
	"echo -ne \"secret\" >/lib/cryptsetup/passfifo"

Weitere Details findet man unter /usr/share/doc/cryptsetup/README.remote auf der Festplatte von Debian.
Viel Spass beim basteln und immer schön lange Passwörter verwenden.

DISCLAIMER: Das obige setup ist nicht 100% sicher. ein lokaler Angreifer kann immer noch böse Dinge tun. Ich habe daher (als zusätzliche Hürde) bei mir die /boot partition im normalbetrieb nur read-only gemounted. Kann ein Angreifer aber unbemerkt darauf rumschreiben, wird Sicherheit schwierig. Man könnte im ssh noch den hash des initramfs-images prüfen, aber auch das ist nicht sicher, da der Angreifer ja das hash-tool ersetzten könnte. Aber alles in allem muss der Angreifer mit diesen Massnahmen sehr viel wissen mitbringen, und auch entsprechend vorbereitet sein. Ein Fehler, und der Angriff wird erkannt.

Flattr this!

Comments 1 Comment »