posts/

Arch Install Guide - Systemd-boot and btrfs

Here are the goals:

  • Disk encryption
  • Systemd-boot instead of grub
  • BTRFS
  • Pipewire
  • Wayland
  • Gnome 40

Builds upon the Arch Wiki, and Willi Mutschler's work.

Create a USB installer, and boot into it. Set up your Internet and Timezone first

WIFINAME="Wifiname"
WIFIPASS="Password"

TIMEZONE="Asia/Kolkata" 

setfont ter-132n

# Configure WiFi
iwctl station wlan0 scan
iwctl station wlan0 get-networks
iwctl --passphrase "$WIFIPASS" station wlan0 connect "$WIFINAME"
ping -c 2 1.1.1.1

# Set timezone and time
timedatectl set-timezone "$TIMEZONE"
timedatectl set-ntp true
echo "Current system time is: $(date)"

Partition the disk

I'm going with a 1 GB boot partition and a 499 GB root partition. 1 GB is actually an overkill for boot; I have only used 79MB of it so far. There is no swap because my laptop has enough RAM (16 GB) for what I do.

First run lsblk to see the name of your disk. If it's a spinning drive, it's probably /dev/sda, and if it's an ssd, it's probably /dev/nvme0n1

Now partitions your disk:

gdisk /dev/nvme0n1
    o
    n
        +1G ef00
    
    n
        all defaults

This should create two partitions, and set the first partition as EFI for boot. Run lsblk again to confirm.

$ lsblk
nvme0n1             259:0    0 476.9G  0 disk  
├─nvme0n1p1         259:1    0     1G  0 part
└─nvme0n1p2         259:2    0 475.9G  0 part 

nvme0n1p1 is gonna be your boot partition, and nvme0n1p2 is gonna be the root partition.

Formatting and Encryption

We are not going to encrypt the boot partition, but as long as you have a strong BIOS password, you should be fine . Format the boot partition as fat32:

Read more

There is an elaborate way to use an encrypted boot partition, but secure boot also makes it tricky to load some kernel modules, and in general is not really worth doing. "Secureboot" is a proprietery closed-source protocol by Microsoft, and I don't really trust it to be secure anyway.

# gdisk probably already does this,
# but I'm gonna do it again because I trust no one!
mkfs.fat -F32 /dev/nvme0n1p1

The second partition is completely encrypted. Your disk layout will be kinda like this at the end of guide:

             [ @root ] [ @home ]            
             [____________btrfs____________]
             [_____________LVM_____________]
[   boot   ] [____________crypt____________]
[ nvme0n1p1] [__________nvme0n1p2__________]
[___________________disk___________________]

First we create a dmcrypt crypt (the encryption). Inside the crypt is an LVM partition. Inside the LVM is a BTRFS filesystem. Inside the filesystem are two subvolumes, one for root, and one for home.

Encryption

You will be asked for a disk-encryption password here. You will need to type it everytime you reboot, so make it secure, but not very difficult to type.

There is no way to recover your data if you forget your password, so maybe write it down on a paper and keep it safe until you have completely memorised it. If you use a Password Manager (and you should!), save the password in it.

modprobe dm-crypt
cryptsetup luksFormat /dev/nvme0n1p2
cryptsetup luksOpen /dev/nvme0n1p2 cryptlvm --allow-discards

ls /dev/mapper

LVM

LVM is a bit of an overkill, since we have btrfs subvolumes, but systemd-boot apparently needs it when using dm-crypt.

pvcreate /dev/mapper/cryptlvm
vgcreate cryptvol /dev/mapper/cryptlvm
lvcreate -l 100%FREE cryptvol -n root

ls /dev/mapper

Filesystem

Formath the LVM with BTRFS. I'm using BTRFS for it's snapshots, and so that I can take remote backups with btrfs-send.

mkfs.btrfs -f /dev/cryptvol/root

Now mount the root partition, create subvolumes, and unmount it:

# Mount without options to create subvolumes
mount /dev/cryptvol/root /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
umount /mnt

@ is the root subvolume, and @home is the home subvolume. Mount @ and create mount points and mount boot and @home.

# Mount created btrfs LVM and create subvolumes
# https://superuser.com/questions/1142782/btrfs-why-subvolid-is-different-than-value-provided-to-mount
mount -o subvol=@,ssd,noatime,space_cache,commit=120,compress=zstd:1,discard=async /dev/cryptvol/root /mnt

mkdir /mnt/boot
mkdir /mnt/home

mount /dev/nvme0n1p1 /mnt/boot
mount -o subvol=@home,ssd,noatime,space_cache,commit=120,compress=zstd:1,discard=async /dev/cryptvol/root /mnt/home

Install Arch

pacstrap /mnt base linux linux-firmware git vim intel-ucode btrfs-progs lvm2

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

pacstrap installs the OS, but we still need to configure it, install some software, and also setup booting.

Let's do that. Chroot into the new install:

arch-chroot /mnt

Now you are inside your install, without rebooting. Let's persist timezone, and setup Networking.

# Only run this after you've chrooted into the new install

ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohc

# Uncomment en_US.UTF-8 UTF-8 en_US ISO-8859-1 in /etc/locale.gen
# then run locale-gen
# locale > /etc/locale.conf
# set LANG=en_US.UTF-8 in above file


echo "MyHostName" >> /etc/hostname
echo "127.0.1.1   MyHostName.localdomain  MyHostName" >> /etc/hosts

Install essential software and setup services. You can customise the packages you want, but here are mine:

pacman -S --noconfirm
vulkan-intel 
efibootmgr 
networkmanager network-manager-applet dialog wpa_supplicant
reflector linux-headers avahi
xdg-user-dirs xdg-utils
inetutils
dnsutils bluez bluez-utils
alsa-utils
openssh
rsync
acpi acpi_call acpid
bridge-utils dnsmasq openbsd-netcat
iptables ipset firewalld
pipewire pipewire-pulse pipewire-jack pipewire-alsa
flatpak
os-prober
terminus-font
zip unzip
htop
curl
sudo

systemctl enable NetworkManager
systemctl enable bluetooth
systemctl enable sshd
systemctl enable avahi-daemon
systemctl enable reflector.timer
systemctl enable fstrim.timer
systemctl enable firewalld
systemctl enable acpid

Setup booting

Edit /etc/mkinitcpio.conf, look for HOOKS variable, amd move keyboard to before the filesystems and add encrypt and lvm2 after keyboard.

It should look like this:

HOOKS="base udev autodetect modconf block keyboard encrypt lvm2 filesystems fsck"

This is because we need to enable keyboard and the others to unlock the encrypted filesystem.

Now generate initramfs and setup bootloader:

# Regenerate initramfs
mkinitcpio -p linux

# Install bootloader
bootctl --path=/boot/efi install

# Edit /boot/efi/loader/loader.conf
default arch
timeout 3
editor 0

# Create a bootloader entry in /boot/efi/loader/entries/arch.conf
# TODO fix linux and initrd locations.
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=UUID={UUID}:cryptlvm root=/dev/mapper/cryptvol-root ro quiet loglevel=0 systemd.show_status=false splash rootflags=subvol=@
# The cryptlvm part is super important ^
# Replace {UUID} with uuid of /dev/nvm0n1p2

Create a user

useradd -m MyUsername
passwd MyUsername
echo "MyUsername   ALL=(ALL) ALL" >> /etc/sudoers.d/MyUsername

# Exit chroot
exit

umount -R /mnt
reboot

Restart

After restart, remove install media, enter your disk-encryption password, and then log-in.

You should see a text terminal. You can install a Desktop Environment of your choice. I'm installing gnome.

There are a lot of sub-packages in the gnome package, and most of them are not really necessary. You get to choose which packages you want on your computer at this stage.


# use nmtui to connect to network.
# nmtui will save your configuration across reboots.

sudo pacman -Syyy
sudo pacman -S wayland gnome
# Install parts of gnome suitable for you

Tags this post has been filed under: