Arch Linux Installation with Fulll Disk Encryption + (Secure Boot, TPM2, UKI and more)

7 minutes read

1. Verify ISO

# Inside the directory of the downloaded iso
b2sum -c b2sums.txt --ignore-missing

or,

sha256sum -c sha256sums.txt --ignore-missing
# First download and import the pulic key in order to verify the signature
gpg --auto-key-locate clear,wkd -v --locate-external-key pierre@archlinux.org

# Then verify
gpg --verify archlinux-2024.01.01-x86_64.iso.sig

2. Connect to the WiFi if not using Ethernet

We can use nmtui which is a terminal user interface. Also we can use iwctl with which we can connect to the WiFi using the following commands.

# Enter the iwctl command environment
iwctl

# List available wifi devices
device list

# Connect to the wifi
station wlan0 connect mywifiname
# It will prompt us to enter the passpharse. SO, enter the passphrase of the wifi.

exit

3. Steps to connect with ssh

# Start the sshd daemon
sudo systemtcl start sshd

# Create a password so that we can login wiht ssh
passwd

4. Check Networks

ping google.com

5. Check EFI Boot Mode

The following should print out something if booted into UEFI Boot mode properly.

efivar -l

Or,

ls /sys/firmware/efi/efivars

6. Set Clock correctly

timedatectl set-ntp true

7. Disk Partitioning

Example partition table (For 1TB Drive)

Example Partition Table partition_table.jpg

Check the correct disk

It should print out the disks and partitions they have. (i.e. “/dev/sda” in this example).

lsblk

Partition with “cfdisk”

cfdisk

8. Prepare the partitions

Format the Boot Partition

mkfs.fat -F 32 /dev/sda1

Create encrypted swap partition

Use cryptsetup-luksFormat(8) to create the encrypted container for the swap partition:

# cryptsetup luksFormat --label swap /dev/sda2

Open the container to /dev/mapper/swap:

# cryptsetup open /dev/disk/by-label/swap swap

Create a swap filesystem inside the mapped partition:

# mkswap /dev/mapper/swap

If not using systemd#GPT partition automounting, add the mapped partition to /etc/fstab by adding the following line:

/dev/mapper/swap none swap defaults 0 0

To set up your system to resume from hibernation, use the resume=/dev/mapper/swap kernel parameter. See Power management/Suspend and hibernate#Pass hibernate location to initramfs for details.

See TPM keys stuff below.

Prepare Btrfs Partition

cryptsetup luksFormat --label cryptpart -v -s 512 -h sha512 /dev/sda3
cryptsetup open /dev/sda3 cryptpart
mkfs.btrfs -L btrfscrypt /dev/mapper/cryptpart
mount /dev/mapper/cryptpart /mnt
cd /mnt

btrfs sub create /mnt/@
btrfs sub create /mnt/@home

umount -R /mnt

See TPM keys stuff below.  

9. Mount the Partitions

mount -o rw,noatime,ssd,space_cache=v2,compress=zstd,discard=async,subvol=@ /dev/mapper/cryptpart /mnt
mount -o rw,noatime,ssd,space_cache=v2,compress=zstd,discard=async,subvol=@home /dev/mapper/cryptpart /mnt/home

mkdir /mnt/boot
mkdir /mnt/efi
mount /dev/sda1 /mnt/efi

10. Install the base system

cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup

pacman -S reflector

reflector --verbose --country BD,DE,HK,IN,SE,CH,SA,US --protocol https --sort rate --latest 20 --download-timeout 6 --save /etc/pacman.d/mirrorlist --score 8
cp /etc/pacman.d/mirrorlist /mnt/etc/pacman.d/mirrorlist
vim /etc/pacman.conf
--------------------
# Add the following lines.
Color
ParallelDownloads = 5
ILoveCandy

[multilib]
Include = /etc/pacman.d/mirrorlist
pacman -Sy
pacstrap -K /mnt base base-devel linux linux-firmware linux-headers linux-zen linux-zen-headers nvim dialog iw wpa_supplicant networkmanager cryptsetup amd-ucode sbctl

11. Generate fstab config

genfstab -U /mnt >> /mnt/etc/fstab

To verify that we can type

cat /mnt/etc/fstab

12. Configure the system in Chroot

arch-chroot /mnt

Set Time-Zone

ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime

hwclock --systohc

Set Localization

echo en_US.UTF-8 UTF-8 >> /etc/locale.gen

locale-gen

Set Language

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

Set Hostname

echo arch > /etc/hostname

Set Root Password

passwd

Create New User

useradd -m -g users -G sys,wheel,adm,log,storage,power -s /bin/bash john

passwd john

Set sudoers

visudo EDITOR=nvim
------------------
# Uncomment or add the following line.

% wheel ALL = (ALL) ALL

Setup /etc/hosts

vim /etc/hosts
-----------------------
127.0.0.1 localhost
:: localhost
127.0.1.1 arch

13. Generate initramfs

echo "quiet rw" > /etc/kernel/cmdline
mkdir -p /efi/EFI/Linux
/etc/mkinitcpio.conf
--------------------------------------------------------------------------------------------------

# vim:set ft=sh
MODULES=()

BINARIES=()

FILES=()

HOOKS=(base systemd autodetect modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)
/etc/mkinitcpio.d/linux.preset
-----------------------------------------------------------------------

# mkinitcpio preset file to generate UKIs

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"
mkinitcpio -P

14. Install the Bootloader

We are using systemd boot here.

bootctl install --esp-path=/efi

15. Install packages

Install some basic packages

pacman -S mesa xdg-user-dirs fuse2 ntfs-3g usbutils cpio git unzip alacritty openssh

Nvidia propieretary stuff

sudo pacman -S nvidia-dkms opencl-nvidia lib32-opencl-nvidia libglvnd nvidia-utils lib32-libglvnd lib32-nvidia-utils nvidia-settings

16. Enable Services

systemctl --enable --startnow NetworkManager
systemctl --enable --startnow wpa_supplicant.service
systemctl --enable fstrim.timer

17. Secure Boot

OK, let’s reboot, and then finish off the installation. Whilst you’re rebooting, head into your UEFI/BIOS and put Secure Boot into “Setup Mode”, you’ll need to check with your PC/Motherboard manufacturer for exact details on how to do that. Basically disabling Secure Boot should put it to “Setup Mode”.

$ sync
$ systemctl reboot --firmware-setup

Ok, now that we’ve rebooted and logged back in (we’re not in chroot anymore we’re inside the actual system), we need to first check that Secure Boot is in “Setup Mode”:

# If sbctl is not installed
sudo pacman -Sy sbctl

# Optionally remove any leftover *.img files
sudo rm -rf /boot/initramfs-*.img
$ sbctl status
Installed:  ✓ sbctl is installed
Setup Mode: ✗ Enabled
Secure Boot:    ✗ Disabled
Vendor Keys:    none

Looks good. Let’s first create and enroll our personal Secure Boot keys:

$ sudo sbctl create-keys
$ sudo sbctl enroll-keys -m

We use the -m option to enroll the Microsoft vendor key as well as our self-created platform key. IF you’re sure that none of your hardware has any OPROMs signed by Microsoft, you can leave this option out. WARNING - Your system CAN get bricked if you’re mistaken. I know it sucks, but it’s usually safer to just install the Microsoft vendor key. YOU HAVE BEEN WARNED!!! :-)

Let’s use sbctl to sign our .efi files. We’ll sign the systemd-boot .efi file, and our UKI files which mkinitcpio is now generating for us. We’ll use the -s option so sbctl will automatically resign them for us when we update the kernel or bootloader through pacman:

$ sudo sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi
$ sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
$ sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi
$ sudo sbctl sign -s /efi/EFI/Linux/arch-linux-fallback.efi
sudo sbctl rm "/efi/EFI/Linux/arch-linux.efi"
sudo sbctl rm "/efi/EFI/Linux/arch-linux-fallback.efi"

This will basically remove the efi binary from the sbctl database which will simply cause sbctl not looking for the efi binary for auto signing.

Let’s reinstall the kernel to make sure it resigns the UKI:

$ sudo pacman -S linux
... (I've cut out the blurb)** ...
(4/4) Signing EFI binaries...
Generating EFI bundles....
✓ Signed /efi/EFI/Linux/arch-linux-fallback.efi
✓ Signed /efi/EFI/Linux/arch-linux.efi

Looking good. Reboot your PC now, so the Secure Boot settings will get saved.  

18. TPM2 Unlocking

Unlocking the Root filesystem with TPM2

Once rebooted we need to configure automatic unlocking of the root filesystem, by binding a LUKS key to the TPM. Let’s generate a new key, add it to our volume so it can be used to unlock it in addition to the existing keys, and bind this new key to PCRs 0 and 7 (the system firmware and Secure Boot state). First things first, let’s generate a recovery key in case it all gets messed up some time in the future:

$ sudo systemd-cryptenroll /dev/gpt-auto-root-luks --recovery-key

Keep this key safe. Keep it hidden. Moving on, we’ll now enroll our system firmware and Secure Boot state. Normally, this would allow our TPM to unlock our encrypted drive, as long as the state hasn’t changed. If you’re particularly paranoid, you can add --tpm2-with-pin=yes, so we get prompted for a PIN code on boot.

$ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7  /dev/gpt-auto-root-luks
$ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+7+11+13+15  /dev/gpt-auto-root-luks

See about TPM PCRs to learn more about them.  

Unlocking the Swap filesystem with TPM2

The following provides unattended swap decryption with a key stored in the TPM.

You can use systemd-cryptenroll to enroll the key to the Luks container and TPM, and wipe the previously created keyslot containing the password:

#Syntax
$ sudo systemd-cryptenroll --tpm2-device auto /dev/device
$ sudo systemd-cryptenroll --wipe-slot password /dev/device

# Example
$ sudo systemd-cryptenroll --tpm2-device auto --tpm2-pcrs=0+1+2+7+11+13 /dev/sda2
$ sudo systemd-cryptenroll --wipe-slot password /dev/sda2

Check the result with

$ systemd-cryptenroll /dev/device
SLOT TYPE
   0 tpm2

19. Reboot

Now we need to reboot and test this. If all goes well, we should be able to unlock our encrypted root partition with just a PIN code.

reboot

20. Install the DE

pacman -S sddm plasma

systemctl --enable --startnow sddm.service

21. Important packages and tweaks (Post Install)

sudo pacman -S gparted nload btop pipewire refelctor devtools xdg-desktop-portal xdg-desktop-portal-kde xdg-user-dirs mpv proton-vpn-gtk-app ufw zsh zsh-autocomplete zsh-completions zsh-syntax-highlighting libreoffice-fresh dnsmasq qemu-desktop virt-manager timeshift cronie dolphin okular gvfs man-db tmux yt-dlp python-mutagen kwallet kwalletmanager gimp
sudo pacman -S ttf-jetbrains-mono-nerd ttf-jetbrains-mono
sudo pacman -S cups system-config-printer skanlite skanpage hplip
sudo pacman -S ffmpegthumbs tumbler

# If something doesn't work, we can try this
sudo pacman -S ffmpegthumbnailer
git clone https://aur.archlinux.org/pikaur.git
cd pikaur
makepkg -si
pikaur -S auto-cpufreq brave-bin vscodium-bin peazip sublime-text-4

sudo systemctl enable auto-cpufreq --now
# First try this
sudo pacman -S vlc vlc-plugin-ffmpeg vlc-plugin-mpeg2 vlc-plugin-x264 vlc-plugin-x265 vlc-plugin-ass vlc-plugin-matroska vlc-plugin-dvd vlc-plugin-bluray vlc-plugin-srt vlc-plugin-soxr libdvdcss libbluray

# If see errors, then try this
sudo pacman -S gst-libav gst-plugins-base gst-plugins-good gst-plugin-pipewire

# If still see errors, then try this
sudo pacman -S libx264 libmpeg2 xvidcore

# If you still see errors, then try this
sudo pacman -S codec2 flac ffnvcodec-headers lib32-flac lib32-libjpeg-turbo lib32-opus lib32-libvpx lib32-speex libde265 libfdkaac libjpeg-turbo libkate libultrahdr libvpx opus sbc speex xvidcore
flatpak install pikabackup
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
mv ~/.config/plasma-localerc ~/.config/plasma-localerc.backup
sudo systemctl enable --now libvirtd cups

Done!