Full Disk Encryption with Two-factor Authentication for Ubuntu: How?

Solution 1:

There's a simple way to have full disk encryption that requires the presence of a particular thumb drive AND your password to boot.

What you do is detach the LUKS header from your fully-encrypted hard drive and store it on your thumb drive.

I'll assume you already have the following setup:

# /dev/sda1 is the boot partition (100MB)
# /dev/sda2 is the encrypted partition
parted /dev/sda mklabel msdos
parted /dev/sda -- mkpart primary ext2 1M 200M
parted /dev/sda -- mkpart primary ext4 200M -100M
cryptsetup luksFormat /dev/sda2

Create a copy of the luks header and erase it from the local device:

mkdir /media/ramdisk && mount -t tmpfs -osize=20m,rw tmpfs /media/ramdisk
cryptsetup luksHeaderBackup /dev/sda2 --header-backup-file /media/ramdisk/header.img
dd if=/dev/urandom of=/dev/sda2 bs=1M count=2

Run the last step several times if you're the target of a high-budget agency. I've also created a ramdisk to hold the header temporarily so it won't linger around afterwards.

With your usb device in /dev/sdb, make a 2MB partition and load the header onto it:

parted /dev/sdb -- mklabel MSDOS
parted /dev/sdb -- mkpart primary 1M 3M
dd if=/media/ramdisk/header.img of=/dev/sdb1

Right now, everything in /dev/sda2 looks like random data, and you have your header in /dev/sdb1. To access the encrypted drive manually you use:

cryptsetup luksOpen --header /dev/sdb1 /dev/sda2 rootfs
mount /dev/mapper/rootfs /target

The next step is to have your boot process ask for the pendrive to be inserted on boot. I found it easier to just assume it will be there and fail otherwise. First, find out your devices' id and UUID:

find -L /dev/disk/by-id/ -samefile /dev/sdb1
/dev/disk/by-id/usb-Generic-_Compact_Flash-part1
find -L /dev/disk/by-id/ -samefile /dev/sda2
/dev/disk/by-id/scsi-SATA_ST3320820AS_5QF28W6V-part2

blkid /dev/sdb1
/dev/sdb1: UUID="63347546-2db3-4bc1-9414-1142739a4c9f" TYPE="crypto_LUKS"

Next edit your /etc/crypttab line to look like this:

root /dev/disk/by-id/scsi-SATA_ST3320820AS_5QF28W6V-part2 none luks,header=/dev/disk/by-id/usb-Generic-_Compact_Flash-part1

(You may need this patch to get support for the header option in crypttab)

Last but not least, update your initram:

update-initramfs -u

You could take this a step further and actually have the whole boot partition loaded on the usb drive. The author of this article was on this very site doing a follow-up.

There are many different approaches you can take, with varying degrees of security and convinience.

A particular note about security: if your passphrase is compromised, anyone with a copy of the header will be able to decrypt the data, even if you change the passphrase later on.

Solution 2:

I know that TrueCrypt is available for OSX, Windows and Linux. You are able to do two levels of encryption for the whole drive. I've used it on Debian with AES full disk encryption. It requires the password on boot to access the data on the hard drive.