git: d020202567 - main - Revert "handbook/zfs: Add new section about ZFS native encryption"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 26 Jun 2026 19:09:57 UTC
The branch main has been updated by bcr:
URL: https://cgit.FreeBSD.org/doc/commit/?id=d020202567aa62090adf23d27862749d1f81ce11
commit d020202567aa62090adf23d27862749d1f81ce11
Author: Benedict Reuschling <bcr@FreeBSD.org>
AuthorDate: 2026-06-26 19:09:36 +0000
Commit: Benedict Reuschling <bcr@FreeBSD.org>
CommitDate: 2026-06-26 19:09:36 +0000
Revert "handbook/zfs: Add new section about ZFS native encryption"
This reverts commit 9ddc2f8625bf8d59738c10c1370ba03eac0677af.
Not approved yet.
---
.../content/en/books/handbook/zfs/_index.adoc | 299 ---------------------
1 file changed, 299 deletions(-)
diff --git a/documentation/content/en/books/handbook/zfs/_index.adoc b/documentation/content/en/books/handbook/zfs/_index.adoc
index 607d905fb8..e1738f9716 100644
--- a/documentation/content/en/books/handbook/zfs/_index.adoc
+++ b/documentation/content/en/books/handbook/zfs/_index.adoc
@@ -2645,305 +2645,6 @@ Another restriction aimed at preventing abuse: non-`root` users must own the mou
`zfs allow _someuser_ allow _mydataset_` gives the specified user the ability to assign any permission they have on the target dataset, or its children, to other users.
If a user has the `snapshot` permission and the `allow` permission, that user can then grant the `snapshot` permission to other users.
-[[zfs-native-encryption]]
-== ZFS Native Encryption
-
-ZFS supports native encryption of datasets and the data stored within them.
-This was not always the case, as previous solutions relied on FreeBSD's GELI-based encryption.
-While this approach is secure, it was not as easily portable to non-FreeBSD systems that lacked GELI support.
-With ZFS native encryption, encrypted datasets can be used on other systems that support this pool feature without relying on third-party components or operating system-native encryption.
-
-Another benefit of ZFS native encryption is that datasets do not need to be decrypted for administrative tasks such as snapshots, replication, or scrub operations.
-ZFS data integrity checks work just as well with natively encrypted datasets, and compression also works encrypted datasets.
-
-Different datasets on the same pool can use separate keys independently.
-Consider a central file server where different users store their data in encrypted home datasets.
-User A has a different key than User B.
-Both users can work side by side and choose to unencrypt their datasets as needed without knowing each other's decryption keys.
-The decryption method can also differ completely between users without affecting one another.
-This allows sensitive data from different users to be stored on the same pool while remaining protected by separate keys.
-
-Before using ZFS native encryption, be aware of the following:
-
-- Encryption is applied at the dataset level, not the pool level.
-- Booting from encrypted ZFS pools is not yet supported on FreeBSD.
-- Encryption can only be enabled when a dataset is created, not afterward.
-- The block cipher, key length, and encryption mode can not be changed after they have been set.
-- ZFS does not encrypt metadata.
-
-The last point may seem like a drawback compared to full-disk encryption.
-However, it provides greater flexibility by allowing different keys to protect datasets within the same pool instead of requiring a single key or passphrase to unlock the entire pool.
-Specifically, ZFS encrypts the following:
-
-* file and zvol data,
-* file attributes,
-* ACLs,
-* permission bits,
-* directory listings,
-* FUID mappings,
-* userused/groupused data, and
-* deduplicated data
-
-Some ZFS metadata and information remains unencrypted, including the following:
-
-* pool structure and name,
-* dataset and snapshot names,
-* dataset hierarchy,
-* properties,
-* file size,
-* file holes, and
-* deduplication tables
-
-This unencrypted metadata allows ZFS to perform routine maintenance operations, such as `zfs scrub`, without first decrypting the data.
-As a result, ZFS can detect and repair corrupted encrypted data that is encrypted data without accessing the unencrypted file contents.
-
-To encrypt existing unencrypted data, copy it to a dataset with encryption enabled.
-This allows data to be migrated to a secure location within the pool, provided the passphrase is supplied to authorize access.
-Typically, this is done by loading the encryption key into memory after confirming knowledge of a secret such as a passphrase.
-Once the key has been loaded, the dataset contents become accessible for reading and writing.
-To re-secure the dataset, unload the key from memory.
-ZFS then makes the dataset inaccessible until the key is loaded again.
-
-When encryption is enabled, some ZFS operations behave differently.
-ZFS applies compression before encryption to preserve compression ratios.
-While ZFS normally uses 256-bit checksums, encryption replaces them with a 128-bit checksum and a 128-bit Message Authentication Code (MAC) provided by the encryption suite.
-This provides additional protection against malicious data modification.
-
-When deduplication is used together with encryption, ZFS performs deduplication only within the encrypted dataset, its snapshots, and its clones.
-This prevents information from leaking between encrypted datasets.
-The tradeoff is lower deduplication efficiency because ZFS cannot compare checksums across the entire pool.
-Even so, deduplication combined with encryption still reveals which blocks are identical and incurs additional CPU overhead for each block written.
-
-Other limitations apply when using ZFS encryption.
-The `embedded_data` feature cannot be used with encryption.
-Datasets with encryption enabled also cannot have the `copies` property set to 3, because the implementation stores encrypted metadata in the location where the third copy would normally reside.
-
-[[zfs-encrypted-dataset-creation]]
-=== Creating an encrypted dataset
-
-ZFS encryption is enabled by setting the `encryption=on` property when creating a dataset.
-Setting this property outside of a `zfs create` command does not enable encryption retroactively, as it only takes effect during dataset creation.
-In the following example, a passphrase is used when mounting the encrypted dataset after it has been created.
-
-[source,shell]
-....
-# zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt zroot/secretdata
-Enter passphrase:
-Re-enter passphrase:
-....
-
-If the passphrase is shorter than eight characters, ZFS rejects it and does not create the dataset.
-After the passphrase has been entered correctly twice, ZFS creates and mounts the dataset in the pool.
-
-Any data stored in the encrypted dataset remains encrypted while it resides there.
-Copying data from an encrypted dataset to an unencrypted location decrypts the data during the copy operation.
-The newly created dataset can then be mounted at a different location if necessary.
-
-[source,shell]
-....
-# zfs set mountpoint=/secretdata zroot/secretdata
-# echo "Hello FreeBSD!" > /secretdata/message
-# cat /secretdata/message
-Hello FreeBSD!
-....
-
-As expected, the data is currently available for reading and writing by anyone who has access to the dataset.
-
-[[zfs-encrypted-dataset-properties]]
-=== Properties of encrypted datasets
-
-Listing the ZFS native encryption properties for a dataset is done with the following command:
-
-[source,shell]
-....
-# zfs get encryption,keylocation,keyformat zroot/secretdata
-NAME PROPERTY VALUE SOURCE
-mypool/secretdata encryption aes-256-gcm -
-mypool/secretdata keylocation prompt local
-mypool/secretdata keyformat passphrase -
-....
-
-The `encryption` property shows `aes-256-gcm`, which is currently the default encryption method used by ZFS.
-As indicated by the `SOURCE` column, neither this property nor the `keyformat` property can be changed using `zfs set` after the dataset has been created.
-See the crossref:zfs-change-encryption-key[zfs-change-encryption-key, changing the encryption key] section for information on how to modify some of these properties.
-The following table lists the encryption-related properties used by ZFS:
-
-[.informaltable]
-[cols="10%,90%"]
-|===
-
-|[[zfs-term-encryptionroot]]encryptionroot
-|The dataset from which the current dataset inherits its encryption key.
-Dataset clones share the encryption key of their originating dataset.
-
-|[[zfs-term-keyformat]]keyformat
-a|The format of the encryption key. Possible values are: `raw`, `hex`, and `passphrase`. Both `raw` and `hex` keys must be 32 bytes long and contain random values.
-|[[zfs-term-encryption]]encryption
-a|The cipher used for encryption, consisting of the block cipher, key length, and encryption mode. Both the `encryption` and `keyformat` properties must be specified when the dataset is created. Possible values for the `encryption` property are:
-
- * `off` (default),
- * `on`,
- * `aes-128-ccm`,
- * `aes-192-ccm`,
- * `aes-256-ccm`,
- * `aes-128-gcm`,
- * `aes-192-gcm`, and
- * `aes-256-gcm` (current standard when `on` is set).
-
-This property cannot be changed once it has been set.
-
-|[[zfs-term-keystatus]]keystatus
-a|Indicates whether an encryption key has been successfully loaded. Possible values are `none`, `available`, and `unavailable`.
-
-|[[zfs-term-keylocation]]keylocation
-a|Specifies the location from which to load the encryption key. Possible values are:
-
-* `prompt`,
-* `file://path/to/file`,
-* `http://some.address`, and
-* `https://other.address`
-
-|[[zfs-term-pbkdf2iters]]pbkdf2iters
-a|The number of iterations used when deriving an encryption key from a passphrase. This forces an attacker to perform a large number of computationally expensive hash operations. As computing power increases, this value should also be increased from its current default of 350000.
-|===
-
-[[zfs-unload-encryption-key]]
-=== Unloading the encryption key
-
-Protecting the data stored in an encrypted dataset requires two steps: first unmount the dataset, then unload the encryption key from memory.
-This distinction is important.
-An unmounted dataset is not protected if its encryption key remains loaded in memory.
-Always run `zfs unload-key` to protect the data.
-To access the dataset again, load the key and provide the passphrase as described in the crossref:zfs-load-encryption-key[zfs-load-encryption-key, loading the encryption key] section.
-ZFS prevents `zfs unload-key` from running while the dataset is still mounted.
-
-[source,shell]
-....
-# zfs unmount zroot/secretdata
-# zfs unload-key zroot/secretdata
-....
-
-Running `zfs unload-key` multiple times results in an error indicating that the key has already been unloaded.
-
-[[zfs-load-encryption-key]]
-=== Loading the encryption key
-
-Before an encrypted dataset can be used like any other dataset, its encryption key must be loaded and the passphrase provided.
-At this point, the `keystatus` property is still set to `unavailable`, and mounting the dataset fails because the key has not yet been loaded:
-
-[source,shell]
-....
-# zfs get keystatus zroot/secretdata
-NAME PROPERTY VALUE SOURCE
-zroot/secretdata keystatus unavailable -
-# zfs mount zroot/secretdata
-cannot mount 'zroot/secretdata': encryption key not loaded
-....
-
-This indicates that the dataset is encrypted and requires an encryption key.
-To mount the dataset, run `zfs load-key` and provide the passphrase when prompted:
-
-[source,shell]
-....
-# zfs load-key zroot/secretdata
-Enter passphrase for 'zroot/secretdata':
-# zfs get keystatus zroot/secretdata
-NAME PROPERTY VALUE SOURCE
-zroot/secretdata keystatus available -
-....
-
-Next, mount the dataset to make it accessible through the filesystem hierarchy:
-
-[source,shell]
-....
-# zfs mount zroot/secretdata
-# mount|grep secretdata
-zroot/secretdata on /secretdata (zfs, local, noatime, nfsv4acls)
-....
-
-To load multiple encryption keys recursively, specify the `-r` option with `zfs load-key`.
-If a key has already been loaded, ZFS reports this with an error message.
-
-[source,shell]
-....
-# zfs load-key zroot/secretdata
-Key load error: Key already loaded for 'zroot/secretdata'.
-....
-
-The `keystatus` property also confirms that the key has been loaded by reporting the value `available`.
-To verify whether a passphrase is correct without loading the key, use the `-n` option to perform a dry run.
-
-[[zfs-change-encryption-key]]
-=== Changing the encryption key
-
-ZFS also supports changing encryption keys, such as replacing a passphrase.
-This operation does not require re-encrypting the dataset.
-Run the following command to change the encryption passphrase:
-
-[source,shell]
-....
-# zfs change-key zroot/secretdata
-Enter new passphrase for 'zroot/secretdata':
-Re-enter new passphrase for 'zroot/secretdata':
-....
-
-Running `zfs change-key` requires the current key to be loaded. If it is not,
-ZFS still prompts for the new key but then displays a warning that the current key has not been loaded.
-
-The zfs change-key command can also modify the `keylocation`, `keyformat`, and `pbkdf2iters` properties by specifying them with the `-o` option.
-Running `zfs change-key` on an encrypted child dataset makes it an encryption root if it is not one already.
-To prevent this behavior and continue inheriting the parent's key, specify the `-i` option.
-
-Be aware that changing the encryption key of a parent dataset also changes the key for child datasets that inherit it.
-Consequently, those child datasets continue to use the parent's encryption key.
-If a child dataset should use a different key, either specify a different `keyformat` when creating it or run `zfs change-key` on the child dataset.
-Doing so creates a new encryption root for the child and breaks its encryption inheritance from the parent.
-
-ZFS clones of an encrypted dataset always use the encryption key of their origin dataset.
-As a result, the `keystatus`, `keyformat`, `keylocation`, and `pbkdf2iters` properties are not inherited like other dataset properties.
-Instead, they use the values defined by the encryption root.
-To determine the encryption root, use the read-only `encryptionroot` property.
-
-If an attacker compromises an encryption key, changing the passphrase with `zfs change-key` does not necessarily protect existing or newly written data.
-New data continues to be encrypted with the same master key as the existing data.
-If an attacker obtains both a user key and its corresponding wrapped master key, running `zfs change-key` does not overwrite the previous master key on disk.
-As a result, the old master key may remain available for forensic analysis for an indeterminate period.
-
-If a master key has been compromised, the preferred solution is to securely erase the underlying storage devices and create a new pool.
-Afterwards, restore the data from a backup to the new pool.
-Alternatively, create a new encrypted dataset, migrate the data using `zfs send` and `zfs receive`, and then run `zpool trim --secure` to erase the freed space.
-If the underlying hardware does not support secure TRIM, use `zpool initialize` instead.
-
-[[zfs-encrypted-send]]
-=== Sending Encrypted Datasets
-
-ZFS replication is based on sending dataset snapshots, which can also be created from encrypted datasets.
-The resulting snapshots remain encrypted.
-
-[source,shell]
-....
-# zfs snapshot zroot/secretdata@snap1
-....
-
-In addition to crossref:zfs-load-encryption-key[zfs-send-ssh, sending encrypted backups over SSH], using the `-w` (raw) option with `zfs send` transfers the encrypted data blocks to the target pool.
-A raw send provides several advantages:
-
-* the receiving system never sees plaintext data.
-* the receiving system does not require the passphrase since no decryption takes place.
-* Backups can be sent without first loading the encryption key.
-* an untrusted system can receive the encrypted data but cannot decrypt or modify it without the encryption key.
-
-To send the snapshot created above as a raw stream to the dataset `secret` in the pool `backup`, enter the following command:
-
-[source,shell]
-....
-# zfs send -w zroot/secretdata@snap1 | zfs recv backup/secret
-....
-
-Without the `-w` option, `zfs send` transmits the data in unencrypted form.
-The receiving system may then re-encrypt the data using a different key.
-However, doing so prevents future incremental raw sends to that destination.
-
[[zfs-advanced]]
== Advanced Topics