Linux disk setup

While it's possible to setup a disk with a handful of commands, I want to showcase the benefits of a more exotic approach and make it more approachable.

Features

Result

To make it easeir to follow, here is the result of running lsblk on my laptop:

`lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 223.6G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 222.6G 0 part └─smol 253:0 0 222.6G 0 crypt ├─smol-alpine 253:1 0 16G 0 lvm / ├─smol-swap 253:2 0 16G 0 lvm [SWAP] ├─smol-arch 253:3 0 16G 0 lvm └─smol-nix 253:4 0 16G 0 lvm sdb 8:16 0 447.1G 0 disk ├─sdb1 8:17 0 100M 0 part ├─sdb2 8:18 0 127.2G 0 part ├─sdb3 8:19 0 682M 0 part └─sdb4 8:20 0 319.1G 0 part └─bicc 253:5 0 319.1G 0 crypt /var/lib/transmission /var/lib/syncthing /bicc `

This setup uses two disks, smol which holds the boot and root partitions. And bicc for extra storage.

The names of disks and partitions in the examples below use this layout as a reference. Make sure to replace them with the correct ones as you follow along.

BIOS vs UEFI

Before you begin partitioning the disk, you have to decide whether to use BIOS or UEFI. Some machines support just one option meaning you can skip having to think about it.

Over the years my opinion on the matter has shifted back and forth. Right now I prefer BIOS for its simplicity.

Partitioning

The first step of the process is the partitioning which breaks the disk up into smaller chunks that are used for different purposes.

My utility of choice for partitioning disks is fdisk which is already installed on most Linux systems. Other options include gdisk and parted.

`sh fdisk /dev/sda o # create aa new DOS/MBR partition table `

Make two partitions:

  1. Boot partition which contains everything required to boot the OS:

Before you begin partitioning, choose the size of the boot partition. It can be as small as 200 MB but because it will be a pain to change later on, use at least 1 GB.

`sh n # create the boot partition p # make it primary ENTER # auto select number ENTER # auto select starting sector +1G # size of the boot partition `

  1. Encrypted data partition which stores system data.

`sh n # create the encrypted data partition p ENTER ENTER ENTER # allow it to take all free space w # save the table to the disk `

Boot partition

After partitioning the disk, format each partition.

For the boot partition, on UEFI use FAT32 and on BIOS use any supported by the bootloader, I use limine which supports ext4.

`sh mkfs.fat -F32 /dev/sda1 # for UEFI mkfs.ext4 /dev/sda1 # for BIOS (limine) `

Encrypted data partition

Formatting the data partition is more complicated as it uses LVM on LUKS.

LUKS

To start, use LUKS to encrypt the whole partition. This prevents access to the data without a password.

Before encrypting the disk, wipe it with random data:

`sh cryptsetup open --type plain -d /dev/urandom --sector-size 4096 /dev/sda2 wipe dd if=/dev/zero of=/dev/mapper/wipe status=progress bs=1M cryptsetup close wipe `

Then encrypt the partition as usual:

`sh cryptsetup luksFormat /dev/sda2 cryptsetup open /dev/sda2 smol `

LVM

With the data partition encrypted, use LVM to split it into virtual partitions.

Start by turning the decrypted partition into a physical volume, and creating a volume group on it:

`sh pvcreate /dev/mapper/smol vgcreate smol /dev/mapper/smol `

Swap

The first virtual partition to create is swap. It acts as extra memory (RAM) which:

  1. Prevents the system from stalling when running out of physical memory.
  2. Store the content of physical memory for suspend/hibernate.

Create a swap partition and enable it:

`sh lvcreate -n swap -L 16G smol mkswap /dev/smol/swap swapon /dev/smol/swap `

Root

Next, create the root partition that will store the distro.

The root partition can stay small, as all it stores is distro specific and not personal data.

Giving the root partition a descriptive name makes it easier to diffrentiate when running extra distros and configurations.

Create the root partition, format and mount it:

`sh lvcreate -n alpine -L 16G smol # root partition mkfs.ext4 /dev/smol/alpine mount /dev/smol/alpine /mnt `

Use the remaining space to either create additional root partitions, or as a personal data partition.

Extra disks

When using more disks in a system (like keeping the space partition on a seperate large disk), create a partition and encrypt it with LUKS same as earlier.

Skip configuring LVM if the extra disks store just personal data.

To prevent entering a password for each encrypted partition on boot, use keyfiles stored on the root disk to automatically decrypt them.

Create a directory to store the keyfiles on the root partition:

`sh mkdir -p /mnt/etc/keys chmod 700 /mnt/etc/keys `

Create a keyfile for each partition and add it to LUKS:

`sh dd bs=512 count=4 if=/dev/urandom of=/mnt/etc/keys/bicc chmod 600 /mnt/etc/keys/bicc cryptsetup luksAddKey /dev/sdb4 /mnt/etc/keys/bicc cryptsetup open /dev/sdb4 bicc --key-file /mnt/etc/keys/bicc `

To decrypt the partitions on boot, use either

(Alpine and Gentoo) or

(Other distros).

To decrypt extra partitions on boot while running Alpine Linux or Gentoo use dm-crypt which requires modifying /etc/conf.d/dmcrypt:

`conf target='bicc' source=UUID='...' key='/etc/keys/bicc' `

Other distros use crypttab. Configure it using /etc/crypttab:

`crypttab bicc UUID=... /etc/keys/bicc `

Space partition

To store personal data and share it between distors, most guides recommend creating a separate home partition and mounting it on /home. This works until you want to share more data outside of the home partition like torrents in /var/lib/transmission or syncthing folders in /var/lib/syncthing etc.

This partition can either take up the rest of the free space in the encrypted disk partition:

`sh lvcreate -n space -l 100%free smol mkfs.ext4 /dev/smol/space `

Or store it on a seperate disk:

`sh mkfs.ext4 /dev/mapper/bicc `

Either way, create a directory on the root partition and mount the partition there:

`sh mkdir /mnt/space mount ... /mnt/space # use the path of the space partition `

Use the space partition to store the home directory:

`sh mkdir /mnt/space/home mount --rbind /mnt/space/home /mnt/home `

Sharing the home directory directly between distros can cause issues with conflicting files (Like sharing Firefox config between distros). Instead share directories that won't conflict like Pictures and Documents and storing the rest on the distro's root partition.

To share other directories, create them as needed:

`sh mkdir /mnt/space/tors mount --rbind /mnt/space/tors /var/lib/transmission `

Initramfs

Initramfs is a temporary file system booted into from the bootloader, it prepares the kernel and the rest of system.

Make sure your distro supports LUKS and LVM. Do this by enabling the required features and regenerating the initramfs image.

This differs between distros, so refer to their documentation.

Cmdline

Cmdline are the options your bootloader passes to the initramfs to configure the system. When using LVM on LUKS, change them to ensure the initramfs can boot.

`sh cryptroot=UUID=... # UUID of LUKS partition /dev/sdX cryptdm=crypt # name of decrypted root partition root=/dev/crypt/alpine # points to the root partition rootfstype=ext4 # root partition's file system resume=/dev/crypt/swap # swap partition for hibernation `

Get the UUID of cryptroot using blkid /dev/sdX.

The format of the cmdline will depend on the initramfs so once again refer to their documentation.

Fstab

fstab is the file used by the mount utility to automatically mount required partitions on boot.

Find the UUID of the boot partition using blkid /dev/sdX.

`sh /dev/crypt/alpine / ext4 rw,relatime 0 1 # root /dev/crypt/swap none swap defaults 0 0 # swap UUID=... /boot ext4 rw,relatime 0 2 # boot # space /dev/crypt/space /space /space/home /home/ none rbind,defaults 0 0 /space/tors /var/lib/transmission none rbind,defaults 0 0 /space/sync /var/lib/syncthing none rbind,defaults 0 0 `

Bootloader

The most popular bootloader on Linux is GRUB, but over its long lifespan it has become bloated and complicated. One alternative I was using was rEFInd which is much simpler but only suports UEFI. I currently use limine which is modern and suckless, a perfect combination.

`sh apk add limine limine-sys cp /usr/share/limine/limine-bios.sys /boot/ limine bios-install /dev/sdX `

References