Jens Krämer

Encrypted root and swap plus suspend to disk with Gutsy

 |  security, encryption, ubuntu, luks, linux

In order to give my trusted T42 a slight speed up I decided to replace the built-in 5400rpm hdd with something faster. I decided to go with Seagate’s ST910021A which seems to be a great choice from what I can tell so far - it’s noticeably faster and despite it’s 7200 rpm it’s nearly as quiet as the original 80GB disk from Hitachi.

But I digress. Initially I just wanted to copy over all the stuff and be done with it, but then I took the chance to do a fresh install of Ubuntu so I could try out the hard disk encryption setup that has been introduced in the alternate installer of 7.10. Until then I only had an encrypted /home, which was pretty useless since most of the time my notebook isn’t shut down but hibernated, and I never needed to type in my passphrase upon resume… 

Installation of Gutsy, including the setup of encrypted partitions for root, swap and home went without problems, however on first boot I only got a blank screen, and no prompt for a passphrase as I expected. Removing the quiet splash options from the kernel boot arguments in Grub solved that one, so I could finally see when to enter the pass phrase.

Not nice, however, that I had to enter it three times now, once for each partition. Maybe I should have guessed this would be the case when the installer also asked me three times, once for each partition…

Seems you can get around this by choosing one of the LVM-based encryption options in the installer, which will set up your partitions inside a single encrypted LVM volume. But I didn’t feel the need for another layer of abstraction between my data and the disk, plus those options all sounded like they would use the whole disk, blowing any existing partitions away. So I decided to fix this on my own.

A bit of googling quickly led me to the EncryptedFilesystemHowto5, which suggests creating a separate encrypted partition where all the keys for the other encrypted partitions will be stored. That way, you only need to type your passphrase once when the keys partition is mounted in order to retrieve the (unencrypted) keys for the other partitions from there. The following steps and the initrd script are roughly based on this howto, however the process is much easier since we’re already starting with a fully encrypted system and only add the additional comfort of that separate keys partition to it.

So here’s, in short, what I did, starting from the encryption setup already created by the alternate installer:

Make backups

I did all this on a fresh install having all my data on the other hard disk lying on the table so there wasn’t much to backup but I thought I’d mention it anyway ;-)

Set up the keys partition

First create a small partition to hold your keys if you didn’t already do so during installation. Let’s say this is /dev/sda6. Then set this up as an encrypted volume and mount it somewhere (you need to be root for all of the following commands):

/sbin/badblocks -c 10240 -s -w -t random -v /dev/sda6 dd if=/dev/urandom of=/dev/sda6 cryptsetup --verify-passphrase --verbose --hash=sha256 --cipher=aes-cbc-essiv:sha256 \ --key-size=256 luksFormat /dev/sda6 cryptsetup luksOpen /dev/sda6 cryptokeys mke2fs -j -O dir_index,filetype,sparse_super /dev/mapper/cryptokeys tune2fs -c 0 -i 0 /dev/mapper/cryptokeys mkdir /mnt/cryptokeys mount -t ext3 /dev/mapper/cryptokeys /mnt/cryptokeys

This will check the partition for bad blocks, overwrite it with pseudo-random data, setup a luks volume on it, create a filesystem there and finally mount this at /mnt/cryptokeys.

Now, create the keys for your root, swap and any other partitions you might have. The fine thing about luks is that you can have any number of keys for a given encrypted volume, so this is pretty straight forward (do the first two lines for root, swap and any other encrypted partitions):

dd if=/dev/random of=/mnt/cryptokeys/sda7-key bs=1 count=256 cryptsetup luksAddKey /dev/sda7 /mnt/cryptokeys/sda7-key chmod 600 /mnt/cryptokeys/*-key

If you should ever happen to lose the keys stored on that partition, you will still be able to access your data with the passphrase you told the alternate installer during installation.

Create a new initial ramdisk

Of course the original initrd image doesn’t know anything about our new keys partition. To change this we create a custom script named /etc/initramfs-tools/scripts/local-top/cryptokeys which will mount the keys partition asking for the passphrase, then unlock all other encrypted partitions and finally close the keys partition again. As a bonus, it also tries to resume from the swap partition after unlocking it.

The script assumes your swap is at /dev/sda8, and root and home are sda7 and sda9. Be sure to edit this to suit your needs.

Before creating the new initrd it’s a good idea to backup the original one in /boot/, just in case we messed something up. You might even want to create a separate boot menu entry using this original initrd in /boot/grub/menu.lst below the END DEBIAN AUTOMAGIC KERNELS LIST line:

title Ubuntu 7.10, kernel 2.6.22-14-generic (old initrd) root (hd0,4) kernel /vmlinuz-2.6.22-14-generic root=/dev/mapper/sda7_crypt ro initrd /

To finally create a new initrd, call:

update-initramfs -u ALL

Try it out

Well, reboot and see if it works :-)

You should get asked once for your passphrase, and then see the other partitions being unlocked automatically. Thanks to the call to /bin/resume in the cryptokeys script resuming from suspend to disk should work, too (which it didn’t with the setup created by the alternate installer).

Please let me know if you spot any bugs or have any other comments/thoughts on this.



Very nice, I may give it a shot. However, I am quite fond of LVM, and I think if you tried it you would be too. So I will probably try that first.