Setting up Arch + LUKS + BTRFS + systemd-boot + apparmor + Secure Boot + TPM 2.0 - A long, nightmarish journey, now simplified
Ever since I started using Arch I've been struggling to configure a system with all of these. And now that I've finally done it, I'd like to document and simplify the process for everyone:
Step 1: The base install
This is the most common part (unless you only used archinstall), I mixed a couple of tutorials (credits in the comments) and a bit of the Arch Wiki.
spoiler
(If you depend on wifi) First, configure your wifi with iwctl;
Syncing the system clock: timedatectl set-ntp true;
Now let´s create your system partitions: gdisk /dev/sda
(The drive name can be different if you use a NVME SSD, but you can find out using the command lsblk):
Create a new partition table: Command (? for help):o
Create an EFI partition (choose the defaults for the partition number and first sector, +550M for the last sector and hex code EF00): Command (? for help):n
Create a root partition (adopt the default values): Command (? for help):n
Write the new partitions to disk: Command (? for help):w
Create an encrypted container for the root file system (you need to define a passphrase): cryptsetup luksFormat /dev/sda2
Open the container (“luks” is a placeholder, you can use some name you like, but remember to adopt the subsequent steps of the guide accordingly): cryptsetup open /dev/sda2 luks
Format the EFI partition with FAT32: mkfs.vfat -F32 /dev/sda1
Format the root partition with BTRFS: mkfs.btrfs /dev/mapper/luks
Create subvolumes for root and home (since we'll be using Timeshift for the snapshot capabilities): mount /dev/mapper/luks /mnt
btrfs sub create /mnt/@
btrfs sub create /mnt/@home
umount /mnt
Mount the subvolumes mount -o noatime,nodiratime,compress=zstd:1,space_cache,ssd,subvol=@ /dev/mapper/luks /mnt
mkdir -p /mnt/{boot,home}
mount -o noatime,nodiratime,compress=zstd:1,space_cache,ssd,subvol=@home /dev/mapper/luks /mnt/home
mount /dev/sda1 /mnt/boot
Install the basic system packages (adjust this list to your needs, in my case I went with linux-zen, so that's what I'll be using for this guide): pacstrap /mnt linux-zen linux-firmware base base-devel btrfs-progs intel-ucode nano
(If you have an AMD CPU you need to install amd-ucode instead of intel-ucode);
Time to create an user and a password, first the root password: passwd
Now, create a user: useradd -mG wheel <YOUR-USERNAME>
Now edit the sudoers file to give your user sudo permissions (you can use any terminal text editor, but I'll go with nano): EDITOR=nano visudo
And uncomment this line:
##Uncomment to allow members of group wheel to execute any command %wheel ALL=(ALL) ALL
And now a password for your user: passwd <YOUR-USERNAME>
Set your host name: echo <YOUR-HOSTNAME> > /etc/hostname
Uncomment the following rows of /etc/locale.gen: en_US.UTF-8 UTF-8 <YOUR-LANGUAGE>.UTF-8 UTF-8
Set locale: echo LANG=<YOUR-LANAGUAGE>.UTF-8 > /etc/locale.conf
Generate locale: locale-gen
Now let's find out your timezone: timedatectl list-timezones | less
OR timedatectl list-timezones | grep <YOUR-REGION>
(if you already have an idea of the region your system uses);
Set time zone: ln -sf /usr/share/zoneinfo/<YOUR-REGION>/<YOUR-ZONE> /etc/localtime
Now it's time to sync your system clock with your timezone:
hwclock --systohc
And now let's install some other useful packages for your system: pacman -S linux-zen-headers networkmanager dialog wpa_supplicant mtools dosfstools git xdg-utils xdg-user-dirs alsa-utils pipewire pipewire-alsa pipewire-pulse apparmor sbctl
You can also install:
bash-completion if you want some more features on your terminal;
network-manager-applet if you depend on WiFi, but you can uninstall it after installing your DE/WM;
bluez and bluez-utils if you have Bluetooth support in your system;
cups and hplip if you have a printer, with the latter just needed if you have a HP one;
After the installation enable the services for these packages:
systemctl enable NetworkManager apparmor (bluetooth cups - optional)
And now let's configure systemd-boot!
Step 2: Installing the bootloader
This is also pretty simple, let's configure the bootloader and add the kernel parameters needed,
You can append the UUID of the root partition to save time: echo blkid -s UUID -o value /dev/sda2 >> /boot/loader/entries/arch.conf
Then edit /boot/loader/entries/arch.conf and fill it with:
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=<UUID OF ROOT PARTITION>=luks root=/dev/mapper/luks rootflags=subvol=@ rd.luks.options=<UUID AGAIN>=discard rw quiet lsm=lockdown,yama,apparmor,bpf
Edit file /boot/loader/loader.conf and add:
default arch.conf
editor no
If you want to select your OS you also need to uncomment timeout and change the number to the number to seconds you want the propmt to show on boot.
Exit chroot, unmount partitions and reboot:
exit umount -a reboot
Step 3: Installing your desktop environment/window manager
This part is optional because it completely depends on the DE/WM you want. In my case I went with GNOME, so I'll leave an install guide for it here.
Step 4: Checking Apparmor and installing Timeshift
Let's deal with AppArmor, which we installed before, and install Timeshift.
spoiler
First, let's check if Apparmor is working properly with sudo aa-status, to see if it's properly loading the profiles. If it is you should get a prompt like this, where ... is filled with the profiles it loads:
apparmor module is loaded.
44 profiles are loaded.
44 profiles are in enforce mode.
...
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
If it shows this, even with different numbers, you're good to go. You can also get more profiles from /usr/share/apparmor/extra-profiles, but those are generally not recommended.
So now, let's install Timeshift for backups. It isn't yet available in Arch's official repos, only in the Arch User Repository. You can download it:
By using an AUR helper (in my case paru, but you can also use pamac-aur, if you want a graphical interface):
First, download the AUR helper and install it the same way as shown above: git clone https://aur.archlinux.org/packages/paru/ cd paru makepkg -si PKGBUILD
Then, you can use it just like pacman (without even needing to use sudo before it, you will get the super user prompt): paru -S timeshift
Or by adding a third-party repository, in this case the chaotic-AUR repo, and then, you can just:
sudo pacman -S timeshift
You just need to open and go through the step-by-step process of configuring it, and select BTRFS as the backup type.
Step 5: Secure Boot + TPM 2.0
Now it's the part where it isn't as well documented and I had nightmares figuring out by myself.
spoiler
We already installed sbctl in step 1, so let's use it.
First, in your system BIOS there should be an option to delete all keys or to enable Setup Mode. After that enable Secure Boot and when you reboot you should see something like this with the sbctl status command:
Now you just need to follow its instructions in the GitHub page.
But, IF you face errors, specially during sbctl enroll-keys, as it was in my case, you might need to install efitools and manually enroll your keys with this command in this order: efi-updatevar -f /usr/share/secureboot/keys/db/db.auth db efi-updatevar -f /usr/share/secureboot/keys/KEK/KEK.auth KEK efi-updatevar -f /usr/share/secureboot/keys/PK/PK.auth PK
After that don't forget to sign your bootloader and your /vmlinuz-linux(-zen in this case, since we installed the zen kernel). After that it should just work.
And last but not least, TPM 2.0. Check if your system supports it by running cat /sys/class/tpm/tpm0/device/description or /sys/class/tpm/tpm0/tpm_version_major. If you have it, let's go!
We already set up the systemd and sd-encrypt hooks earlier, so now what we have to do is to run systemd-cryptenroll --tpm2-device=list to check if everything went well. You should get a single device as a result. If everything is okay, run: sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0,7 /dev/sdX (in our case /dev/sda2).
After that add tpm2-device=auto to your rd.luks.options in /boot/loader/entries/arch.conf. which means your options should end up looking like this:
Reboot, and if everything went correctly you should now get to your login manager without needing to use your disk decryption password for a more seamless experience.
I wouldn't recomment. Every system us unique, and commands and best practices change over time.
Plus you're learning what you're doing by manually doing this
Ah, I see why you met with some success. I was trying to do this painfully with GRUB and I just couldn't get it to work for the life of me. I may try again but I am okay just using LUKS with a fully encrypted root partition on an EFI system with GRUB as my bootloader. I at least managed to get the keyfile portion working so I only have to enter my password once.