Arch Linux with UEFI boot and full disk encryption

Created: 2020-09-30   Updated: 2020-10-15   Category: linux   Print this pageBack to Home


This post contains some notes when I install Arch Linux with UEFI boot and full disk encryption. The following commands can be performed with a live Arch CD or USB booting UEFI.


Create and format

For UEFI boot, I use GUID Partition Table (GPT) with the following partitions (which I created using cfdisk).

Partition Mount point Size Type Format Purpose
/dev/sda1   2M BIOS boot   required if using GRUB
/dev/sda2 /boot/efi 300M EFI System FAT32
mkfs.fat -F32 /dev/sda2
EFI system partition
/dev/sda3 /boot 500M Linux filesystem EXT4
mkfs.ext4 /dev/sda3
boot partition
/dev/sda4 / Remaining space Linux filesystem LUKS encryption
cryptsetup luksFormat -v -s 512 -h sha512 /dev/sda4
cryptsetup open /dev/sda4 luks_root
mkfs.ext4 /dev/mapper/luks_root
root partition

Mount to /mnt

mount /dev/mapper/luks_root /mnt
mkdir -p /mnt/boot && mount /dev/sda3 /mnt/boot
mkdir -p /mnt/boot/efi && mount /dev/sda2 /mnt/boot/efi

Create 1GB swap in /mnt

cd /mnt
dd if=/dev/zero of=swap bs=1M count=1024 # create `swap` block file
mkswap swap # format `swap`
swapon swap # enable swap
chmod 600 swap # change permission


See this post. In particular, you need to be careful about the followings.

Generate fstab

genfstab -t PARTUUID /mnt > /mnt/etc/fstab

Modify /etc/default/grub

Modify the line containing GRUB_CMDLINE_LINUX= as follows.

GRUB_CMDLINE_LINUX="cryptdevice=PARTUUID=<partuuid of root partition /dev/sda4>:luks_root root=/dev/mapper/luks_root rw"

where <partuuid of root partition /dev/sda4> can be found by running blkid /dev/sda4.

Modify /etc/mininitcpio.conf

Chroot into the system with arch-chroot /mnt. Then, modify the line containing HOOK= in /etc/mkinitcpio.conf as follows.

HOOKS=(base udev block keyboard keymap autodetect modconf encrypt filesystems fsck)

And remeber to run mkinitcpio -p linux after saving the modification.

Boot with GRUB

arch-chroot /mnt # if not done already
grub-install --target=x86_64-efi --boot-directory=/boot/efi --efi-directory=/boot/efi /dev/sda # Keep all files, including configurations, in `/boot/efi`
grub-mkconfig -o /boot/efi/grub/grub.cfg

Boot with systemd-boot

See this page for more details. To install the EFI boot manager, run

arch-chroot /mnt # if not done already
bootctl --esp-path=/boot/efi --boot-path=/boot/efi install

Create /boot/efi/loader/entries/arch.conf with the following contents

title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options cryptdevice=PARTUUID=<partuuid of root partition /dev/sda4>:luks_root root=/dev/mapper/luks_root rw

and modify /boot/efi/loader/loader.conf by adding

timeout 3
default arch
editor 0

Secure boot with systemd-boot and PreLoader

See this page for more details.

  • Install preloader-signed.

    yay -S preloader-signed 
  • Copy PreLoader.efi and HashTool.efi to the boot loader directory.

    sudo cp -vp /usr/share/preloader-signed/{PreLoader,HashTool}.efi /boot/efi/EFI/systemd
  • Copy over the boot loader binary and rename it to loader.efi.

    sudo cp -vp /boot/efi/EFI/systemd/systemd-bootx64.efi /boot/efi/EFI/systemd/loader.efi 
  • Create a new NVRAM entry to boot PreLoader.efi, note that /dev/sda2 is the EFI system partition.

    sudo efibootmgr --verbose --disk /dev/sda --part 2 --create --label "PreLoader" --loader /EFI/systemd/PreLoader.efi 

If there are problems booting the custom NVRAM entry, copy HashTool.efi and loader.efi to the default loader location booted automatically by UEFI systems:

sudo cp -vp /usr/share/preloader-signed/HashTool.efi /boot/efi/EFI/Boot
sudo cp -vp /boot/efi/EFI/systemd/systemd-bootx64.efi /boot/efi/EFI/Boot/loader.efi

then copy over PreLoader.efi and rename it:

sudo cp -vp /usr/share/preloader-signed/PreLoader.efi /boot/efi/EFI/Boot/bootx64.efi

Extra tips and tricks

Increase the size of LUKS encrypted partitions (no LVM)

Assume that there is space on the disc available which is not yet used by the encrypted LUKS volume. The steps to increase the volume size (which were originally described here) are:

  1. Increase the partition’s size used by the encrypted volume.

    In this case, I want to resize /dev/sda4. This can be done using gparted.

  2. Increase the size of the encrypted LUKS volume.

    cryptsetup open /dev/sda4 luks_root
    cryptsetup resize luks_root -v # increase the LUKS volume to fit the resized partition `/dev/sda4`   
  3. Resizing the file-system of the volume

    e2fsck -f /dev/mapper/luks_root # check file-system
    resize2fs /dev/mapper/luks_root # resize file-system

Note: This situation may happen when using Clonezilla to clone one LUKS encrypted partition to another partition having much larger size than the original one.

Decrease the size of LUKS encrypted partitions (no LVM)

Let say I want to decrease the size of the encrypted LUKS volume on /dev/sda4. (See this page for more details.)

  1. Decrease the size of the encrypted LUKS volume.

    cryptsetup open /dev/sda4 luks_root

    The command cryptsetup resize /dev/mapper/luks_root -b <size in sectors> can be used to decreases the size of the encrypted LUKS volume. To compute the value of <size in sectors>, we first need to know the size of luks_root, which can be obtained by running cryptsetup status luks_root, and look at the value of size:. As an example, here is the result of this command running on my current system

    /dev/mapper/luks_root is active and is in use.
    type:    LUKS2
    cipher:  aes-xts-plain64
    keysize: 512 bits
    key location: keyring
    device:  /dev/sda4
    sector size:  512
    offset:  32768 sectors
    size:    121602048 sectors
    mode:    read/write

    and the size of luks_root is 121602048 sectors (since the sector size is 512 bytes, this is equivalent to 121602048 * 512 = 62260248576 bytes = 57.98 GiB). Thus, to subtract 1 GiB, the value of <size in sectors> should be 121602048 - 1 * 1024 * 1024 * 2 = 119504896. In short, run

    cryptsetup resize /dev/mapper/luks_root -b 119504896

    Then, we can

    e2fsck -f /dev/mapper/luks_root # check file-system
    resize2fs /dev/mapper/luks_root # resize file-system

    and then cryptsetup close luks_root.

  2. Resize /dev/sda4 (be careful, do not make its size smaller than the size of the encrypted volume), which can be done using cfdisk.

Automount LUKS encrypted non-root partitions on system start

Assume that I have a LUKS encrypted partition /dev/sda5 which I want to mount automatically on system start. The steps I will perform are as follows. (See the original guide here.) All commands are run as root.

  1. (Optional) Create a key to unlock the volume.

    LUKS encryption supports multiple keys. These keys can be passwords entered interactively or key files passed as an argument while unlocking the encrypted partition. The following command will generate a file with 4 KB of random data to be used as a key to unlock the encrypted volume.

    dd if=/dev/urandom of=/etc/luks-keys/disk_secret_key bs=512 count=8

    With the following commands the created key file is saved in /etc/luks-keys and added as a key to the LUKS encrypted volume.

    mkdir -p /etc/luks-keys && cryptsetup -v luksAddKey /dev/sda5 /etc/luks-keys/disk_secret_key

    You can save your secret key in any place, instead of /etc/luks-keys. To verify that the key is working, the following command can be executed manually.

    cryptsetup -v open /dev/sda5 luks_part --key-file=/etc/luks-keys/disk_secret_key
  2. Automatically open the encrypted volume.

    This can be done by adding to /etc/crypttab the following line

    luks_part /dev/disk/by-partuuid/<partuuid of /dev/sda5> /etc/luks-keys/disk_secret_key luks 

    where <partuuid of /dev/sda5> can be found by running blkid /dev/sda5. In case you do not want to use keys, replace /etc/luks-keys/disk_secret_key by none, and you will then have to manually enter the passphrase to unlock the LUKS volume.

    Finally, to automatically mount the volume, say, to /data, on system start, add the following line to /etc/fstab. (Assuming that the volume is ext4 formatted).

    /dev/mapper/luks_part /data ext4 nofail 0 2

Automount VeraCrypt encrypted files on system start

Let say I have a VeraCrypt encrypted file /secret.hc, formatting as ext4, and unlocking it requires a passphrase and a key file /key.file. To unlock /secret.hc, run the following command as root.

cryptsetup -v open /secret.hc --type tcrypt --veracrypt --key-file /key.file veracrypt

The command will output Command successful after you enter the correct passphrase after the line Enter passphrase for /secret.hc:, and you will see that /dev/mapper/veracrypt is available.

As above, in order to automatically open /secret.hc, add the following line to /etc/crypttab

veracrypt /secret.hc <passphrase> tcrypt-veracrypt,tcrypt-keyfile=/key.file

When using an empty passphrase in combination with one or more key files, use /dev/null instead of <passphrase> as the password file in the third field. Otherwise, replace <passphrase> with your passphrase to unlock /secret.hc.

Finally, to automatically mount the volume on system start, add the following line to /etc/fstab.

/dev/mapper/veracrypt /mnt/veracrypt ext4 nofail 0 2

Automount Bitlocker encrypted partitions on system start

To open a Bitlocker encrypted partition, you need to install dislocker, which can be done in Arch Linux by running yay -S dislocker-git. Let say I have a Bitlocker encrypted partition /dev/sda6, formatting as ntfs, and unlocking it requires a passphrase. To unlock /dev/sda6, run the following commands as root.

mkdir -p /media/bitlocker 
dislocker -v -V /dev/sda6 -u<passphrase> -- /media/bitlocker 

If the commands run successfully, you will see that /media/bitlocker/dislocker-file is available. You can replace /media/bitlocker with any directory you want, and replace <passphrase> with your own secret passphrase. If you want to use recovery password instead of passphrase, use -p instead of -u. Next, you can mount /media/bitlocker/dislocker-file to any folder, say /data, as follows. To mount a NTFS partition, you need ntfs-3g.

export your_uid=$(id -u)
export your_gid=$(id -g)
sudo mount -t ntfs-3g -o gid=$your_gid,uid=$your_uid,dmask=022,fmask=133 /media/bitlocker/dislocker-file /data

The options gid=$your_gid,uid=$your_uid,dmask=022,fmask=133 is to keep the common permissions of files and folders in Linux (permissions on a Linux system are normally set to 755 for folders and 644 for files) in use for the NTFS partition as well.

Finally, to automatically mount the volume on system start, add the following lines to /etc/fstab. (Remember to replace the parts <...> with your own values.)

PARTUUID=<partuuid of /dev/sda6> /media/bitlocker fuse.dislocker user-password=<passphrase>,nofail 0 0
/media/bitlocker/dislocker-file /data ntfs-3g gid=<your_gid>,uid=<your_uid>,dmask=022,fmask=133 0 0

Valid CSS! Valid HTML 4.01 Transitional Back to top
Powered by Jekyll
The content on this site is shared under a CC BY-SA 4.0 license, unless otherwise noted Last Modified: October 15, 2020