Securing My Arch System

Published on 2025-03-01 by Leouob

Foreword

When I was trying to recover the root password of a virtual machine, I was surprised by how easy it could be. All I needed was a single kernel parameter, systemd.debug_shell. For non-systemd distros, init=/bin/bash would also do. Or I could just boot from a live USB and chroot into the system. Why did I not think of this before? As a result, I decided to switch to systemd-boot + LUKS + UKI + Secure Boot.

Full disk encryption

The first thing to do was encrypt the disk. LUKS is the obvious choice for Linux. I just followed the Arch Wiki page. There is even a dedicated section on how to encrypt an existing partition.

After that, I added the sd-encrypt hook to the initramfs. Then, when I was figuring out how I should update my /etc/fstab and /etc/crypttab, I learned that systemd can automatically mount the partitions for me if they have the right partition types.

UKI

Full disk encryption protects against someone with physical access to my laptop. But what if someone tampers with my bootloader? That is where Secure Boot comes in. A UKI (Unified Kernel Image) bundles the kernel, initramfs, and other bits into a single image, which makes it easier to sign for Secure Boot.

I chose mkinitcpio for this, since it is the first option listed. First, I moved my kernel command-line parameters from the systemd-boot configuration to /etc/kernel/cmdline. Then I modified the preset /etc/mkinitcpio.d/linux.preset to generate UKIs. It is fortunate that systemd-boot can pick up UKIs from /boot/EFI/Linux automatically, so I removed the configured systemd-boot entries. So clean!

Secure Boot

Secure Boot is a UEFI feature that helps prevent loading unauthorized binaries. By signing the bootloader and the UKIs, I can ensure that only files signed by me can be loaded. This way, no one can tamper with my bootloader or kernel.

Setting up Secure Boot was a bit trickier. I first tried to follow the "Assisted process with systemd" section of the Arch Wiki page. It seemed to work, but I could not boot into the system and was greeted by an invalid signature error.

After that, I found that more people use sbctl to manage the keys. So I undid the changes I had made and followed the instructions in the sbctl section. I needed to sign more files manually, but it worked on the first try. This part is a little tricky and I am afraid I will forget it, so I will quote it here:

If you use Systemd-boot and systemd-boot-update.service, the boot loader is only updated after a reboot, and the sbctl pacman hook will therefore not sign the new file. As a workaround, it can be useful to sign the boot loader directly in /usr/lib/, as bootctl install and update will automatically recognize and copy .efi.signed files to the ESP if present, instead of the normal .efi file. See bootctl(1).

# sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi

Conclusion

I then completed the setup. It was actually much easier than I had thought (and heard). Some people say that Secure Boot is a Microsoft conspiracy and not worth setting up for a normal user, but with sbctl and other tools, setting up Secure Boot is not that hard. I think it is worth the effort.

References

  1. https://wiki.archlinux.org/title/Reset_lost_root_password
  2. https://wiki.archlinux.org/title/Dm-crypt/Device_encryption
  3. https://wiki.archlinux.org/title/Systemd#GPT_partition_automounting
  4. https://wiki.archlinux.org/title/Unified_kernel_image
  5. https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot