Skip to content

Instantly share code, notes, and snippets.

Arch Install Guide 2025 - PART 1 - Secure Boot and Encrypted Device

Arch Install Guide 2025 - PART 1

Secure Boot and Encrypted Device

Precursor

This guide will install Arch Linux on a Secure Boot enabled drive using block level at-rest LUKS encryption with passwordless unlocking using TPM. TPM will issue an passkey if and only if Secure Boot is enabled and the system firmware has not been altered. We will also be creating a unified kernel image so that we can boot Linux directly in the EFI partition without requiring a boot loader.

We will also be creating a backup key to enable booting of the drive in case of BIOS upgrade or other event that may make TPM not serve the key. The code should obviously be stored securely elsewhere off system.

Note that Arch installation procedures may change from time to time. Be sure to consult the Arch installation guide to check for any differences.

This is part 1. After installing Arch, follow the post install guide (not a gist atm) to install a GUI and all the applications we need to make this our daily driver.

Prerequisites

Download Ventoy and create a bootable USB drive. The command below will use sdb as the bootable drive. Be sure to replace the drive with the correct one.

paru -s ventoy-bin
ventoy -i /dev/sdb # will format device in sdb and make it bootable

Copy the latest Arch linux ISO image to the partition created by Ventoy. Download from here. https://archlinux.org/download/

Ventoy will allow any ISO copied to the partition to be selected during boot, which is pretty cool.

If installing on an existing drive, it is recommended that the existing drive be safely wiped before commencing. See the Secure Wipe wiki article for more info.

We will be following this guide: (part 3) Encrypting_an_entire_system. Reread the guide in case anything has changed since this document was created.

BIOS Configuration & Boot

Boot to BIOS and enter Safe Boot setup mode. For my mother board this means deleting all existing Safe Boot keys. Note that if you have existing drives (including windows on another partition), this could make the drives useless. Do not do this if you want to keep any existing partitions working.

Next select set the BIOS boot order to boot the second UEFI partition on the USB key formatted with Ventoy. We have to load an UEFI partition otherwise we cannot enable secure boot and TPM.

I also had to ensure the following settings were configured in the BIOS…

  • CSM/Boot Device Control: UEFI only
  • CSM/Boot from storage Devices: UEFI driver first
  • Secure Boot: Other OS (not microsoft).
  • Ensure SSD drive is not enrolled in RAID.
  • Advanced/PCH-FW: Set TPM device to Firmware TPM

Also right now you should add a BIOS password as an additional security layer. It isn’t completely necessary as TPM will not release the encryption key if safe boot is disabled.

Save settings and reboot. You should see the Ventoy menu. Check the status bar at the bottom of the menu. It should say UEFI and not Bios.

Boot using normal mode into Arch Live ISO.

Now check we have booted into EFI mode. If this didn’t work, we cannot continue as we need EFI booting enabled to complete this guide.

cat /sys/firmware/efi/fw_platform_size

The efi directory will not exist if boot is using BIOS mode. If this is the case - abort.

Partitioning

List all of your current drives:

fdisk -l

Record the drive you want to install your boot partition and encrypted linux partition on. In my case it is nvme0n1. Replace nvme0n1 with your drive throughout this guide.

gdisk /dev/nvme0n1

n [Enter] [Enter] [Enter] +1024mb [Enter] ef00 [Enter] #efi boot - bigger than needed but meh
n [Enter] [Enter] [Enter] [Enter] 8304 [Enter] # root to be encrypted
p [Enter] # show partitions for double checking
w [Enter] y [Enter] # write partition

I typically have a second HDD drive in my setups (root is normally a SDD). I normally configure a swap file and data space on the second drive.

This is done as follows. Ensure you replace sda with your correct drive:

gdisk /dev/sda

n [Enter] [Enter] [Enter] +64G [Enter] 8200 [Enter] # swap
n [Enter] [Enter] [Enter] [Enter] 8300 [Enter] # remaining as a data drive
p [Enter] # show partitions for double checking
w [Enter] y [Enter] # write partition

Note that I do not typically use LUKS on the data drive. Instead I create a soft link to directories on the data drive (eg typically I have Downloads, Pictures (like wallpaper etc - not personal pics), Videos (like tv series etc - not personal vids) etc on the data drive) to the user's home drive on the root which I keep on the encrypted root partion. I then enable flags such as nodev, nosuid and noexec on the data drive. If you do require encryptionon the data drive, consider using encfs(https://wiki.archlinux.org/title/EncFS) or a similar file system that allows inidividual directory encryption with the possibility of auto unlocking on login.

OK now we are going to create an encrypted drive with a blank password. This is OK as later we will use TPM to add a passkey.

Create an encrypted partition and mount it:

cryptsetup luksFormat /dev/nvme0n1p2 # use an empty passphrase
cryptsetup open /dev/nvme0n1p2 root
mkfs.ext4 /dev/mapper/root # or use your fs type of choice
mount /dev/mapper/root /mnt

Prepare the EFI partition and mount:

mkfs.fat -F 32 /dev/nvme0n1p1
mount --mkdir /dev/nvme0n1p1 /mnt/boot

If you have created is a swap file, enable it:

mkswap /dev/sda1
swapon /dev/sda1

If you created a data drive, mount it now.

mkdir /mnt/mnt/data
mount /dev/sda2 /mnt/mnt/data

Install Arch

timedatectl
pacstrap -K /mnt base linux linux-firmware nano sudo intel-ucode

Note that install may fail due to old keyrings if using an old boot usb. To fix, run the following and then rerun the pacstap command:

# ONLY IF NEEDED \
pacman -Sy archlinux-keyring && pacman -Syy

Now we will enable fstab. We only need this if there are other drives or maps we want to include that are additional to the encrypted root drive.

# ONLY IF NEEDED
genfstab -U /mnt >> /mnt/etc/fstab
nano /mnt/etc/fstab

And remark out the root and boot drive (as we are going to boot directly to root).

It is probably a good idea to tighten up your data drive too now (if added) and disable execution. Note this will make the data drive just that - a data drive. Do not do this if you want to allow scripts or bin files to be executed from the data drive. See security guide for more dtails.

Add nodev,nosuid,noexec to the data drive mount point. Eg:

# /dev/sda2 LABEL=data
UUID=df4092d0-60b0-407d-960e-29589fee40db       /mnt/data       ext4            rw,relatime,nodev,nosuid,noexec 0 2

Now:

arch-chroot /mnt

passwd # set root password. Make it good.

ln -sf /usr/share/zoneinfo/Australia/Brisbane /etc/localtime

hwclock --systohc

echo en_US.UTF-8 >> /etc/locale.gen
locale-gen
echo LANG=en_US.UTF-8 >> /etc/locale.conf

touch /etc/vconsole.conf

echo YOUR_HOST_NAME >> /etc/hostname # replace YOUR_HOST_NAME with a name for your device (eg mydevice)
echo “127.0.0.1 localhost” >> /etc/hosts
echo “::1 localhost” >> /etc/hosts
echo “127.0.1.1 $HOSTNAME.localdomain $HOSTNAME” >> /etc/hosts

pacman -S networkmanager # wpa_supplicant if using wifi
systemctl enable NetworkManager

Update kernel hooks:

nano /etc/mkinitcpio.conf

And scroll down to hooks line and set as follows:

HOOKS=(base systemd udev autodetect microcode modconf kms keyboard sd-vconsole consolefont block sd-encrypt filesystems fsck)

Prepare Bootloader

Now we need to create a unified kernel image. This is an image that can be booted dreictly from an UEFI firmware. See Unified_kernel_image.

nano /etc/mkinitcpio.d/linux.preset

Make sure the boot file looks like this:

ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default' 'fallback')
default_uki="boot/EFI/Linux/arch-linux.efi"
default_options="--splash=/usr/share/systemd/bootctl/splash-arch.bmp"
fallback_uki="boot/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"

Now:

bootctl install
mkinitcpio -P

exit
reboot #remove usb key

Secure Boot

Enter the BIOS settings and enable Secure Boot. For me this meant setting the mode to “Windows EFI”. Do not install any default secure boot keys - we will be adding them in the next steps.

pacman -S sbctl

sbctl create-keys
sbctl enroll-keys -m
sbctl status
sbctl verify

Sign all the files listed in the verify step. The list so far should be:

sbctl sign -s /boot/vmlinuz-linux
sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI
sbctl sign -s /boot/EFI/Linux/arch-linux-fallback.efi
sbctl sign -s /boot/EFI/Linux/arch-linux.efi
sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efi

sbctl verify

Check all files are verified and then reboot.

Enroll With TPM

This will add a passphrase to the drive and enroll it with TPM. TPM will automatically provide the passphrase as long as Secure Boot is enabled and the firmware passes a checksum test.

Copy the recovery key somewhere safe (and not accessible by others) off system. It will be needed if TPM does not provide the key:

systemd-cryptenroll /dev/nvme0n1p2 --recovery-key
systemd-cryptenroll /dev/nvme0n1p2 --wipe-slot=empty --tpm2-device=auto

If you get an error, try this to see if there is a valid TPM device using this command:

systemd-cryptenroll --tpm2-device=list

If no device is found, check the BIOS to ensure TPM is enabled. For me, I had to switch to Internal TPM instead of discrete TPM.

Reboot.

Swap File Encryption

If you created a swap file, we will now encrypt the swap file for added system security. We will be using this guide. Read it to ensure nothing has changed since this document was authored.

We are going to disable hibernation and implement a non-hybernate swap file. I don't like or use hybernation so for me it is easier to disable. If you do use it, I'd suggest you skip.

First we need to disable hibernation in the OS:

mkdir /etc/systemd/sleep.conf.d/
nano /etc/systemd/sleep.conf.d/00-disable-hibernation.conf

## [Sleep]
AllowHibernation=no
AllowSuspendThenHibernate=no
AllowHybridSleep=no

Run this command to see which drive has swap file enabled. Record it. My swap drive is sda1. Make sure to replace this with the correct drive. You will need to start the installation process all over if you get this wrong.

swapon --show

Now switch off swap.

swapoff /dev/sda1

Now we are going to format the swap file so that we can keep a consistent label. If we don’t do this the drive will be completely encrypted each time and the label will not be available on boot. Note that this is a safeguard as adding the wrong drive to crypttab below will erase the contents - so this measure ensures that no matter what happens on the system, we will not erase the wrong drive in the future. This is kind of cool - it creates a 1MB fake drive with a label and the swap partition is then added after it. Smart thinking whoever came up with that.

mkfs.ext2 -L cryptswap /dev/sda1 1M

Enable decryption. This will create a random key so that the swapfile is useless after the system is shut down:

nano /etc/crypttab

swap  LABEL=cryptswap  /dev/urandom  swap,offset=2048,cipher=aes-xts-plain64,size=512,sector-size=4096

Update fstab to auto mount the swap file:

nano /etc/fstab

/dev/mapper/swap  none   swap     defaults        0 0

Reboot.

Post Configuration

This guide ensures a safe, encrypted and bootable version of Arch Linux.

Now that Arch is up and running, we can now follow the post installation guide (not available atm) to install a GUI and other applications.

@mark-akturatech
Copy link
Author

mark-akturatech commented Feb 17, 2025

Encrypt data drive and auto unlock at boot using key file on encrypted root driver:

cryptsetup luksFormat /dev/sda2 # use an empty passphrase
cryptsetup open /dev/sda2 data
mkfs.ext4 /dev/mapper/data
mount --mkdir /dev/mapper/data /mnt/data
dd if=/dev/urandom of=/root/.data-keyfile bs=1024 count=4
chmod 0400 /root/.data-keyfile
chown root:root /root/.data-keyfile
cryptsetup luksAddKey /dev/sda2 /root/.data-keyfile
blkid | grep /dev/sda2 >> /etc/crypttab
nano /etc/crypttab
#turn the uuid line we just added in to the following (using the UUID as applicable)
data UUID= /root/.data-keyfile luks,discard
nano /etc/fstab
/dev/mapper/data /mnt/data ext4 rw,relatime,nodev,nosuid,noexec 0 2

This seems to break swap though.
needed to change swap to use /dev/sda1 in the crypttab file. this isn't optimal but somehow the swap label is being removed after each boot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment