Compare commits
6 Commits
bfc6f814ef
...
9943b6c61b
Author | SHA1 | Date | |
---|---|---|---|
9943b6c61b | |||
a19adbfe28 | |||
10c9ae589f | |||
930d5f4687 | |||
60136f4807 | |||
9b11a12f4c |
25
README.md
25
README.md
@@ -63,9 +63,11 @@ After installation you're going to want to at least touch these points in your n
|
||||
|
||||
# Password change
|
||||
|
||||
After installation you're going to want to change your ZFS encryption password.
|
||||
|
||||
## Steps
|
||||
|
||||
After installation you're going to want to change your ZFS encryption password. This generally means in a running OS:
|
||||
In a running OS:
|
||||
|
||||
1. Change password in `keylocation` file, e.g. `/etc/zfs/zpool.key` or whatever other `"${zpool_name}"'.key'` file you used during setup
|
||||
1. Set this key as the new encryption key:
|
||||
@@ -83,7 +85,7 @@ After installation you're going to want to change your ZFS encryption password.
|
||||
|
||||
With your password changed in two locations (key file and initramfs) The boot process works as follows.
|
||||
|
||||
At boot time ZFSBootMenu will scan all pools that it can import for a `bootfs` property. If it only finds one pool with that property the dataset given as `bootfs` will be selected for boot with a 10-second countdown allowing manual interaction. With `bootfs` set ZFSBootMenu will not actively search through datasets for valid kernel and initramfs combinations, it'll instead accept `bootfs` as the default boot entry without entering the pool decryption passphrase.
|
||||
At boot time ZFSBootMenu will scan all pools that it can import for a `bootfs` property. If it only finds one pool with that property the dataset given as `bootfs` will be selected for boot with a 10-second countdown allowing manual interaction. With `bootfs` set ZFSBootMenu will not actively search through datasets for valid kernel and initramfs combinations, it'll instead accept `bootfs` as the default boot entry without us entering the pool decryption passphrase.
|
||||
|
||||
Upon loading into a given dataset ZFSBootMenu will attempt to auto-load the matching decryption key. In our setup this will fail because we purposely stored the encryption key inside our `zpool/root/archlinux` dataset. ZFSBootMenu will prompt us to type in the decryption key.
|
||||
|
||||
@@ -91,9 +93,9 @@ Lastly ZFSBootMenu loads our OS' kernel and initramfs combination via `kexec`. F
|
||||
|
||||
## Caveats in a password change
|
||||
|
||||
ZFS differentiates between user keys - also called wrapping keys - and the master key for any given encryption root. You never interact with the master key, you only pick your personal user key. Subsequently a user key change (in our use case we perceive this simply as a password change) has zero effect on data that's already encrypted. The operation is instant and merely reencrypted the already existing master key, the so-called _wrapped_ master key.
|
||||
ZFS differentiates between user keys - also called wrapping keys - and the master key for any given encryption root. You never interact with the master key, you only pick your personal user key. Subsequently a user key change (in our use case we perceive this simply as a password change) has zero effect on data that's already encrypted. The operation is instant and merely reencrypts the already existing master key, the so-called _wrapped_ master key.
|
||||
|
||||
ZFS generates the master key exactly once when you enable encryption on a dataset - technically when it becomes an encryption root. Among other inputs it uses your user key to encrypt (to _wrap_) the master key. So when you change your user key it just means that the master key stays exactly the same and only the encrypted (_wrapped_) key changes.
|
||||
ZFS generates the master key exactly once when you enable encryption on a dataset - technically when it becomes an encryption root. Among other inputs it uses your user key to encrypt (to _wrap_) the master key. When you change your user key it just means that the master key stays exactly the same and only the encrypted (_wrapped_) key changes.
|
||||
|
||||
`man 8 zfs-change-key` from `zfs-utils` version 2.1.9 adds:
|
||||
> If the user's key is compromised, `zfs change-key` does not necessarily protect existing or newly-written data from attack. Newly-written data will continue to be encrypted with the same master key as the existing data. The master key is compromised if an attacker obtains a user key and the corresponding wrapped master key. Currently, `zfs change-key` does not overwrite the previous wrapped master key on disk, so it is accessible via forensic analysis for an indeterminate length of time.
|
||||
@@ -110,6 +112,7 @@ In order to generate a new master key after you've changed your user key as ment
|
||||
|
||||
1. Change user key
|
||||
- Update `/etc/zfs/zpool.key`
|
||||
- Update zpool with new key via `zfs change-key -l zpool`
|
||||
- Generate new initramfs with `mkinitcpio -P`
|
||||
1. Create a snapshot from current system dataset
|
||||
```
|
||||
@@ -140,19 +143,29 @@ In order to generate a new master key after you've changed your user key as ment
|
||||
- We `zfs receive -F` destroying any target snapshots and file systems beyond the snapshot we're transferring. In this example the target `zpool/root/archlinux-frn` doesn't even exist so `-F` isn't necessary to clean anything up. It's just good practice.
|
||||
- With `-v` we get verbose progress output
|
||||
- Argument `-u` makes sure the dataset does not get mounted after transfer. ZFS would mount it into `/` which wouldn't be helpful since we're currently using that filesystem ourselves.
|
||||
- We set encryption properties `keyformat`, `keylocation` and most importantly `encryption`. The latter will turn our transferred dataset into its own `encryptionroot` which in turn generates a new master key. The auto-generated new master key gets wrapped with our updated passphrase in `keylocation`. This basically rekeys all data on our pool during transfer.
|
||||
- We set encryption properties `keyformat`, `keylocation` and most importantly `encryption`. The latter will turn our transferred dataset into its own `encryptionroot` which in turn generates a new master key. The auto-generated new master key gets wrapped with our updated passphrase in `keylocation`. This basically reencrypts all data in this dataset during transfer.
|
||||
- We set `mountpoint` and `canmount` as well as a `org.zfsbootmenu:commandline` as we would for any new system dataset.
|
||||
1. Change zpool's `bootfs` property to new system dataset
|
||||
```
|
||||
zpool set bootfs=zpool/root/archlinux-frn zpool
|
||||
```
|
||||
1. Boot into new system dataset
|
||||
1. Update the new system dataset's `encryptionroot` by letting it inherit key data from its parent:
|
||||
1. After reboot and now that you're in the new system dataset change its `encryptionroot` by letting it inherit data from its parent:
|
||||
```
|
||||
zfs change-key -i -l zpool/root/archlinux-frn
|
||||
```
|
||||
The parent `zpool/root` is inheriting this property from `zpool` which will make sure that `zpool/root/archlinux-frn` essentially gets its key now from `zpool`. Both `zpool/root/archlinux-frn` and `zpool` use the same exact `keylocation` with identical content. This operation is instant.
|
||||
|
||||
## Finishing touches
|
||||
|
||||
Just to confirm that the master key has changed run this commands. It takes a moment to output data:
|
||||
|
||||
```
|
||||
zfs send --raw zpool/root/archlinux-frn@rekey | zstream dump | sed -n -e '/crypt_keydata/,/end crypt/p; /END/q'
|
||||
```
|
||||
|
||||
Repeat for source dataset `zpool/root/archlinux-sxu@rekey`. You're particularly interested in parameters `DSL_CRYPTO_MASTER_KEY_1` and the initialization vector `DSL_CRYPTO_IV`. Notice that they differ between old and new dataset confirming that your new dataset has a new master key.
|
||||
|
||||
Optionally you may want to clean up:
|
||||
|
||||
1. In newly keyed/reencrypted system dataset destroy its snapshot
|
||||
|
Reference in New Issue
Block a user