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 uncommenten_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
changingPermitRootLogin
to yes
Generate the keys withssh-keygen -A
Run the sshd service with/usr/bin/sshd -Dd
Find your IP address withip addr
Connect
(you might need to stop the sshd process from archiso image, thereforesystemctl 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
- configure wifi network at reboot (i.e. enable both
dhcpcd
andiwd
services and configure the adapter withiwctl
) - install the CPU relevant microcode https://wiki.archlinux.org/title/Microcode
- deploy a new unprivileged user
- deploy a privilege elevation tool (i.e. sudo or doas) https://wiki.archlinux.org/title/List_of_applications/Security#Privilege_elevation
- reconfigure SSH to disallow root access with password
- deploy a GUI (e.g. Wayland or Xorg)