Last night I installed a new server with an LUKS encrypted drive. The server also has a large ZFS pool that is used as the main data storage, of course that needs to be encrypted as well.
If you just like to know how ZFS encryption works, I recommend that you read Jim Salter's excellent article about it.
Compared to LUKS, ZFS encryption is a feature you enable on datasets/volumes. This has the disadvantage that you can see the structure and metadata of unlocked datasets/volumes. For example the name of a dataset, disk usage and so on. This is most likely not a problem, but a minor detail that is good do know.
zfs create \
-o encryption=aes-256-gcm \
-o keylocation=file:///etc/zfs-disk-encryption-key \
-o keyformat=passphrase \
pool/encrypted
I can now place whatever datasets/volumes I prefer to keep encrypted under pool/encrypted
. I picked the name "encrypted" to make it obvious for future me to understand what is encrypted and what's not.
I run LXD containers on this server, they will be stored under pool/encrypted/lxd
. It's important that the dataset is unlocked before lxd starts. The root is encrypted with LUKS so I felt comfortable placing the encryption passphrase inside a file. If you do this, make sure that you have a second copy of the file (or it's something you remember). It would be annoying to lose access to the ZFS dataset just because the OS drive failed.
ArchWiki has a nice systemd service that unlocks the dataset at the appropriate time. I had to modify the path slightly for Ubuntu, here it is:
[Unit]
Description=Load encryption keys
DefaultDependencies=no
After=zfs-import.target
Before=zfs-mount.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/zfs load-key -a
StandardInput=tty-force
[Install]
WantedBy=zfs-mount.service
And of course, do not forgot to enable the service with a systemctl enable zfs-load-key.service
.