Ubuntu Secure Boot

Installing Ubuntu with encryption enabled only encrypts the root folder. That is enough if you’re only worried about someone stealing your laptop and seeing your files. However, there is another attack vector: someone gains access to your laptop, modifies the kernel (he can since it’s on unencrypted /boot) and hands it back, without you knowing. If you want to defend against that, read on.

The default UEFI installation of Ubuntu works as follows:

  1. It uses GRUB which installs /boot/efi/*/shimx64.efi/shimaa64.efi file, which is cryptographically signed by Microsoft. If you have Secure Boot enabled in your BIOS, it will check the signature and will reject to boot if this file is changed.
  2. Shim boots grub.efi, which is the GRUB itself. The signature of this file is checked not by Secure Boot, but by shim*.efi instead, which is enough.
  3. GRUB then loads kernel and initrd image from /boot and runs it.
  4. Kernel+initrd locates encrypted root, allows you to input the password and continue with the boot process.

The problem is step 3 - the /boot partition is unencrypted and can be tampered by the attacker.

GRUB + Encrypted /boot

One idea is to encrypt /boot itself, with LUKS/LVM, and have GRUB ask for password and decrypt /boot. Unfortunately this won’t work since GRUB’s support for encrypted /boot is limited. In short, GRUB only supports LUKS1 and has limited support for LUKS2: it only supports PBKDF2 and not Argon2.

All distros use LUKS2 and Argon2, and you should too. However, that renders this option not applicable.

You can try install Ubuntu Server and put /boot on an encrypted LUKS/LVM volume - the installer will allow you to do that, but the installation will crash at some point.

Unified Kernel Image (UKI)

There’s another way. We can package kernel and initrd into one efi file, sign it, and have GRUB or systemd-boot run that. That’s UKI. You have two options:

  1. Use mkinitcpio to build UKI and continue using GRUB, or
  2. Use systemd-boot with systemd-ukify.

virt-manager + Secure Boot

The best way to test this is to setup Ubuntu Desktop in a VM, say via virt-manager.

Since Ubuntu 22.04, both TPM2.0 and Secure Boot is supported by virt-manager; make sure to have the ovmf package installed, and your VM is using UEFI instead of virt-manager’s default BIOS. Also, make sure to include the TPM in your VM: add the TPM hardware to your VM and make sure it’s Model CRB Version 2.0. Also, go to “Boot Options” and enable “Enable boot menu”: this gives you time to press F2 when the VM boots, to go into BIOS and confirm that Secure Boot is indeed enabled.

systemd-boot with systemd-ukify

To setup systemd-boot, you need to install it:

$ sudo apt install systemd-boot

This installs systemd-boot-efi and a bunch of other dependencies. This also automatically creates entries in /boot/efi and adds EFI systemd boot option to the EFI non-volatile RAM called “Linux Boot Manager” which you can now choose to boot from, in your BIOS UEFI boot menu.

Note that the GRUB shim.efi and grub.efi are still around. That means that you can now pick how you want your system to boot, via your UEFI BIOS boot menu:

  • choosing Ubuntu boots your Ubuntu via GRUB
  • choosing “Linux Boot Manager” boots your system via systemd-boot.

Unfortunately, systemd-boot won’t boot with Secure Boot on, since systemd-bootx64.efi isn’t cryptographically signed correctly. We’ll fix that later on.

systemd-ukify

There is surprisingly not much information at systemd documentation page; some information can be found at kernel-install man page. There’s a great tutorial at copyninja.in.

To install ukify:

$ sudo apt install systemd-ukify

However, nothing really happens yet. You need to activate UKI, by creating /etc/kernel/install.conf with these contents:

layout=uki

More info at ArchLinux: kernel-install.

Now you need to reinstall kernel module, to run kernel-install:

$ sudo dpkg-reconfigure linux-image-$(uname -r)

This creates the .efi file named EFI/Linux/*-generic.efi and also adds an entry to the systemd boot list, as can be verified with

$ sudo bootctl list

You can now unlink all Type #1 entries, via sudo bootctl unlink command. Reboot - your system should now boot using the UKI .efi kernel.

Signing .efi for Secure Boot

Lots of information in this regard at copyninja.in - TODO review.

TODO how to sign ukify-generated efi file via /etc/kernel/uki.conf (see example in /usr/lib/kernel/uki.conf). TODO where are the keys/certificates? Probably I need to generate those and register them via MOK utility.

AI-generated stuff which sounds helpful: Configure ukify to sign the UKI. This involves creating a signing key and certificate, which can be done with ukify genkey using a configuration file. The generated keys and certificates are then used by ukify to sign the UKI during the build process.

Also, ArchWiki kernel-install mentions kernel-install inspect but it fails on Ubuntu.

Script 91-sbctl.install is mentioned which looks interesting, but doesn’t exist on Ubuntu. sbctl does not exist on Ubuntu either.

Also, AI mentions that ukify is not really ready to be used in Ubuntu since the necessary script hooks are missing.

Remove the /boot partition

Copy all files from the /boot partition to your root partition, then unmount the /boot partition:

$ sudo cp -ax /boot /boot2
$ sudo umount -l /boot
$ sudo rm -rf /boot
$ sudo mv /boot2 /boot

Uncomment the /boot partition from /etc/fstab and reboot. Your system now boots without an unencrypted /boot partition! You can nuke the /boot filesystem via mkfs.ext4 or remove the original /boot partition, to make sure that it isn’t used anymore.

Even better - you can leave the partition as-is, as a honeypot for the attacker. However, the attacker may reconfigure your laptop to boot via GRUB - this can be done not just via BIOS (which should be protected via password), but also by booting his Linux via USB and running efibootmgr.

Nuke GRUB?

Now that /boot partition is gone, GRUB can’t boot your system anymore, and therefore you can nuke it. Unfortunately that’s not easy since trying to remove grub removes shim-signed and mokutil and amd64-microcode and we might need those in the future. A better option is to keep GRUB installed and .efi files registered to UEFI nvram: simply never boot “Ubuntu” UEFI boot item and you’re fine. Alternatively you can disable GRUB updates, but that’s not a good idea since it may disable updates to amd64-microcode and you want that thing to be updated.

Best thing is to leave GRUB as-is. The amd64-microcode goes into initrd anyway, which is then built into UKI .efi and therefore taken into effect also via systemd-boot.

Protect BIOS

Password-protect the BIOS. This prevents the attacker from changing the default boot option from the BIOS boot menu (F2).

An attacker can insert rogue Linux on USB stick, press F12, boot from USB stick and tamper the UEFI boot menu via efibootmgr. Disable or password-protect the F12 boot menu.

Written on September 18, 2025