Installing Arch Linux with Full Disk Encryption
Updates
- 2022-12-17: The official
archinstall
script greatly simplify the Arch Linux installation, even with full disk encryption. Most steps in this guide (except 18 unlock automatically) are automated by that script. Check it out!
I recently re-installed my Arch Linux with full disk encryption (FDE), as one of the first steps, to bring privacy into my life. This guide documents the installation process in a step-by-step manner. I hope this can help people who also want to practice privacy.
Each step in this guide are linked to the corresponding ArchWiki, precised to section level. You are suggested to read these references and, of course, the official installation guide because
- it is better to understand the process instead of blindly copy-and-pase, and
- I had omitted some uncommon steps that you might need (e.g., non US locale and keyboard layout)
This guide uses modern options like:
Options | This Setup | |
---|---|---|
Disk Encryption | Yes, No | Yes |
Firmware | BIOS, UEFI | UEFI |
Disk Partition | MBR, GPT | GPT |
Boot Loader | GRUB, Syslinux, systemd-boot, etc | systemd-boot |
In addition, I have verified this guide twice by installing on both hard disk and virtual machine respectively. I think it is reproducible.
Let’s start!
1. Verify the boot mode (ref)
This guide assumes we use UEFI. You must ensure that the system is booted in UEFI mode. To verify the boot mode, list the efivars directory:
# ls /sys/firmware/efi/efivars
If the command shows the directory without error, then the system is booted in UEFI mode.
2. Update the system clock (ref)
Use timedatectl
to ensure the system clock is accurate:
# timedatectl set-ntp true
3. Partition the disks (ref, GPT fdisk)
The final disk layout from this guide contains two partitions,
Partition | Size | Code | Name |
---|---|---|---|
Boot (/dev/sda1) | 512.0 MiB | EF00 | EFI system partition |
Root (/dev/sda2) | Rest of the disk | 8300 (default of gdisk) | Linux filesystem |
Traditionally, it is suggested to create an extra swap partition. I don’t because there are more flexible alternatives over allocating a fixed partition for swap. For example, uses swap file, or systemd-swap to automate the swap file on demand.
Use gdisk
to partition the disk. See this video.
When completed, gdisk -l /dev/sda
should print the disk partitions
like these:
GPT fdisk (gdisk) version 1.0.5
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 41943040 sectors, 20.0 GiB
Model: VBOX HARDDISK
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 8EFD04A2-473C-4FCA-9C89-459EEB658DB0
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 41943006
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00 EFI system partition
2 1050624 41943006 19.5 GiB 8300 Linux filesystem
4. Prepare the encrypted root partition (ref)
Create and mount the encrypted root partition. You will need to choose the passphrase for the encryption!
# cryptsetup luksFormat /dev/sda2
# cryptsetup open /dev/sda2 cryptroot
# mkfs.ext4 /dev/mapper/cryptroot
# mount /dev/mapper/cryptroot /mnt
5. Prepare the boot partition (ref)
Create and mount the non-encrypted boot partition.
# mkfs.fat -F32 /dev/sda1
# mkdir /mnt/boot
# mount /dev/sda1 /mnt/boot
6. Generate an fstab file (ref)
Run:
# genfstab -U /mnt >> /mnt/etc/fstab
7. Install essential packages (ref)
Use the pacstrap
script to install these packages. I added vim
for
editing config files and dhcpcd
for connecting to the Internet after
reboot.
# pacstrap /mnt base linux linux-firmware vim dhcpcd
8. Chroot (ref)
# arch-chroot /mnt
9. Time zone (ref)
# ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
# hwclock --systohc
10. Localization (ref)
Edit /etc/locale.gen
and uncomment en_US.UTF-8 UTF-8
and other
needed locales. Generate the locales by running:
# locale-gen
# localectl set-locale LANG=en_US.UTF-8
11. Network configuration (ref)
Add the /etc/hosts
:
127.0.0.1 localhost
::1 localhost
12. Configuring mkinitcpio (ref)
Edit /etc/mkinitcpio.conf
, - add the encrypt
hooks - move the
keyboard
hooks before encrypt
( so that you can type the
passphrase :p )
For example, after this step, HOOKS
should look like:
HOOKS=(base udev autodetect modconf block keyboard encrypt filesystems fsck)
13. Generate the initramfs (ref)
Since we have changed to /etc/mkinitcpio.conf
manually, we have to
re-generates the boot images (e.g., /boot/initramfs-linux.img
). Run
this command:
# mkinitcpio -P
14. Set the root password (ref)
# passwd
15. Patch the CPU’s microcode (ref)
- For AMD processors, install the
amd-ucode
package. - For Intel processors, install the
intel-ucode
package.
For exmaple, run
# pacman -S intel-ucode
16. Configure the Boot Loader with systemd-boot
(ref, systemd-boot)
16.1. Install the EFI boot manager
# bootctl install
16.2. Create /boot/loader/entries/arch.conf
- Replace
intel-ucode.img
withamd-ucode.img
if you have an AMD CPU - Replace the
UUID
(notPARTUUID
) to the one mapping to/dev/sda2
(Runblkid
to find out)
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX:cryptroot root=/dev/mapper/cryptroot rw
16.3. Replace /boot/loader/loader.conf
to
default arch.conf
timeout 5
console-mode max
editor no
16.4. Review the configuration
# bootctl list
Boot Loader Entries:
title: Arch Linux (default)
id: arch.conf
source: /boot/loader/entries/arch.conf
linux: /vmlinuz-linux
initrd: /intel-ucode.img
/initramfs-linux.img
options: cryptdevice=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX:cryptroot root=/dev/mapper/cryptroot rw
17. Reboot (ref)
Exit the chroot environment by typing exit
or pressing Ctrl+d
. Then
run reboot
.
If everything works, it should ask for a password to access the cryptroot, like this screenshot below:
One last thing, if you computer, like mine, is sitting behind a DHCP
(e.g., a typical router), you will need to enable dhcpcd
to access the
Internet. Run,
# systemctl enable dhcpcd
Congratulations! You have installed Arch Linux with Full Disk Encryption!
18. (Optional) Unlocking the Root Partition at boot (ref)
The above setup requires manual interruption on each reboot by entering the password to unlock the disk. There are ways to avoid at the expense of reducing the security level because the decryption key is exposed.
The one I use is to include the decryption key to the _{initram-fs.img}
so that the systemd module encrypt
can use it to decrypt the root
partition automatically.
Steps:
- adds a key file to
/crypto_keyfile.bin
, the default location read by theencrypt
module used above. - adds the
/crypto_keyfile.bin
toFILES=()
array in/etc/mkinitcpio.conf
, so that this file is copied to the image (e.g., _{initram-fs.img}). - regenerates the images with
mkinitcpio -P
.