In traditional Linux boot workflows, the UEFI firmware launches a bootloader such as GRUB, which in turn reads an unauthenticated kernel command line, loads the Linux kernel binary (vmlinuz), and initializes an initial RAM disk (initrd) from an unencrypted boot partition. While UEFI Secure Boot verifies the GRUB binary itself, the subsequent loading of configuration files and initrd archives often leaves the early boot sequence vulnerable to physical tampering, initrd manipulation, and evil maid attacks. The Unified Kernel Image (UKI) specification addresses this vulnerability by combining the UEFI stub loader, kernel image, initrd, os-release metadata, and kernel command line into a single, self-contained, cryptographically signed UEFI PE binary.
In modern Ubuntu installations (including Ubuntu 24.04 LTS), the systemd-ukify utility provides an automated framework to compile, assemble, and sign UKIs directly. This guide details how to install ukify, configure image assembly recipes, embed kernel command lines, sign binaries with local Secure Boot keys, and boot unified images directly through UEFI firmware or systemd-boot.
Understanding Unified Kernel Images and systemd-stub
A Unified Kernel Image replaces separate boot assets with a single Portable Executable (PE) binary executed directly by UEFI firmware. The binary contains distinct PE sections recognized by the systemd-stub bootloader:
.linux: The decompressed or EFI-stub-enabled Linux kernel image (/boot/vmlinuz-...)..initrd: The complete early userspace initial RAM filesystem containing storage drivers and cryptographic unlocking tools..cmdline: The static, immutable kernel command line parameters (such as root partition UUIDs, cgroup configurations, and console settings)..osrel: System identity metadata extracted directly from/etc/os-release..splash: Optional early boot splash bitmap images displayed during hardware handover..tpm2_pcr_sig: Optional cryptographic signatures over pre-calculated TPM2 PCR registers (PCR 11), ensuring the kernel boots only if the exact measured firmware state is preserved.
Because the entire package is signed as a unified binary, any modification to the initrd or kernel command line breaks the cryptographic signature, causing UEFI Secure Boot to halt execution before untrusted code runs.
Installing ukify on Ubuntu
In Ubuntu, ukify is packaged alongside modern systemd utilities. Install the required tools using apt:
# Update package repositories and install ukify and signing tools
sudo apt update
sudo apt install systemd-ukify binutils sbsigntool
To verify that ukify is functional and review the installed version:
# Inspect ukify version and argument flags
ukify --version
Preparing Kernel Command Line and Splash Assets
Because the kernel command line is compiled directly into the binary section, create a configuration file defining your production boot parameters. Avoid referencing volatile device nodes like /dev/sda1; always use persistent filesystem UUIDs:
# Create directory for UKI build assets
sudo mkdir -p /etc/kernel/uki
# Export production kernel command line parameters
echo "root=UUID=$(findmnt / -o UUID -n) ro quiet splash vt.handoff=7" | sudo tee /etc/kernel/uki/cmdline
Verify the contents of the command line definition:
# Inspect generated kernel command line
cat /etc/kernel/uki/cmdline
Generating a Unified Kernel Image Using ukify
To construct a UKI, identify your current running kernel version or target installed kernel. You will combine the UEFI stub (linuxx64.efi.stub), the vmlinuz kernel, the generated initrd.img, and the command line file:
# Set target kernel version variable
KERNEL_VER=$(uname -r)
# Build the unified kernel image binary
sudo ukify build \
--linux="/boot/vmlinuz-${KERNEL_VER}" \
--initrd="/boot/initrd.img-${KERNEL_VER}" \
--cmdline="/etc/kernel/uki/cmdline" \
--os-release="/etc/os-release" \
--output="/boot/efi/EFI/Linux/ubuntu-${KERNEL_VER}.efi"
If the /boot/efi/EFI/Linux directory does not exist on your EFI System Partition (ESP), create it before building:
# Ensure standard EFI Linux directory exists on the ESP
sudo mkdir -p /boot/efi/EFI/Linux
Cryptographically Signing the Image for Secure Boot
To run on hardware with UEFI Secure Boot enabled, the generated UKI must be signed using your custom Machine Owner Key (MOK) or platform signing certificate.
Generating a Custom MOK Key Pair
If you have not already enrolled a local MOK key in the system firmware, generate a 2048-bit RSA key pair:
# Create dedicated directory for local boot keys
sudo mkdir -p /etc/kernel/keys
sudo chmod 700 /etc/kernel/keys
# Generate private key and X.509 certificate
sudo openssl req -new -x509 -newkey rsa:2048 \
-keyout /etc/kernel/keys/db.key \
-out /etc/kernel/keys/db.crt \
-days 3650 -nodes \
-subj "/CN=Ubuntu Local Secure Boot Key/"
Signing during the ukify Build Process
You can pass private keys and certificates directly to ukify build, allowing image assembly and PE signing in a single command:
# Assemble and cryptographically sign UKI in one step
sudo ukify build \
--linux="/boot/vmlinuz-${KERNEL_VER}" \
--initrd="/boot/initrd.img-${KERNEL_VER}" \
--cmdline="/etc/kernel/uki/cmdline" \
--os-release="/etc/os-release" \
--signtool=sbsign \
--secureboot-private-key=/etc/kernel/keys/db.key \
--secureboot-certificate=/etc/kernel/keys/db.crt \
--output="/boot/efi/EFI/Linux/ubuntu-${KERNEL_VER}.efi"
To verify that the resulting binary contains a valid Secure Boot signature:
# Inspect digital signature headers on the generated binary
sbverify --list /boot/efi/EFI/Linux/ubuntu-${KERNEL_VER}.efi
Inspecting Internal PE Sections of the Generated Image
You can verify that all components are correctly mapped inside the resulting binary using objdump or systemd-dissect:
# Inspect PE sections within the UKI binary
objdump -h /boot/efi/EFI/Linux/ubuntu-${KERNEL_VER}.efi
The output confirms the presence and exact byte sizes of the embedded assets:
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000a420 0000000000001000 0000000000001000 00001000 2**4
1 .osrel 00000195 000000000000c000 000000000000c000 0000c000 2**2
2 .cmdline 00000052 000000000000d000 000000000000d000 0000d000 2**2
3 .initrd 02812f80 000000000000e000 000000000000e000 0000e000 2**4
4 .linux 00e48100 0000000002821000 0000000002821000 02821000 2**4
Automating UKI Generation on Kernel Upgrades
To ensure new Unified Kernel Images are built automatically whenever apt installs an updated Ubuntu kernel package, configure a kernel post-install hook in /etc/kernel/postinst.d/:
# Create automated kernel upgrade hook script
cat << 'EOF' | sudo tee /etc/kernel/postinst.d/zz-build-uki
#!/bin/sh
set -e
VERSION="$1"
LOCATION="$2"
if [ -x /usr/bin/ukify ]; then
echo "Generating Unified Kernel Image for kernel ${VERSION}..."
ukify build \
--linux="/boot/vmlinuz-${VERSION}" \
--initrd="/boot/initrd.img-${VERSION}" \
--cmdline="/etc/kernel/uki/cmdline" \
--os-release="/etc/os-release" \
--signtool=sbsign \
--secureboot-private-key=/etc/kernel/keys/db.key \
--secureboot-certificate=/etc/kernel/keys/db.crt \
--output="/boot/efi/EFI/Linux/ubuntu-${VERSION}.efi"
fi
EOF
# Make hook executable
sudo chmod +x /etc/kernel/postinst.d/zz-build-uki
Troubleshooting UKI Generation and Secure Boot Booting
When deploying Unified Kernel Images, keep these key troubleshooting pointers in mind:
- Missing EFI Stub Binary: If
ukifyoutputs an error reporting thatlinuxx64.efi.stubcannot be located, ensuresystemd-bootorsystemd-ukifypackages are completely installed, or specify the stub path explicitly using--stub=/usr/lib/systemd/boot/efi/linuxx64.efi.stub. - ESP Partition Space Exhaustion: Because each UKI contains both the full kernel and compressed initrd (often 60–100 MB per image), maintaining multiple UKIs on a small 100 MB default ESP can exhaust disk space. Resize your EFI System Partition to at least 1 GB when adopting UKI workflows.
- Secure Boot Verification Failed (Access Denied): If the motherboard firmware refuses to launch the UKI with an “Access Denied” or “Invalid Signature” error, verify that the custom MOK certificate (
db.crt) was successfully enrolled into the system NVRAM usingmokutil --import /etc/kernel/keys/db.crtfollowed by a reboot to complete the MOK enrollment dialog.
By leveraging ukify, system administrators can convert standard Ubuntu boot assets into tamper-resistant, standalone UEFI binaries that protect systems against unauthorized boot-level tampering.