Encryped Arch Linux Install Guide
After corebooting my Thinkpad T480 I wanted to increase the security of the system further by installing Arch Linux with full disk encryption and a Unified Kernel Image signed with my own keys.
Pre-Installation
Download installation image
Download the latest ISO from here.
I like to verify the file hash of the image when downloading from a mirror.
Download the b2sums.txt from the download page and place it in the same folder as the downloaded image. Verify the checksums with b2sum -c b2sums.txt.
b2sum -c b2sums.txt
---
archlinux-2026.04.01-x86_64.iso: OK
Write the image to the USB with dd:
sudo dd if=archlinux-2026.04.01-x86_64.iso of=/dev/sdb bs=8M status=progress
Replace sdb with the device identifier of your USB.
Boot the live system
Make sure to disable Secure Boot, as the installation image does not support it.
Set keymap
The Arch Linux installation image comes with US keymap by default. If not on a US keyboard, list the keymaps with:
localectl list-keymaps
Load a keymap (e.g. german):
loadkeys de-latin1
If on high-DPI screen, increase the font size (-d for double):
setfont -d
Configure networking
An Ethernet cable is preferred for simplicity. If you want to use WiFi, use iwd:
iwctl
[iwd] device list
[iwd] station wlan0 scan
[iwd] station wlan0 connect WIFI_NAME
# Enter your Password
# Check Connection
[iwd] station wlan0 show
[iwd] exit
Test network connectivity:
ping archlinux.org
(Optional) SSH into the live installer from a different system
If you have a second system available, you can use that to SSH into the live installer, enabling you to copy/paste commands directly and prevent typos.
- Run
passwdto set a password for the root user. - Add
PermitRootLogin yesto/etc/ssh/sshd_config. - Run
systemctl restart sshdto apply the configuration change. - Get your IP address by typing
ip a. - On the secondary machine, enter
ssh root@<ip-address>and enter the newly created password.
Setup the system clock
The live system needs the current precise time for package verification and to prevent TLS certificate errors. Set the time with timedatectl:
timedatectl set-ntp true
timedatectl list-timezones
# Example
timedatectl set-timezone Europe/Amsterdam
# Check status
timedatectl
Partition your disk
List the available devices:
fdisk -l
In the case of my ThinkPad T480 I have /dev/nvme0n1.
Use cfdisk to format the device:
cfdisk /dev/nvme0n1
You probably already have partitions on your disk. Delete all of them so you only have Free Space available.
You will need to create the following partitions:
| Mount Point | Size | Type |
|---|---|---|
| /boot | 1G | EFI System |
| / | Remainder of the device | Linux Filesystem |
Create the boot partition: select [Free Space], enter 1G for the size and select [Type] to change the type to EFI System.
For the root partition select [Free Space] - press Enter on the size to select the remainder of the space. The Type is Linux Filesystem by default.
Select [Write] to write the changes to disk.
You can display your created partitions with lsblk.
Format your partitions
Format the EFI partition as FAT32:
mkfs.fat -F32 /dev/nvme0n1p1
Encrypt the root partition and open it:
cryptsetup luksFormat --type luks2 /dev/nvme0n1p2
cryptsetup open /dev/nvme0n1p2 cryptroot
Create the file system:
mkfs.ext4 /dev/mapper/cryptroot
Mount the file systems
Mount the root volume to /:
mount /dev/mapper/cryptroot /mnt
Mount the EFI partition:
mount --mkdir /dev/nvme0n1p1 /mnt/boot
Check that both are mounted with lsblk.
Install the Base System
Install the base system with pacstrap:
pacstrap -K /mnt base linux linux-headers linux-firmware networkmanager cryptsetup sudo neovim base-devel efibootmgr systemd-ukify sbsigntools efitools
Generate the file system table
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab
Harden the boot partition, by adding fmask=0137, dmask=0027 so only root can write, everybody else is blocked. Your fstab should look like this:
UUID=XXXX-XXXX /boot vfat rw,relatime,fmask=0137,dmask=0027,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2
Chroot into the new installation
You can directly interact with the new systems tools and configurations by changing root into the root volume:
arch-chroot /mnt
Create a user and set the password:
useradd -m -G wheel -s /bin/bash user
passwd user
Set the root password:
passwd
Configure sudo for the wheel group by editing /etc/sudoers and uncommenting the following line:
%wheel ALL=(ALL:ALL) ALL
Localization
To use the correct language-specific formatting edit, edit /etc/locale.gen and uncomment the locales you want to have on your system. After doing that, run locale-gen to generate them.
Edit /etc/locale.conf to set you default locale:
/etc/locale.conf
---
LANG=en_US.UTF-8
If not on a US keyboard, persist the keymap with vconsole.conf:
/etc/vconsole.conf
---
KEYMAP=de-latin1
Configure the initramfs
initramfs stands for initial RAM file system and provides the necessary tools to locate, access and mount the root file system. mkinitcpio is a script used to create the initramfs.
Edit /etc/mkinitcpio.conf and set the MODULES, FILES and HOOKS:
# Only needed if using an NVMe drive
MODULES=(nvme)
FILES=(/etc/crypttab.initramfs /etc/vconsole.conf)
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
To tell the initramfs where the encrypted partition is located, create the file /etc/crypttab.initramfs and add the UUID of the encrypted partition:
nvim /etc/crypttab.initramfs
---
cryptroot UUID=your-uuid-here none luks,discard
Edit the mkinitcpio kernel preset
A mkinitcpio preset is simply a list of information required to create initial ramdisk image. It is also used to automatically regenerate the image after a kernel update.
Edit /etc/mkinitcpio.d/linux.preset:
/etc/mkinitcpio.d/linux.preset
---
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default' 'fallback')
# If you want a splash screen image uncomment this line:
# default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
default_uki="/boot/EFI/Linux/arch-linux.efi"
fallback_uki="/boot/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"
Install the bootloader and set up the UKI
The next part is going to cover the setup of the Unified Kernel Image, as well as the install of the systemd-boot bootloader.
Setup the kernel cmdline
First you need to configure the kernel cmdline to be able to look up and unlock the enrcrypted cryptroot partition.
Save the UUID of the partition with blkid and save it to a temporary file:
blkid /dev/nvme0n1p2 > /tmp/uuid.txt
Add the following line to /etc/kernel/cmdline:
nvim /etc/kernel/cmdline
---
rd.luks.name=your-uuid-here=cryptroot root=/dev/mapper/cryptroot rw quiet
Configure the UKI
Copy the default configuration to /etc/kernel/uki.conf and edit it:
cp /usr/lib/kernel/uki.conf /etc/kernel/uki.conf
Uncomment the following to configure the location of the secure boot certificate and signing key:
nvim /etc/kernel/uki.conf
---
[UKI]
SecureBootPrivateKey=/etc/kernel/secure-boot-private-key.pem
SecureBootCertificate=/etc/kernel/secure-boot-certificate.pem
SignKernel=yes
Generate the certificate and key:
ukify genkey --config /etc/kernel/uki.conf
Build the UKI
Create the directory for the UKI and build the image:
mkdir -p /boot/EFI/Linux
mkinitcpio -P
Verify the build:
ls /boot/EFI/Linux/
---
# should show:
arch-linux.efi arch-linux-fallback.efi
Install the systemd-boot
Use bootctl to install systemd-boot to the EFI system partition (/boot):
bootctl install
Lock down the permissions:
chmod 700 /boot
chmod 600 /boot/loader/random-seed
Configure the options of systemd-boot in /boot/loader/loader.conf:
nvim /boot/loader/loader.conf
---
timeout 4
console-mode auto
auto-entries 1
secure-boot-enroll force
Verify the bootloader status:
bootctl status
Sign the bootloader and prepare enrollment
Sign the bootloader EFI binary:
/usr/lib/systemd/systemd-sbsign sign \
--private-key /etc/kernel/secure-boot-private-key.pem \
--certificate /etc/kernel/secure-boot-certificate.pem \
--output /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed \
/usr/lib/systemd/boot/efi/systemd-bootx64.efi
Install the keys for auto-enrollment:
bootctl install \
--secure-boot-auto-enroll yes \
--certificate /etc/kernel/secure-boot-certificate.pem \
--private-key /etc/kernel/secure-boot-private-key.pem
Verify the .auth files are available:
ls /boot/loader/keys/auto/
---
KEK.auth PK.auth db.auth
Fix the boot partition permissions:
chmod 700 /boot
That’s everything done from inside the live system. For networking to work after reboot, enable NetworkManager. Exit the chroot environment, unmount the partitions and close the encrypted partition before reboot.
systemctl enable NetworkManager
exit
umount /mnt/boot
umount /mnt
cryptsetup close cryptroot
reboot
Enroll the Secure Boot keys
Auto-Enrollment
For automatic enrollment to work you need to delete the Secure Boot Platform Key (PK) in the firmware interface (UEFI) of your device. This will enter Setup Mode.
In my Tianocore firmware menu the process is as follows:
- Boot into the UEFI firmware interface (
EscorF2during startup) - Go to Secure Boot Configuration
- Change Secure Boot Mode to Custom Mode
- In Custom Secure Boot Options, remove the PK entry (this will enter Setup Mode)
- Reboot - systemd-boot will display a timer and automatically enroll your keys
- After sucessfull enrollment Reboot again and turn on Secure Boot
After rebooting one more you can check the bootloader status with:
bootctl status | grep -i secure
# should include `Secure Boot: enabled (user)`
Manual enrollment
In case the auto-enroll does not work (as it did for me the first time I flashed a T480), you can enroll the certificates manually.
Create a temporary directory and generate the required files:
mkdir -p ~/secureboot
Convert the secure boot certificate to DER format:
sudo openssl x509 -in /etc/kernel/secure-boot-certificate.pem -out ~/secureboot/db.cer -outform DER
Convert to the signature list as well:
cert-to-efi-sig-list /etc/kernel/secure-boot-certificate.pem ~/secureboot/db.esl
Sign the list:
sudo sign-efi-sig-list \
-k /etc/kernel/secure-boot-private-key.pem \
-c /etc/kernel/secure-boot-certificate.pem \
db ~/secureboot/db.esl ~/secureboot/db.auth
Copy the files to the EFI system partition:
sudo cp ~/secureboot/db.cer /boot/db.cer
sudo cp ~/secureboot/db.auth /boot/db.auth
Reboot and enter the Tianocore firmware menu.
Navigate to Device Manager → Secure Boot Configuration → Custom Secure Boot Options → DB Options → Enroll Signature → Enroll Signature Using File - Choose db.cer.
Provide a valid GUID when asked (in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Make sure Secure Boot is enabled, commit the changes and reboot once more.
After the reboot, check the bootloader status with:
bootctl status | grep -i secure
# should include `Secure Boot: enabled (user)`
After sucessfull enrollment you can delete the enrollment files:
sudo rm /boot/db.cer /boot/db.auth