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 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: `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. > 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. 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 # ZFS setup explained
The ZFS pool and dataset setup that makes this tick, explained in plain English. The ZFS pool and dataset setup that makes this tick, explained in plain English.