AlexBolli.ch
This is my personal website where I keep some useful guides on things I worked at in the past.
Linux
This section contains guides on Linux.
Arch Linux
This section contains guides on Arch Linux in particular.
Install Arch Linux on ZFS on LUKS
The goal of this guide is to show the necessary steps to install Arch Linux using the ZFS file system on top of an encrypted LUKS container.
Prerequisites
Before the installation on the target machine can take place, some prerequisites need to be established.
Custom Install ISO
In order to be able to create and mount volumes with ZFS, a custom installation medium (ISO) is required, since the official image and repositories do not contain the necessary packages.
The complete instructions can be found in the official Arch Linux wiki, but these are the main steps.
Installation of Tooling
sudo pacman -S archiso git
Copy Profile (Template)
The archiso package installed above provides a template (Arch Linux calls this a profile) which will later be turned into an ISO image that can be modified to create a custom installation medium.
cd ~/
cp -r /usr/share/archiso/configs/releng/ archlive
Build ZFS Packages
Since the requried packages are not (yet) available from the official repositories, the AUR packages needs to be built manually. Afterwards, they will be copied to the ISO template in a future step.
cd ~/temp
git clone https://aur.archlinux.org/zfs-utils.git
git clone https://aur.archlinux.org/zfs-dkms.git
cd ~/temp/zfs-utils
makepkg -s
cd ~/temp/zfs-dkms
makepkg -s
Modify pacman.conf
In order for pacman to find the just compiled AUR packages, a custom repository that is stored locally needs to be created.
cd ~/temp
cp zfs-utils/zfs-utils*.pkg.tar.zst .
cp zfs-dkms/zfs-dkms*.pkg.tar.zst .
repo-add custom.db.tar.gz zfs-utils*.pkg.tar.zst zfs-dkms*.pkg.tar.zst
The custom repository now needs to be referenced in the template's pacman.conf.
cat >> ~/archlive/pacman.conf << EOF
[custom]
SigLevel = Optional TrustAll
Server = file://$HOME/temp
EOF
Add AUR Packages to List of Packages
During the build of the installation ISO, pacman will install a list of
packages to the built image. This list is stored in the template's
package.x86_64
file. To this file the two manually built packages need to be
added.
cat >> packages.x86_64 << EOF
zfs-utils
zfs-dkms
linux-headers
EOF
Note: linux-headers
is required for using dkms.
Build the Installation ISO Image
Finally the installation ISO image can be built using the following command. This might take some time.
cd ~/archlive
sudo mkarchiso -v .
After the image has been built, the ISO image can be found in the
~/archlive/out
directory.
Flash the ISO to a Thumbdrive
This is the same procedure like with a standard Arch install ISO.
sudo dd if=~/archlive/iso/archlinux-*.iso \
of=/dev/sdx bs=8M oflag=sync status=progress
After the image has been flashed, the target machine can be booted from the thumbdrive.
System Installation
Most of the installation is the same like a standard Arch Linux install, so this section will focus only a few steps.
Partitioning
The goal is create a partitioning that looks something like this:
PARTITION TYPE MOUNT COMMENT
sda disk GPT schema
├─sda1 part /boot Type: EFI, FAT32 EFI partition, Size: 100M
└─sda2 part Type: Linux Filesystem
└─cryptoroot crypt LUKS container, GPT schema
├─cryptoroot1 part [SWAP] Type: Linux Swap, Simple swap partition (mkswap)
└─cryptoroot2 part Type: Solaris Root, Partition that holds ZFS pool
Setting up Partitions
Formatting the EFI Boot Volume
mkfs.fat -F32 /dev/sda1
Creating the LUKS Container
cryptsetup luksFormat /dev/sda2
cryptsetup open /dev/sda2 cryptoroot
Partitioning Inside LUKS Container
Two partitions needs to be created, a smaller swap partition (preferrably slightly larger than the system's RAM, so hibernation will work) and a partition that fills the rest of the container.
Setting up ZFS
First a cache file for the zpool needs to be created.
touch /etc/zfs/zpool.cache
Creating ZPool
Next, the pool can be created on the second partition inside the LUKS container.
zpool create \
-o cachefile=/etc/zfs/zpool.cache \
-o ashift=12 \
-m none \
-R /mnt \
zroot \
/dev/mapper/cryptoroot2
Creating Datasets Inside ZPool
After the pool has been created the datasets that hold the actual files can be created.
zfs create -o mountpoint=none -o compression=lz4 zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/default
zfs create -o mountpoint=/home zroot/home
zfs create -o mountpoint=/root zroot/home/root
zpool set bootfs=zroot zroot
Afterwards, the pool needs to be reimported.
zpool export zroot
zpool import -R /mnt zroot
Mounting Boot Partition
Importing the ZFS pool already took care of mounting all the datasets, however the boot partition needs to be mounted manually as it is stored outside of the pool.
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
Installation of Base System
This step is again very similar to a standard Arch Linux install, so these are the basic steps.
pacstrap -i /mnt base base-devel linux linux-firmware linux-headers bash vim \
grub efibootmgr git sudo mkinitcpio parted networkmanager wpa_supplicant \
# etc.
Generate fstab Entries
genfstab -U -p /mnt | grep boot >> /mnt/etc/fstab
genfstab -U -p /mnt | grep swap >> /mnt/etc/fstab
Chroot Into new Installation
arch-chroot /mnt /bin/bash
Create Personal User
useradd john
mkdir /home/john
chown john:john /home/john
To make sure the personal user is able to administrate the system, they need to be added to the wheel group and the group needs to be added to the whitelisted groups.
usermod -aG wheel john
sed -i '/%wheel ALL=(ALL) ALL/ s/# //' /etc/sudoers
Install AUR Package Manager
In order to install the two AUR packages and keep them up-to-date, an AUR package manager needs to be installed. The current most-popular choice is yay.
As the personal user:
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
Install ZFS Packages From AUR
After the AUR package manager has been install, the two ZFS packages can be installed with it.
yay -S zfs-utils zfs-dkms
Enable ZFS Services
Using ZFS requires little administrative effort, as most things are handled by systemd services. These need to be enabled now.
systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target
Create Bootloader Hook
Since the bootloader only probes once for partitions (before the LUKS container has been opened) a hook needs to be created that probes for partitions again after the container has been opened.
cat > /etc/initcpio/install/load_part << EOFHOOK
#!/bin/bash
build() {
add_binary 'partprobe'
add_runscript
}
help() {
cat << HELPEOF
Probes mapped LUKS container for partitions.
HELPEOF
}
EOFHOOK
cat > /etc/initcpio/hooks/load_part << EOFHOOK
run_hook() {
partprobe /dev/mapper/cryptoroot
}
EOFHOOK
Set up mkinitcpio
The HOOKS
value in the /etc/mkinitcpio.conf
file needs to be updated to
contain the encrypt
hook after the keyboard
hook. After which the custom
load_part
hook created above can be placed, followed by zfs
and
filesystems
. The final line should look similar to the following.
HOOKS="base udev autodetect modconf block keyboard encrypt load_part resume zfs filesystems"
After the file has been updated, mkinitcpio
needs to be run to recreate the
initramfs.
mkinitcpio -p linux
Install Bootloader
The setup of GRUB is very similar to a standard installation. In order for the LUKS container to be decrypted and the ZFS pool to be imported on boot, the kernel commandline needs to be changed to contain the following.
cryptdevice=/dev/disk/by-uuid/<uuid>:cryptoroot zfs=zroot/ROOT/default rw resume=UUID=<swap UUID>
The UUIDs can be retrieved using blkid
. The first UUID is the id of
/dev/sda2
while the swap UUID is the ID of /dev/mapper/cryptoroot1
.
Afterwards the bootloader can be installed with the following commands.
grub-install --target=x86_64-efi --efi-directory=/boot
ZPOOL_VDEV_NAME_PATH=1 grub-mkconfig -o /boot/grub/grub.cfg