Encrypting Unencrypted ZFS Datasets
Summary
I recently discovered ZFS datasets are sent unencrypted by default and that they need to be sent with a flag to preserve their encrypted status. Well too late, I had already migrated my data, and deleted the old datasets by the time I had discovered this. After doing some research I found encrypting a dataset that is already created is not possible, so in order to fix this you need to send the unencrypted data set to an encrypted dataset.
The process
Thankfully the process is pretty simple, I renamed the dataset, took a snapshot, created a new encrypted dataset, then moved the data back, like so:
# Rename the current dataset
zfs rename pool/jhanafin pool/jhanafin-unenc
# Take a snapshot for migration
zfs snapshot -r pool/jhanafin-unenc@$(date +'%Y-%m-%d')
# Recreate dataset with encryption
zfs create -o encryption=on -o keylocation=prompt -o keyformat=passphrase pool/jhanafin
# Send the dataset
zfs send -R pool/jhanafin-unenc@2024-09-20 | zfs receive -x encryption pool/jhanafin
# Destroy the old dataset
zfs destroy -R pool/jhanafin-unenc@$(date +'%Y-%m-%d')
If you look at the sources below you will notice the command used on the FreeBSD forum is:
zfs send -R pool/data-unenc@encryptionprep | zfs receive -o encryption=on -o keyformat=passphrase -o compression=lz4 -o (and so forth for every property I want to set) pool/data
this will not work due to the -o keyformat=passphrase
requiring stdin input and the dataset is being sent via stdin/out. My root pool/jhanafin
has no data in it, so there was no need to send a snapshot to it, if however you do have data in your root dataset you will need to use the forums answer, but instead of passphrase you will need to use a file then switch the key to passpharse if that is your preference.
Sources
- Is this a correct way to enable native ZFS encryption on a dataset?
- syncing unecrypted dataset to encrypted dataset