Installing Arch Linux with Disk Encryption and systemd-boot (from scratch)
Series: General
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:
- caligula (for Linux)
- balenaEtcher (for macOS and Windows)
- 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 mediumand pressEnterto enter the installation environment. - You will be logged in on the first virtual console as the
rootuser, and presented with aZshshell prompt.
Console Keyboard Layout and font
- The default console keymap is US.
- Available layouts can be listed with:
localectl list-keymaps
- To set the keyboard layout, for example, to set a German keyboard layout:
loadkeys de-latin1
- The console font is quite small and difficult to read.
- You make increase the font size with:
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:
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:
# 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:
ping ping.archlinux.org
Update the System Clock
Use timedatectl to ensure the system clock is accurate:
# 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/nvme0n1or/dev/mmcblk0. - To identify these devices, use
lsblkorfdisk -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.
- One partition for the root directory
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:
# 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.
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
FAT32usingmkfs.fat:
mkfs.fat -F32 /dev/nvme0n1p1
- To create an
Ext4file system on the root partition:
# 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:
# 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:
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:
pacman -Syy reflector
Next, we get the servers sorted by rate, save to the mirrorlist, and resync them:
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 isbase, 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:
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:
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:
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:
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:
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
As a final step, update the fstab:
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:
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:
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.
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:
echo 'LANG=en_US.UTF-8' >> /etc/locale.conf
If you set the console keyboard layout, make the changes persistent in vconsole.conf:
echo 'KEYMAP=us' >> /etc/vconsole.conf
You can also make the larger font persistent, so when the system reboots the text is readable:
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:
nvim /etc/hostname
Add matching entries to hosts file:
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.
pacman -S iwd impala networkmanager network-manager-applet
- Configure NetworkManager to use
iwdas the Wi-Fi backend:
# edit the file
nvim /etc/NetworkManager/conf.d/wifi-backend.conf
# set the content to
[device]
wifi.backend=iwd
- Enable NetworkManager and iwd services
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:
nvim /etc/mkinitcpio.conf
We need to update the HOOKS line (number 55) to the following:
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
systemdis here for the partition detectionsd-encryptwill detect LUKS partitions and unlock them (prompting us for the password if necessary)
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
passwdcommand. - Create a non-root user:
useradd -mG wheel gaurav
passwd gaurav
- Edit sudoers file to ensure
gauravhas the privileges to execute any command:
# 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:
bootctl install
- The following steps configure the boot loader, assuming the
sd-encrypthook was used. - Get and push the UUID of the root partition:
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.conffile to the following:
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.conffile to be:
#timeout 3
#console-mode keep
default arch-*
And with that your minimal Arch Linux system is ready to roll.
Reboot
- Exit the chroot with
exitcommand. - 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
rebootexecuteshutdown 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.
gauravin 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.