2024-12-24
My computing setup has expanded since I shared my first public note earlier this year. In addition to my reliable Lenovo Thinkpad T480, I have since built an x86-64 based small form factor (SSF) PC. My plans for this new machine include productivity and programming use — and perhaps the occasional match of CS2. Naturally, I have installed my preferred Linux distro (Arch, btw).
This note includes the full installation sequence and some of my learnings.
Contents:
My philosophy is to keep my install light-weight and as stable as possible, despite the rolling release distribution model employed by Arch. The minimal base package, extensive documentation, pacman
, and the combination of yay
and the AUR, I think, has cemented Arch as my preferred distro for personal or professional use (Xubuntu for enterprise work). I am willing to accept that things may break sometimes and see it as a learning opportunity. I've opted to follow a minimal and proven set-up paradigm as you will find below — it follows that I've chosen to keep using X in lieu of Wayland for the forseeable future.
arch release: 2024.12.01
arch version: x86_64
init system: systemd
boot mode: UEFI
bootloader: GRUB
display server: X
desktop environment: xfce4
window manager: xwfm4
network manager: iwd w/ built in DHCP
Before beginning the install, it is important to think about the partioning scheme. The below assumes the use of a GUID Partition Table (GPT).
Option #1: Full Disk Encryption (encrypted /boot
)
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 1.8T 0 disk
├─nvme0n1p1 259:1 0 500M 0 part /efi
├─nvme0n1p2 259:2 0 1G 0 part
│ └─cryptboot 254:0 0 1G 0 crypt /boot
├─nvme0n1p3 259:3 0 100G 0 part
│ └─cryptroot 254:1 0 100G 0 crypt /
└─nvme0n1p4 259:4 0 1.6T 0 part
└─crypthome 254:2 0 1.6T 0 crypt /home
This scheme provides the greatest level of security by decreasing the attack surface of the system. An encrypted boot partition protects against the Evil Maid attack where a nefarious actor with physical access to the system compromises the kernel and initramfs image when the user is logged on and the computer is left unnattended. The EFI System Partition (ESP) containing the bootloader is mounted to /efi
and is the only unencrypted block. No secrets are stored on the unencrypted ESP.
A major draw-back of this scheme is the added complexity and the longer boot time. When the system boots, the bootloader must access the kernel and the initramfs image. With an encrypted /boot
, the bootloader must first decrypt the partition to gain access to its content. Luckily, GRUB
provides the ability to unlock encrypted LUKs devices. However, as I found out first-hand, GRUB is excrutiatingly slow at performing this function. In my testing, it took GRUB almost (20) seconds to unlock /boot
, which is simply not acceptable for many who daily drive their machine or use it for productivity.
Though I initially went with Option #1 and an encrypted /boot
for the added security, I quickly grew tired of the increased boot times, so I wiped my system and started from scratch using Option #2 with non-encrypted /boot
partition. Instructions for Option #1 (full disk encryption) are included in these notes, for posterity and to allow others to try it out for themselves. In my case, it was not worth it.
Option #2: Block Device Encryption (non-encrypted /boot
)
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 1.8T 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
├─nvme0n1p2 259:2 0 100G 0 part
│ └─cryptroot 254:0 0 100G 0 crypt /
└─nvme0n1p3 259:3 0 1.7T 0 part
└─crypthome 254:1 0 1.7T 0 crypt /home
This scheme encrypts everything but /boot
. Consequently, the system remains vulnerable to Evil Maid attacks, at least in theory. This seems to be the most common setup for its lesser complexity and shorter boot times when compared to the alternative. All secrets are kept in the encrypted partitions, and unless you make a habit of leaving your system logged in and physically unnattended around unknown individuals, your kernel and initramfs will most likely not be tampered with. I highly encourage others to try both schemes for themselves; it is satisfying to confirm your preference first-hand.
Enough background, below is the installation sequence:
Reference Arch Linux Installation Guide
fdisk
cryptsetup -v luksFormat /dev/<root_partition>
cryptsetup open /dev/<root_partition> <cryptroot>
mkfs.ext4 /dev/mapper/<cryptroot>
mount /dev/mapper/<cryptroot> /mnt
/home
cryptsetup -v luksFormat /dev/<home_partition>
cryptsetup open /dev/<home_partition> <crypthome>
mkfs.ext4 /dev/mapper/<crypthome>
mount --mkdir /dev/mapper/<crypthome> /mnt/home
cryptroot
and crypthome
can be any name you choose but must remain subsequently consistent/boot
cryptsetup luksFormat --pbkdf pbkdf2 <boot_partition>
cryptsetup open /dev/<boot_partition> <cryptboot>
mount /dev/mapper/<cryptboot> /mnt/boot
/boot
mkfs.fat -F32 <boot_partition>
mount --mkdir <boot_partition> /mnt/boot
pacstrap
pacstrap -K /mnt base linux linux-firmware
vi
, vim
, nvim
man-db
, man-pages
unzip
, sudo
, openssh
iwd
terminus-font
grub
efibootmgr
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
ln -sf /usr/share/zoneinfo/Region/City /etc/localtime
/etc/adjtime
hwclock --systohc
/etc/locale.gen
to uncomment en_US.UTF-8
echo "myhostname" > /etc/hostname
/etc/mkinitcpio.conf
initramfs
; the hooks are different for systemd-based initramfs
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)
FILES=(/etc/cryptsetup-keys.d/cryptroot.key)
initramfs
mkinitcpio -P
dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/cryptroot.key
cryptsetup -v luksAddKey /dev/nvme0n1p2 /etc/cryptsetup-keys.d/cryptroot.key
dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/crypthome.key
cryptsetup -v luksAddKey /dev/nvme0n1p3 /etc/cryptsetup-keys.d/crypthome.key
passwd
grub
and efibootmgr
(if not installed with pacstrap
)
pacman -S grub efibootmgr
grub-install --target=x86_64_efi --efi-directory=/boot --bootloader-id=GRUB
lsblk -f
/etc/default/grub
with the following:
GRUB_ENABLE_CRYPTODISK=y
GRUB_CMDLINE_LINUX="cryptdevice=UUID=UUID_of_LUKS_device root=dev/mapper/<cryptroot>"
/etc/crypttab
to append:
/boot
crypthome UUID=UUID_of_LUKS_DEVICE /etc/cryptsetup-keys.d/crypthome.key
/boot
cryptboot UUID=UUID_of_LUKS_DEVICE /etc/cryptsetup-keys.d/cryptboot.key
crypthome UUID=UUID_of_LUKS_DEVICE /etc/cryptsetup-keys.d/crypthome.key
grub-mkconfig -o /boot/grub/grub.cfg
useradd -m user
-m
option creates the home directory and sets the proper permissionspasswd user
/etc/iwd/main.conf
sysetmd-resolved
:
[General]
EnableNetworkConfiguration=true
systemctl enable --now iwd.service
systemctl enable --now systemd-resolved.service
/etc/vconsole.conf
to add larger font
mkinitcpio -P
to ensure console font is loaded early in boot sequencelinux-headers
if using nvidia DKMS driversvi
mode in the terminal
bash
)
set -o vi
to .bashrc
sudo