Manual Disk Encryption Setup in Lubuntu 18.04 Installer
This guide describes how I set up disk encryption and LVM manually while installing Lubuntu Desktop 18.04. Since the installer doesn’t support manipulation of LVM partitions in the GUI, this guide gives step-by-step instructions for setting up LUKS and LVM in the command line.
While I wrote this while installing Lubuntu, this guide should also work with regular Ubuntu and the other Ubuntu variants.
To begin, boot the Lubuntu installer and select “Try without installing”. Don’t launch the installer program yet, as we will need to set up our disk encryption and LVM in the terminal first.
Step 1: partitioning
The first step is to create the GPT partitions on the disk.
For this post we’ll use /dev/sda
as the device name.
Make sure to change this to the device that you are installing Lubuntu on.
I chose to use an unencrypted /boot
partition for simplicity.
If you also need /boot
to be encypted, this will be a more complex process, but there are other guides on full-disk encryption that may help.
This step can be done easily with a GUI: I used gparted
, for example.
If there isn’t one already, create an EFI system partition (see this Arch Linux wiki page for more details).
As mentioned above, I also created a plain ext4 partition for /boot
.
Finally, I wanted to encrypt the rest of my disk, so I created one last partition, spanning the rest of the disk, with no filesystem (we’ll format this partition for encryption in the next step).
If using gparted
, click “Apply all operations” (the checkmark in the toolbar, or under the Edit menu) to write the partition table.
You should now be able to run lsblk
to see these changes.
At the end of this step, my setup looks like this:
sda
|-sda1 480M /boot/efi
|-sda2 1G /boot
|-sda3 <rest>
Step 2: setup dm-crypt
In this step, we will encrypt the partition sda3
and set it up as a LVM physical volume.
First, setup LUKS, which is the disk encryption format that Ubuntu uses:
cryptsetup luksFormat --type=luks1 /dev/sda3
Note that I chose the luks1
format, but there is also a newer luks2
.
StackOverflow has a discussion on the trade-offs between the two.
Once the partition is formatted for LUKS, we can now “open” (i.e. create a mapping) the device so that we can setup LVM. The data stored on disk is encrypted, but by mapping the device, we create a virtual, decrypted version of the partition that we can manipulate. This allows us to easily layer on LVM, or even plain filesystems, while keeping the underlying physical storage encrypted. Open (“decrypt”) the device as follows:
cryptsetup open /dev/sda3 sda3_crypt
Note that sda3_crypt
is an arbitrary name for the mapped device, which will be available at /dev/mapper/sda3_crypt
.
You can select whatever name you want as long as you use the same name in the steps below.
Step 3: setup LVM
In this step, we will setup LVM on the encrypted device. LVM allows us to take one physical volume (i.e. our encrypted volume) and partition it flexibly into multiple logical volumes. Unlike a physical disk, these logical volumes can be manipulated much more easily after they are created, including resizing, moving, and creating new volumes.
There are three main concepts in LVM: physical volume (PV), volume group (VG), and logical volume (LV). A logical volume is the equivalent of a traditional partition: after creating a logical volume, you can format it as ext4 and mount it, for example. A volume group groups together several logical volumes, and you can think of it as the equivalent of a traditional physical disk. Finally, a physical volume (PV) represents the underlying storage for a volume group. Usually, this is a physical disk partition, or in our case, a LUKS device.
We’ll set up one PV (the mapped LUKS device) and one VG, and put our partitions inside that one VG. First the PV:
pvcreate /dev/mapper/sda3_crypt
Now we’ll create a VG on top of this PV. Note that lubuntu-vg
is an arbitrary name:
vgcreate lubuntu-vg /dev/mapper/sda3_crypt
Finally, we can create our logical volumes inside this VG. You can customize this step to your needs, but in this example we’ll create two partitions for swap and root:
lvcreate -L 8G --name lubuntu-vg
# 100%FREE uses the rest of the VG
lvcreate -l 100%FREE --name root lubuntu-vg
There is no need to format these partitions, as we’ll use the Lubuntu installer to do that next.
This section illustrated only a very basic use of LVM, but LVM has many more advanced features and use cases that weren’t covered here. This StackOverflow post has some pointers to more resources if you’re interested in diving deeper.
Step 4: install Lubuntu
Once the LVM setup is done, we can perform the Lubuntu installation.
Simply open the installer, and select “Something else” when prompted about the disk.
You should see the LVM volumes you created here.
Select them and pick the mount point as usual.
Make sure that you select the LVM volumes rather than the underlying crypt device (sda3_crypt
) or physical partition (sda3
).
Finish the installation, but do not reboot the system yet.
Step 5: tweaks to boot encrypted root partition
Before rebooting into your new system, we must perform some final steps to ensure that the new system will boot properly. If this is not done, it’s possible that you’ll be dropped into an “initramfs” recovery prompt.
- Initrd must contain the required software to decrypt/map the encrypted partition.
- Initrd must know which partition to decrypt.
Because these steps need to be performed in the newly installed (target) system, and we are still in the Lubuntu live USB environment, we need to chroot
into the target.
Mount the target and chroot
The target’s root filesystem should already be mounted at /target
, but if not, do that before continuing.
Also, make sure that special filesystems are mounted in the target root before chrooting, in particular:
mount -o bind /dev /target/dev
mount -t proc proc /target/proc
mount -t sysfs sysfs /target/sys
mount -o bind /run /target/run
If you are using a separate /boot
partition like me, make sure that is mounted as well, since we will be updating the initrd images (make sure to replace /dev/sda2
with your boot partition):
mount /dev/sda2 /target/boot
Now we are ready to chroot into the target:
chroot /target /bin/bash
Now we are operating in the context of the target, installed system.
Include cryptsetup modules in initrd
The first tweak we should make is to include the cryptsetup modules in the initrd.
Open the file /etc/cryptsetup-initramfs/conf-hook
and make sure that CRYPTSETUP=y
.
See this StackOverflow post for more details.
Add partition to crypttab
Next, we need to indicate which partition to be decrypted on boot.
There are at least two ways to do this: a cryptopts
boot kernel parameter, and crypttab
.
I picked the crypttab
method, which involves adding a line like the following to /etc/crypttab
:
sda3_crypt UUID=<uuid> none luks,discard
Replace <uuid>
with the UUID of your encrypted partition.
You can find this out by running blkid
as root, which will print out something like:
/dev/sda3: UUID="12345678-abcd-abcd-abcd-1234567890ab" TYPE="crypto_LUKS" PARTUUID=...
Paste the UUID displayed into /etc/crypttab
.
For the example above, that would be:
sda3_crypt UUID=12345678-abcd-abcd-abcd-1234567890ab none luks,discard
The final option discard
is optional, and presents a trade-off between SSD performance and security.
Adding discard
enables TRIM which can potentially enable higher performance on SSDs, by allowing the SSD to reclaim freed blocks in the background.
However, this comes with a security trade-off in the form of potentially leaking some metadata.
Personally, I chose to enable discard
because the type of metadata that may be leaked (the filesystem that’s being used is given as an example) is not important to my use case.
See this page on the Arch Linux wiki for more details.
If you prefer the cryptopts
method, this post contains an example.
This line should be added to the kernel boot options in /etc/default/grub
(don’t forget to update GRUB afterwards).
Rebuild the initrd image
After making the two above tweaks, rebuild the initrd image:
update-initramfs -u -k all
To ensure that the changes were applied successfully without rebooting, you can inspect the generated image with unmkinitramfs
.
For example, this will extract the contents of the image to /tmp/initrd
:
mkdir /tmp/initrd
unmkinitramfs /boot/initrd.img-5.3.0-53-generic /tmp/initrd
These files should be present:
ls -l /tmp/initrd/main/sbin/cryptsetup
ls -l /tmp/initrd/main/conf/conf.d/cryptroot
Check that the cryptroot
file contains the same UUID that you added to crypttab
above.
If the initrd looks good, then it’s time to reboot and try booting into your new encrypted Lubuntu system!
Other resources
https://medium.com/@chrishantha/encrypting-disks-on-ubuntu-19-04-b50bfc65182a https://github.com/jjakob/wiki/wiki/Migrating-an-unencrypted-PureOS-Debian-install-to-fully-encrypted