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.
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.
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.
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:
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 least1 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
`
`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
`
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)
`
Formatting the data partition is more complicated as it uses LVM on 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
`
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
`
The first virtual partition to create is swap. It acts as extra memory (RAM) which:
Create a swap partition and enable it:
`sh
lvcreate -n swap -L 16G smol
mkswap /dev/smol/swap
swapon /dev/smol/swap
`
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.
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
`
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 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 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 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
`
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
`