Encrypted Zfs Mounted In Ubuntu As Home

2 minute read

Considerations and assumptions:

Assumptions:

  • system is booted from NVMe SSD
  • root(/), swap, boot(/boot) are on NVMe SSD (encrypted with LUKS)
  • ZFS pool is created from minimum 3 HDD/SSD devices
  • ZFS pool is in raidz/raidz1 for single-parity configuration
  • dataset is encrypted
  • dataset is mounted as /home directory
  • dataset needed passphrase provided when booting (before user login)

Considerations:

  • ZFS Ubuntu package was chosen instead of building from source
  • above was done in order to provide future system upgrade compatibility
  • after auto mounting is configured, when new block device is plugged in => could cause troubles
  • automount doesn’t work after plug-in external drive

ZFS installation, pool, dataset creation:

As the newly created dataset will be mounted as /home, the backup of current /home needs to be done:

# Make a temporary admin user or switch to root
sudo -i
# Copy users home dir
cp -rp /home/<username> /root/<username>

After sudo -i, sudo is NO longer needed . If temporary admin user was create, sudo is still needed

# Install ZFS (from Ubuntu packages)
apt install zfsutils-linux -y
# One could list block devices for pool creationz
lsblk
# Create a pool from HDD/SSD devices
zpool create <POOLNAME> raidz /dev/sd[a-f]
# Check the status of the pool and list pools
zpool status
zpool list
# Create encrypted dataset in <POOLNAME> and mount it as `/home`
zfs create -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=prompt <POOLNAME>/home -o mountpoint=/home

ZFS mounting setup:

Created dataset is encrypted, and it will NOT be mounted automatically.

Normally in systemd ZFS services zfs mount -a is called and zfs pool is mounted.

This does not work for encrypted datasets, command needed for that is zfs mount -l -a.

zfs-mount-generator will be set to mount the /home directory before user login.

# Instructions can be found here: https://manpages.ubuntu.com/manpages/focal/man8/zfs-mount-generator.8.html
touch /etc/zfs/zfs-list.cache/<POOLNAME>
ln -s "/usr/lib/zfs-linux/zed.d/history_event-zfs-list-cacher.sh" "/etc/zfs/zed.d"
systemctl enable zfs-zed.service
systemctl restart zfs-zed.service
zfs set canmount=on <POOLNAME>/home

In my case I have root (/) directory encrypted with LUKS as well as home (/home) directory encrypted with ZFS, I am asked twice for password after each reboot.

Moving user directory, to mounted encrypted dataset:

# Switch to root
sudo -i
# Check if encrypted dataset is mounted
zfs get mounted <POOLNAME>/home
# Copy users home dir
cp -rp /root/<username> /home/<username>
# If somehow files were copied with different permissions do:
chown <username>:<username> /home/<username>

Tips:

Important things to remember:

  • after plugin a block device(E.g. external HDD), encrypted partition could not mount correctly, due to changes in SDx
  • works like a charm when no changes in SDx devices

Useful links:

Updated: