Is it possible to encrypt an existing dataset (including snapshots) in
ZFS on Linux >= 0.8, e.g. by using
send | recv and destruction of the original dataset?
Yes, it is. See this simple example (tested on ZoL 0.8.3).
If you would like to use a raw keyfile (rather than a passphrase):
dd if=/dev/urandom of=/path/to/keyfile bs=32 count=1 chmod 000 /path/to/keyfile
Create a snapshot first:
zfs snapshot -r tank/home@transfer
Then, as proposed,
send | recv (with replication option
-R), but provide your encryption options on the receive side:
zfs send -R tank/home@transfer | zfs receive \ -o encryption=aes-256-gcm \ -o keyformat=raw \ -o keylocation=file:///path/to/keyfile \ tank/newhome
If the original dataset is mounted, the new one will not be mounted straightaway:
cannot mount '/tank/home': directory is not empty
Destroy the unencrypted dataset and replace it with your new one:
zfs destroy -r tank/home zfs rename tank/newhome tank/home
If your dataset does not have any children, mounting is easy:
zfs mount tank/home
zfs list -rH -o name tank/home | xargs -L 1 zfs mount
zfs mount -a if you don’t have other datasets which should not be mounted).
And that was about it!
Finally, destroy the snapshot, if you like:
zfs destroy -r tank/home@transfer