Full-disk encryption on Archlinux with LVM+LUKS+BTRFS
Table Of Contents
This article will guide you through a basic Archlinux installation with full-disk encryption and the usage of the BTRFS filesystem for managing subvolumes and snapshots.
The steps shown here are all available in the Arch Wiki, but I wanted to make an installation example from scratch until OS startup.
This installation will presume you are booting from an EFI System and that you will be using a SWAP partition. Again, this is a concrete real-world example but feel free to make it match to your likings.
Planning the disk layout
In this case we’re going to make two main partitions in a GPT partition table:
/dev/sda1
, the ESP (UEFI Boot Partition) that will hold our kernel and the bootloader. Formatted as FAT32 with a size of 512MB withmkfs.fat -F 32 /dev/sda1
/dev/sda2
, is a partition that will contain an encrypted container which at the same time will contain an LVM physical volume which at the same time will contain logical volumes for both the root and swap filesystems. Yeah, this seems a little bit crazy but it is a very flexible configuration :)
Setting up the disk layout and volumes
Supposing you’ve already created the two partitions mentioned about and formatted /dev/sda1
as FAT32, the next step is to create the encrpyted container:
# cryptsetup luksFormat /dev/sda2
# cryptsetup open /dev/sda2 cryptlvm
Consecutively, a physical volume called cryptlvm
is going to be created. We will also add that physical volume to a volume group called secure
# pvcreate /dev/mapper/cryptlvm
# vgcreate secure /dev/mapper/cryptlvm
Then we’re going to focus on creating the swap and root filesystems:
The swap partition will be 4GB and the rest will be used for the BTRFS system partition
lvcreate -L 4G secure -n swap
lvcreate -l 100%FREE secure -n root
Initialize the swap partition:
mkswap /dev/mapper/secure-swap
swapon /dev/mapper/secure-swap
Create the BTRFS filesystem and their subsequent subvolumes: ‘@’ for root, ‘@home’ for the home folder and ‘@snapshots’ for making filesystem backups. This makes it to discriminate directories when making backups.
mkfs.btrfs /dev/mapper/secure-system
mount /dev/mapper/secure-system /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
umount /mnt
Now we’re going to mount all the volumes and we’re going to enable zstd compression.
mount -o subvol=@,compression=zstd /dev/mapper/secure-system /mnt
mkdir -p /mnt/{home,boot}
mount -o subvol=@home,compression=zstd /dev/mapper/secure-system /mnt/home
mount /dev/sda1 /mnt/boot
Continue with the usual Arch install
Follow the normal install of the base system and basic config. in the Installation guide
Finishing the installation
When arriving at the mkinitcpio part some extra steps will be required:
Install intel-ucode
(or the AMD counterpart) and install systemd-boot on the ESP:
bootctl –path=/boot install
Head over to the ESP (/boot) and create arch.conf
inside the entries
directory with the following content:
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img # ONLY FOR INTEL CPUs!!
initrd /initramfs-linux.img
options luks.uuid=<LUKS_UUID> root=/dev/mapper/secure-system rootflags=subvol=@ rd.luks.options=discard
Replace <LUKS_UUID>
with the UUID shown in blkid
in the filesystem flagged as LUKS.
Add default arch
inside the loader.conf
file.
Edit the HOOKS line in /etc/mkinitcpio.conf
with the following modules:
HOOKS=(base systemd autodetect modconf keyboard sd-vconsole block sd-encrypt sd-lvm2 filesystems fsck)
Lastly run mkinitcpio -p linux
and reboot
. If you’re lucky enough you will enter to your newly installed operating system.