September 30, 2023

Deep in the boot process: systemd-boot

Tuesday, July 04, 2023, Dante Calabresi

Data carriers (especially portable ones) should generally be secured with encryption. One Latest information It prompted me to check my laptop’s encryption.
Result: The LUKS encoder should be updated.
However, it turns out that GRUB doesn’t do that state of the art Supports drive encryption and thus makes booting from a data bus encrypted in this way impossible.
The solution to this is systemd boot.
This is a modern, lightweight bootloader that allows starting GNU/Linux from encrypted data vectors (and much more).

In this article I would like to describe the setup and configuration of the system boot.
A follow-up article may address other possibilities systemd boot on me.

Disclaimer: The easiest way to set up the system boot is to reinstall the GNU/Linux system (eg with archinstall ). This variant must be given preference at all times. The steps mentioned here are for Mainly for teaching purposes They are no way best practices It may stop working after kernel updates.

Systemd boot setup (along with GRUB) using LUKS

I have collected the information for this article from various sources [1]And [2]And [3] This article is based on the structure of Kiwan Tonkabuni’s article.

When working on your system’s boot process, have a backup running duty And you should always have a bootable device USB stick with live system To come in handy in case your system starts up.

Boot status analysis

In a modern UEFI system, the command appears

$ efibootmgr

Displays a list of the current boot options and their order.

See also  'Extremely brutal' gamma-ray bursts hit Earth

BootCurrent: 0004
Timeout: 0 seconds
BootOrder: 0004,0003,0000,0001
Boot0000* UEFI KXG60ZNV1T02 NVMe KIOXIA 1024GB [...]
Boot0001* Linux Firmware Updater [...]
Boot0003* ubuntu [...]
Boot0004* EndeavourOS [...]

In addition, you can

$ mokutil --sb-state

Determine if SecureBoot is enabled. For the purposes of this article, I’m assuming that SecureBoot is disabled (which can at best be modified in your computer’s UEFI BIOS).

In addition, in file /etc/fstab the EFI system section, usually /boot/efirevealing his identity.

install systemd boot

It can be Systemd booted (on the usual path /boot/efi) command

$ bootclt install

Very easy to install. After that it appears in efibootmgr New entry Linux Boot Managerwhich has now become shortening is set.

BootCurrent: 0005
Timeout: 0 seconds
BootOrder: 0005,0004,0003,0000,0001
Boot0005* Linux Boot Manager [...]

Reboot will now fail because systemd boot is active but not configured yet.

System boot configuration

Now we have to make an entry for our system in the new boot manager. These will be in the directory /boot/efi/loader/entries foot. However, this can be done using the command kernel-install Do it automatically.

However, this is where I faced my first challenge. kernel-install creates it initramfs because of /etc/mkinitcpio.conf. However, booting with GRUB requires different kernel parameters than booting systemd, which is why this configuration must be modified.

Since I have my GRUB configuration as to retreat Wanting to keep it, I resorted to the following (slightly not elegant) hack to create the kernel and corresponding portlet:

1. mkinitcpio.conf copy

$ cp /etc/mkinitcpio.conf /etc/mkinitcpio-systemd.conf

2. Kernel parameters in mkinitcpio-systemd.conf customize for systemd boot

HOOKS="systemd keyboard keymap sd-vconsole block sd-encrypt autodetect modconf filesystems fsck"

3. Install the kernel with its customization mkinitcpio-systemd.conf to implement

in the configuration file /usr/lib/kernel/install.d/50-mkinitcpio.install variable GENERATOR_CMD about the following --config complementary argument.

GENERATOR_CMD=(mkinitcpio -k "$KERNEL_VERSION" --config /etc/mkinitcpio-systemd.conf)

Then create your custom kernel (and corresponding portlet).

$ kernel-install -v add $(uname -r) /boot/vmlinuz-linux

Now call

$ bootctl list

entry for the new kernel with _MACHINE_ID_ and _KERNEL_ under `/boot/efi/loader/entries/MACHINE_ID-KERNEL’

This entry must now be modified to run from an encrypted data bus.

To do this, the UUID of the LUKS data bearer must be specified:

$ lsblk --output=NAME,UUID

NAME          UUID
├─nvme0n1p1   XXXX-XXXX
└─nvme0n1p2   39e4d8c4-18b9-11ee-be56-0242ac120002 <<===
  └─cryptroot 21cffcfa-18b9-11ee-be56-0242ac120002

Copy the UUID of the hard disk partition, Not a LUKS container.

The UUID should now be on options in /boot/efi/loader/entries/MACHINE_ID-KERNEL are entered

options    root=/dev/mapper/cryptroot

with bootclt list And efibootmgr Let’s check if everything was transferred correctly.

be brave

After rebooting, the LUKS container password should now be requested during the boot process and then the operating system should start.

In an emergency, you can still start via GRUB via the UEFI boot menu.

In my case, the boot process didn’t work on the first try. After booting with GRUB and another reboot it worked without any issues.

Automatic upgrade

In order for the new kernel to also be installed for systemd boot in case of a kernel upgrade, the following additional modifications are necessary.

customize from kernel-install

in the file /usr/lib/kernel/install.d/90-loaderentry.install He should BOOT_OPTIONS can be modified.


kernel-install automatically

It should also be a file hook It is stored, which is executed when the Linux kernel is updated and kernel-install calls.
The new entry is automatically saved as shortening hiring.

See also  iFixit explains the iPad Mini's "Jelly Scroll" problem in a teardown . video

On my system I have the following file in /usr/share/libalpm/hooks/eos-systemd-boot-update-kernel.hook foot.

Operation = Install
Operation = Upgrade
Type = Package
Target = linux

Description = Update kernel for systemd-boot after upgrading a kernel.
When = PostTransaction
Depends = systemd
Exec = kernel-install -v add $(uname -r) /boot/vmlinuz-linux


Booting with a system boot has some advantages. Among other things, a hardware token for decryption can also be stored in the LUKS header. Thus, the tedious typing of the password at system start-up can be shortened to a FIDO2 token at the press of a button.

I’m going to hold off changing the LUKS address to the current cryptographic algorithms for a bit longer, as this might make my GRUB system impossible to start and I’d like to wait and see how the system behaves with a kernel update.