There is a newer version of this guide for Ubuntu 19.04.
Booting ZFS Ubuntu of MBR is story I already told. But what if we want an encrypted UEFI ZFS setup?
Well, it's quite simple to previous steps and again just a derivation on ZFS-on-Linux project.
As before, we first need to get into root prompt:
Terminalsudo -i
Followed by getting a few basic packages ready:
Terminalapt-add-repository universe
apt update
apt install --yes debootstrap gdisk zfs-initramfs
Disk setup is quite simple with only two partitions:
Terminalsgdisk --zap-all /dev/disk/by-id/ata_disk
sgdisk -n2:1M:+511M -t2:EF00 /dev/disk/by-id/ata_disk
sgdisk -n1:0:0 -t1:8300 /dev/disk/by-id/ata_disk
sgdisk --print /dev/disk/by-id/ata_disk
Number Start (sector) End (sector) Size Code Name
1 1050624 67108830 31.5 GiB 8300
2 2048 1050623 512.0 MiB 8300
I believe full disk encryption should be a no-brainer so of course we set up LUKS:
Terminalcryptsetup luksFormat -qc aes-xts-plain64 -s 512 -h sha256 /dev/disk/by-id/ata_disk-part1
cryptsetup luksOpen /dev/disk/by-id/ata_disk-part1 luks1
Creating ZFS stays the same as before:
Terminalzpool create -o ashift=12 -O atime=off -O canmount=off -O compression=lz4 -O normalization=formD \
-O xattr=sa -O mountpoint=none rpool /dev/mapper/luks1
zfs create -o canmount=noauto -o mountpoint=/mnt/rpool/ rpool/system
zfs mount rpool/system
Getting basic installation on our disks follows next:
Terminaldebootstrap cosmic /mnt/rpool/
zfs set devices=off rpool
zfs list
And then we setup EFI boot partition:
Terminalmkdosfs -F 32 -n EFI /dev/disk/by-id/ata_disk-part2
mount /dev/disk/by-id/ata_disk-part2 /mnt/rpool/boot/
We need to ensure boot partition auto-mounts:
Terminalecho PARTUUID=$(blkid -s PARTUUID -o value /dev/disk/by-id/ata_disk-part2) /boot vfat noatime,nofail,x-systemd.device-timeout=5s 0 1 >> /mnt/rpool/etc/fstab
cat /mnt/rpool/etc/fstab
Before we start using anything, we should prepare a few necessary files:
Terminalcp /etc/hostname /mnt/rpool/etc/hostname
cp /etc/hosts /mnt/rpool/etc/hosts
cp /etc/netplan/*.yaml /mnt/rpool/etc/netplan/
sed '/cdrom/d' /etc/apt/sources.list > /mnt/rpool/etc/apt/sources.list
If you are dual-booting system with Windows, do consider turning off UTC BIOS time:
Terminalecho UTC=no >> /mnt/rpool/etc/default/rc5
With chroot we can get the first taste of our new system:
Terminalmount --rbind /dev /mnt/rpool/dev
mount --rbind /proc /mnt/rpool/proc
mount --rbind /sys /mnt/rpool/sys
chroot /mnt/rpool/ /bin/bash --login
Now we can update our software:
Terminalapt update
Immediately followed with locale and time zone setup:
Terminallocale-gen --purge "en_US.UTF-8"
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US
dpkg-reconfigure --frontend noninteractive locales
dpkg-reconfigure tzdata
Now we install Linux image and basic ZFS boot packages:
Terminalapt install --yes --no-install-recommends linux-image-generic
apt install --yes zfs-initramfs
Since we're dealing with encrypted data, our cryptsetup should be also auto mounted:
Terminalapt install --yes cryptsetup
echo "luks1 UUID=$(blkid -s UUID -o value /dev/disk/by-id/ata_disk-part1) none luks,discard,initramfs" >> /etc/crypttab
cat /etc/crypttab
Now we get grub started:
Terminalapt install --yes grub-efi-amd64
And update our boot environment again (seeing errors is nothing unusual):
Terminalupdate-initramfs -u -k all
And then we finalize our grup setup:
Terminalupdate-grub
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=ubuntu --recheck --no-floppy
Finally we get the rest of desktop system:
Terminalapt-get install --yes ubuntu-desktop samba linux-headers-generic
apt dist-upgrade --yes
We can omit creation of the swap
dataset but I always find it handy:
Terminalzfs create -V 4G -b $(getconf PAGESIZE) -o compression=off -o logbias=throughput -o sync=always \
-o primarycache=metadata -o secondarycache=none rpool/swap
mkswap -f /dev/zvol/rpool/swap
echo "/dev/zvol/rpool/swap none swap defaults 0 0" >> /etc/fstab
echo RESUME=none > /etc/initramfs-tools/conf.d/resume
If one is so inclined, /home directory can get a separate dataset too:
Terminalrmdir /home
zfs create -o mountpoint=/home rpool/data
Only remaining thing before restart is to create user:
Terminaladduser user
usermod -a -G adm,cdrom,dip,lpadmin,plugdev,sambashare,sudo user
chown -R user:user /home/user
As install is ready, we can exit our chroot environment and reboot:
Terminalexit
reboot
You will get stuck after the password prompt as our mountpoint for system
dataset is wrong. That's easy to correct:
Terminalzfs set mountpoint=/ rpool/system
exit
reboot
Assuming nothing went wrong, your UEFI system is now ready.
PS: There are versions of this guide using the native ZFS encryption for other Ubuntu versions: 21.10 and 20.04
PPS: For LUKS-based ZFS setup, check the following posts: 20.04, 19.10, and 19.04.