www.walian.co.uk Open in urlscan Pro
2606:4700:3037::ac43:866c  Public Scan

Submitted URL: http://walian.co.uk/
Effective URL: https://www.walian.co.uk/
Submission: On March 15 via manual from GB — Scanned from GB

Form analysis 0 forms found in the DOM

Text Content

WALIAN'S TECH/LINUX BLOG

 * tutorial


ARCH INSTALL WITH SECURE BOOT, BTRFS, TPM2 LUKS ENCRYPTION, UNIFIED KERNEL
IMAGES.

Published: Fri 25 August 2023 By Walian

In tutorial.

tags: ["arch linux" "secure boot" "btrfs" "tpm2" "luks" "arch" "linux"]

This is a twist on my current Arch install method.

This install will result in a very clean base install using btrfs for a
filesystem, mkinitcpio set up to generate UKIs, Secure Boot handled by sbctl,
and your TPM handling encryption unlocking. You just need to bake in your DE of
choice.

You'll need to grab the latest Arch Linux ISO, write it a USB drive and boot off
it. From there, do your usual checks for internet access, and then we can begin.


DISK PREPARATION

We'll use a 512MB FAT32 system partition for our EFI partition and we're going
to use btrfs, inside of a LUKS encrypted partition, for the root. We're going to
take the time and effort to use correct partition types, so systemd can detect
them (see this page for more information on Discoverable Partitions
Specification).

First of all, let's find our drive name:

$ lsblk
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0   7:0    0   673M  1 loop /run/archiso/airootfs
sr0    11:0    1 793.3M  0 rom  /run/archiso/bootmnt
vda   254:0    0    30G  0 disk 


Our drive, in this case, is /dev/vda/, so let's use sgdisk to setup the disk:

$ sgdisk -Z /dev/vda
$ sgdisk -n1:0:+512M -t1:ef00 -c1:EFI -N2 -t2:8304 -c2:LINUXROOT /dev/vda
$ partprobe -s /dev/vda


We should now have an EFI partition on /dev/vda1 and our root partition on
/dev/vda2. Let's check:

$ lsblk /dev/vda
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda    254:0    0   30G  0 disk 
├─vda1 254:1    0  512M  0 part 
└─vda2 254:2    0 29.5G  0 part


Looking good, next, let's encrypt our root partition with LUKS, using
cryptsetup:

$ cryptsetup luksFormat --type luks2 /dev/vda2
$ cryptsetup luksOpen /dev/vda2 linuxroot


Let's create the filesystems:

$ mkfs.vfat -F32 -n EFI /dev/vda1
$ mkfs.btrfs -f -L linuxroot /dev/mapper/linuxroot


Let's mount our partitions, and create our btrfs subvolumes:

$ mount /dev/mapper/linuxroot /mnt
$ mkdir /mnt/efi
$ mount /dev/vda1 /mnt/efi
$ btrfs subvolume create /mnt/home
$ btrfs subvolume create /mnt/srv
$ btrfs subvolume create /mnt/var
$ btrfs subvolume create /mnt/var/log
$ btrfs subvolume create /mnt/var/cache
$ btrfs subvolume create /mnt/var/tmp



BASE INSTALL

Let's update the pacman mirrors, and then pacstrap a base install:

$ reflector --country GB --age 24 --protocol http,https --sort rate --save /etc/pacman.d/mirrorlist
$ pacstrap -K /mnt base base-devel linux linux-firmware amd-ucode vim nano cryptsetup btrfs-progs dosfstools util-linux git unzip sbctl kitty networkmanager sudo 


Update our locale settings:

$ sed -i -e "/^#"en_GB.UTF-8"/s/^#//" /mnt/etc/locale.gen
$ systemd-firstboot --root /mnt --prompt
Welcome to your new installation of Arch Linux!
Please configure your system!

-- Press any key to proceed --
‣ Please enter system keymap name or number (empty to skip, "list" to list options): uk
/mnt/etc/vconsole.conf written.
‣ Please enter timezone name or number (empty to skip, "list" to list options): Europe/London
/mnt/etc/localtime written
‣ Please enter hostname for new system (empty to skip): archinstall9001
/mnt/etc/hostname written.

$ arch-chroot /mnt locale-gen
Generating locales...
  en_GB.UTF-8... done
Generation complete.



USER CREATION

Let's create our local user account, in this case the username will be "walian",
add him/her to the wheel group, and then give the wheel group sudo privileges:

$ arch-chroot /mnt useradd -G wheel -m walian 
$ arch-chroot /mnt passwd walian
$ sed -i -e '/^# %wheel ALL=(ALL:ALL) NOPASSWD: ALL/s/^# //' /mnt/etc/sudoers



UNIFIED KERNEL FUN

We want to create Unified Kernel Images, so first, let's create our kernel
cmdline file. This doesn't need to contain anything because we're using
Discoverable Partitions, we just do it so mkinitcpio doesn't complain:

$ echo "quiet rw" >/mnt/etc/kernel/cmdline


Let's create the EFI folder structure:

$ mkdir -p /mnt/efi/EFI/Linux


We need to change the HOOKS in mkinitcpio.conf to use systemd, so make yours
look like:

/mnt/etc/mkinitcpio.conf

# vim:set ft=sh
MODULES=()

BINARIES=()

FILES=()

HOOKS=(base systemd autodetect modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)


And now let's update the .preset file, to generate a UKI:

/mnt/etc/mkinitcpio.d/linux.preset

# mkinitcpio preset file to generate UKIs

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"


And now let's generate our UKIs:

$ arch-chroot /mnt mkinitcpio -P
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'default'
==> Using configuration file: '/etc/mkinitcpio.conf'
  -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -U /efi/EFI/Linux/arch-linux.efi --splash /usr/share/systemd/bootctl/splash-arch.bmp --microcode /boot/amd-ucode.img
==> Starting build: '6.4.12-arch1-1'
  -> Running build hook: [base]
  -> Running build hook: [systemd]
  -> Running build hook: [autodetect]
  -> Running build hook: [modconf]
  -> Running build hook: [kms]
  -> Running build hook: [keyboard]
==> WARNING: Possibly missing firmware for module: 'xhci_pci'
  -> Running build hook: [sd-vconsole]
  -> Running build hook: [sd-encrypt]
  -> Running build hook: [block]
  -> Running build hook: [filesystems]
  -> Running build hook: [fsck]
==> Generating module dependencies
==> Creating zstd-compressed initcpio image: '/tmp/mkinitcpio.Hp46P3'
==> Image generation successful
==> Creating unified kernel image: '/efi/EFI/Linux/arch-linux.efi'
  -> Using UEFI stub: '/usr/lib/systemd/boot/efi/linuxx64.efi.stub'
  -> Using os-release file: '/etc/os-release'
  -> Using cmdline file: '/etc/kernel/cmdline'
  -> Using splash image: '/usr/share/systemd/bootctl/splash-arch.bmp'
  -> Using kernel image: '/boot/vmlinuz-linux'
  -> Using microcode image: '/boot/amd-ucode.img'
==> Unified kernel image generation successful
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'fallback'
==> Using configuration file: '/etc/mkinitcpio.conf'
  -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -U /efi/EFI/Linux/arch-linux-fallback.efi -S autodetect --microcode /boot/amd-ucode.img
==> Starting build: '6.4.12-arch1-1'
  -> Running build hook: [base]
  -> Running build hook: [systemd]
  -> Running build hook: [modconf]
  -> Running build hook: [kms]
==> WARNING: Possibly missing firmware for module: 'ast'
  -> Running build hook: [keyboard]
==> WARNING: Possibly missing firmware for module: 'xhci_pci'
  -> Running build hook: [sd-vconsole]
  -> Running build hook: [sd-encrypt]
  -> Running build hook: [block]
==> WARNING: Possibly missing firmware for module: 'aic94xx'
==> WARNING: Possibly missing firmware for module: 'bfa'
==> WARNING: Possibly missing firmware for module: 'qed'
==> WARNING: Possibly missing firmware for module: 'qla1280'
==> WARNING: Possibly missing firmware for module: 'qla2xxx'
==> WARNING: Possibly missing firmware for module: 'wd719x'
  -> Running build hook: [filesystems]
  -> Running build hook: [fsck]
==> Generating module dependencies
==> Creating zstd-compressed initcpio image: '/tmp/mkinitcpio.nCqFo4'
==> Image generation successful
==> Creating unified kernel image: '/efi/EFI/Linux/arch-linux-fallback.efi'
  -> Using UEFI stub: '/usr/lib/systemd/boot/efi/linuxx64.efi.stub'
  -> Using os-release file: '/etc/os-release'
  -> Using cmdline file: '/etc/kernel/cmdline'
  -> Using kernel image: '/boot/vmlinuz-linux'
  -> Using microcode image: '/boot/amd-ucode.img'
==> Unified kernel image generation successful


If we have a look into our EFI partition, we should see our UKIs:

$ ls -lR /mnt/efi
/mnt/efi:
total 4
drwxr-xr-x 3 root root 4096 Aug 25 20:51 EFI

/mnt/efi/EFI:
total 4
drwxr-xr-x 2 root root 4096 Aug 25 21:02 Linux

/mnt/efi/EFI/Linux:
total 118668
-rwxr-xr-x 1 root root 29928960 Aug  9 14:07 arch-linux.efi
-rwxr-xr-x 1 root root 91586048 Aug  9 14:07 arch-linux-fallback.efi



SERVICES AND BOOT LOADER

OK, we're just about done in the archiso, we just need to enable some services,
and install our bootloader:

$ systemctl --root /mnt enable systemd-resolved systemd-timesyncd NetworkManager
$ systemctl --root /mnt mask systemd-networkd
$ arch-chroot /mnt bootctl install --esp-path=/efi


OK, let's reboot, and then finish off the installation. Whilst you're rebooting,
head into your UEFI/BIOS and put Secure Boot into "Setup Mode", you'll need to
check with your PC/Motherboard manufacturer for exact details on how to do that:

$ sync
$ systemctl reboot --firmware-setup



SECURE BOOT WITH TPM2 UNLOCKING

Ok, now that we've rebooted and logged back in, we need to first check that
Secure Boot is in "Setup Mode":

$ sbctl status
Installed:  ✓ sbctl is installed
Setup Mode: ✗ Enabled
Secure Boot:    ✗ Disabled
Vendor Keys:    none


Looks good. Let's first create and enroll our personal Secure Boot keys:

$ sudo sbctl create-keys
$ sudo sbctl enroll-keys -m


We use the -m option to enroll the Microsoft vendor key as well as our
self-created platform key. IF you're sure that none of your hardware has any
OPROMs signed by Microsoft, you can leave this option out. WARNING - Your system
CAN get bricked if you're mistaken. I know it sucks, but it's usually safer to
just install the Microsoft vendor key. YOU HAVE BEEN WARNED!!! :-)

Let's use sbctl to sign our .efi files. We'll sign the systemd-boot .efi file,
and our UKI files which mkinitcpio is now generating for us. We'll use the -s
option so sbctl will automatically resign them for us when we update the kernel
or bootloader through pacman:

$ sudo sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi
$ sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
$ sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi
$ sudo sbctl sign -s /efi/EFI/Linux/arch-linux-fallback.efi


Let's reinstall the kernel to make sure it resigns the UKI:

$ sudo pacman -S linux
... (I've cut out the blurb)** ...
(4/4) Signing EFI binaries...
Generating EFI bundles....
✓ Signed /efi/EFI/Linux/arch-linux-fallback.efi
✓ Signed /efi/EFI/Linux/arch-linux.efi


Looking good. Reboot your PC now, so the Secure Boot settings will get saved.
Once rebooted we need to configure automatic unlocking of the root filesystem,
by binding a LUKS key to the TPM. Let's generate a new key, add it to our volume
so it can be used to unlock it in addition to the existing keys, and bind this
new key to PCRs 0 and 7 (the system firmware and Secure Boot state). First
things first, let's generate a recovery key in case it all gets messed up some
time in the future:

$ sudo systemd-cryptenroll /dev/gpt-auto-root-luks --recovery-key


Keep this key safe. Keep it hidden. Moving on, we'll now enroll our system
firmware and Secure Boot state. Normally, this would allow our TPM to unlock our
encrypted drive, as long as the state hasn't changed. If you're particularly
paranoid, you can add --tpm2-with-pin=yes, so we get prompted for a PIN code on
boot.

$ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7  /dev/gpt-auto-root-luks


Now we need to reboot and test this. If all goes well, we should be able to
unlock our encrypted root partition with just a PIN code.


JOB DONE

And with that, we have a very nice base install completed. You can now go ahead
and install your Desktop Environment. I'll throw a YouTube video together in the
next few days, walking through this install and update this blogpost. Until
then, have a good one!


UPDATE

I've embedded a YouTube video below for your viewing pleasure.


MORE INFORMATION

Discoverable Partitions Specification. Install Arch with Secure boot, TPM2-based
LUKS encryption, and systemd-homed Trusted Platform Module Linux Boot Partitions
Brave New Trusted Boot World Unlocking LUKS2 volumes with TPM2, FIDO2, PKCS#11
Security Hardware on systemd 248

There are 5 Comments.


OTHER ARTICLES

--------------------------------------------------------------------------------


 1. SETTING UP PI-HOLE AS A RECURSIVE DNS SERVER USING AN UNBOUND CONTAINER
    
    Published: Tue 22 August 2023 By Walian
    
    In tutorial.
    
    tags: ["cockpit" "raspberry pi" "pi" "ubuntu" "pihole" "pi-hole" "recursive
    dns"]
    
    In the last blogpost, we set up a Raspberry Pi to be a DNS level ad-blocker,
    using Ubuntu Server, Cockpit, Podman, and Pi-Hole.
    
    Now lets go one step further and take back control by running our own
    recursive DNS server in a Podman container. We'll do this by installing an …
    
    read more
    
    There are 0 Comments.


 2. INSTALL COCKPIT AND PI-HOLE ON YOUR RASPBERRY PI
    
    Published: Sat 19 August 2023 By Walian
    
    In tutorial.
    
    tags: ["cockpit" "raspberry pi" "pi" "ubuntu" "pihole" "pi-hole" "ad
    blocking"]
    
    This article describes my Pi-Hole setup which uses a docker container
    installed on a Raspberry Pi running Ubuntu Server ARM.
    
    Download the latest version of Ubuntu Server 22.04: Ubuntu on a Raspberry
    Pi.
    
    
    WHAT YOU'LL NEED
    
     * A microSD card (4GB minimum, 8GB recommended) or USB drive.
     * A Raspberry Pi …
    
    read more
    
    There are 0 Comments.


SOCIAL

 * GitHub
 * YouTube

Proudly powered by Pelican, which takes great advantage of Python.

The theme is by Smashing Magazine, thanks!