This is a brief tutorial on how to install Arch Linux on UEFI enabled system with full hard drive encryption using LUKS ( Linux Unified Key Setup). LUKS is a disk encryption specification which helps you achieve file encryption, disk encryption, data encryption in one bundle.

LUKS helps you secure your drive against things like theft, but it doesn’t protect your data from access once unlocked. It can be used with other encryption softwares to achieve bullet-proof data security.

Previously i had written an article on how to install Arch Linux on LVM but it was lacking luks encryption feature. The link is given below:

Install Arch Linux with LVM on UEFI system

This blog post aims at filling that gap of disk encryption, so definitely expect less theory.

This should not be done on vp, vps hosting, vps server, cloud vps, vps server hosting e.t.c. All those acronyms has the same meaning anyway.

Setting up disk partitions:

My partition scheme will have /dev/sda1 as efi partition, /dev/sda2 as boot partition, /dev/sda3 as LVM physical volume, /dev/arch/root as root partition to install Arch Linux , /dev/arch/home as home partition, /dev/arch/swap as swap partition.

The tool of choice for partitioning is Parted, you can use gdisk for efi or fdisk for MBR as well. parted work for both though. Please replace gpt label with mbr for the correct disk label type.

parted /dev/sda
mklabel gpt
mkpart ESP fat32 1MiB 200MiB
set 1 boot on
name 1 efi

mkpart primary 200MiB 800MiB
name 2 boot

mkpart primary 800MiB 100%
set 3 lvm on
name 3 lvm
print

Configure LUKS

Next step is to load kernel modules to install Arch Linux with luks . Before using cryptsetup, always make sure the dm_crypt kernel module is loaded.

modprobe dm-crypt 
modprobe dm-mod

Then go ahead and create encrypted device using cryptseup  command. Cryptsetup is the command line tool to interface with dm-crypt for creating, accessing and managing encrypted devices.

Cryptsetup has support for different encryption types that rely on the Linux kernel device-mapper and the cryptographic modules.

The tool is used as follows:

# cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname>

The devices accessed via the device-mapper are called blockdevices.

You can check available options using:

$ cryptsetup --help 

Let’s now create a new LUKS device on /dev/sda3

# cryptsetup luksFormat -v -s 512 -h sha512 /dev/sda3

Options used:

luksFormat: formats a LUKS device
-v, –verbose:  Shows more detailed error messages
-s, –key-size:  The size of the encryption key, 512 bits in this case.
-h, –hash: The hash used to create the encryption key from the passphrase

When you execute command above, you’ll get a warning message. Just type YES to continue, then enter and verify passphrase to use.

Now that we have created luks encrypted device, we need to open the device as mapping <name>. The syntax is:

# cryptsetup open <device> <name>

<name> is the device to create under /dev/mapper
<device> is the encrypted device

So mine will look something like below:

# cryptsetup open /dev/sda3 luks_lvm

LVM Configuration

For those new to LVM, the basic building blocks of LVM are:

Physical volume (PV)
– Partition on hard disk (or even the disk itself or loopback file) on which you can have volume groups.
– It has a special header and is divided into physical extents.
– Think of physical volumes as big building blocks used to build your hard drive.

Volume group (VG)
– Group of physical volumes used as a storage volume (as one disk).
– They contain logical volumes.
– Think of volume groups as hard drives.

Logical volume (LV)
– A “virtual/logical partition” that resides in a volume group and is composed of physical extents.
– Think of logical volumes as normal partitions.

Physical extent (PE)
– The smallest size in the physical volume that can be assigned to a logical volume (default 4MiB).
– Think of physical extents as parts of disks that can be allocated to any partition.

The configuration part:

Create physical volume:

pvcreate /dev/mapper/luks_lvm

Create volume group named arch:

vgcreate arch /dev/mapper/luks_lvm

Create Logical volumes for root, home and swap partitions:

lvcreate -n home -L 70G arch
lvcreate -n root -L 120G arch
lvcreate -n swap -L 1G -C y arch

Format the partitions:

mkfs.fat -F32 /dev/sda1
mkfs.ext4 /dev/sda2
mkfs.btrfs -L root /dev/mapper/arch-root
mkfs.btrfs -L home /dev/mapper/arch-home
mkswap /dev/mapper/arch-swap

Mount Partitions:

swapon /dev/mapper/arch-swap
swapon -a ; swapon -s
mount /dev/mapper/arch-root /mnt
mkdir -p /mnt/{home,boot}
mount /dev/sda2 /mnt/boot
mount /dev/mapper/arch-home /mnt/home
mkdir /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi

Confirm if all are mounted properly:

lsblk -f

Install Arch Linux:

Install base system:

pacstrap /mnt base base-devel efibootmgr vim dialog \
xterm btrfs-progs grub --noconfirm

Generate fstab file:

genfstav -U -p /mnt > /mnt/etc/fstab

Switch to chroot environment:

arch-chroot /mnt /bin/bash

Configuring mkinitcpio

vim /etc/mkinitcpio.conf

Scroll down till you find HOOKS section. Then add these lines before filesystem:

encrypt lvm2

Hooks are referred to by their name, and executed in the order they exist in the HOOKS setting in the config file. The HOOKS line will look something like this:

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

Generate a new initramfs image:

mkinitcpio -v -p linux

Install grub and generate grub.cnf file:

pacman -s grub --noconfirm
grub-install --efi-directory=/boot/efi

Configuring the kernel parameters

In order to enable booting an encrypted root partition, a subset of the following kernel parameters need to be set. Add the options to the kernel parameters if using the encrypt hook. The file to modify is /etc/default/grub.

cryptdevice=/dev/<partition>:devicemapper_name cryptkey=<path>

device is the path to the device backing the encrypted device.
devicemapper_name is the device-mapper name given to the device after decryption, which will be available as /dev/mapper/devicemapper_name.

For example:

GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=/dev/mapper/swap \
cryptdevice=/dev/sda3:luks_lvm"

Note that relevant parameters are best added to /etc/default/grub before generating the boot configuration.

Unlocking the root partition at boot (Optional)

To unlock root filesystem at boot using keyfile, you’ll have to generate the keyfile, give it suitable permissions and add it as a LUKS key:

dd if=/dev/urandom of=/crypto_keyfile.bin  bs=512 count=10
chmod 000 /crypto_keyfile.bin
chmod 600 /boot/initramfs-linux*
cryptsetup luksAddKey /dev/sda3 /crypto_keyfile.bin

Now include /crypto_keyfile.bin file under FILES directive in mkinicpio.conf file.

# vim /etc/mkinitcpio.conf 

Add:

FILES=/crypto_keyfile.bin

Regenerate ramdisk file.

mkinitcpio -p linux

Regenerate grub.cfg file:

grub-mkconfig -o /boot/grub/grub.cfg
grub-mkconfig -o /boot/efi/EFI/arch/grub.cfg

Post installation configurations.

The remaining part is to install essential software packages like Xorg server, pulseaudio, alsa utilities, synaptics touchpad drivers, set root password, add standard user account, set timezone, add aur and multilib repositories.

I wrote a simple bash script to automate this process. Below is a procedure on how to use the script.

pacman -S git --noconfirm
git clone https://github.com/jmutai/dotfiles.git
cp dotfiles/setup/pacman.conf /etc/pacman.conf
cp dotfiles/setup/live-setup.sh .
chmod +x live-setup.sh
./live-setup.sh

You can modify live-setup script to change timezone settings and system hostname. Installation of i3 can be replaced with your Desktop Environment of choice. After successful setup, exit chroot environment, unmount the partitions and reboot your system.

exit 
umount -R /mnt
reboot