How to deploy a new Arch linux with encrypted disk

Why this article?

The reason is pretty much simple: Arch Linux is so stable and everlasting that I always forget how to properly start from zero!
This article is a personal reminder about how to properly deploy a new Arch Linux system running on an encrypted disk using Luks.

First step is to download and read the official installation guide

One of the reasons why Arch is so famous is its documentation.
First step is to download the ISO from https://archlinux.org/download/
Second step is to read the official installation guide https://wiki.archlinux.org/title/Installation_guide

Use torrent for the download

It’s faster, much faster!
What’s the point of paying for a Gbit internet connectivity if then you download files from shitty servers?

Burn the image on an USB flash drive

Identify the USB flash drive device (i.e. using dmesg after having plugged the USB device)

sudo dd if=archlinux-2022.12.01-x86_64.iso of=/dev/sdX bs=4M status=progress
sudo sync

Let’s start!

Arch Linux installation is different than most Linux distributions: it dose not come with a graphical installer.
This might be seen as a bad/difficult thing, although gives the user much more flexibility, and allows the distro maintainers to focus on other parts of the OS.

After booting with the USB stick on, the user is prompted to a console, logged as root.

Choosing the right partitioning scheme

Disk partitioning is the most important step.
We are going to use dm_crypt with Luks, therefore it would be good to choose the most fitting partitioning method (fitting to your scenario).

My golden rule when things are encrypted is: Keep It Simple and Stupid

Therefore you can choose a more advanced partitioning schema from the official user guide https://wiki.archlinux.org/title/dm-crypt/Encrypting_an_entire_system#Overview or we can proceed with the most simple: LUKS on a partition (whose disadvantage is lacks of flexibility, but who cares, I do not have multiple disks in my laptop!).

Partition the disk

Using cfdisk /dev/sdX we can create a number of partitions.
We need at least three:

  • EFI usually around 500MB (type EFI System)
  • /boot which is expected to be > 300MB (type Linux filesystem)
  • / which will be encrypted and use the whole remaining space (type Linux filesystem)
>>  /dev/nvme0n1p1                  2048           1026047           1024000        500M EFI System            
    /dev/nvme0n1p2               1026048           3123199           2097152          1G Linux filesystem
    /dev/nvme0n1p3               3123200        1953525134        1950401935        930G Linux filesystem

There are no SWAP partitions. The reason is because we are going to rely on swapfiles, which are encrypted too.
The purpose of this installation is to encrypt the whole system, except the /boot directory.

A suggested size for /boot is 200 MiB unless you are using EFI system partition as /boot, in which case at least 300 MiB is recommended. If you want to install multiple kernels or want to be future proof, you can use 1 GiB to be on the safe side. ( https://wiki.archlinux.org/title/Partitioning#Partition_scheme )

Preparing the root partition

The following commands create and mount the encrypted root partition.
Default cryptsetup values are the most widely used. I struggle to see any good reason to alter them.
Should you wonder if your encryption will be safe for the time being, the default cipher aes-xts-plain64 is widely adopted by most major distributions.
It’s fast and reliable - considering that a full disk encryption should block any attempt of gaining control of your data, let’s say within the next 10 years - which seems a good compromise to me!

cryptsetup -y -v luksFormat /dev/sda3
cryptsetup open /dev/sda3 root
mkfs.ext4 /dev/mapper/root
mount /dev/mapper/root /mnt

Warning: the first command will ask for a new passphrase.
It can be changed after, although it is essential to specify a phrase rather than a word.
I often suggest a combination of passwords, for example on a mispelled sentence.
If you are not english, use your own language as dictionary attacks will be more difficult!
Therefore it is stupid to use a song, book, movie or any phrase taken from a finite database!!

Preparing the boot partition

Partition mounted on /boot must not be encrypted, therefore the steps are quite well known.

mkfs.ext2 /dev/sda2
mkfs.fat -F32 /dev/sda1
mount --mkdir /dev/sda2 /mnt/boot
mount --mkdir /dev/sda1 /mnt/boot/EFI

Configure lan (internet) access

Check that the kernel has all the needed drivers for your network cards, use ip link command.
If you are on a laptop, most likely you’ll need iwctl https://wiki.archlinux.org/title/Iwd#iwctl

Connecting to a Wifi from console requires some information gathering step:

Enter the iwctl console using the command:

iwctl
  • [iwd]# device list list all Wi-Fi devices
  • [iwd]# station [device] scan scan for networks
  • [iwd]# station [device] get-networks list all available networks
  • [iwd]# station [device] connect SSID connect to a network

iwd automatically stores network passphrases in the /var/lib/iwd directory and uses them to auto-connect in the future

If the connect command executes correctly (it should ask for a password!), you can verify the network connectivity:

ping codref.com 
PING codref.com(2606:4700:3037::ac43:c69b (2606:4700:3037::ac43:c69b)) 56 data bytes
64 bytes from 2606:4700:3037::ac43:c69b (2606:4700:3037::ac43:c69b): icmp_seq=1 ttl=58 time=9.94 ms

Install essential packages

Use pacstrap command to install:

  • base packages
  • kernel
  • firmware
  • vim (or any other editor!)
  • iwd
  • dhcpcd
pacman -Sy archlinux-keyring
pacstrap -K /mnt base linux linux-firmware vim iwd dhcpcd 

The default mirrors are used, go to the guide to choose different ones!

Configure the system

Generate the fstab file and open it to check for errors!

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

Enter the system!

Use the command arch-chroot to move the system root to the /mnt partition:

arch-chroot /mnt

Set the timezone:

ln -sf /usr/share/zoneinfo/[Region]/[City] /etc/localtime
hwclock --systohc
date

Set the proper locale:

  • Edit /etc/locale.gen and uncomment en_US.UTF-8 UTF-8 and other needed locales. Generate the locales by running:
locale-gen
  • Create the /etc/locale.conf file, and set the LANG variable accordingly:
LANG=en_US.UTF-8

Set the hostname creating the file etc/hostname with one single line, containing your host-name:

myhostname

Set the root password using the passwd command!

Create initramfs

Disk encryption requires us to configure /etc/mkinitcpio.conf adding the keyboard, keymap and encrypt hooks:

HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt filesystems fsck)

Regenerate the initramfs after saving the changes:

mkinitcpio -P

Install the bootloader

You are free to choose any working bootloader https://wiki.archlinux.org/title/Arch_boot_process#Boot_loader
To continue using grub:

pacman -S grub os-prober efibootmgr
grub-install --target=x86_64-efi --bootloader-id=grub_uefi --recheck

The below requires some copy-paste for the disk UUID, therefore you might want to install OpenSSH and allow root user login
pacman -S openssh
Edit file /etc/ssh/sshd_config changing PermitRootLogin to yes
Generate the keys with ssh-keygen -A
Run the sshd service with /usr/bin/sshd -Dd
Find your IP address with ip addr Connect
(you might need to stop the sshd process from archiso image, therefore systemctl stop sshd from outside the chroot)

Edit the bootloader kernel parameters changing the file /etc/default/grub:

GRUB_CMDLINE_LINUX="cryptdevice=UUID=[device-UUID]:root root=/dev/mapper/root"

Where the [device-UUID] can be taken from the command blkid

As an alternative one can enable the param GRUB_ENABLE_CRYPTODISK which according to the official documentation https://www.gnu.org/software/grub/manual/grub/html_node/Simple-configuration.html does the very same! LOL

Deploy the configuration:

grub-mkconfig -o /boot/grub/grub.cfg

Finally, exit the chroot typing exit or CTRL+d and then reboot

If you stopped in between of the process

Just remember to:

cryptsetup open /dev/sda3 root
mount /dev/mapper/root /mnt
mount --mkdir /dev/sda2 /mnt/boot
mount --mkdir /dev/sda1 /mnt/boot/EFI
arch-chroot /mnt

Troubleshoot wrong device mapping

It might happen that, at reboot, the kernel is not able to recognize the device UUID.
An handy workaround (but not very clean) is to disable the GRUB_DISABLE_LINUX_UUID from the default file.
I also suggest to remove the quiet from the default kernel string (to show a nice log at boot!).

Whats’ next, a useful checklist