For years the Ubuntu installer has supported full-disk encryption but the installer has suffered from not properly handling full-disk encryption in combination with manual partitioning. Such a setup is useful, for example, in a dual boot environment with both a Windows and an Ubuntu install, or with multiple Ubuntu partitions. Even though the installer doesn’t support it well, it is possible to do full-disk encryption (well, really, “full-partition” encryption) with a custom partition setup with a small amount of extra manual work. Here is how.
Note: I developed this using the Kubuntu 20.04 installer but the same procedure will work with the regular Ubuntu 20.04 or other variants.
Create Partitions
Boot into the live environment from the install medium. I used a Kubuntu 20.04 USB disk and selected the “Try Kubuntu” option to get to a live environment.
Open a Terminal and run sudo -i
to get a root prompt. We’ll be using the gdisk
utility to create partitions. (If you use an old MBR-style partitioned disk instead of GPT, you can use fdisk
instead).
The main partitions we’ll need to add will be a boot and a system partition. The boot partition will not be encrypted in this scenario but the full system partition will be. This type of a setup does not necessarily protect from a targeted attack of someone inserting malicious code into the boot chain. But it does protect against someone stealing your laptop and also having access to proprietary company data or other private data, for example.
If you are starting from scratch with an empty disk and booting with UEFI, you’ll need to create an EFI system partition. I will assume this is in place already.
You can run lsblk
to see your block devices. For me the disk I’m installing to is /dev/nvme0n1
. Run gdisk /dev/nvme0n1
to open gdisk
for this disk.
You can use d
to delete any partitions first if necessary.
To create the boot partition, type n
, select partition number, first sector, and enter +1G
for the last sector to make the boot partition 1GB. Hit enter for hex code to use the default.
To create the system partition, type n
again. I just hit enter to use the defaults for partition number, first sector, last sector, and hex code since I wanted to use the remainder of the disk for my encrypted Kubuntu installation.
Use the p
command if desired to double-check the partitions and if you are ready to write them to disk then use the w
command.
Run lsblk
to see the updated partitions. Now we will format and create the encrypted partition, which will ease the installer into doing what we want.
For me my boot partition was /dev/nvme0n1p1
and my system partition was /dev/nvme0n1p2
. Replace those names in the commands below with the correct partitions for your setup.
Run mkfs.ext4 /dev/nvme0n1p1
to format the boot partition.
Run cryptsetup luksFormat /dev/nvme0n1p2
to create an encrypted LUKS partition in the system partition. Enter YES
to confirm and type enter your desired passphrase.
Run cryptsetup open /dev/nvme0n1p2 crypt_sys
to open the encrypted partition.
Run mkfs.ext4 /dev/mapper/crypt_sys
to create the root file system.
Install System
Run the installer. When you get to the Installation type screen to select your partition method, select Manual.
Select the /dev/nvme0n1p1
boot partition, set the type to ext4
and mount point to /boot
.
Select the /dev/mapper/crypt_sys
root file system device, set the type to ext4
and mount point to /
.
Continue with the installation, but when the Installation Complete pop-up at the end pops up, do not select anything yet.
Make System Bootable
The Ubuntu installer has installed the new system to the encrypted partition, but has not configured the system to actually be able to boot from an encrypted partition. If you left the pop-up open at the end of the installation, then the installer will have left the new target system mounted at /target
. You can see what file systems are mounted to /target
with the command mount -l | grep /target
.
Run the following commands to “chroot” into the target system:
mount -o bind /sys /target/sys
mount -o bind /proc /target/proc
mount -o bind /dev /target/dev
cp /etc/resolv.conf /target/etc
chroot /target /bin/bash
You now have a prompt within the context of the new target system. We need to create the /etc/crypttab
file to allow the kernel to be able to locate the encrypted root file system.
Run blkid /dev/nvme0n1p2
to see the UUID of the encrypted partition. Copy the UUID, not including the doublequote characters.
Next run echo "crypt_sys UUID=copied_uuid none luks" >> /etc/crypttab
(replacing “copied_uuid” with the copied UUID) to create /etc/crypttab.
Ok, now we need to update our “initial ramdisk file system” (initrd) in the /boot
partition.
Run update-initramfs -u -k all
.
You can now run exit
to leave the chroot target environment and select Restart Now to reboot into the new system.
Troubleshooting
If the system does not boot or you miss a step and need to recover, you can boot into the live environment from an installation medium and attempt recovery without needing to go through the installation again.
From a terminal, run these commands to open the encrypted block device and mount the system to /target
:
cryptsetup open /dev/nvme0n1p2 crypt_sys
mkdir /target
mount /dev/mapper/crypt_sys /target
mount /dev/nvme0n1p1 /target/boot
# If you have an EFI system partition, mount it as well:
#mount /dev/nvme0n1pX /target/boot/efi
This will recreate the state that the system was in when the installer was finished, and you can repeat any of the above commands necessary.