Why
I wanted to install a new arch linux configuration but using zfs as root file system, so that i can see if i can configure snapshots for updates. But i want to have as much as posible encrypted so, my setup will be
- partition 1: efi partition, vfat unencrypted for /boot/efi
- maybe secure it with secure boot
- partition 2: luks 1 encrypted / ext4 formated for /boot and grub
- luks v1 is needed because grub can’t open luks v2
- partition 3: luks 2 encrpted / lvm with swap and zfs root filesystem
- zfs can’t handle a swap file, so using lvm so that swap partition and zfsroot are encrypted
- i want the swap partition encrypted so that i can have a encrypted suspend to disk
For who
For a advanced linux user
Step 1
Boot a ubuntu iso or usb, i am using ubuntu-24.04.2-desktop-amd64.iso (the arch installer iso doesn’t have zfs tools, so it is easier to use a ubuntu iso with all tooling) and configure and partitions and format them. Please remember i give examples for /dev/nvme0n1 or /dev/sda but use your disk and partitions like you have (check with fdisk -l)
- Open a terminal and use sudo to become root
- install some default packages
apt-get install -y arch-install-scripts vim rsync docker.io
- Use gdisk to partition the file disk
gdisk /dev/sda
# or
gdisk /dev/nvme0n1
# or
gdisk /dev/<yuur disk>
- Create a partition table like this
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00 EFI system partition
2 1050624 3147775 1024.0 MiB 8309 Linux LUKS
3 3147776 41940991 18.5 GiB 8309 Linux LUKS
- How to use gdisk
- use n to create a new partition
- partition number 1, 2 and 3 (use default value)
- first sector (use default value)
- last sector (use +512m for first partition, +1024m for second partition and default for last partition), or use you’re own values
- Hex Code, use EF00 (1 partition), 8309 (2 and 3 partition)
- after creating 3 partition use w to write
- format efi partition
mkfs.fat -F 32 /dev/sda1 -n ARCH2025ZFS
or
mkfs.fat -F 32 /dev/nvme0n1p1 -n ARCH2025ZFS
- create luks for /boot parition and format /boot partition
# format cryptboot
cryptsetup luksFormat --type luks1 /dev/sda2
or
cryptsetup luksFormat --type luks1 /dev/nvme0n1p2
# open cryptboot
cryptsetup open /dev/nvme0n1p2 cryptboot
or
cryptsetup open /dev/sda2 cryptboot
# format
mkfs.ext4 /dev/mapper/cryptboot
or
mkfs.btrfs /dev/mapper/cryptboot
- crypte luks for zfsroot and create lvm
cryptsetup luksFormat /dev/sda3
or
cryptsetup luksFormat /dev/nvme0n1p3
# open cryptlvm
cryptsetup open /dev/sda3 cryptlvm
or
cryptsetup open /dev/nvme0n1p3 cryptlvm
# create lvm
# by restart vgchange -a y
pvcreate /dev/mapper/cryptlvm
vgcreate arch2025 /dev/mapper/cryptlvm
- create swap lvm and mkswap
lvcreate -L 8G arch2025 -n swap
mkswap /dev/mapper/arch2025-swap
- create lvm root fs and create zfs pool
lvcreate -l 100%FREE arch2025 -n root
zpool create -f -o ashift=12 \
-O acltype=posixacl \
-O relatime=on \
-O xattr=sa \
-O dnodesize=legacy \
-O normalization=formD \
-O mountpoint=none \
-O canmount=off \
-O devices=off \
-R /mnt \
-O compression=lz4 \
-O dedup=on \
rpool /dev/arch2025/root
- set mountpoint and mount zfs
zfs create -o mountpoint=none rpool/arch2025
zfs create -o mountpoint=/ -o canmount=noauto rpool/arch2025/root
# finally export the zfs pool and import it again: https://forum.manjaro.org/t/howto-install-full-manjaro-on-zfs-filesystem/69168
zpool export rpool
zpool import -d /dev/arch2025/root -R /mnt rpool -N
zfs mount rpool/arch2025/root
- check is rpoot is mount with df /mnt
- mount boot en boot/efi
mkdir /mnt/boot
mount /dev/mapper/cryptboot /mnt/boot
# and boot/efi
mkdir /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi
or
mount /dev/nvme0n1p1 /mnt/boot/efi
- check mounts
df | grep /mnt
rpool/arch2025/root 20315520 128 20315392 1% /mnt
/dev/mapper/cryptboot 1046528 5920 924544 1% /mnt/boot
/dev/sda1 523244 4 523240 1% /mnt/boot/efi
- Export zpool.cache
zpool set bootfs=rpool/arch2025/root rpool
zpool set cachefile=/etc/zfs/zpool.cache rpool
mkdir -p /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache
Step 2
Bootstrap arch linux using a docker arch container, i tried to install pacman and pacstrap in ubuntu in initialize the pacman key, but i managed to get it working once, but i got a lot of gpg checksum errors most of the time, so using docker seems the easiest way. We need to use the linux-lts kernel because it the time of writing kernel 6.13 didn’t have zfs support, you can offcourse change the packages that you need
- start docker container
docker run --privileged --rm --name docker-arch -v /mnt:/mnt -h docker-arch -t -i archlinux:latest /bin/bash
- in the docker container run the following command to boot strap arch linux
pacman -Sy --noconfirm arch-install-scripts rsync
pacstrap -K /mnt base linux-lts linux-firmware linux-lts-headers vim git base-devel plocate grub efibootmgr os-prober lvm2 wireless-regdb scx-scheds less git base-devel vim netctl git vim dialog networkmanager iwd modemmanager os-prober sudo alsa-utils efibootmgr refind openssh wget screen tmux syncthing
- rsync the pacman conf in the container to the /mnt partition, offcourse you can change mirrors and config later on if needed
rsync -avP /etc/pacman.conf /mnt/etc/
rsync -avP /etc/pacman.d/ /mnt/etc/pacman.d/
- exit docker with ctrl-d or exit
- if you have added you’re private ssh key to the ubuntu live cd for easy acces, copy it to the arch install
rsync -avP /root/.ssh/ /mnt/root/.ssh/
- chroot to the arch install in /mnt
arch-chroot /mnt
- create a normal user in the chroot to do the yay install and zfs packages install i am using richard as the user, but you can choice you’re own name
useradd -G wheel -m richard
passwd richard
- enable the wheel group to add root access using sudo
vim /etc/sudoers
# find and uncomment wheel group line in sudoers file and save with :wq!
- edit the hook line in mkinitcpio.conf
vim /etc/mkinitcpio.conf
# find and change hooks file to
HOOKS=(base udev autodetect modconf kms block keyboard keymap encrypt lvm2 zfs resume filesystems fsck)
- You need to know the uuid of you’re newly created partitions so store them somewhere
blkid /dev/sda1
or
blkid /dev/nvme0n1p1
UUID="xxxx-xxxx" # check output of command
# Do the same for partition 2 and 3, there UUID wil be longer like
UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # for partition 2 and
UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # for partition 3
- Create a cryptboot, using the value for partition 2 and partition 3
vim /etc/crypttab
# add the following lines
cryptboot UUID=parition 2 uuid
cryptlvm UUID=partition 3 uuid
# for me it is
cryptboot UUID=cb96cf72-b5d8-43f1-b369-fb33a49fe8a0
cryptlvm UUID=d368565b-1cb3-4cdc-a6b7-8e4e425ac511
- Now we need to change /etc/default/grub we will need the value for uuid partition 3
vim /etc/default/grub
# change line: GRUB_CMDLINE_LINUX=""
GRUB_CMDLINE_LINUX="cryptdevice=/dev/disk/by-uuid/<UUID partition 3>:cryptlvm"
# for me it is
GRUB_CMDLINE_LINUX="cryptdevice=/dev/disk/by-uuid/d368565b-1cb3-4cdc-a6b7-8e4e425ac511:cryptlvm"
# enable the grub_enable_cryptodisk
enable the GRUB_ENABLE_CRYPTODISK=y in /etc/default/grub
- update fstab and add partitions there, change uuid /boot/efi of course to you’re setup
vim /etc/fstab
# add lines
/dev/mapper/cryptboot /boot auto nofail,defaults,noatime 0 2
UUID=<uuid partition 1> /boot/efi auto defaults,noatime 0 2
/dev/mapper/arch2025-swap none swap sw 0 0
# for me it is
/dev/mapper/cryptboot /boot auto nofail,defaults,noatime 0 2
UUID=4070-5871 /boot/efi auto defaults,noatime 0 2
/dev/mapper/arch2025-swap none swap sw 0 0
- install grub on root disk (if you are using refind, you can use –no-nvram to not update bios
grub-install /dev/sda
or
grub-install /dev/nvme0n1
or
grub-install --no-nvram /dev/sda
or
grub-install --no-nvram /dev/nvme0n1
- Now you need to use the user that you created (for me richard)
su - richard
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg --noconfirm -si
- Install zfs-dkms and zfs-utils using yay
yay --noconfirm zfs
# install zfs-dkms and zfs-utils
- Exit you’re user and return to root in you’re chroot
exit
- No we are ready to create a grub config
grub-mkconfig -o /boot/grub/grub.cfg
- change root password
passwd root
- Enable some systemd services in you’re chroot
systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target
systemctl enable NetworkManager
systemctl enable sshd
- Generate the hostid
zgenhostid $(hostid)
- change hostname
vim /etc/hostname
- And know umount and export rpool so that we are read
umount -a
exit # out of chroot
zfs unmount -a
zfs umount /mnt
# export rpool so that you can boot from it
zpool export rpool
- Reboot in you’re new installation
shutdown -r now
Todo
- create subvolumes zfs for /home etc.
- create snapshot with pacman updates in zfs and btrfs boot
- create grub boot options for older snapshots
- give some tips to change the 3 times password prompts on boot to 2 or 1
- prompt 1: grub unlocks /boot for grub.cfg and kernel and initramfs
- prompt 2: unlock root fs luks file system
- prompt 3: unlock /boot in lkernel boot