mykb/docs/luks2.md

7.9 KiB

LUKS2 fully encrypted Arch-Linux

As the Key-derivation functions for LUKS1 are lacking but GRUB normally only supports LUKS1, additional steps are required to get a working fully encrypted LUKS2 encrypted hard drive. The basic process is similar to a LUKS1 encrypted hard-drive but afterwards before the reboot into your installed OS additional measures need to be taken. This works only with UEFI-systems.

In this tutorial we're assuming you want to install everything to /dev/sda and an ext4 FS. BTRFS requires additional steps to my knowledge.

Boot into ISO, create LVM and mount

We want two partitions: sda1: 500M, sda2: a lvm container for the rest for your encrypted hard-drive. Create partition table via cfdisk or similar tools. Note: for BIOS systems a dummy 1M parition would be also required. For UEFI this is not needed.

Create LVM

cryptsetup luksFormat /dev/sda2
cryptsetup open /dev/sda2 cryptlvm
pvcreate /dev/mapper/cryptlvm
vgcreate vg /dev/mapper/crypylvm

Create your wanted partitions. Ergo something similar to:

lvcreate -L 8G vg -n swap
lvcreate -L 32G vg -n root
lvcreate -l 100%FREE vg -n home

and mkfs them:

mkfs.ext4 /dev/vg/root
mkfs.ext4 /dev/vg/home
mkswap /dev/vg/swap

and finally mount them. EFI should be mounted to /mnt/efi

mount /dev/vg/root /mnt
mount --mkdir /dev/vg/home /mnt/home
swapon /dev/vg/swap

mount --mkdir /dev/sda2 /mnt/efi

Continue with your normal Arch install:

Note the lack of grub in the pacstrap, we will build this later

pacstrap -K /mnt base base-devel git linux linux-firmware lvm2 efibootmgr networkmanager neovim ...
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
echo YourHostName > /etc/hostname
nvim /etc/locale.gen
locale-gen
ln -sf /usr/share/zoneinfo/Europe/Zurich /etc/localtime
hwclock --systohc
passwd

Edit /etc/mkinitcpio.conf to support encryption

In /etc/mkinitcpio.conf edit the HOOKS to include these highlighted ones as well:

HOOKS=(base __udev__ autodetect modconf kms keyboard keymap consolefont block __encrypt__ __lvm2__ filesystems fsck)

and rebuild initramfs:

mkinitcpio -P

Create new user, download AUR helper, and install grub-improved-luks2-git

useradd -m -G wheel alex
passwd alex

Give him sudo permissions: in /etc/sudoers add:

%wheel ALL=(ALL) ALL

Now install paru or equivalent AUR helper:

su - alex
git clone https://aur.archlinux.org/paru
cd paru
makepkg -si
paru -S grub-improved-luks2-git

We now have a patched GRUB installed and can continue as if we would encrypt using LUKS1 for now:

Edit /etc/default/grub and grub-install

Get encrypted partition UUID into the /etc/default/grub via

ls -l /dev/disk/by-uuid >> /etc/default/grub

and adjust two things in the file:

GRUB_ENABLE_CRYPTODISK=y

and add to GRUB_CMDLINE_LINUX: (can have multiple, space-separated arguments so don't delete anything if it's there, just add.)

GRUB_CMDLINE_LINUX="cryptdevice=UUID=device-UUID:cryptlvm"

and replace "device-UUID" with the uuid we got for /dev/sda2 from the previous ls command. Of course remove all the trailing ls output.

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --recheck
grub-mkconfig -o /boot/grub/grub.cfg

LUKS2 support

Now create an additional file in /boot/grub/grub-pre.cfg with the follwing content:

set crypto_uuid=device-UUID
cryptomount -u $crypto_uuid
set root=lvm/vg-root
set prefix=($root)/boot/grub
insmod normal
normal

and replace device-UUID with the same device-UUID as before, (again, a ls -l /dev/disk/by-uuid >> /boot/grub/grub-pre.cfg can help here to get the UUID for /dev/sda2)

Now we can overwrite our previously generated grubx64.efi with a luks2 compatible one:

grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi lvm luks2 part_gpt cryptodisk gcry_rijndael argon2 gcry_sha256 ext2
install -v /tmp/grubx64.efi /efi/EFI/GRUB/grubx64.efi

We should now be done. exit, umount -R /mnt, and reboot into GRUB to see whether everything worked. This still requires you to enter your passphrase twice but can be alleviated just as with the LUKS1 case:

Only enter the password once

Create a keyfile:

dd bs=512 count=4 if=/dev/random of=/crypto_keyfile.bin iflag=fullblock
chmod 600 /crypto_keyfile.bin
cryptsetup luksAddKey /dev/sda2 /crypto_keyfile.bin

Add this to the initramfs:

FILES=("/crypto_keyfile.bin")

And rebuld via

mkinitcpio -P

And add this file to the GRUB_CMDLINE_LINUX in /etc/default/grub:

GRUB_CMDLINE_LINE="... cryptkey=rootfs:/crypto_keyfile.bin"

And again rebuild GRUB

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --recheck
grub-mkconfig -o /boot/grub/grub.cfg
grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi lvm luks2 part_gpt cryptodisk gcry_rijndael argon2 gcry_sha256 ext2
install -v /tmp/grubx64.efi /efi/EFI/GRUB/grubx64.efi

Auto-decrypt additional encrypted hard-drives on bootup

You can decrypt additional hard-drives automatically. For this we will use /etc/crypttab as well as /etc/fstab. This requires systemd to work.

Create your additional encrypted hard-drives if not already existant:

cryptsetup luksFormat /dev/sdX
cryptsetup open /dev/sdX YourDiskNameHere
mkfs.ext4 /dev/mapper/YourDiskNameHere

If you do not wish to have to enter the additional password on boot-up you will have to create a keyfile like we did for our /dev/sda2 above. Of course this will lessen security as any additional hard-drives can also be decrypted if /dev/sda2 has been decrypted or cracked.

Systemd can autodetec keys in /etc/cryptsetup-keys.d if they have the pattern YourDiskNameHere.key. Create this directory if not already present:

mkdir /etc/cryptsetup-keys.d

Add an additional keyfile to your newly created encrypted hard-drive:

dd bs=512 count=4 if=/dev/random of=/etc/cryptsetup-keys.d/YourDiskNameHere.key iflag=fullblock
chmod 600 /etc/cryptsetup-keys.d/YourDiskNameHere.key
cryptsetup luksAddKey /dev/sdX /etc/cryptsetup-keys.d/YourDiskNameHere.key

Get the UUID of your new hard-drive via ls -l /dev/disk/by-uuid and edit /etc/crypttab:

YourDiskNameHere	UUID=TheUUIDYouJustGot	/etc/crypsetp-keys.d/YourDiskNameHere.key

If you use /etc/cryptsetup-keys.d and name your keys YourDiskNameHere.key you could leave out the third column as this is automatically tested for.

after a systemctl daemon-reload you should now be able to start a service called systemd-cryptsetup@YourDiskNameHere. You can verify this via a systemctl start systemd-cryptsetup@YourDiskNameHere. You should not require to enter a password now.

If everything works we can now modify the /etc/fstab for the automatic mounting. This is done like any unencrypted hard-drive by appending:

/dev/mapper/YourDiskNameHere	/YourMountPoint	ext4	defaults	0	2

Your encrypted drive should now automount on boot-up without an additional password-prompt.

NOT TESTED, assumed to be the same as the LUKS1 case

Use swap for hibernations

Add the resume hook in /etc/mkinitcpio.conf:

HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt lvm2 __resume__ filesystems fsck)

and rebuild via mkinitcpio -P.

Then: add to the GRUB_CMDLINE_LINUX in /etc/default/grub:

GRUB_CMDLINE_LINUX="... resume=/dev/vg/swap"

and rebuild GRUB.

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --recheck
grub-mkconfig -o /boot/grub/grub.cfg
grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi lvm luks2 part_gpt cryptodisk gcry_rijndael argon2 gcry_sha256 ext2
install -v /tmp/grubx64.efi /efi/EFI/GRUB/grubx64.efi