Last week I had to install my new work computer. Although I am a Debian guy, I thought I should give a chance to Arch Linux as well.
In theory full disk encryption and Linux is not a big deal (there's a lot of documentation out there) and it should be pretty straight forward. In practice, probably because it was the first time doing it on Arch, it took me some time to figure it out how to do it right.
My biggest problem was that the current version of grub shipped with Arch doesn't include support the following combination: NVMe, LVM, LUKS. Apparently the git version has the fix for that issue.
So here is what I did (This post comes without warranty of any kind! I do not issue any guarantee that this will work for you!)
- Partition the disk - no Windows, no UEFI needed, my disk is only 256G and I will need only one primary partition so... there is no reason to use GPT.
parted -a optimal -s /dev/nvme0n1 mklabel msdos parted -s /dev/nvme0n1 mkpart primary 2048s 100%
- Encrypt the newly created partition
cryptsetup luksFormat /dev/nvme0n1p1 cryptsetup luksOpen /dev/nvme0n1p1 disk
- Setup logical volumes
pvcreate /dev/mapper/disk vgcreate vg0 /dev/mapper/disk lvcreate -L 32G vg0 -n swap lvcreate -L 15G vg0 -n root lvcreate -l +100%FREE vg0 -n home
- Create filesystem
mkswap -L swap /dev/vg0/swap mkfs.ext4 /dev/vg0/root mkfs.ext4 /dev/vg0/home
- Mount the partitions
mount /dev/vg0/root /mnt mkdir -vp /mnt/home mount /dev/vg0/home /mnt/home
- Set mirror list
pacman -Sy pacman -S pacman-contrib cd /etc/pacman.d/ wget "archlinux.org/mirrorlist/?country=SE" -O mirrorlist.b sed -i 's/^#//' mirrorlist.b rankmirrors -n 3 mirrorlist.b > mirrorlist
- Install base system
pacstrap /mnt base base-devel vim less dhclient genfstab -p -U /mnt > /mnt/etc/fstab
- Chroot time!
arch-chroot /mnt /bin/bash
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen locale-gen export LANG=en_US.UTF-8 echo LANG=en_US.UTF-8 > /etc/locale.conf rm -f /etc/localtime ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime hwclock --systohc --utc
- Set the hostname
echo jonas > /etc/hostname vim /etc/hosts
... 127.0.0.1 localhost.localdomain localhost jonas ::1 localhost.localdomain localhost jonas ...
- Install various packages
pacman -S wget
- Identify the network card and enable dhcp client
ip link systemctl enable dhcpcd@<interface>.service systemctl enable dhcpcd.service
- Add a new user
useradd -m -g users -s /bin/bash jonas passwd jonas visudo
... ## ## User privilege specification ## root ALL=(ALL) ALL jonas ALL=(ALL) ALL ...
- Set the root password
- Create a key so I won't enter the LUKS passphrase twice
dd if=/dev/urandom of=/crypto_keyfile.bin bs=512 count=4 cryptsetup luksAddKey /dev/nvme0n1p1 /crypto_keyfile.bin
- Create the initial ramdisk environment
MODULES="ext4" HOOKS="base udev autodetect modconf block encrypt lvm2 resume filesystems keyboard fsck" FILES=/crypto_keyfile.bin
mkinitcpio -p linux
- The current version of grub shipped with Arch doesn't include support for NVMe, but grub-git it seems it does
[archlinuxfr] SigLevel = Optional TrustAll Server = http://repo.archlinux.fr/$arch
pacman -Syu pacman -S yaourt # required packages to build grub-git pacman -S git rsync freetype2 ttf-dejavu python autogen help2man fuse su -l jonas # add unifont gpg key (more details here) export KEY="1A09227B1F435A33" gpg --recv-keys $KEY gpg --edit-key $KEY # install grub-git (please note that you will need at least 2G available on your /tmp) yaourt -S grub-git
- We don't need to be "jonas" anymore
- Now that we have grub installed, let's configure and install it
grub-mkconfig -o /boot/grub/grub.cfg grub-install /dev/nvme0n1
- Security considerations
chmod 000 /crypto_keyfile.bin chmod -R g-rwx,o-rwx /boot
One thought on “Full Disk Encryption on Arch Linux: NVMe, GRUB2, LVM and LUKS”
Bit late to the party, just leaving this here in case anyone runs this and encounters issues with the bootloader like I did.
Instead of using yaourt, I ended up installing git, cloning the grub-git package from the AUR, makepkg and installing it. Once that was done I had to:
mount –bind /run /mnt/hostrun
arch-chroot /mnt /bin/bash
mount –bind /hostrun/lvm /run/lvm
then I was able to:
grub-mkconfig -o /boot/grub/grub.cfg
grub-install –target=i386-pc /dev/sdx