Introduction

Ubuntu’s installer provides a simple option for installing on top of encrypted lvm. The option however does not allow to modify partition layout and that for me is a showstopper. The other option is to create an encrypted container for all the partitions which works fine but then one has to enter the passphrase to each and every device individually.

This guide explains how to install ubuntu on top of an encrypted lvm and also give user the power of specifying partition layout. Using LVM makes it possible to specify partition sizes and unlock the encrypted device with a single passphrase. The alternative is to use encrypted devices for each partition and store keyfiles, that are used to unlock the other devices, on the root device.

In this example I’m installing Ubuntu on my laptop with a single SSD drive but this guide can be adapted to work on other distributions as well. I started by creating two partitions /dev/sda1 and /dev/sda2. The former will not be encrypted and will be mounted as /boot in our system. The latter partition will be encrypted and used as base for our lvm setup.

Partitioning

To do the actual partitioning the Ubuntu live environment provides gparted, disks and fdisk. Choose whichever suits you best or install an alternative from the repositories.

Filesystems

Now that you’ve created the partitions described in the previous chapter it’s time to write filesystems on them. I’m still prefering ext4 instead of btrfs but your free to chose your favorite.

sudo mkfs.ext4 /dev/sda1
sudo mkfs.ext4 /dev/sda2

LUKS container

The cryptsetup package shipping with Ubuntu 13.10 still uses the cbc-essiv cipher mode. The current cryptsetup package has since then switched to use aes-xts-plain64 mode. The default values are also plenty safe so do as you wish, just pick a really good passphrase. Also the cryptsetup package will be upgraded in Ubuntu 14.04 to use the values I specify here by default.

  1. Create the LUKS container
  sudo cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 /dev/sda2

Verify the command with YES in capital letters. Then write your passphrase twice.

  1. Open the LUKS container.
sudo cryptsetup luksOpen /dev/sda2 luks_container

Create LVM volumes

  1. Create LVM physical volume
sudo pvcreate /dev/mapper/luks_container
  1. Create LVM volume group
sudo vgcreate vg_system /dev/mapper/luks_container
  1. Create logical volumes You can think of logical volumes as partitions. I will create two partitions, one for root and one for home. If you need a swap space then you can create one for yourself now. The root partition will be 40GB and home shall have all the remaining space.
sudo lvcreate -n lv_root -L 40G vg_system
sudo lvcreate -n lv_home -l 100%FREE vg_system
  1. Write filesystems on the logical volumes
sudo mkfs.ext4 /dev/mapper/vg_system-lv_root
sudo mkfs.ext4 /dev/mapper/vg_system-lv_home

Installation of Ubuntu

Use the graphical installer to install Ubuntu like always. If you don’t know how to install Ubuntu then google some of the many fine guides. During the filesystem layout options, clikc something else and choose the logical volumes we just created. Mount them as / and /home. Do not forget to add regular unencrypted partition /dev/sda1 to /boot. Otherwise you will not be able to boot later on.

The important thing is to NOT restart the machine when the installation finishes! Click continue testing as we are not yet done.

Where the magic happens

No it’s time for the tricky part.

  1. Find out the UUID of your encrypted luks container
sudo blkid /dev/sda2
/dev/sda2: UUID="93xbb3a7-9x55-4kb1-87ce-7f1l6l45cv4af" TYPE="crypto_LUKS"

Write the UUID down as we will need it later.

  1. Mount the logical volumes chroot to it
        sudo mkdir /mnt/root
        sudo mount /dev/mapper/vg_system-lv_root /mnt/root
        sudo mount /dev/mapper/vg_system-lv_home /mnt/root/home
        sudo mount --bind /dev /mnt/root/dev
        chroot /mnt/root

And then within chroot do the following

mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devpts devpts /dev/pts
After this point all the commands are run in the chrooted environment!
  1. Create file /etc/crypttab in the chrooted environment with following line. Replace the UUID with the UUID of your luks container.
# <target name> <source device> <key file> <options>
luks_container UUID=93xbb3a7-9x55-4kb1-87ce-7f1l6l45cv4af none luks,retry=1,lvm=vg_system
  1. Create a file named /etc/initramfs-tools/conf.d/cryptroot in the chrooted environment with following line. Replace the UUID with your luks containers UUID.
CRYPTROOT=target=luks_container,source=/dev/disk/by-uuid/93xbb3a7-9x55-4kb1-87ce-7f1l6l45cv4af
  1. Update your initrd image.
update-initramfs -k all -c
  1. Edit file named /etc/default/grub and find a line that looks like this
GRUB_CMDLINE_LINX=""

And replace it with following. Again replace the UUID with the one your luks container.

GRUB_CMDLINE_LINUX="cryptopts=target=luks_system,source=/dev/disk/by-uuid/93xbb3a7-9x55-4kb1-87ce-7f1l6l45cv4af,lvm=vg_system"
  1. Update GRUB config with following command
update-grub

Reboot your machine and you should be prompted for password.