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);

Generate /etc/fstab:
genfstab -U /mnt >> /mnt/etc/fstab

Time to chroot into the system:
arch-chroot /mnt/

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

Define hosts in /etc/hosts:
nano /etc/hosts

127.0.0.1 localhost
::1 localhost
127.0.1.1 <YOUR-HOSTNAME>.localdomain <YOUR-HOSTNAME>

Configure the creation of initramfs:
nano /etc/mkinitcpio.conf
Change the MODULES to:
MODULES=(btrfs) And the line HOOKS=… to:\

HOOKS=(base udev systemd autodetect keyboard modconf block sd-encrypt filesystems)

Recreate initramfs:
mkinitcpio -P

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,

spoiler

Install systemd-boot:
bootctl --path=/boot install

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:

==> WARNING: Setup Mode: Enabled
==> WARNING: Secure Boot: Disabled

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:

options rd.luks.name=<UUID OF ROOT PARTITION>=luks root=/dev/mapper/luks rootflags=subvol=@ rd.luks.options=<UUID AGAIN>=tpm2-device=auto,discard rw quiet lsm=lockdown,yama,apparmor,bpf

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.


And with that you’re done! Enjoy your system!