Encrypted root and swap plus suspend to disk with Gutsy
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:
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
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
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
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)
kernel /vmlinuz-2.6.22-14-generic root=/dev/mapper/sda7_crypt ro
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.