Extended Brain Storage

Arch Linux: Full Disk Encryption

Posted on January 14, 2016

This is a brief manual for installation of Arch Linux with full disk encryption (FDE)...

The Goal

The aim is to install the system on a desktop computer having one SSD for system (root and swap partitions/volumes) and one SATA disk for the home directory. Both disk will be encrypted using Linux Unified Key Setup (LUKS) and partitioned using Logical Volume Manager (LVM) on an MBR disk scheme (aka LVM on LUKS). LUKS is now part of an enhanced version of cryptsetup and uses dm-crypt as the disk encryption backend.

Using mkinicpio's kernel hooks, a binary key-file can be added into the initramfs image in order to be able to decrypt and mount the disk (partition) automatically. Users insert the password only a single time, when the computer starts (once GRUB asks for it).

The Installation Process

The installation ISO can be downloaded from several mirrors.

The great thing with Arch Linux (surely with other operating systems as well) is that the installation process can be done from a remote machine. Thus, enabling administrators to copy-paste the necessary commands. For that purpose, SSH needs to be run. And for SSH purpose, a root password needs to be set up (it is just for the installation process, permitting root login via SSH is not advised):

$ passwd
$ echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
$ echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
$ systemctl enable sshd.service
$ systemctl start sshd.service

Disks Availability

The available disks can be checked as follows:

$ parted -s /dev/sda print

Disk Format and Partitioning

Disk format is performed using parted program and WILL DELETE DATA.

$ parted -s /dev/sda mklabel msdos

Both disks (sda and sdb) will contain a single partition that will be encrypted afterwards:

$ parted -s -a optimal /dev/sda mkpart "primary" "ext4" "0%" "100%"
$ parted -s /dev/sda set 1 boot on
$ parted -s -a optimal /dev/sdb mkpart "primary" "ext4" "0%" "100%"

The alignment of partitions can be always checked by running:

$ parted -s /dev/sda print
$ parted -s /dev/sda align-check optimal <PARTITION_NUMBER>

Disk Encryption and Logical Volumes

The cryptsetup (used for LUKS disk encryption) command comes with the following default options. Therefore, they will be omitted in the following commands:

$ cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 2000 --use-urandom --verify-passphrase luksFormat /dev/sdXY

First, the SATA disk (to contain the home directory) will be initialised (as lvm-data) and opened in order to be available (decrypted) by the device mapper (in /dev/mapper/lvm-data):

$ cryptsetup luksFormat -v /dev/sdb1
$ cryptsetup luksOpen /dev/sdb1 lvm-data

The SATA disk will contain only a single physical volume (in lvm-data), single volume group (lvmData) and a single logical volume (volHome) providing versatility for future needs (of resizing and changing the number of logical volumes):

$ pvcreate /dev/mapper/lvm-data
$ vgcreate lvmData /dev/mapper/lvm-data
$ lvcreate -l +100%FREE lvmData -n volHome

Second, the SSD (to contain the swap and root volumes) will be initialised (as lvm-system) and opened in order to be available (decrypted) by the device mapper (in /dev/mapper/lvm-system):

$ cryptsetup luksFormat -v /dev/sda1
$ cryptsetup luksOpen /dev/sda1 lvm-system

The SSD will contain a single physical volume (in lvm-system), single volume group (lvmSystem) and a two logical volumes (volSwap of 16GB and volRoot) providing versatility for future needs (of resizing and changing the number of logical volumes):

$ pvcreate /dev/mapper/lvm-system
$ vgcreate lvmSystem /dev/mapper/lvm-system
$ lvcreate -L 16G lvmSystem -n volSwap
$ lvcreate -l +100%FREE lvmSystem -n volRoot

Note: If any of the commands produces the following warning, it can be ignored, as: "This is because /run is not available inside the chroot."

/run/lvm/lvmetad.socket: connect failed: No such file or directory


WARNING: Failed to connect to lvmetad. Falling back to device scanning.


WARNING: failed to connect to lvmetad: No such file or directory. Falling back to internal scanning.

Having all disks, partitions and volumes ready, it is possible to format them as follows (swap, ext4 for / and ext4 for /home):

$ mkswap /dev/lvmSystem/volSwap
$ mkfs.ext4 /dev/lvmSystem/volRoot -L volRoot
$ mkfs.ext4 /dev/lvmData/volHome -L volHome

Having each partition formatted, they can be mounted as follows:

$ swapon /dev/lvmSystem/volSwap
$ mount /dev/lvmSystem/volRoot /mnt
$ mkdir /mnt/home
$ mount /dev/lvmData/volHome /mnt/home

Packages Installation, Kernel Compilation

Optionally, if a WiFi interface needs to be set up in order to reach the Internet, the following command can be run:


Finally, the operating system parts can be downloaded and installed as follows:

$ pacstrap /mnt base base-devel

The /etc/fstab file can be created using various system identifiers, the following step uses UUIDs:

$ genfstab -p -U /mnt >> /mnt/etc/fstab

Now, it is time to change root (chroot) to the newly installed environment:

$ arch-chroot /mnt /bin/bash

Setting up system locale and hostname can be done as follows (e.g. for Australian):

$ echo -e "en_AU.UTF-8 UTF-8" >> /etc/locale.gen
$ locale-gen
$ echo LANG=en_AU.UTF-8 > /etc/locale.conf
$ export LANG=en_AU.UTF-8
$ ln -s /usr/share/zoneinfo/Continent/City /etc/localtime
$ echo "archlinux" > /etc/hostname

The /etc/mkinitcpio.conf file enables to set up various kernel parameters. Within the HOOKS part, the encrypt lvm2 need to be put between block and filesystems keywords in order to enable the FDE. It may also be useful to include the resume keyword to enable suspend to disk options.

HOOKS="base udev autodetect modconf block encrypt lvm2 resume filesystems keyboard fsck"

Now, the kernel can be compiled and a new initramdisk created:

$ mkinitcpio -p linux

Consequently, the root password needs to be set up:

$ passwd

Optionally, all solid-state disk (SSD) mountpoints can be updated with the discard option to enable TRIM:

$ sed -i "s/ordered/ordered,discard/g" /etc/fstab

However, there are opinions that recommend against that. If in doubt about the hardware, the Periodic TRIM can be applied instead.

Optionally, size of the TMPFS partition can be changed as follows:

$ echo "tmpfs	/tmp	tmpfs	nodev,nosuid,size=8G	0 0" >> /etc/fstab

Boot Loader Installation

There are various bootloaders. However, the following commands use the GRUB (and its optional dependencies):

$ pacman -S grub
$ pacman -S dosfstools freetype2 fuse2 libisoburn mtools os-prober
$ pacman -S iw memtest86+ wpa_supplicant

Grub needs to be configured in /etc/default/grub in order to find the LUKS-encrypted partition as follows:


Optionally, Grub colours can be modified as follows:


Finally, Grub can be installed at the beginning of the first disk (/dev/sda) as follows:

$ grub-install --recheck /dev/sda
$ grub-mkconfig -o /boot/grub/grub.cfg

Optionally, the SWAP partition can be also configured using the UUID in /etc/fstab (the previous swap record needs to be removed first):

$ sed -i "/swap/d" /tmp/fstab
$ blkid | grep volSwap | awk '{print $2}' | sed "s/^.*=\"/UUID=/g" | sed 's/"/ none swap defaults 0 0/g' >> /etc/fstab

Optionally and if required, the resume partition needs to be configured in the /etc/default/grub file using its <SWAPUUID> (can be identified using the previous blkid command) as follows:


Every change in the configuration of Grub needs to be followed by the following command in order to be applied:

$ grub-mkconfig -o /boot/grub/grub.cfg

Automated Disk Decryption by Grub

For more details regarding usage of /dev/random and /dev/urandom for keys generation, this ArchWiki page can be visited. A random byte files can be generated in order to serve as keys to the encrypted partitions (one for the sda called crypto_keyfile.bin and one for the sdb called lvm-data.bin):

$ mkdir -m 700 /etc/luks-keys
$ dd if=/dev/random of=/crypto_keyfile.bin bs=512 count=8 iflag=fullblock
$ dd if=/dev/random of=/etc/luks-keys/lvm-data.bin bs=512 count=8 iflag=fullblock

It is necessary to configure LUKS to accept these keys by running:

$ cryptsetup luksAddKey /dev/sda2 /crypto_keyfile.bin
$ cryptsetup luksAddKey /dev/sdb1 /etc/luks-keys/lvm-data.bin

Optionally, LUKS can also be told to remove the keys as follows:

$ cryptsetup luksRemoveKey /dev/sdXY /path/to/the/key_file.bin

or even to remove the password (one method should always remain to prevent locking the partition out):

$ cryptsetup luksRemoveKey /dev/sdXY

In order to prevent the password to open the LUKS volume to be asked the second time, the /etc/mkinitcpio.conf file (the FILES variable) needs to be updated with the password file path reference as follows:


The initramfs file needs to be regenerated (the kernel recompiled):

$ mkinitcpio -p linux

The UUID of the SATA disk's partition (sdb1) can be resolved as follows:

$ blkid | grep sdb1 >> /etc/crypttab

The UUID is necessary for the sdb1 partition in order to be automatically decrypted by the operating system during boot. The /etc/crypttab need to contain the following line:

lvm-data UUID="<UUID>" /etc/luks-keys/lvm-data.bin

Network Setup

Before restarting, the network needs to be set up, since the Arch installer does not install any by default. The are several ways to configure a network service. Unfortunately, all of them are mutually exclusive. Obviously, everyone has their needs for operating the computer either from terminal (without having X installed) or from a GUI. Assuming that the desktop computer will run a GTK-based X window system (such as XFCE4), a Network Manager feature may can handy. It can be enabled as follows:

$ pacman -S network-manager-applet

The only one downside of this program is that the passwords are stored in clear text in:

$ grep -H '^psk=' /etc/NetworkManager/system-connections/*

NTP Daemon Setup

Network time protocol service can be setup as follows:

$ pacman -S ntp
$ systemctl enable ntpd
$ pacman -S networkmanager-dispatcher-ntpd

Adding a Non-privileged User

As an example, the following list of commands adds a non-privileged user (USERNAME) into the system as part of the users default group and other groups (if available) including a prompt for password:

$ sed -i 's/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g' /etc/sudoers
$ useradd -m -g users -G audio,games,lp,optical,power,scanner,storage,video,wheel -s /bin/bash USERNAME
$ passwd USERNAME

AUR Package Manager

Installation of the yaourt package manager, as a non-privileged user (from sudoers group):

$ cd /tmp
$ wget https://aur.archlinux.org/cgit/aur.git/snapshot/package-query.tar.gz -O - | tar xvz
$ cd package-query
$ makepkg -si
$ wget https://aur.archlinux.org/cgit/aur.git/snapshot/yaourt.tar.gz -O - | tar xvz
$ cd yaourt
$ makepkg -si

Installation of the X Window System

In order to install X.Org, Xfce4 and lightdm, the following commands can be run (assuming an old Nvidia graphic card):

$ yaourt -S xorg-server
$ yaourt -S libvdpau nvidia-340xx-dkms nvidia-340xx-utils opencl-nvidia-340xx lib32-nvidia-340xx-utils lib32-opencl-nvidia-340xx
$ yaourt -S xfce4 xfce4-goodies
$ yaourt -S lightdm lightdm-gtk-greeter


The system now needs to be rebooted:

$ exit
$ reboot

Post Installation Steps

The are a couple of security considerations regarding access rights to the following files

$ chmod 000 /crypto_keyfile.bin # actually, even root doesn't need to access the keys
$ chmod 000 /etc/luks-keys/*    # dtto
$ chmod -R g-rwx,o-rwx /boot    # just to be safe


If sound is muted, the channels need to be unmuted by running (as root):

$ alsamixer
$ alsactl store

The annoying PC speaker beeping can be deactivated simply blacklisting the kernel module as follows:

$ echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf

Udev renames interfaces, the following can be used to return back to eth0 etc.:

$ ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules

Tags: #Arch Linux #security #encryption #FDE #systemd #BIOS #MBR #LUKS #LVM

⏴ Previous Post Next Post ⏵