1-get-initial-setup-working #2

Merged
hygienic-books merged 92 commits from 1-get-initial-setup-working into main 2023-03-05 03:02:48 +00:00
Showing only changes of commit bfc6f814ef - Show all commits

View File

@ -93,7 +93,7 @@ Lastly ZFSBootMenu loads our OS' kernel and initramfs combination via `kexec`. F
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 generates the master key exactly once when you enable encryption on a dataset. 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. 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.
`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.
@ -104,6 +104,66 @@ On one hand changing the ZFS encryption password is generally a good and useful
By extension this means after a password change your data remains at risk until you've copied it to a new dataset and erased previously used space thereby erasing any previous wrapped master keys.
## Changing master key
In order to generate a new master key after you've changed your user key as mentioned in `man 8 zfs-change-key` from `zfs-utils` version 2.1.9 one example workflow goes like this:
1. Change user key
- Update `/etc/zfs/zpool.key`
- Generate new initramfs with `mkinitcpio -P`
1. Create a snapshot from current system dataset
```
# Assuming current system dataset is zpool/root/archlinux-sxu
# where '-sxu' is a random suffix to differentiate datasets
# and has no real meaning
zfs snapshot zpool/root/archlinux-sxu@rekey
```
1. Within same pool `send`/`receive` snapshot
```
zfs send \
--large-block \
--compressed \
'zpool/root/archlinux-sxu@rekey' | \
zfs receive \
-Fvu \
-o 'encryption=on' \
-o 'keyformat=passphrase' \
-o 'keylocation=file:///etc/zfs/zpool.key' \
-o 'mountpoint=/' \
-o 'canmount=noauto' \
-o 'org.zfsbootmenu:commandline=rw nowatchdog rd.vconsole.keymap=de-latin1' \
'zpool/root/archlinux-frn'
```
Explanation:
- We specifically don't `zfs send -R` (`--replicate`). While it would normally be nice to transfer all of a dataset's children at once such as all of its snapshots the `-R` argument conflicts with the `encryption` property. See [comment by Tom Caputi on GitHub openzfs/zfs issue 10507 from June 2020](https://github.com/openzfs/zfs/issues/10507#issuecomment-651162104) for details. Basically if `encryption` is set then `-R` doesn't work. We could transfer existing encryption properties with `-w`/`--raw` but we don't actually want to transfer encryption properties at all. We want them to change during transfer, see the bullet point four points down from here talking about `encryption`.
- 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 `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:
```
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.
Optionally you may want to clean up:
1. In newly keyed/reencrypted system dataset destroy its snapshot
```
zfs destroy zpool/root/archlinux-frn@rekey
```
1. Recursively destroy source dataset
```
zfs destroy -r zpool/root/archlinux-sxu
```
# ZFS setup explained
The ZFS pool and dataset setup that makes this tick, explained in plain English.