Partitioning
2021-10-11
Partitioning is the most tedious part of the OS installation process. Everything else is either very fast to set up or can easily be automated. Even with declarative systems, they mostly assume you already have prepared your hard drives before applying the configuration. Partitioning cannot be mutated as easily as configuration, therefore it requires proper planning and a lot of attention. I tend to think about it more than I should.
Needless to say, I want my stuff encrypted. My basic setup follows this article:
https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS
With coreboot (or libreboot) I can encrypt the entire drive without leaving the boot partition readable. My GRUB payload has LUKS and LVM support compiled in. It can decrypt the drive and boot straight away or load another GRUB config file from the decrypted drive.
Check out guides on Libreboot's website before commit 48b04d0993 to see how that's done:
https://notabug.org/libreboot/lbwww/src/8844c201ef0d1ab856fed2aa5148b89100fffe0d/site/docs/gnulinux
The parabola one was especially helpful when I was first setting it up. Currently it is available here:
https://wiki.parabola.nu/Installing_Parabola_on_Libreboot_with_full_disk_encryption_(including_/boot)
Unfortunately not all my machines are officially supported by the coreboot project. In such a case the UEFI boot must suffice. That usually means leaving out an unencrypted EFI boot partition which makes the GRUB config and possibly the kernel vulnerable to tampering. Unless we also properly set up Secure Boot... I won't.
Just be wary - when someone gains physical access to the machine, although they won't be able to read the valuable content of the drive right away, they could still do a lot of harm. If that happens to you - do not boot from that drive again. Boot from some other safe media, nuke all readable content on the drive, then regenerate it from within the system.
We will use fdisk cli for partitioning, however if you prefer a graphical utility - GParted is a nice one.
$ fdisk /dev/sda
First we choose "g" to create new GPT partition label, then "n" to create a new partition. The boot partition should span a few hundred MB (300M should be enough). Use "t" to change it's type to "EFI System" - option 1. Next is the general partition for LUKS which should cover all available space left on the drive. Write changes with "w".
Format the boot partition with:
$ mkfs.fat -F32 /dev/sdxY
Format the general LUKS partition with:
$ cryptsetup -v --iter-time 600 --type luks1 luksFormat /dev/sdXY
The type flag was needed for GRUB compatibility. If your bootloader is fresh and shiny you may skip it. The iteration time is set to 2 seconds by default. I prefer to set it lower, like 600ms in the example above.
Options and defaults are described here: https://wiki.archlinux.org/title/Dm-crypt/Device_encryption#Encryption_options_for_LUKS_mode
Basic LVM setup:
$ cryptsetup luksOpen /dev/sdxY cryptlvm
$ pvcreate /dev/mapper/cryptlvm
$ vgcreate vgrp /dev/mapper/cryptlvm
$ lvcreate -l 100%FREE vgrp -n root
$ mkfs.ext4 /dev/vgrp/root
At this point you can mount your partitions and install the system or whatever.
In the end we get to something like this: drive -> LUKS -> LVM -> ext4
We need to tell our kernel how to deal with this. Therefore in /etc/mkinitcpio.conf we set:
` HOOKS=(base udev autodetect keyboard keymap consolefont modconf block encrypt lvm2 filesystems fsck) `
Run mkinitcpio:
$ mkinitcpio -P
We also need to set kernel parameters:
` cryptdevice=UUID=[device-UUID]:cryptlvm root=/dev/vgrp/root `
How to do that depends on a bootloader. For GRUB we can simply modify grub.cfg (on the boot partition or in cbfs).
For systemd-boot we would put those parameters on the "options" line of a proper /boot/loader/entries/*.conf file.
Of course we can use something else instead of the good old ext4 filesystem. My first pick would be btrfs which offers some cool features like subvolumes and snapshots. I don't feel like fully explaining it now though (maybe in a btrfs post?). Long story short - subvolumes could suffice for partitions and the LVM layer may not be needed, since btrfs is flexible enough by itself.
For automatic snapshots on btrfs:
Snapshot destination should be in a different subvolume than the directory you are snapshotting.
I also highly recommend putting /home on a different subvolume or on a different partition altogether.
Therefore you need at least 3 subvolumes: root, home, snapshots. Snapshot root and home separately.
Check out snapper and snap-pac (both available in Arch Linux community repo).
Here's an example of kernel parameters for root on a btrfs subvolume:
` cryptdevice=[device-partition]:cryptroot root=/dev/mapper/cryptroot rootfstype=btrfs rootflags=subvol=/@ `
If you decrypt with coreboot payload, you may want to add a keyfile and additional kernel parameters. This should be described in at least one of the articles I linked at the top.
Some people also like to partition off swap space, although you can simply use a swapfile. This is not necessary, but if you'll want to hibernate your system or you've ever run out of RAM - look into setting up swap next.