full system encryption

June 2nd, 2011

In the age of laptops I was thinking maybe it's time I finally try encrypting my disk. I've never done it before, so before going for it I needed a small approfondimento.

The common strategy seems to be roughly:

  1. Leave /boot unencrypted.
  2. Encrypt the rest of the disk with LUKS. You then have dm-crypt that provides a mapping between the partition (according to the partition table) and the corresponding unencrypted block device, which becomes a node like /dev/mapper/nodename, depending on what you call it.
  3. Use /dev/mapper/nodename as the "physical" partition which you assign to lvm and make into a volume group.
  4. Create logical volumes in the volume group, so that each logical volume corresponds to what we used to call a partition on the old model, ie. /, /home, /var etc.

lvm is practical here, because you need at least two partitions, / and swap. You could just as well create multiple partitions sda5,sda6,... and encrypt each one, but then you'd have to unlock them individually on boot, which is hacky.

The setup is a bit involved and I would rather be spared the trouble of doing it manually. The ubuntu alternate install cd has a fully automatic feature that does this, using the whole disk. If you're happy with the basic scheme, but you want more partitions or you want to size them differently, you can use the curses gui following a nice guide like this one.

So far so good, but now comes the inevitable question. Much like with compression you want to be able to not only compress but also to decompress. What if I screw up my boot sector or my fstab and I need to boot from a rescue cd? How do I mount /dev/sda5 now?

Mounting manually

First of all, in case we don't have all the tools we need:

$ apt-get install lvm2
$ modprobe dm-mod

We obviously need to know what the physical partitions actually are:

$ fdisk -l /dev/sda

Disk /dev/sda: 32.2 GB, 32212254720 bytes
255 heads, 63 sectors/track, 3916 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a30a5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13       96256   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              13        3917    31357953    5  Extended
/dev/sda5              13        3917    31357952   83  Linux

/dev/sda1 is /boot, that's easy. Then we have /dev/sda5, which is the encrypted partition and mounting it directly will not work. This is where dm-crypt comes into the picture: we are going to unlock the partition, obtaining a block device that represents the unencrypted view of the partition.

$ cryptsetup luksOpen /dev/sda5 vg0
$ cd /dev/mapper
$ ls -lh
crw-------    1 root     root       10, 236 Jun  2 16:44 control
lrwxrwxrwx    1 root     root           7 Jun  2 16:47 vg0 -> ../dm-0

We have decided to call the block device vg0, and it thus appears as /dev/mapper/vg0. Since we know this is an lvm volume group we use the lvm tools to figure out what it contains:

$ vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "vg0" using metadata type lvm2
$ vgs
  VG   #PV #LV #SN Attr   VSize  VFree
  vg0    1   2   0 wz--n- 29.90g    0 
$ lvscan
  inactive          '/dev/vg0/swap' [1.86 GiB] inherit
  inactive          '/dev/vg0/root' [28.04 GiB] inherit

We have two logical volumes in there. But they are inactive, which means they are not visible under /dev, ie. we can't mount them. To make them active:

$ vgchange -a y
  2 logical volume(s) in volume group "vg0" now active

The device names listed before are now visible and we can mount them:

$ cd /dev/vg0
$ ls -lh
lrwxrwxrwx 1 root root 7 Jun  2 18:24 root -> ../dm-2
lrwxrwxrwx 1 root root 7 Jun  2 18:24 swap -> ../dm-1
$ swapon /dev/vg0/swap
$ mount /dev/vg0/root /mnt

:: random entries in this category ::