Disk encryption with USB drive as the key
I’ve been playing around with dm-crypt and LUKS.
I’ve come up with a 10-step process to encrypt a couple of hard disks (not the boot drive) and use a USB key plugged in at boot time to unlock them – boot without the USB key in, and you boot fine, but the drives aren’t mounted or readable.
Initially I was going to try some UDEV rules to unlock+mount the drives whenever a USB key was plugged in, but in true UDEV style, it didn’t work – we got an endless loop of cryptsetup processes, also there’s a method for reading the keyfile from the USB drive from Grub, but that didn’t seem to work either, so I’m sticking with my method below.
- Create a partition on each disk, optionally filling with random data first:
dd if=/dev/urandom of=/dev/sdb
dd if=/dev/urandom of=/dev/sdc
fdisk /dev/sdb
fdisk /dev/sdc
- Format and encrypt in one command:
luksformat -t ext3 /dev/sdb1
luksformat -t ext3 /dev/sdc1
- Fill keyfile with random data:
dd if=/dev/urandom of=secretkey bs=512 count=4
- Add keyfile to LUKS volumes:
cryptsetup luksAddKey /dev/sdb1 secretkey
cryptsetup luksAddKey /dev/sdc1 secretkey
- Fill USB key with random data, an old 64Mb disk took a few minutes:
dd if=/dev/urandom of=/dev/disk/by-id/usb-Mobile_Drive_7777777777777777-0\:0
- Write keyfile to USB key’s MBR, note this will be invisible as its outside the partition table, and there’s no partitions defined, so it won’t mount the drive either:
dd if=secretkey of=/dev/disk/by-id/usb-Mobile_Drive_7777777777777777-0\:0 bs=512 seek=4
- Secure delete the keyfile from hard disk – note you still have the passphrase (created in #2) to unlock the volumes if things go wrong:
shred --remove --zero secretkey
- Update /etc/crypttab (chown root:root, chmod 600):
data1 /dev/sdb1 /dev/disk/by-id/usb-Mobile_Drive_7777777777777777-0\:0 luks,keyscript=/usr/local/bin/unlock-luks
data2 /dev/sdc1 /dev/disk/by-id/usb-Mobile_Drive_7777777777777777-0\:0 luks,keyscript=/usr/local/bin/unlock-luks
- Create /usr/local/bin/unlock-luks (chown root:root, chmod 700):
#!/bin/sh
if [ -e $1 ]
then
dd if=$1 bs=512 skip=4 count=4
fi
- Mount the encrypted volume at boot.
We do this in /etc/rc.local (chown root:root, chmod 700) as its the last part of the boot process – testing to see if LUKS managed to map the volumes first:
#!/bin/sh -e
if [ -e /dev/mapper/data1 -a -e /dev/mapper/data2 ]
then
mount /dev/mapper/data1 /export/data1
mount /dev/mapper/data2 /export/data2
fi
exit 0