Site Overlay

LUKS encrypted Ubuntu with LVM and SSD cached HDD drive

This post is an adapted clone of Arne Rantzen’s instructions (archived version).

1. Preliminary steps

  • We start with a completely wiped HDD and a completely wiped SSD
  • We boot the system we would like to install from a USB media. Make sure that we boot in UEFI mode and not in legacy BIOS mode.
  • Do not proceed unless you are convinced that you booted your Ubuntu installation / testing USB system in UEFI mode (you should see an explicit entry in your startup F8 boot menu mentioning UEFI or EFI or similar).
  • Once booted into Ubuntu from USB, choose “Try Ubuntu” (not “Install” for the moment)
  • Open a terminal, make yourself root by issuing sudo -i and put the /dev path of the SSD and the HDD into some variables:

1.1 Partitioning

Launch gparted from the testing system, format both drives as GPT devices (not MBR).

My general setup is as follows:

  • I have a 128 GB SSD. 60 GB are held back for a later Win 11 installation, 38 GB are used to hold the core Linux system (without /var, /opt and /home), 21 GB are used for caching the most frequently accessed blocks on the HDD device and the rest is for small administrative partitions (/boot, /boot/efi, Microsoft hidden partitions etc.)
  • A 2 TB HDD is completely used as a backing device for the cache, i.e. all data going to /home, /var/ and /opt essentially written to that bcache partition.

Therefore we create the following partitions using gparted:

PartitionNameFile SystemSizeRemarks
sda1EFI System partitionFAT32512 MBtick esp and boot flags; will later be mounted as /boot/efi
sda2bootEXT41024 MBwill later be mounted as /boot
sda3cachecleared (will later be LUKS-formatted)21 GBthis will be our bcache device that holds most active blocks for fast access
sda4systemEXT4 (but doesn’t matter)38 GBwill be managed both PV and VG, hold core system
Initial partitioning

For our HDD we don’t have to do anything except writing the gpt partition table. The complete 2 TB will be taken as a backend for bcache. No need to create any partitions or format anything.

Next we set some variables in our terminal window:

1.2 Setting up caching with bcache

Still in our terminal as root, issue the following commands to install bcache-tools and wipe the file systems relating that later make up our virtual hybrid drive:

Then set up the cache partition (-C) of the SSD and the backing device (-B), the HDD partition and tweak bcache to use the writeback caching mode. Finally, add the resulting mapped partition of the cache on the SSD and the data partition on the HDD to a new variable.

1.3 Setting up LUKS encryption

Our whole file system of the HDD together with the cache on the SSD is now mapped to $BCACHE (/dev/bcache0) and the system partition still at $SSD_SYSTEM. Now we have to encrypt it. To setup LUKS we first have to create and format our encrypted devices. You will be asked for a password and confirm each time. Choose identical passwords as we want to have a master password to unlock the complete system at the startup.

Next we have to open and unlock the container in order to proceed with further installations. You will be asked for the master encrytpion password that you in the previous step (again twice as you unlock two LUKS containers).

When opening a container, you can assign them a name, which will be cRoot and cCache respectively. These will be the names under which the containers can be accessed in the device mapper under /dev/mapper/.

Next we export the device mapper paths of our opened containers:

1.4 Setting up Logical Volume Management

Initialization of physical volumes

We will now set up the logical volume manager. What do we want LVM to manage? First of all, we have a system partition on the sda4 on the SSD which LUKS has already mapped to /dev/mapper/cRoot (or $CROOT) and which will hold the core system files (basically everything that is ‘non-data’).

Secondly, we have our hybrid drive which we combined from the sda3 SSD partition and the complete sdb HDD into a virtual hybrid drive ($BCACHE or /dev/bcache0). This was encrypted by LUKS and is now accessible as ($CCACHE or /dev/mapper/cCache)

So we first tell LVM what physical volumes we have. Note that ‘physical’ in the language of LVM does not require a volume to be a separate tangible unit such as a hard drive. It might be a complete drive, but it can be a single partition or – as in our case – a mapped device.

This initializes the hybrid drive and the SSD system partition for logical volume management. Our next step is to

Creation of volume groups

The next level up from the physical volume (PV) is a volume group (VG). Each PV can (but not necessarily needs to) be a member of exactly one VG and a VG can hold an arbitrary amount of PVs.

We create two logical volume groups: One data group that will later hold everything that goes into /home, /var and /opt. And one system group that holds everything except these three. The vgcreate command allows us to create a group and at the same time determine what PVs should got into the group:

Creation of logical volumes

In our final step, we have to create logical volumes which we will use to put mount points on later in the system installation.

2. Installation of Ubuntu

We now have everything in place to install Ubuntu. Still do not close the terminal window. With the the terminal window remaining open, launch Install Ubuntu from the desktop of your USB instance.

Fill in the usual chit-chat about language, keyboard etc. until you are asked about what Installation Type you desire. Pick Something else.

After this you will be shown a dialog similar to the gparted window you saw before. Don’t let yourself be confused by the fact that the same installation destination might be listed multiple times. Assign the destination devices for installation as in the following table:

Device pathUse asFormatMount Point
/dev/sda1FAT32 ?not sure/boot/efi
/dev/sda2ext4True/boot
/dev/mapper/system-rootext4True/
/dev/mapper/data-homeext4True/home
/dev/mapper/data-varext4True/var
/dev/mapper/data-optext4True/opt
Mount Points in Ubuntu’s graphical Ubiquity installation manager

Finally choose /dev/sda as the device for the boot loader installation and click Install Now. Complete any remaining chit-chat about the user name, the machine name and so on.

When the graphical installer tells you that the installation has been completed, and offers you to reboot your machine into the installed system do not choose to reboot! Choose Continue Testing.

3. Post Install Steps

Now that the installation is over, we have to make sure that our system is able to use the cache and understand the encryption. Remember that so far only our testing system is really aware that

  • we have combined an SSD partition and a HDD into a hybrid drive using bcache
  • we have encrypted that hybrid drive and a system partition using LUKS
  • we have created physical volumes, volume groups and logical volumes inside the LUKS

All this information will be gone once we shut down the testing installation. Therefore we have to mount the freshly installed system to install the caching kernel and set up encryption.

Go back to the terminal window and mount the system we just installed inside the testing system:

Now we change to be root in the installed system we just mounted:

So far the installed system has not even bcache-tools installed (only our USB live system has). But as we just have become root in the installed system that we have mounted under /mnt inside our live system, we can now install bcache-tools:

To tell the installed system about our LUKS encrypted partitions, we have to set up /etc/crypttab:

I am told the last command is super important, as without updating initramfs, the system will ignore the settings we just put into the crypttab file.

We almost there. What remains are some final cleanups:

  • exit chroot,
  • sync the system state (not sure what this is good for, but it can’t do harm either),
  • unmount the installed system partitions
  • deactivate the volume groups
  • close the LUKS partition

4. Installing Windows

Once we have established that our Ubuntu installation works as intended, we can care about the Windows installation.

4.1 Preparing the installation media

To prepare the USB key that holds the installation media I recommend the Rufus USB creation tool. This is particularly useful as it allows you to alter the installation image such that:

  • you can bypass the dismal Win 11 ‘compatibility’ check which will even reject machines with an advanced i7 processor if it is not the latest generation
  • you can thwart Microsoft’s desire to know more about you by
    • bypassing the need to create an online account
    • directly suppress data collection

Download the desired Windows 10 or 11 installation ISO from Microsoft. In my case it’s the Win 11 64bit English US version.

Let Rufus put a customize installation image onto your USB stick.

4.2 Installing Windows

In my case I need a native Windows installation for a one and only one single purpose: running Autodesk Fusion 360. There is no Linux version of this software available and it draws so heavily on machine ressources that it is not a good idea to run it inside a Windows virtual machine under Ubuntu.

Therefore I will install Win 11 on the remaining 60-something GB of SSD space, which is just enough to hold Windows and install Fusion 360 which will then have the undivided attention of my Core i7 processor, 24 Gigs of RAM and a fast SSD device. (Still Autodesk recommends replacing my 10-year-old AMD Radeon Dualhead graphics adapter, which was top of the shop when I bought it but now seems to be incredibly outdated…)

Now power down your machine, pop in the USB stick, power it up again, hit F8 to open the boot menu and choose the UEFI USB installation media that should show up.

There is no rocket science in the installation itself. I have used the installation notes at itsfoss.com as a rough guideline. It worked for me without the Ventoy thing and as we already have left 60 GB plus/minus small change on the SSD when installing Linux, there is no need to resize partitions either.

The only important moment is when the installer asks you Which type of installation do you want? As before the only correct answer is Custom Install.

When next asked Where do you want to install Windows? make sure to choose Drive 0 Unallocated Space (approx. 60 GB) at the end of the list. This will be the niche we left for Windows on the SSD. Click Next and the installation should start.

The installer will restart your machine several times along the installation. After everything is ready, you will find out that your machine will boot straight into Windows. Don’t panic. Your Ubuntu installation is not gone. You just have to rearrange the boot order in your BIOS again so that it boots into Ubuntu (UEFI) by default.

Itsfoss recommends to run sudo update-grub to have windows listed as a boot option. In my case however, I really rarely use Windows (see above). So I prefer that the default behavior of my workstation is to boot into Ubuntu unless explicitly told otherwise. For the few moments when I want to boot Windows, I hit F8 after powering up my machine an hit F8 to get the complete list of UEFI boot options and choose Windows from there.