Page MenuHomeFreeBSD

D57889.id180769.diff
No OneTemporary

D57889.id180769.diff

diff --git a/documentation/content/en/books/handbook/zfs/_index.adoc b/documentation/content/en/books/handbook/zfs/_index.adoc
--- a/documentation/content/en/books/handbook/zfs/_index.adoc
+++ b/documentation/content/en/books/handbook/zfs/_index.adoc
@@ -2645,6 +2645,305 @@
`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

File Metadata

Mime Type
text/plain
Expires
Sun, Jul 5, 6:34 AM (15 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34411611
Default Alt Text
D57889.id180769.diff (15 KB)

Event Timeline