Install Arch with full disk encryption, btrfs and EFI

4 minute read

I recently had to re-install my beloved Arch Linux. For security I need (and use) full disk encryption. This is a cheatsheet for the whole procedure, because although the Arch Linux Wiki is excellent, it is also huge and sometimes you must pick your stuff together from many pages.

This is what I am doing here 🙂

NOTE: Usually you only have to follow the one subsection I link to!


One after another, we will do the following steps

  • Download and prepare Arch USB stick (skipped, you should know that 😉
  • Prepare the hard disk
  • Prepare the disk partitions
  • Add LVM “inside” the crypted partition
  • Create filesystems & mount partitions
  • Install arch
  • Configure boot manager

Prepare the hard disk

Use parted to init the disk and …

  1. init the disk using a GPT partitioning scheme, then create
  2. a GPT boot partition and put 100% of the remaining space in another partition (the first two actions behind the link)

Prepare the disk partitions


  1. use the cryptsetup command to encrypt the main (big) partition,
  2. and create a file system on the boot partition (remember: it must be FAT32 for EFI boot, and it must be _un_encrypted!)

Add an LVM “inside” the encrypted partition

Cause we want “properly” encrypted swap (you can also encrypt swap using a /dev/random key every time, but then you will not persist data between reboots and you can’t do things like suspend-to-disk), we need at least two “partitions” “inside” the crypted volume. Sounds like LVM on LUKS? It does. We already used it 🙂 .

  1. Create LVM partitions inside the encrypted volume (Don’t forget to use cryptsetup luksOpen before, usually in step 1 in the last section 🙂

NOTE: Do not follow the above link down to “prepare the boot partition”, cause they use ext2 and we need FAT32 for EFI boot partitions. Just don’t.

I use the name “secure” for the VG, and I use btrfs cause I am so incredibly elite, and so we don’t need to set a specific size for the / and /home “partitions” and can just use btrfs subvolumes, while still being able to wipe the system without the home directories. That’s pretty neat if you need it (I never did, but now I can ;). So that’s the final setup:

/dev/mapper/secure-swap    40 GB, swap
/dev/mapper/secure-system  rest, btrfs with 2 subvols: root & home

Create filesystems & mount partitions

Of course, Arch has already a wiki page section for that. I did it 3 times in a different way until I found it and had to do it again. So here is my summary.

$ 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

$ mount -o subvol=@ /dev/mapper/crypted-system /mnt
$ mkdir -p /mnt/home /mnt/boot
$ mount -o subvol=@home /dev/mapper/crypted-system /mnt/home
$ mount /dev/sda1 /mnt/boot

NOTE: /boot is not on an encrypted partition 😉 , and the leading “@” is a convention for subvolumes which should be mounted somewhere. I also don’t use compress=...  parameters, cause I don’t need / want transparent compression.

Install arch

Then you follow up with the usual installation procedure, but you stop at the “Initramfs” section. Here we will pick up again.

Configure boot manager

We are using systemd-boot. Or bootctl, as the binary is called. It should be already installed. The procedure is also outlined here. We also enable TRIM support, it seems to lessen security, but it raises SSD performance and life time.

  1. First, check if your system EFI is all right.
  2. Optionally install the Intel microcode updater package if you have an Intel CPU by doing pacman -S intel-ucode.
  3. Then run … bootctl -path=/boot install to install systemd-boot.

Now create those files (all inside /mnt and relative to it, but of course you should be in a chroot right now :):

title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img       # ONLY FOR INTEL CPUs!!
initrd /initramfs-linux.img
options luks.uuid=FS_UUID root=/dev/mapper/secure-system rootflags=subvol=@ rd.luks.options=discard

You can get FS_UUID in the options line above by using the blkid command. If you don’t want to copy the UUID by hand, you can start console mouse support with copy-on-mark and paste-on-middleclick with gpm -m /dev/input/mice -t imps2. Note that the FS_UUID is the UUID of the encrypted luks partition, and not the filesystem within!

The list of normal and dm-crypt related kernel parameters … well, is also in the Arch wiki.

default arch    # the file above without .conf extension, can have wildcards!!
timeout 2
editor  0
# Just MODIFY that file, to be precisely this line:
HOOKS=(base systemd autodetect modconf keyboard sd-vconsole block sd-encrypt sd-lvm2 filesystems fsck)

The key idea is to use the “systemd” parameters instead of the “normal” ones. The full list of hooks is of course also available, and the order is important.

Now execute:

mkinitcpio -p linux

… and actually, that should be it.

$ reboot


  • 2018-03-27 fixed a typo in the HOOKS documentation, clarified kernel boot parameters