Installing Linux with full partition encryption

So, this is going to be one of any number of posts out on the web about setting up a dev environment on Linux, but it’ll be good for me as reference in the future. This is going to cover setting up Ubuntu 19.10 on a ThinkPad X1C (7g), dual-boot with Windows 10, with both OSes fully encrypted at the partition level (full-disk encryption is technically impossible since we’re splitting the disk for Windows and Linux).

A lot of these instructions are very top-level. If you can’t remember what to do exactly, DDG will almost certainly be able to tell you.

  1. Set up Windows. It will encrypt itself. This part is boring.
  2. Resize your Windows install with the Windows Disk Manager/Disk Utility
  3. Disable fast boot in Windows
  4. Disable Secure Boot in the BIOS (technically the UEFI firmware), so that we can boot things other than the Redmond pile
    • you can get to the UEFI fw manager by holding <Shift> and clicking “Restart” in the Windows menu, then hunting around for the right option
  5. Prep Linux (Ubuntu) installation Live USB
  6. Boot from the Live USB by holding shift while selecting “Restart” from the Windows menu, and choosing to boot from your (inserted) Live USB by name
  7. Once booted into the Live USB, slow down, DO NOT JUST INSTALL UBUNTU

This is where it gets interesting.

Encrypted Ubuntu partitions

Ubuntu unfortunately does not offer a default encryption option, and even if it did, it wouldn’t work for us since we aren’t encrypting the entire disk, but only the Linux partition.

Check: did you resize your Windows installation in Windows?

Fire up GParted, and identify your free space. We need to make two new partitions:

One, for /boot, which is the only part of our install that will sit outside the encrypted area (there are ways to get this into encryption too, since GRUB can handle it, but it’s just more headache and we’re not big enough fish to really be worried about people tampering with our computer)

Two, which we’ll call MAIN for simplicity for now for the rest of our install,

First, create the /boot partition, and format it ext3, as a primary partition. Give it at least 1 GB. I gave it 10 because I had space to spare.

Second, create the MAIN partition, and leave it unformatted and mark it as a logical volume/partition. Give it as much space as you can, because this is going to hold /, /home, and swap.

Once these are created, take note of their paths. These should be something like /dev/sda3 and /dev/sda4. For now, I’m going to refer to them as /dev/sdaBOOT and /dev/sdaMAIN for clarity, but Sean, and this is important, these won’t be the same paths on the next machine you’re working with.

Now we’re going to deal with the unformatted MAIN partition, by turning it into a LUKS encrypted volume. The name encryptedubuntu is just an arbitrary name I’m giving to the volume being created, which will become it’s mount name. Name it what you want.

$ sudo cryptsetup luksFormat /dev/sdaMAIN # will ask you to create a password. FFS don't forget this
$ sudo cryptsetup luksOpen /dev/sdaMAIN encryptedubuntu

Now that you’ve named and opened the LUKS volume, we should wipe zero out any data that was there before to make the hackers work a little bit harder to get our gold:

$ sudo dd if=/dev/zero of=/dev/mapper/cryptcherries bs=16M

It’ll take a second, be patient.

Now, on this LUKS… partition/volume/whatever (I don’t know the right word OK?), we’re going to actually set up the volumes:

# identify a physical volume on the mounted LUKS partition
$ sudo pvcreate /dev/mapper/encryptedubuntu

# create a family of volumes
$ sudo vgcreate VGencryptedubuntu /dev/mapper/encryptedubuntu

# create the logical volumes: /, /home, swap
$ sudo lvcreate -n LVencryptedubuntuROOT -L 128g VGencryptedubuntu
$ sudo lvcreate -n LVencryptedubuntuSWAP -L 32g VGencryptedubuntu # 2x my installed RAM
$ sudo lvcreate -n LVencryptedubuntuHOME -L 100g VGencryptedubuntu # or the rest of your available space really

Now these new LVs need file systems:

$ sudo mkfs.ext4 /dev/mapper/VGencryptedubuntu-LVencryptedubuntuROOT
$ sudo mkfs.ext4 /dev/mapper/VGencryptedubuntu-LVencryptedubuntuHOME

$ sudo mkswap /dev/mapper/VGencryptedubuntu-LVencryptedubuntuSWAP

Now, without rebooting (seriously, don’t do it until I explicitly say to), fire up the Ubuntu installer. Choose your language (US English), keyboard layout (US PC) (yes, even, and especially if you have a UK PC layout keyboard).

When it asks you if you want to install alongside Windows, or nuke the disk from orbit, choose something else.

This takes you into a partition manager screen a lot like GParted, where we’re going to select the different available spaces for the different parts of the system.

Assuming things are going like they are here, you should:

  • choose /dev/sdaBOOT as /boot (remember this one partition outside of LUKS?)
  • choose VGencryptedubuntu-LVencryptedubuntuROOT as /
  • choose VGencryptedubuntu-LVencryptedubuntuHOME as /home
  • choose VGencryptedubuntu-LVencryptedubuntuSWAP as swap space

Now let the installer do its thing. DO NOT REBOOT YET. When it asks if it can, don’t let it.

We first need to tell the OS how to find the logical volumes that we’ve installed it to for when we reboot.

First, we need to snag the UUID of the encrypted partition where we’ve got our LUKS volumes:

$ sudo blkid /dev/sdaMAIN
 /dev/sdaMAIN: UUID="some-uuid-that-you-need-to-remember" TYPE="crypto_LUKS"

This involves mounting the relevant LVs and then chrooting into the context of the newly installed OS:

$ sudo mount /dev/mapper/VGencryptedubuntu-LVencryptedubuntuROOT /mnt
$ sudo mount /dev/sdaBOOT /dev/boot # Remember this unencrypted partition we're using for boot?
$ sudo mount --bind /dev /mnt/dev
$ sudo chroot /mnt

# And now in the chroot shell
% mount -t proc proc /proc
% mount -t sysfs sys /sys
% mount -t devpts devpts /dev/pts

Now, still in the chroot, we need to create a file to tell the boot process how and where to find /:

# ... still in chroot
% sudo vi /etc/crypttab

And then give it the content:

# <target name> <source device> <key file> <options>
encryptedubuntu UUID=some-uuid-that-you-needed-to-rememeber none luks,retry=1,lvm=VGencryptedubuntu

If in a minute something complains about unknown options, come back and remove that option from that comma-separated list at the end.

And now, finally, still in the chroot, update the initial filesystem:

% sudo update-initramfs -k all -c

With this done, you have everything installed. Reboot into Ubuntu. You should be asked for your password twice (once in order to unlock the disks, and then to log in as your user).

The last thing to do is to test that your data is sitting inside the encrypted LUKS volumes:

For your / and /home mounts, I’m a fan of passing mount through grep to verify the right logical volume is attached to the right mount:

$ mount | grep VG # assuming you prefixed your vol-group with VG
 /dev/mapper/VGencryptedubuntu-LVencryptedubuntuROOT on / type ext4 (...permissions)
 /dev/mapper/VGencryptedubuntu-LVencryptedubuntuHOME on /home type ext4 (...permissions)

The grep is not necessary, but helps filter down to what we’re interested in. If you don’t see the logical volumes mapped to those mounts, something’s gone funny, and it might be easiest to back up to the volume setup.

For swap, you can check by running swapon -s. Problem for me is that I don’t get it listed as mapped to /dev/mapper/VGencryptedubuntu-LVencryptedubuntuSWAP, but rather as sitting on /dev/dm-N, and I have no idea what that path is. But there’s a decent chance that dm stands for device-mapper (spoilers, it does), which means we’re probably in the right place… but let’s check anyways.

To verify this, I then run

$ lsblk -o NAME,KNAME /dev/sdaMAIN
  NAME                                              KNAME
  sdaMAIN                                           sdaMAIN
  └─encryptedubuntu                                 dm-0
    ├─VGencryptedubuntu-LVencryptedubuntuROOT       dm-1
    ├─VGencryptedubuntu-LVencryptedubuntuSWAP       dm-2
    └─VGencryptedubuntu-LVencryptedubuntuHOME       dm-3

As long as the report from swapon -s matches the KNAME from lsblk, we’re in business and swap is encrypted.

All credit for the setup of the encrypted volumes goes to the author of this SO post