As part of a new homeserver build I plan to finish this year, I wanted to look into where the ecosystem is regarding LUKS volumes unlocked by TPM. This was sparked from how seamless it was when I set up my framework last year.
I gave my self a few conditions for this setup I would like to meet. The first one is Secure boot, it’s 2025, I should be able to do this by now, I also became aware of tooling that makes this easier. I would like this setup to use sdboot, for really no particular reason than to try something else than grub. If I could fulfill this, UKI could also be a additional implementation detail.
I decided to use Ubuntu for this. Ubuntu 24.04 supports setting up LUKS on root as part of its installer, I used that for the initial LUKS setup.
Replacing grub with sdboot
I based this from this Gist comment
This also installs the requisites for creating a Unified Kernel Image with TPM support
|
|
The dependency chain for libtss2-esys
does not include the required sysusers files to create the tss account in the initramfs. This should have been resolved in this commit, but I can only assume the configure script used in debian/ubuntu is not set up to output these (which Arch has done). Therefore we have to grab this manually.
|
|
Now it’s time to reboot, we should now be booting with sdboot, as the systemd-boot
package also installed the bootloader into the EFI partition previously used by grub. We can confirm the bootloader with bootctl
, looking at the product under the current boot loader entry.
Secure Boot
With a touch of FoxWare we can easily achieve Secure Boot. The goal here is to run our own secure boot certificate, and sign the kernel ourself.
I use sbctl for this, as it makes the whole setup painless. It is not currently packed for the default debian/ubuntu repositories, but it is getting there. There is however a community package available in the meantime.
|
|
With sbctl installed, it is now time to create and enroll the needed keys for secure boot. This is just two commands with sbctl. This assumes that your motherboard is already configured to be able to receive custom keys
|
|
At this point we can run sbctl verify
to get a list of entries detected in the bootloader. It should also note these are not currently signed. Now that we have enrolled keys, secure boot should not be in setup mode, and thus require images to be signed.
I like to sign all entries in the bootloader at this stage. I usually do that by assuming all entries are in a couple of directories in /boot
.
|
|
After verifying these are signed, it should now be safe to reboot. In this reboot, it is worth checking with the uefi that secure boot is enabled.
Unified Kernel Image
Now that we have secure boot, as well as sdboot going, we can implement booting with a UKI. This allows us to use some of the measurements UKI booting does, to tie into cryptsetup and automatic LUKS unlocks.
The steps to make this happen differs a bit between versions. The difference might just boil down to me missing something, but my untested theory is that some package has moved the heavy lifting to kernel-install
, as 24.10 also automatically signs the image with sbctl as well as sorting out the bootloader entry.
While writing this, I used both Ubuntu 24.10 and 24.04.
For both versions, I told Dracut to run with hostonly
.
|
|
For 24.10, only
kernel-install
needs to be told to create a UKI.1 2 3
cat << EOF | sudo tee /etc/kernel/install.conf layout=uki EOF
For the current LTS, we need to tell Dracut to create a UKI with the option
--uefi
.1 2 3
cat << EOF | sudo tee /etc/dracut.conf.d/uefi.conf uefi="yes" EOF
As mentioned above, my experience is that there is a couple of manual tasks left to do.
Sign the UKI
Tell the bootloader to use the UKI as the default entry.
You can do this with
bootctl set-default
and pointing it to the entry matching the name Dracut built.
Now we add TPM support to the UKI, by telling Dracut to include the tpm2-tss
module, as well as forcing a build.
|
|
Verify that the image is signed before rebooting.
To verify the UKI was used to boot, we can use bootctl
and check that TPM2 Support
and Measured UKI
are true.
TPM Backed LUKS
For this writeup I used somewhat relaxed measurements. The explanations are fetched from UAPI.
- 0: Core system firmware executable code
- 2: Extended or pluggable executable code; includes option ROMs on pluggable hardware
- 7: SecureBoot state
While testing I used blkid to fetch the mount path or UUID of a device with LUKS set up. This substitution works if there is only one LUKS device in the system.
We can now enroll TPM2 as a keyslot for the LUKS partition.
|
|
Since we use Dracut, we also need to set the crypttab. This line should probably be a sed, but while writing, the Ubuntu installer always set up the LUKS volume with the same name, and this was just easier.
|
|
We should now be able to reboot, without being prompted by the LUKS password.
Updates
Depending on the measurements used, you might have to bind the keyslot again, with the new values of the measurement.
BIOS updates would change the value of PCR0, and thus require a setting the keyslot again.
The command is quite similar to the original enrollment, with the addition of telling it to wipe the previous tpm slot.
|
|