Linuxpad

Got Linux?

Arch linux Installation With Luks + Btrfs + Uki + Secure Boot

Arch linux Installation With Luks + Btrfs + Uki + Secure Boot

Arch Linux is a lightweight, flexible, and user-centric Linux distribution designed for competent users who value simplicity, control, and up-to-date software. It follows a rolling release model, meaning it continuously receives the latest stable versions of software without requiring full system upgrades. My servers are powered by Arch Linux over my favorite Gentoo, due to the fact that I don't want to spend time compiling on a low resource pc.

Now if you prefer this great setup on your pc or laptop as your daily driver, follow the steps below to get this done.

Boot from a valid Arch ISO, configure the network, and set up SSH if possible.

Set up your UEFI Standard partition layout

cfdisk /dev/nvme0n1
Device          Start       End         Sectors    Size   Type
/dev/nvme0n1p1  882423808   884520959   2097152    1G     EFI System
/dev/nvme0n1p2  34816       629198847   629164032  300G   Linux filesystem

Encrypt your block device for root filesystem{#2}

cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 --pbkdf argon2id --pbkdf-memory 1048576 --iter-time 4000 /dev/nvme0n1p2

cryptsetup open /dev/nvme0n1p2 root

Create filesystems{#3}

mkfs.vfat -n ArchBoot -F 32 /dev/nvme0n1p1
mkfs.btrfs -L ArchRoot /dev/mapper/root

Setup Mounts

mount LABEL=ArchRoot /mnt

# Create btrfs subvolumes accordingly your needs
btrfs su cr /mnt/{@,@home,@.snapshots,@opt,@srv,@db,@log,@tmp,@crash,@spool,@systemd,@NetworkManager,@pkg,@boot}

umount -l /mnt

mount -o subvol=@ LABEL=ArchRoot /mnt/

mkdir -p /mnt/{home,.snapshots,opt,srv,boot,efi,var/{db,log,tmp,crash,spool,lib/{systemd,NetworkManager},cache/pacman/pkg}}

mount -o subvol=@home LABEL=ArchRoot /mnt/home
mount -o [email protected] LABEL=ArchRoot /mnt/.snapshots
mount -o subvol=@opt LABEL=ArchRoot /mnt/opt
mount -o subvol=@srv LABEL=ArchRoot /mnt/srv
mount -o subvol=@db LABEL=ArchRoot /mnt/var/db
mount -o subvol=@log LABEL=ArchRoot /mnt/var/log
mount -o subvol=@tmp LABEL=ArchRoot /mnt/var/tmp
mount -o subvol=@crash LABEL=ArchRoot /mnt/var/crash
mount -o subvol=@spool LABEL=ArchRoot /mnt/var/spool
mount -o subvol=@systemd LABEL=ArchRoot /mnt/var/lib/systemd
mount -o subvol=@NetworkManager LABEL=ArchRoot /mnt/var/lib/NetworkManager
mount -o subvol=@pkg LABEL=ArchRoot /mnt/var/cache/pacman/pkg
mount -o subvol=@boot LABEL=ArchRoot /mnt/boot
mount LABEL=ArchBoot /mnt/efi

Set default btrfs subvolume

btrfs inspect-internal rootid /mnt
btrfs subvolume set-default 256 /mnt

Install the base system with some necessary packages{#1}

pacstrap -K /mnt base linux linux-firmware linux-headers mkinitcpio cryptsetup btrfs-progs sbctl sudo nano networkmanager

Entering chroot env

arch-chroot /mnt

Set up localizations

nano /etc/locale.gen

en_GB.UTF-8 UTF-8
locale-gen

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

ln -sf /usr/share/zoneinfo/YourRegion/City /etc/localtime

timedatectl set-local-rtc 1 ; timedatectl set-ntp true

echo Arch > /etc/hostname

Add sudo privileged user account

useradd -m -s /bin/bash -G audio,video username
passwd username

EDITOR=nano visudo
username ALL=(ALL) ALL

Add fstab mounts

nano /etc/fstab

LABEL=ArchRoot / btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@ 0 0
LABEL=ArchRoot /home btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@home 0 0
LABEL=ArchRoot /.snapshots btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@.snapshots	0 0
LABEL=ArchRoot /opt btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@opt 0 0
LABEL=ArchRoot /srv btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@srv 0 0
LABEL=ArchRoot /var/db btrfs rw,nosuid,nodev,noexec,noatime,lazytime,skip_balance,ssd,discard,space_cache=v2,compress-force=zstd:10,commit=120,subvol=/@db	0 0
LABEL=ArchRoot /var/log btrfs rw,nosuid,nodev,noexec,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@log	0 0
LABEL=ArchRoot /var/tmp btrfs rw,nosuid,nodev,noexec,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@tmp	0 0
LABEL=ArchRoot /var/crash btrfs rw,nosuid,nodev,noexec,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@crash	0 0
LABEL=ArchRoot /var/spool btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@spool 0 0
LABEL=ArchRoot /var/lib/systemd btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@systemd 0 0
LABEL=ArchRoot /var/lib/NetworkManager btrfs rw,nodev,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@NetworkManager 0 0
LABEL=ArchRoot /var/cache/pacman/pkg btrfs rw,nosuid,nodev,noexec,noatime,lazytime,skip_balance,ssd,discard,space_cache=v2,compress-force=zstd:10,commit=120,subvol=/@pkg 0 0
LABEL=ArchRoot /boot btrfs rw,nosuid,nodev,noexec,noatime,lazytime,skip_balance,nodatacow,ssd,discard,space_cache=v2,commit=120,subvol=/@boot 0 0
LABEL=ArchBoot /efi vfat rw,nosuid,nodev,noexec,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=mixed,utf8,discard,flush,errors=remount-ro	0 2

Configure mkinitcpio for UKI{#4}

nano /etc/mkinitcpio.conf

MODULES=(nvme)    # Add your hardware related modules here
# Change existing hooks to systemd-based
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-encrypt block filesystems fsck)

nano /etc/mkinitcpio.d/linux.preset

ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default')

default_uki="/efi/EFI/Boot/BOOTX64.efi"  # Set a bootable path and rename the UKI for direct boot
default_uki="/efi/EFI/Linux/arch-linux.efi"  # For systemd-boot, use the default

default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

Set kernel parameters

Add the UUID to the kernel command line

blkid /dev/nvme0n1p2

nano /etc/kernel/cmdline

rd.luks.name=<UUID FOR nvme0n1p2>=root root=LABEL=ArchRoot rootfstype=btrfs rootflags=subvol=@

Generate UKI

Create a directory based on your UKI path

mkdir -p /efi/EFI/Boot
mkdir -p /efi/EFI/Linux

# Now generate the UKI
mkinitcpio -P

If you’ve set a bootable UKI path, you can now reboot from here

Systemd boot{#5}

bootctl install

nano /efi/loader/loader.conf

default @saved
timeout  3
console-mode max

Finalize and reboot

exit
reboot

Enabling Secure Boot{#6}

Backup your current Secure Boot variables if important, and then process with the sbctl

# Configure Secure Boot to setup mode in your UEFI settings
sbctl status
sbctl create-keys
sbctl enroll-keys -m  # Exclude -m if you are not a Windows user
sbctl verify  # Check for unsigned files

# Now sign those file(s)
sbctl sign -s /efi/EFI/Boot/BOOTX64.efi
sbctl sign -s /efi/EFI/Linux/arch-linux.efi
sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi
sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi

Configure TPM2 for LUKS2 unlocking{#7}

Ensure your secureboot is enabled

systemd-cryptenroll /dev/nvme0n1p2 --recovery-key
systemd-cryptenroll /dev/nvme0n1p2 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=0+7

If you experience any issues during installation, please follow the official Arch Linux Installation guide. I used references from ArchWiki and Gentoo Wiki with some minor tweaks myself. I hope you find something helpful.