Install Arch Linux on Encrypted Disk
23 July 2023
I installed Arch Linux before but using archinstall script. archinstall
is a helper library which automates the installation. It is packaged with different pre-configured installers that work like a "guided" installer. Linux enthusiasts will oppose to this way of installing since Arch Linux is meant to be DIY.
Then I attempted to do the encrypted version using the same archinstall
. I am not happy with the result due to the following reasons.
-
It has very limited swap space size.
archinstall
is creating 4GB swap by default and cannot find a way around it. -
It doesn't wake up from hibernation. The only way to recover is through hard restart.
On this post, I will put the step by step guide I followed for an encrypted Arch Linux setup. I had three attempts before I get a working one. Common issue I have is along bootloader and missing resume hook to wake up from deep sleep. I learned my lessons the hard way!
This setup will create an LVM on LUKS with GRUB boot loader.
Preparing the USB boot disk
The steps here are for Linux users. If you're a Windows user, please look for alternative way from Arch Linux Wiki. rufus or Balena etcher will do the job for you.
-
Download the
.iso
image from Arch Linux website. I downloaded mine using qBittorrent. -
Plug your USB drive stick and check it's location usng
lsblk
.$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 1 7.5G 0 disk ├─sda1 8:1 1 798M 0 part /run/media/drmanalo/ARCH_202307 └─sda2 8:2 1 15M 0 part
-
Verify the file integrity using its checksum from the Arch Linux Download Page.
$ sha256sum archlinux-2023.07.01-x86_64.iso 1a2c1cdea0118b60525f55ee616e9cd4cf68fe17db906ce3d8e46fd06f9907eb archlinux-2023.07.01-x86_64.iso
-
Burn the
.iso
image with thedd
tool.$ sudo dd bs=4M if=/path/to/archlinux-2023.07.01-x86_64.iso of=/dev/sda oflag=sync status=progress 852832256 bytes (853 MB, 813 MiB) copied, 210 s, 4.1 MB/s 203+1 records in 203+1 records out 852832256 bytes (853 MB, 813 MiB) copied, 209.578 s, 4.1 MB/s
-
Let your machine reboot from the live USB. The prompt should say
root@archiso
. Below is optional should the default font be small for your eyes.root@archiso ~ # setfont latarcyrheb-sun32
Pre-installation
-
Plug in your Ethernet cable or connect to your WiFi network using iwctl.
-
Update the system clock.
# timedatectl set-ntp true
-
Partition your disk.
nvme0n1
is my block device name. Uselsblk
to find yours. Once ongdisk
, delete existing partitions usingd
.# gdisk /dev/nvme0n1 o n [Enter] 0 +1M ef02 n [Enter] [Enter] +550M ef00 n [Enter] [Enter] [Enter] 8309 w
Installation
-
Create the Linux Unified Key Setup (LUKS) encrypted container on your
ext4
partition.# cryptsetup luksFormat --type luks1 --use-random -S 1 -s 512 -h sha512 -i 5000 /dev/nvme0n1p3
-
Decrypt the container and make it available at
/dev/mapper/cryptlvm
.# cryptsetup open /dev/nvme0n1p3 cryptlvm
-
Create physical volume on the opened LUKS container.
# pvcreate /dev/mapper/cryptlvm
-
Create the volume group.
# vgcreate vg /dev/mapper/cryptlvm
-
Create the logical volumes. The size here is your personal preference.
# lvcreate -L 40G vg -n swap # lvcreate -L 500G vg -n root # lvcreate -l 100%FREE vg -n home
-
Format filesystems on each logical volume.
# mkfs.ext4 /dev/vg/root # mkfs.ext4 /dev/vg/home # mkswap /dev/vg/swap
-
Mount filesystems.
# mount /dev/vg/root /mnt # mkdir /mnt/home # mount /dev/vg/home /mnt/home # swapon /dev/vg/swap
-
Create FAT32 filesystem for the EFI system partition.
# mkfs.fat -F32 /dev/nvme0n1p2
-
Create mount point for EFI system partition at /efi.
# mkdir /mnt/efi # mount /dev/nvme0n1p2 /mnt/efi
-
Install the bare minimum packages.
# pacstrap /mnt base linux linux-firmware mkinitcpio lvm2 neovim dhcpcd wpa_supplicant
-
Generate fstab file.
# genfstab -U /mnt >> /mnt/etc/fstab
-
Change root into the new system.
# arch-chroot /mnt [root@archiso /]#
-
Set the
/etc/localtime
to you respective timezone.# ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
-
Generate
/etc/adjtime
.# hwclock --systohc
-
Generate
/etc/locale.conf
. Uncomment en_US.UTF-8 UTF-8 in/etc/locale.gen
and generate locale.# locale-gen # echo 'LANG=en_US.UTF-8' > /etc/locale.conf
-
Create your hostname file.
# echo yourhostname > /etc/hostname
-
Add entries to hosts table.
# nvim /etc/hosts 127.0.0.1 localhost ::1 localhost 127.0.1.1 yourhostname.localdomain yourhostname
-
Add
encrypt
,lvm2
andresume
hooks to/etc/mkinitcpio.conf
NOTE: The order of hooks matters.# nvim /etc/mkinitcpio.conf ... ## NOTE: If you have /usr on a separate partition, you MUST include the # usr and fsck hooks. HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems resume fsck)
-
Recreate the initramfs image.
# mkinitcpio -p linux
-
Set the root password using
passwd
. -
Install GRUB boot loader.
# pacman -S grub
-
Install EFI boot manager.
# pacman -S efibootmgr # grub-install --target=x86_64-efi --efi-directory=/efi
-
Install microcode.
grub-mkconfig
will automatically detect microcode updates and configure accordingly. There'samd-ucode
package for AMD CPUs.# pacman -S intel-ucode
-
Embed a keyfile in initramfs to avoid having to enter the encryption passphrase twice (once for GRUB, once for initramfs.)
# mkdir /root/secrets && chmod 700 /root/secrets # head -c 64 /dev/urandom > /root/secrets/crypto_keyfile.bin && chmod 600 /root/secrets/crypto_keyfile.bin # cryptsetup -v luksAddKey -i 1 /dev/nvme0n1p3 /root/secrets/crypto_keyfile.bin
-
Add the keyfile to the initramfs image.
# nvim /etc/mkinitcpio.conf FILES=(/root/secrets/crypto_keyfile.bin)
-
Recreate the initramfs image.
# mkinitcpio -p linux
-
Configure GRUB. Set kernel parameter to unlock the LVM physical volume at boot using
encrypt
hook and allow hibernation to the swap space usingresume
hook. Pass thecryptkey
file parameter you're going to generate later on.# nvim /etc/default/grub # GRUB boot loader configuration GRUB_DEFAULT=0 GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="Arch" GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet cryptdevice=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:cryptlvm resume=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx root=/dev/vg/root cryptkey=rootfs:/root/secrets/crypto_keyfile.bin" #GRUB_CMDLINE_LINUX # Preload both GPT and MBR modules so that they are not missed GRUB_PRELOAD_MODULES="part_gpt part_msdos" # Uncomment to enable booting from LUKS encrypted devices GRUB_ENABLE_CRYPTODISK=y
You can get the required UUID using
blkid
.# blkid /dev/mapper/vg-swap: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="swap" /dev/nvme0n1p3: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="crypto_LUKS" PARTLABEL="Linux LUKS" PARTUUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
-
Generate GRUB's configuration files.
# grub-mkconfig -o /boot/grub/grub.cfg
-
Obtain the volume's major and minor device numbers from
lsblk
and echo it to/sys/power/resume
.# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS nvme0n1 259:0 0 1.8T 0 disk ├─nvme0n1p1 259:1 0 1M 0 part ├─nvme0n1p2 259:2 0 550M 0 part /efi └─nvme0n1p3 259:3 0 1.8T 0 part └─cryptlvm 254:0 0 1.8T 0 crypt ├─vg-swap 254:1 0 40G 0 lvm [SWAP] ├─vg-root 254:2 0 500G 0 lvm / └─vg-home 254:3 0 1.3T 0 lvm /home # echo 254:1 > /sys/power/resume
-
Restrict /boot permissions.
# chmod 700 /boot
At this point, you have a completely encrypted Arch Linux setup. DON'T reboot if you're not on Ethernet. You will lose the WiFi credentials from iwctl
and it's impossible to install additional packages.
Post-installation
I'm always a GNOME fan so I'm going to install gnome
as my Graphical User Interface. sway
is another option but I will not put the install instructions here. Perhaps it's for another blog post.
-
Create a non-root account.
# useradd -m -G wheel,users -s /bin/bash username # passwd username New password: Retype new password: passwd: password updated successfully
-
Install
sudo
.# pacman -S sudo # visudo ... ## ## User privilege specification ## root ALL=(ALL) ALL # Options Defaults editor=/usr/bin/nvim, !env_editor Defaults insults # Full Access username ALL=(ALL) ALL # Last rule as a safety guard username ALL=/usr/sbin/visudo # Uncomment to allow member of group wheel to execute any command %wheel ALL=(ALL) ALL ...
-
Install GNOME.
# pacman -S gnome dhclient iw dialog # pacman -Sy networkmanager network-manager-applet xf86-input-libinput
-
Enable Gnome Display and Network Manager.
# systemctl enable gdm # systemctl enable NetworkManager
-
Exit
chroot
and unmount your filesystems.# exit # umount -R /mnt
-
Finally, reboot.
# reboot
Congratulations! You have survived Arch Linux installation.