Encrypt your ZFS home directory in Ubuntu 20.04


Short version…
Note that this does not integrate with PAM and you’ll need to enter your password twice, once on boot , once on login. Make sure you use your login password for the encryption.

# rename current dir, remove mountpoint and snapshot:
zfs rename rpool/USERDATA/greg_pfgwqx rpool/USERDATA/noenc_greg_pfgwqx

zfs set mountpoint=none rpool/USERDATA/noenc_greg_pfgwqx

zfs snapshot rpool/USERDATA/noenc_greg_pfgwqx@mv1


# get the zsys property for copy to new fs
# use its VALUE for send/recv below
zfs get com.ubuntu.zsys:bootfs-datasets rpool/USERDATA/noenc_greg_pfgwqx

#make a new file, save your password in it
/home/admin/.zfs.key

zfs send -v -c rpool/USERDATA/noenc_greg_pfgwqx@mv1 | zfs recv \
  -v -o encryption=aes-256-gcm \
  -o keyformat=passphrase -o keylocation=file:///home/admin/.zfs.key \
  -o mountpoint=/home/greg \
  -o com.ubuntu.zsys:bootfs-datasets=rpool/ROOT/ubuntu_1ogzx2 \
  rpool/USERDATA/greg_pfgwqx 

zfs set keylocation=prompt rpool/USERDATA/greg_pfgwqx
chown greg:greg /home/greg

rm /home/admin/.zfs.key

Long version with more details…

I found a few articles on this, but I came with a slightly different way. This is actually pretty easy for the encryption part. What I have not done here, though, is create a script for PAM to auto mount and login. The below solution is adding encryption which will require a password when Ubuntu boots. This password is in addition to the password to login. In other words, you’ll have to enter your password twice.

I plan on adding a script and PAM handling later, but the link below is what I used for inspiration and has the PAM portion too. What you could do is modify their ZFS encryption parts with my solution.

https://talldanestale.dk/2020/04/06/zfs-and-homedir-encryption/

The real difference with their solution is the way they create and copy data. They create a new ZFS home directory with encryption properties and they rsync the data. What I’ve done is make a snapshot, then use zfs send receive to transfer with properties. Not sure there’s much benefit either way, except I prefer to use ZFS to do the transfering.

Here’s the steps. You’ll need to do this using a different admin account.

  • Rename your current ZFS home directory, remove mount point, make a snapshot
  • Get the special Ubuntu property
  • Create a temporary key file with your password
  • Do a ZFS send receive
  • Change a property on new dir
  • chown

We’ll be working with my home dir, you’ll need to replace “greg_pfgwqx” with your name, of course. Rename and then snapshot it.

zfs rename rpool/USERDATA/greg_pfgwqx rpool/USERDATA/noenc_greg_pfgwqx

zfs set mountpoint=none rpool/USERDATA/noenc_greg_pfgwqx

zfs snapshot rpool/USERDATA/noenc_greg_pfgwqx@mv1

Get the VALUE needed for Ubuntu:

zfs get com.ubuntu.zsys:bootfs-datasets rpool/USERDATA/noenc_greg_pfgwqx

My system returned this, use your VALUE:
rpool/ROOT/ubuntu_1ogzx2

In your other admin account home, make a key file put your password in it. You’ll remove this later. Store it wherever you like, I put mine here: /home/admin/.zfs.key

Combining all the above, replace the needed properties with your values and perform the ZFS send receive to create our new encrypted home directory. Notice we’re setting the key location to your temporary key file. We also set all the needed properties, including the special Ubuntu property.

zfs send -v -c rpool/USERDATA/noenc_greg_pfgwqx@mv1 | zfs recv \
  -v -o encryption=aes-256-gcm \
  -o keyformat=passphrase -o keylocation=file:///home/admin/.zfs.key \
  -o mountpoint=/home/greg \
  -o com.ubuntu.zsys:bootfs-datasets=rpool/ROOT/ubuntu_1ogzx2 \
  rpool/USERDATA/greg_pfgwqx 

Lastly, set the keylocation to “prompt” and set ownership. Then remove the key file.

zfs set keylocation=prompt rpool/USERDATA/greg_pfgwqx
chown greg:greg /home/greg
rm /home/admin/.zfs.key