System information
| Type |
Version/Name |
| Distribution Name |
Ubuntu |
| Distribution Version |
20.04 |
| Linux Kernel |
5.4.0-72-generic |
| Architecture |
x86_64 |
| ZFS Version |
0.8.3-1ubuntu12.7 |
| SPL Version |
0.8.3-1ubuntu12.6 |
Describe the problem you're observing
Following up from #6624 and #9273 it happens that a certain Long-Term Support release from Ubuntu that natively ships with ZFS 0.8.1 (meanwhile updated to 0.8.3) can still produce datasets that have a broken encryption hierarchy, despite all appears to be well at first.
In #6624 (comment) @tcaputi speaks of:
I can probably provide you some code for a small binary that will call the FORCE NEW KEY command (the opposite of FORCE INHERIT) which should allow you to mount the dataset again.
Is it possible to apply this workaround in a way to restore the ability to mount the datasets? For this case, let's consider the source is not available anymore for retransmission. This is due to a juggling of datasets for downsizing a pool in a mirrored setup, where the source has been replaced by a smaller version of itself.
Two things are odd here:
- The dataset seems to have a valid encryption key and states its key to be available
encryptionroot is a read-only value. How is it possible to re-set it?
Describe how to reproduce the problem
- create two encrypted zpools and fill the first datasets
- recursively snapshot the first pool
- raw send the first level of datasets into the second pool w/ stripping the name of the source
- recreate the first pool (destroy, create)
- raw send the first level of datasets into the first pool
- the datasets at the target are not mountable
Messages from the logs
zpool create -o ashift=12 -o autotrim=on -O atime=off -O dedup=off -O compression=lz4 -O acltype=posixacl -O xattr=sa -O normalization=formD -O dnodesize=auto -O encryption=on -O keyformat=passphrase -O keylocation=prompt -m /pool1 pool1 /dev/sda3
zpool create -o ashift=12 -o autotrim=on -O atime=off -O dedup=off -O compression=lz4 -O acltype=posixacl -O xattr=sa -O normalization=formD -O dnodesize=auto -O encryption=on -O keyformat=passphrase -O keylocation=prompt -m /pool2 pool2 /dev/sdb3
zfs create pool1/test
zfs create pool1/test/temp
zfs snapshot -r pool1@snap
zfs send -Rw pool1/test@snap | zfs recv -d pool2
zpool destroy pool1
cfdisk /dev/sda # to downsize the partition
zpool create ... pool1 /dev/sda3
zfs send -Rw pool2/test@snap | zfs recv -d pool1
$ zfs get encryption,encryptionroot,keystatus pool1
NAME PROPERTY VALUE SOURCE
pool1 encryption aes-256-gcm -
pool1 encryptionroot pool1 -
pool1 keystatus available -
$ zfs get encryption,encryptionroot,keystatus pool1/test
NAME PROPERTY VALUE SOURCE
pool1/test encryption aes-256-gcm -
pool1/test encryptionroot pool1 -
pool1/test keystatus available -
$ zfs load-key pool1
Key load error: Key already loaded for 'pool1'.
$ zfs load-key pool1/test
Key load error: Keys must be loaded for encryption root of 'pool1/test' (pool1).
$ zfs mount pool1/test
filesystem 'pool1/test' can not be mounted: Permission denied
cannot mount 'pool1/test': Invalid argument
Additional information
This is also discussed in:
Interestingly running zfs load-key -r pool1 will not try to load the keys for the datasets for which keys are available (via their encryption root pool1), yet still they remain unmountable. Also some of the descendent encryption roots that Docker apparently created are decryptable, but others aren't. This gives hope, next to the key not being rejected for the other datasets, that all USERDATA is still available and recoverable.
Some datasets decrypt, others don't, especially from Docker.
$ zpool export pool1
$ zpool import -l pool1
Enter passphrase for 'pool1':
Enter passphrase for 'pool1/DOCKER/lib/697917a208c21f64616d09db164318acd0f20e4d1fffa7e4e66f8de95fa47bb2':
Enter passphrase for 'pool1/DOCKER/lib/79944167f45fa8346086f0ff167a2d423bdb4f7d9ded72e9c401f64a15e49ac8':
Enter passphrase for 'pool1/DOCKER/lib/33a48ff62d295e54f5d83675ad75b833f75713a7c3d7b56a89c69b08aceb9d0f':
Enter passphrase for 'pool1/DOCKER/lib/1fb15fd5d836f0dbbe60645d532f4a13225704f790d64510e5785e841a6a9dfb':
Enter passphrase for 'pool1/DOCKER/lib/f9bc3e5084268da84adc5a2e17e5f894dd1b3d7e5c8ac9bc7f947ce30c4c8a40':
Enter passphrase for 'pool1/DOCKER/lib/130b413032e79c2a252a83dc7226f3f4106536074c2cc7c2729dc85e2959712a':
Enter passphrase for 'pool1/DOCKER/lib/eae4f3bd5bea07d25f88c7fc2ffd6324b595ea067162e6ed67d0c5f16097dd56':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/eae4f3bd5bea07d25f88c7fc2ffd6324b595ea067162e6ed67d0c5f16097dd56'.
Enter passphrase for 'pool1/DOCKER/lib/eae4f3bd5bea07d25f88c7fc2ffd6324b595ea067162e6ed67d0c5f16097dd56':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/eae4f3bd5bea07d25f88c7fc2ffd6324b595ea067162e6ed67d0c5f16097dd56'.
Enter passphrase for 'pool1/DOCKER/lib/eae4f3bd5bea07d25f88c7fc2ffd6324b595ea067162e6ed67d0c5f16097dd56':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/eae4f3bd5bea07d25f88c7fc2ffd6324b595ea067162e6ed67d0c5f16097dd56'.
Enter passphrase for 'pool1/DOCKER/lib/683b04ac797d220ea673d705db7246e9254cb24f5f14171f251b3e45012cb93b':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/683b04ac797d220ea673d705db7246e9254cb24f5f14171f251b3e45012cb93b'.
Enter passphrase for 'pool1/DOCKER/lib/683b04ac797d220ea673d705db7246e9254cb24f5f14171f251b3e45012cb93b':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/683b04ac797d220ea673d705db7246e9254cb24f5f14171f251b3e45012cb93b'.
Enter passphrase for 'pool1/DOCKER/lib/683b04ac797d220ea673d705db7246e9254cb24f5f14171f251b3e45012cb93b':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/683b04ac797d220ea673d705db7246e9254cb24f5f14171f251b3e45012cb93b'.
Enter passphrase for 'pool1/DOCKER/lib/291c9a86a0bfdcd8546cff5b6edf7805f6cd548f04ae799ffbea333faf18c8b2':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/291c9a86a0bfdcd8546cff5b6edf7805f6cd548f04ae799ffbea333faf18c8b2'.
Enter passphrase for 'pool1/DOCKER/lib/291c9a86a0bfdcd8546cff5b6edf7805f6cd548f04ae799ffbea333faf18c8b2':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/291c9a86a0bfdcd8546cff5b6edf7805f6cd548f04ae799ffbea333faf18c8b2'.
Enter passphrase for 'pool1/DOCKER/lib/291c9a86a0bfdcd8546cff5b6edf7805f6cd548f04ae799ffbea333faf18c8b2':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/291c9a86a0bfdcd8546cff5b6edf7805f6cd548f04ae799ffbea333faf18c8b2'.
Enter passphrase for 'pool1/DOCKER/lib/968ecf6144a9ac309982de243e23e0bc782f77fd68941248b5f3c827463e5368':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/968ecf6144a9ac309982de243e23e0bc782f77fd68941248b5f3c827463e5368'.
Enter passphrase for 'pool1/DOCKER/lib/968ecf6144a9ac309982de243e23e0bc782f77fd68941248b5f3c827463e5368':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/968ecf6144a9ac309982de243e23e0bc782f77fd68941248b5f3c827463e5368'.
Enter passphrase for 'pool1/DOCKER/lib/968ecf6144a9ac309982de243e23e0bc782f77fd68941248b5f3c827463e5368':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/968ecf6144a9ac309982de243e23e0bc782f77fd68941248b5f3c827463e5368'.
Enter passphrase for 'pool1/DOCKER/lib/dc45835eb73741e53f87fc316342fae82a41f2c7421714ebefc6a2d5b04cebbb':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/dc45835eb73741e53f87fc316342fae82a41f2c7421714ebefc6a2d5b04cebbb'.
Enter passphrase for 'pool1/DOCKER/lib/dc45835eb73741e53f87fc316342fae82a41f2c7421714ebefc6a2d5b04cebbb':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/dc45835eb73741e53f87fc316342fae82a41f2c7421714ebefc6a2d5b04cebbb'.
Enter passphrase for 'pool1/DOCKER/lib/dc45835eb73741e53f87fc316342fae82a41f2c7421714ebefc6a2d5b04cebbb':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/dc45835eb73741e53f87fc316342fae82a41f2c7421714ebefc6a2d5b04cebbb'.
Enter passphrase for 'pool1/DOCKER/lib/3071a1943c5d067abbfea06ff3721dd6aac6ff56c25ad83c9a65281a115326bc':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/3071a1943c5d067abbfea06ff3721dd6aac6ff56c25ad83c9a65281a115326bc'.
Enter passphrase for 'pool1/DOCKER/lib/3071a1943c5d067abbfea06ff3721dd6aac6ff56c25ad83c9a65281a115326bc':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/3071a1943c5d067abbfea06ff3721dd6aac6ff56c25ad83c9a65281a115326bc'.
Enter passphrase for 'pool1/DOCKER/lib/3071a1943c5d067abbfea06ff3721dd6aac6ff56c25ad83c9a65281a115326bc':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/3071a1943c5d067abbfea06ff3721dd6aac6ff56c25ad83c9a65281a115326bc'.
Enter passphrase for 'pool1/DOCKER/lib/52bfa76983a9904e7e3cfbc911c1c2e0e92d69ee26467e46f002a8de614dc6d9':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/52bfa76983a9904e7e3cfbc911c1c2e0e92d69ee26467e46f002a8de614dc6d9'.
Enter passphrase for 'pool1/DOCKER/lib/52bfa76983a9904e7e3cfbc911c1c2e0e92d69ee26467e46f002a8de614dc6d9':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/52bfa76983a9904e7e3cfbc911c1c2e0e92d69ee26467e46f002a8de614dc6d9'.
Enter passphrase for 'pool1/DOCKER/lib/52bfa76983a9904e7e3cfbc911c1c2e0e92d69ee26467e46f002a8de614dc6d9':
Key load error: Incorrect key provided for 'pool1/DOCKER/lib/52bfa76983a9904e7e3cfbc911c1c2e0e92d69ee26467e46f002a8de614dc6d9'.
7 / 14 keys successfully loaded
filesystem 'pool1/DOCKER/lib' can not be mounted: Permission denied
cannot mount 'pool1/DOCKER/lib': Invalid argument
filesystem 'pool1/USERDATA/bases' can not be mounted: Permission denied
cannot mount 'pool1/USERDATA/bases': Invalid argument
filesystem 'pool1/USERDATA/lake' can not be mounted: Permission denied
cannot mount 'pool1/USERDATA/lake': Invalid argument
filesystem 'pool1/BACKUP/bases' can not be mounted: Permission denied
cannot mount 'pool1/BACKUP/bases': Invalid argument
filesystem 'pool1/ROOT/system' can not be mounted: Permission denied
cannot mount 'pool1/ROOT/system': Invalid argument
filesystem 'pool1/ROOT/shell' can not be mounted: Permission denied
cannot mount 'pool1/ROOT/shell': Invalid argument
Further mentions of similar behaviours are:
Following on from #6847 (comment) also doesn't help in this case, where the encryption root has been replaced:
$ zfs change-key -i pool1/ROOT
Key change error: Key inheritting can only be performed on encryption roots.
$ zfs change-key -i pool1
Key change error: Root dataset cannot inherit key.
The pool itself does not report any data errors:
$ zpool status pool1
pool: pool1
state: ONLINE
scan: resilvered 11.1G in 0 days 00:00:39 with 0 errors on Wed May 5 04:23:34 2021
config:
NAME STATE READ WRITE CKSUM
pool1 ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda3 ONLINE 0 0 0
sdb3 ONLINE 0 0 0
errors: No known data errors
May it be possible to reintroduce a new encryption root for those datasets that don't mount currently, eventually by decomposing and reconstructing the pool into two and back again, or are there any other known workarounds I am not aware of, yet?
Thank you for your kind help, our users will appreciate it.
Reflection and conclusion
Reading the linked references brings up their reasoning and questioning again:
- Is it neccessary that the first level of a zpool is also a dataset in itself (that can be encrypted)?
- Is it considered harmful to directly encrypt the root dataset of a zpool imlicitly upon creation?
Which other good practices are known to omit the side effects and edge cases we produce here, other than creating independently encrypted datasets under the root dataset of the pool that act as encryption roots for their descendants, and leaving that itself unencrypted?
When trying to do send | recv -x encryption, the command output complains about a missing raw flag, while we have migrated datasets from unencrypted pools into encrypted ones before. Now this looks even more bestranging:
$ zfs send pool1/USERDATA/lake@downsize | zfs recv -x encryption pool2/TRASH/lake
warning: cannot send 'pool1/USERDATA/lake@downsize': source key must be loaded
cannot receive: failed to read from stream
$ zfs get keystatus -r pool1/USERDATA/lake
NAME PROPERTY VALUE SOURCE
pool1/USERDATA/lake keystatus available -
pool1/USERDATA/lake@downsize keystatus available -
Is the source key actually available and loaded, or is it not? From the given output of the commands, for me it is not possible to depict anymore.
Reading through zfs-receive.8 makes me guess that we now probably have different initialization vectors (IV) for the AEAD cipher in the pool1 dataset and its descendants, why recreating the encrypted zpool with the same passphrase does not mean it can act as an encryption root for its newly retrieved childs.
- Given this hypothesis is true; would it be possible to extract and reintroduce the IV from the child datasets to the new encryption root, and allow the key (= passphrase + random IV?) to decrypt all datasets again?
- In replicating only descendant datasets below a the zpool's root dataset that also acted as encryption root, did I accidentally omit to also transfer the salt that is used and needed to derive the encryption key from the passphrase?
System information
Describe the problem you're observing
Following up from #6624 and #9273 it happens that a certain Long-Term Support release from Ubuntu that natively ships with ZFS 0.8.1 (meanwhile updated to 0.8.3) can still produce datasets that have a broken encryption hierarchy, despite all appears to be well at first.
In #6624 (comment) @tcaputi speaks of:
Is it possible to apply this workaround in a way to restore the ability to mount the datasets? For this case, let's consider the source is not available anymore for retransmission. This is due to a juggling of datasets for downsizing a pool in a mirrored setup, where the source has been replaced by a smaller version of itself.
Two things are odd here:
encryptionrootis a read-only value. How is it possible to re-set it?Describe how to reproduce the problem
Messages from the logs
Additional information
suggests never to encrypt the primary dataset of a pool, thus the pool, but to create encrypted datasets as malleable encryption roots below
This is also discussed in:
Interestingly running
zfs load-key -r pool1will not try to load the keys for the datasets for which keys are available (via their encryption rootpool1), yet still they remain unmountable. Also some of the descendent encryption roots that Docker apparently created are decryptable, but others aren't. This gives hope, next to the key not being rejected for the other datasets, that all USERDATA is still available and recoverable.Some datasets decrypt, others don't, especially from Docker.
Further mentions of similar behaviours are:
-d-Fand also replicates encryption roots distinctivelychange-key -iIt is not possible to set a new keylocation for dependant datasets in the encryption hierarchy.
Following on from #6847 (comment) also doesn't help in this case, where the encryption root has been replaced:
The pool itself does not report any data errors:
May it be possible to reintroduce a new encryption root for those datasets that don't mount currently, eventually by decomposing and reconstructing the pool into two and back again, or are there any other known workarounds I am not aware of, yet?
Thank you for your kind help, our users will appreciate it.
Reflection and conclusion
Reading the linked references brings up their reasoning and questioning again:
Which other good practices are known to omit the side effects and edge cases we produce here, other than creating independently encrypted datasets under the root dataset of the pool that act as encryption roots for their descendants, and leaving that itself unencrypted?
When trying to do
send | recv -x encryption, the command output complains about a missing raw flag, while we have migrated datasets from unencrypted pools into encrypted ones before. Now this looks even more bestranging:Is the source key actually available and loaded, or is it not? From the given output of the commands, for me it is not possible to depict anymore.
Reading through zfs-receive.8 makes me guess that we now probably have different initialization vectors (IV) for the AEAD cipher in the
pool1dataset and its descendants, why recreating the encrypted zpool with the same passphrase does not mean it can act as an encryption root for its newly retrieved childs.