As of ZoL 2.1.0 (released in 2021), native ZFS encryption is fully supported and production-ready. This includes both dataset-level encryption and the critical zfs send -w
functionality for encrypted replication streams.
The encryption stack supports:
- AES-256-GCM (default) and AES-256-CCM
- PBKDF2 key derivation with 350,000 iterations
- Both passphrase and key file authentication
# Creating an encrypted dataset
zfs create -o encryption=on -o keyformat=passphrase tank/secure_data
# Sending encrypted stream
zfs snapshot tank/secure_data@backup1
zfs send -w tank/secure_data@backup1 | ssh backup-server "zfs recv pool/backups"
Native encryption adds minimal overhead (typically 5-15%) compared to LUKS solutions because:
- Encryption happens at the ZFS layer alongside compression
- No separate block device mapping required
For systems running older ZoL versions without native encryption:
# Option 1: Upgrade to ZoL 2.1+ and migrate data
sudo apt install zfs-2.1
zfs create -o encryption=on tank/new_encrypted
rsync -a /tank/unencrypted/ /tank/new_encrypted/
# Option 2: Temporary workaround with zvols
zfs create -V 10G tank/encrypted_vol
cryptsetup luksFormat /dev/zvol/tank/encrypted_vol
mkfs.ext4 /dev/mapper/encrypted_vol
- Always use
keylocation=file://
for production systems - Rotate encryption keys periodically with
zfs change-key
- Combine with ZFS redundancy (raidz/mirror) for data protection
As of 2023, ZFS on Linux (ZoL) fully supports native encryption through the OpenZFS 2.0+ implementation. This capability was introduced in ZoL 0.8.0 and has matured significantly. Unlike LUKS-based solutions, native ZFS encryption provides:
- Per-dataset encryption granularity
- Transparent encryption during zfs send/receive operations
- Key rotation without re-encrypting data
- Inheritable encryption properties
For users still on older ZoL versions without encryption support, the traditional workaround was:
# Suboptimal zVol approach (avoid if possible)
zfs create -V 10G pool/encrypted_vol
cryptsetup luksFormat /dev/zvol/pool/encrypted_vol
mkfs.ext4 /dev/mapper/encrypted_backup
The native ZFS encryption approach is superior because:
- Maintains ZFS features (compression, checksums, snapshots)
- Allows encrypted raw sends:
zfs send -w pool/encrypted@snap
- Supports multiple encryption algorithms (aes-256-gcm preferred)
Creating an encrypted dataset for secure backups:
# Create encrypted dataset with passphrase
zfs create -o encryption=aes-256-gcm -o keyformat=passphrase \
-o keylocation=prompt pool/secure_backups
# Verify encryption status
zfs get encryption,keylocation,keyformat pool/secure_backups
# Send encrypted snapshot to untrusted backup server
zfs snapshot pool/secure_backups@initial
zfs send -w pool/secure_backups@initial | ssh backup-server "zfs recv backup_pool/restored"
For production environments, consider these robust approaches:
# Using keyfiles instead of passphrases
dd if=/dev/urandom of=/etc/zfs/keys/backup.key bs=32 count=1
chmod 400 /etc/zfs/keys/backup.key
zfs create -o encryption=aes-256-gcm -o keyformat=raw \
-o keylocation=file:///etc/zfs/keys/backup.key pool/prod_data
For automated systems, implement PKCS#11 token integration via:
zfs set keylocation=pkcs11:token=backup_token;object=zfs_key pool/prod_data
Common issues and solutions:
- Error: "cannot receive encrypted filesystem unencrypted" - Add
-o encryption=off
to zfs receive for decrypted targets - Permission denied on keyfiles - Ensure zfs-import-cache.service has access to /etc/zfs/keys
- Performance overhead - Use aes-gcm instead of cbc modes for modern CPUs