Contents

Installing Arch Linux with Disk Encryption and systemd-boot (from scratch)

Installing Arch Linux from scratch can be an intimidating experience. This blogpost aims to help you with the exact steps to install Arch and also encrypt the disk with LUKS.


Pre-installation

Prepare an Installation Medium

  • Visit the download page and, depending on how you want to boot, acquire the ISO file or a netboot image.
  • In order to prepare a bootable disk you can may use:
  • For the netboot image, follow Netboot#Boot from a USB flash drive to prepare a USB flash drive for UEFI booting.

Boot the Live Environment

Note: Arch Linux installation images do not support Secure Boot. You will need to disable Secure Boot to boot the installation medium.

  • Point the current boot device to the installation medium.
  • When the installation medium’s boot loader menu appears, select Arch Linux install medium and press Enter to enter the installation environment.
  • You will be logged in on the first virtual console as the root user, and presented with a Zsh shell prompt.

Console Keyboard Layout and font

  • The default console keymap is US.
  • Available layouts can be listed with:
1
localectl list-keymaps
  • To set the keyboard layout, for example, to set a German keyboard layout:
1
loadkeys de-latin1
  • The console font is quite small and difficult to read.
  • You make increase the font size with:
1
setfont ter-132b
  • Console fonts are located in /usr/share/kbd/consolefonts/, so you can choose a different font if you like.

Verify the boot mode

To verify the boot mode, check the UEFI bitness:

1
cat /sys/firmware/efi/fw_platform_size
  • 64 - the system is booted in UEFI mode and has a 64-bit x64 UEFI.
  • 32 - the system is booted in UEFI mode and has a 32-bit IA32 UEFI. While this is supported, it will limit the boot loader choice to those that support mixed mode booting.
  • If it returns No such file or directory, the system may be booted in BIOS (or CSM) mode.

Connect to the Internet

  • If you have an ethernet cable, just plug it in and move to the next step.
  • If you are on a Wi-Fi connection, use the following steps:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# get the device name
iwctl device list

# initiate a scan of networks (assuming wlan0 is the device name)
iwctl station wlan0 scan

# list all available networks
iwctl station wlan0 get-networks

# connect to a network; enter the passphrase if prompted
iwctl station wlan0 connect SSID
  • Verify internet connection:
1
ping ping.archlinux.org

Update the System Clock

Use timedatectl to ensure the system clock is accurate:

1
2
3
4
5
6
7
8
# list timezones
timedatectl list-timezones

# set the right timezone
timedatectl set-timezone Europe/Berlin

# activate network time synchronization
timedatectl set-ntp true

To check the service status, use timedatectl status.


Partition the Disks

  • When recognized by the live system, disks are assigned to a block device such as /dev/sda, /dev/nvme0n1 or /dev/mmcblk0.
  • To identify these devices, use lsblk or fdisk -l.
  • The following partitions are required for a chosen device:
    • One partition for the root directory /.
    • For booting in UEFI mode: an EFI system partition.

Note: If the disk from which you want to boot already has an EFI system partition (1G or more), do not create another one, but use the existing partition instead.

The following section uses fdisk to create the partitions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# fdisk /dev/the_disk_to_be_partitioned
fdisk /dev/nvme0n1

# Create a new label
# Since you are doing an EFI, you should create a GPT partition table ('g')
Command (m for help): g

# Add EFI partition to disk.
# ArchWiki recommends a minimum of 1G as the size of the EFI system partition.
# Why? - Because it prevents every common failure mode when using:
# ✔ systemd-boot
# ✔ unified kernel images
# ✔ multiple kernels
# ✔ Secure Boot
# ✔ dual boot
# ✔ rolling release upgrades
# However, if you do not plan to do either of the above, you can chose a smaller size like 512M.
Command (m for help): n
Partition number (1-128, default 1): <press return>
First sector (34-1000215182, default 2048): <press return>
Last sector: +1G

# A new partition with 'Linux filesystem' type is created.
# The type is incorrect for EFI partition, we will change it to correct type in a bit.

# Add Linux filesystem partition to disk.
Command (m for help): n
Partition number (2-128, default 2): <press return>
First sector: <press return>
Last sector: <press-return> # give everything remaining to Linux filesystem

# Change type for EFI partition from 'Linux filesystem' to 'EFI System'.
Command (m for help): t
Partition number (1-2, default 2): 1
Partition type or alias (type L to list all): 1

# We don't need to change the type for partition 2.
# It has to be 'Linux filesystem'.

# Write the partition table to disk and exit.
Command (m for help): w

# Verify the changes.
fdisk -l

Encrypt the Linux Partition

Note: Skip this section, if you do not want to encrypt the partition.

Encrypting the Linux partition gives you some extra security if your machine’s disk is no longer in your possession, for instance:

  • if the machine (or its disk) gets stolen
  • if you need to send back the machine or the disk for replacement or repair (and can’t wipe the disk before)

The commands below will prompt you for a password. It’s therefore important to know that LUKS does not derive the encryption key based on your password. Instead, it generates a secure key and store it in a key slot, itself encrypted with the password. So, it’s okay to use a dummy password at this point and change it later without having to re-encrypt the disk.

1
2
cryptsetup luksFormat --type luks2 /dev/nvme0n1p2
cryptsetup open /dev/nvme0n1p2 cryptroot

You can learn more about cryptsetup and luks from their documentation.


Format the Partitions

Once the partitions have been created (and encrypted), each newly created partition must be formatted with an appropriate file system.

  • If you created an EFI system partition, format it to FAT32 using mkfs.fat:
1
mkfs.fat -F32 /dev/nvme0n1p1
  • To create an Ext4 file system on the root partition:
1
2
3
4
5
# if you encrypted the partition
mkfs.ext4 /dev/mapper/cryptroot

# if you did not encrypt the partition
mkfs.ext4 /dev/nvme0n1p2

Mount the File Systems

  • Mount the root volume to /mnt:
1
2
3
4
5
# if you encrypted the partition
mount /dev/mapper/cryptroot /mnt

# otherwise
mount /dev/nvme0n1p2 /mnt
  • For UEFI systems, mount the EFI system partition to /mnt/boot:
1
mount --mkdir /dev/nvme0n1p1 /mnt/boot

Installation

Update the Mirrors

You certainly want to ensure you have the fastest servers available to install the packages. In order to do that you need to install reflector:

1
pacman -Syy reflector

Next, we get the servers sorted by rate, save to the mirrorlist, and resync them:

1
2
reflector -c Germany -a 6 --sort rate --save /etc/pacman.d/mirrorlist
pacman -Syy

Install essential packages

The ArchWiki installation guide states that:

No configuration (except for /etc/pacman.d/mirrorlist) gets carried over from the live environment to the installed system. The only mandatory package to install is base, which does not include all tools from the live installation, so installing more packages is frequently necessary.

So, it’s worth checking the current essential packages.

It’s time to install the base packages along with a few additional ones:

1
pacstrap -K /mnt base base-devel linux linux-firmware linux-headers nvim git intel-ucode terminus-font

Configure the System

fstab

To get needed file systems (like the one used for the boot directory /boot) mounted on startup, generate an fstab file. Use -U or -L to define by UUID or labels, respectively:

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

You can check the resulting /mnt/etc/fstab file, and edit it in case of errors. At this point it must have the / (root) and the /boot partition.


Chroot

Change root into the new system so we can directly interact with the new system’s environment, tools, and configurations:

1
arch-chroot /mnt

Create a swapfile

If you didn’t create a swap partition (like I didn’t), now is the time to create a swapfile:

1
2
3
4
fallocate -l 8G /swapfile

# if the above command fails (very rare)
dd if=/dev/zero of=/swapfile bs=1G count=8 status=progress

Next, set the right permissions:

1
2
3
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

As a final step, update the fstab:

1
2
3
4
5
nvim /etc/fstab

# add the following line to the end of the file
/swapfile none swap defaults 0 0
# save and exit

Time zone

  • First identify your REGION by ls /usr/share/zoneinfo
  • Identify your CITY by ls /usr/share/zoneinfo/REGION/
  • Now, set the time zone:
1
2
3
4
ln -sf /usr/share/zoneinfo/REGION/CITY /etc/localtime

# For example:
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
  • Lastly, set the system clock:
1
hwclock --systohc

Localization

Edit /etc/locale.gen and uncomment the en_US.UTF-8 UTF-8 line. You may also want to uncomment other needed locales.

1
2
3
4
5
nvim /etc/locale.gen

# :171 (might vary)
# uncomment en_US.UTF-8 UTF-8
# save and exit

Generate the locales by executing the locale-gen command. We also need to add/update a locale.conf file:

1
echo 'LANG=en_US.UTF-8' >> /etc/locale.conf

If you set the console keyboard layout, make the changes persistent in vconsole.conf:

1
echo 'KEYMAP=us' >> /etc/vconsole.conf

You can also make the larger font persistent, so when the system reboots the text is readable:

1
echo 'FONT=ter-v22n' >> /etc/vconsole.conf

Here, I’m using the terminus-font, however, you may want to use something else.


Network Configuration

Create the hostname file:

1
nvim /etc/hostname

Add matching entries to hosts file:

1
2
3
4
5
6
vim /etc/hosts

# add the below entries, replacing 'hostname' with your hostname
127.0.0.1	localhost
::1			localhost
127.0.1.1	hostname.localdomain	hostname

A common practice is to install a network manager before you reboot the system. A network manager lets you manage network connection settings in so called network profiles to facilitate switching networks.

1
pacman -S iwd impala networkmanager network-manager-applet
  • Configure NetworkManager to use iwd as the Wi-Fi backend:
1
2
3
4
5
6
# edit the file
nvim /etc/NetworkManager/conf.d/wifi-backend.conf

# set the content to
[device]
wifi.backend=iwd
  • Enable NetworkManager and iwd services
1
2
systemctl enable iwd.service
systemctl enable NetworkManager

Initramfs

When Arch boots, it will first load the initial RAM file system (initramfs). So, you need to configure it to tell how to correctly boot the system. For example:

  • which system manager you are using (like systemd)
  • are you using encrypted partition(s) (yes)

Creating a new initramfs is usually not required, because mkinitcpio was run on installation of the kernel package with pacstrap.

However, for system encryption you have to modify mkinitcpio.conf and recreate the initramfs image:

1
nvim /etc/mkinitcpio.conf

We need to update the HOOKS line (number 55) to the following:

1
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
  • systemd is here for the partition detection
  • sd-encrypt will detect LUKS partitions and unlock them (prompting us for the password if necessary)
1
mkinitcpio --allpresets

At this point you should not see any errors. You can ignore the warnings and move to the next step.


Root password

  • Set the root password with passwd command.
  • Create a non-root user:
1
2
useradd -mG wheel gaurav
passwd gaurav
  • Edit sudoers file to ensure gaurav has the privileges to execute any command:
1
2
3
4
5
# change the editor if you like
EDITOR=nvim visudo

# uncomment the line
%wheel ALL=(ALL:ALL) ALL

Install a Boot Loader

A boot loader is a piece of software started by the firmware—UEFI or BIOS. It is responsible for loading the kernel with the wanted kernel parameters and any external initramfs images.

A boot manager presents a menu of boot options, or provides some other way to control the boot process—i.e. it just runs other EFI executables.

The following steps are the systemd-boot UEFI boot manager.

  • Install the systemd-boot:
1
bootctl install
  • The following steps configure the boot loader, assuming the sd-encrypt hook was used.
  • Get and push the UUID of the root partition:
1
blkid -s UUID -o value /dev/nvme0n1p2 >> /boot/loader/entries/arch.conf
  • Keep the UUID safe and change the content of the /boot/loader/entries/arch.conf file to the following:
1
2
3
4
title   Arch Linux
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options rd.luks.name=<UUID>=cryptroot root=/dev/mapper/cryptroot rw

Refer the documentation for more details.

  • Update the content of the /boot/loader/loader.conf file to be:
1
2
3
#timeout 3
#console-mode keep
default arch-*

And with that your minimal Arch Linux system is ready to roll.


Reboot

  • Exit the chroot with exit command.
  • Unmount the file system umount -a.
  • Reboot into Arch Linux with reboot.

A note for VM

  • If you are trying everything in a VM, instead of reboot execute shutdown 0.
  • Open VM settings, go to Storage tab and detach the ISO.
  • Start the VM.

Login

  • At startup, you will be prompted for the passphrase to decrypt the disk.
  • Login with the user created earlier. gaurav in my case.
  • Check if internet is working with ping ping.archlinux.org.
  • You can connect with a Wi-Fi network following the steps from the connect to the internet section.

Now execute fastfetch and feel awesome!!

Congratulations!! Welcome to the Arch family.

In the next post(s), I will share the steps to setup a working development environment with Hyperland.