SDB:Static Initrd and Unified Kernel Image
Introduction and Motivation
An unsigned initrd
The initramfs (or initrd) is a compressed archive generated by dracut (mkosi-initrd, ...). It contains the minimal set of services needed in order to mount the root file system and in this case the initramfs can only be used by the system it was generated on. Therefore, as built locally in the machine, it cannot be signed by the vendor. The bootchain isn't entirely secure and an attacker could change or corrupt the cpio archive, containing the initramfs.
Use static initrd and Unified Kernel Image
To improve security of the boot chain, one idea would be to build a static initramfs on the vendor side and let him sign it. We used OpenBuildService (OBS) to build this project and provide it through the package manager in the distribution. In order to provide more robust and secure images, the next step starting from the static initrd, is to use the Unified Kernel Image (UKI). It provides an all-in-one EFI binary containing Kernel, Modules, initramfs, kernel-cmdline-parameters, etc..It centralizes all builds, where the Kernel and the initrd are build from the OBS, and everything is signed one-time. The distribution becomes more robust and more secure
Important links
Install a static initrd and an Unified Kernel Image from Factory
Install the unsigned static initrd
sudo zypper install static-initrd-<flavor>-unsigned
- A static initrd will be installed into
/usr/share/initrd/static-initrd-<flavor>-<kernel_version>.unsigned
- A flavor is a "dedicated" initrd, for specific use-cases, e.g.:
- "generic" → Contains all modules to be the most generic initrd as possible, should works for the most cases.
- "base" → Contains the minimum set of modules, could not work for all use-cases and needs to be extended via add-ons
- "network" → An example of a dedicated initrd, which contains the basics and all "network" modules
- All flavors are built unsigned. Unsigned ones are made to be used with the UKI project (see next sections). It is also useful to test the static initrd without caring about signatures.
localhost:~ # zypper se -t package static-initrd-* Loading repository data... Reading installed packages... S | Name | Summary | Type ---+--------------------------------+--------------------------------+-------- | static-initrd-base-unsigned | Unsigned static base initrd | package | static-initrd-generic-unsigned | Unsigned static generic initrd | package | static-initrd-network-unsigned | Unsigned static network initrd | package
Add bootloader entry
- Requires the uki-tool package
sudo zypper install uki-tool
- Call the command to add the bootloader entry (/!\ Put the same kernel version used to build the static initrd, found in the initrd filename)
# For grub2 uki-tool grub2 --add --initrd /usr/share/initrd/static-initrd-generic-<kernelver>.unsigned --kerver <kernelver> # For sdboot uki-tool sdboot --add --initrd /usr/share/initrd/static-initrd-generic-<kernelver>.unsigned --kerver <kernelver> # To see entries at boot with sdboot, edit the /boot/efi/loader/loader.conf with "timeout 5"
Install the Unified Kernel Image (uki-<kernel_flavor>)
# UKI based on the "default" kernel flavor sudo zypper install uki-default
The package will:
- install the UKI into
/usr/lib/modules/${uname}/uki-<kernel_flavor>-<uki_version>.efi
- Install the certificate to enroll into
/usr/share/unified/certs/uki-<kernel_flavor>-<uki_version>-<cert_id>.crt
- According to your bootloader add a new menu entry
Remove installed static initrd and UKI
Remove the unsigned static initrd
sudo zypper remove static-initrd-<flavor>-unsigned # for grub2 uki-tool grub2 --remove --initrd /boot/static-initrd-<flavor>-<kernelver>.unsigned # for sdboot uki-tool sdboot --remove --initrd /boot/efi/<machine-id>/<kernelver>/static-initrd
Remove the UKI
sudo zypper remove uki-default
Experimentation
UKI extension
Extensions are placed into an extra UKI directory:
- Global extra in
/usr/lib/modules/uki.extra.d
- UKI specific extra in
/usr/lib/modules/$(uname -r)/${uki_name}.efi.extra.d/
(/usr/lib/modules/6.9.1-1.foo/bar_123.efi.extra.d/
)
Build locally using the uki-tool
ukit extension\ --packages "strace"\ --type raw\ --arch x86_64\ --uki /usr/lib/modules/$(uname -r)/${efi_file}\ --name strace
This example creates a formatted extension, containing strace, including its dependencies, named "strace"
localhost:~ # ukit extension -n "debug" -p "strace" -u /usr/lib/modules/6.9.7-1-default/uki-0.1.0.efi [INFO] Check the uki /usr/lib/modules/6.9.7-1-default/uki-0.1.0.efi and extract the initrd... [INFO] Create the extension 'debug-ext.raw' with 'strace' in format squashfs at type raw for the uki /usr/lib/modules/6.9.7-1-default/uki-0.1.0.efi [INFO] Get all dependencies to install... [INFO] Create an image of sized 18M... [============================================================================================================================================================================================================================================================================================================\] 200/200 100% [INFO] extension image created at ./debug-ext.raw localhost:~ # cp ./debug-ext.raw /boot/efi/EFI/opensuse/uki-0.1.0.efi uki-0.1.0.efi uki-0.1.0.efi.extra.d/ localhost:~ # cp ./debug-ext.raw /boot/efi/EFI/opensuse/uki-0.1.0.efi.extra.d/
Install through packages
Will come soon ...
Work with snapshots
Add-ons
To work with snapshots for UKI, we need to use the UKI's "add-ons" feature. Add-ons are companions files as for extensions and they aim to dynamically add cmdline options. For snapshots, we would need the add-ons that adds one rootflag option to specify the correct snapshots.
EFI specific add-ons
To answer this problem, goal is to create a new kind of add-on, where the add-on will need to be chosen in the menu entry of the bootloader to be loaded with the UKI. For example with grub2, you would need to have the keyword "add-on" from the grub.cfg following the path to the binary to load.
In investigation ...
Snapper plugin
To automatically deal with snapshots for sd-boot or grub2, a snapper plugin can be developed.
In investigation ...
UKI profiles
In investigation ...