zfs
zfs copied to clipboard
Autounlock ZFS Encrypted Root Filesystems using TPM 2.0
Motivation and Context
Presently, native encryption of a ZFS root filesystem requires a passphrase or keyfile to be available every boot. A TPM 2.0 chip has the ability to store and release data, if certain criteria are met. This PR provides an optional method, which allows TPM 2.0 to be used to automatically unlock the filesystem, without user intervention.
This is a DRAFT PR to foster discussion surrounding the method. THIS MAY NOT CONFORM TO STYLE GUIDES OR EVEN GOOD CODING PRACTICES. Code nit comments are not unwelcome, but methodology is the initial goal.
Description
This PR does the following:
- Within zfs's initramfs hooks, detects and copies needed tpm2-tools 4.x+ to the initrd
- Provides zfs initramfs's script a method of detecting and unlocking using TPM2 tools
- If TPM2 unlock is not successful, allows Initramfs to fallback to other manual passphrase methods
- Stores required (and user definable) unlocking variables in the encryption root using
org.openzfs.tpm2:indexandorg.openzfs.tpm2:pcrs - Provides a utility that maintains the TPM and the above zfs properties
- The zfs passphrase is locked within the TPM's nvram, and only releasable with an expected PCR state and password (GUID used to confirm encrypted filesystem match)
- The nvram region of the TPM is locked from further reading following the retrieval of the password within the initramfs script, preventing even root users access to the password post-boot.
Quick (and probably correctish) PCR usage:
PCR - Use
0 - Bios/Platform Code
1 - Bios/Platform Config
2 - Option Rom / UEFI Driver Code
3 - Option Rom / UEFI Config Data
4 - Bootloader code (GPT), boot attempts?
5 - Bootloader data
6 - Manufacturer use / wake events?
7 - Manufacturer use / Secureboot policy
8 - Grub 2.04 - Grub, Kernel, and Module Commands
9 - Grub 2.04 - ANY file read by Grub (includes kernel and initrd)
10 - Linux Integrity Measurement Architecture (IMA)
1-7 Hardware
8+ Operating System
How Has This Been Tested?
Tpm-tools 4.x revamped its arguments. Grub 2.04 is secure boot compatible and now reports additional boot time measurements that could harden the boot protections. Therefore, this has been developed and tested solely on Ubuntu Focal pre-release (to be 20.04 LTS) on Dell TPM 2.0 hardware using UEFI boot. Testing different distros, kernels, and hardware TPM devices need to be conducted.
Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Performance enhancement (non-breaking change which improves efficiency)
- [ ] Code cleanup (non-breaking change which makes code smaller or more readable)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation (a change to man pages or other documentation)
Checklist:
- [ ] My code follows the ZFS on Linux code style requirements.
- [ ] I have updated the documentation accordingly.
- [X] I have read the contributing document.
- [ ] I have added tests to cover my changes.
- [ ] I have run the ZFS Test Suite with this change applied.
- [ ] All commit messages are properly formatted and contain
Signed-off-by.
Things to Explore / Current Status (will be edited over time)
- Dracut integration
- Include kernel commandline
panic=5monitoring/injection to prevent snooping from the initrd prompt - Consider updating TPM within the initrd, following autounlock failure, but successful manual entry (ie. after kernel/initrd updates)
- Documentation of TPM PCRs
- Consider the ability to use keyfiles (recovery method must match what is in the TPM)
- Prove functionality on other platforms
Resources
Tpm2-tools man pages Grub manual (specifically Measured Boot Section) UEFI PCR explanation on Pg. 2 Another PCR description on 4th page
Codecov Report
Merging #9852 into master will decrease coverage by
0.42%. The diff coverage isn/a.
@@ Coverage Diff @@
## master #9852 +/- ##
==========================================
- Coverage 79.81% 79.39% -0.43%
==========================================
Files 395 385 -10
Lines 125087 121481 -3606
==========================================
- Hits 99836 96444 -3392
+ Misses 25251 25037 -214
| Flag | Coverage Δ | |
|---|---|---|
| #kernel | 79.66% <ø> (-0.73%) |
:arrow_down: |
| #user | 66.77% <ø> (+0.82%) |
:arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
| Impacted Files | Coverage Δ | |
|---|---|---|
| module/os/linux/spl/spl-vmem.c | 54.16% <0.00%> (-45.84%) |
:arrow_down: |
| lib/libzpool/util.c | 76.04% <0.00%> (-20.17%) |
:arrow_down: |
| module/os/linux/spl/spl-kmem-cache.c | 75.31% <0.00%> (-14.78%) |
:arrow_down: |
| include/os/linux/zfs/sys/trace_arc.h | 85.71% <0.00%> (-14.29%) |
:arrow_down: |
| module/zfs/zrlock.c | 86.15% <0.00%> (-10.57%) |
:arrow_down: |
| module/zfs/zfs_onexit.c | 76.19% <0.00%> (-9.86%) |
:arrow_down: |
| module/zfs/aggsum.c | 93.02% <0.00%> (-6.98%) |
:arrow_down: |
| lib/libtpool/thread_pool.c | 53.00% <0.00%> (-5.68%) |
:arrow_down: |
| module/os/linux/spl/spl-err.c | 30.55% <0.00%> (-5.56%) |
:arrow_down: |
| lib/libzfs/os/linux/libzfs_mount_os.c | 63.71% <0.00%> (-5.16%) |
:arrow_down: |
| ... and 254 more |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update 417e646...d72c06d. Read the comment docs.
I want to thank @williamcroberts for taking the time to look at this. He is a regular voice on the tpm2 mailing list ([email protected]) and has been a great resource to me as I explored tpm2-tools.
The existing precedent is for org.open-zfs (with a dash) for property names.
Half of this code should probably be rewritten as a Clevis PIN or simply discarded, since Clevis already ships with (reviewed) TPM 2.0 support. The other half should be added to Clevis so that Clevis learns how to unlock ZFS datasets. If added to Clevis / upstreamed as a PIN, it will work across all distributions.
https://github.com/latchset/clevis
EDIT: someone already started to use Clevis to do exactly this: https://www.reddit.com/r/zfs/comments/dimtjv/guide_setting_up_tpm2based_decryption_for_zfs_on/
To follow up on using Clevis for TPM support to unlock encryptionroots, there are now also this issue and this PR available at upstream:
- https://github.com/latchset/clevis/issues/218
- https://github.com/latchset/clevis/pull/373
Half of this code should probably be rewritten as a Clevis PIN or simply discarded, since Clevis already ships with (reviewed) TPM 2.0 support. The other half should be added to Clevis so that Clevis learns how to unlock ZFS datasets. If added to Clevis / upstreamed as a PIN, it will work across all distributions.
https://github.com/latchset/clevis
EDIT: someone already started to use Clevis to do exactly this: https://www.reddit.com/r/zfs/comments/dimtjv/guide_setting_up_tpm2based_decryption_for_zfs_on/
This is being done by @techhazard already, not sure why the repetition of efforts, but he has a working pull request AFAIK (for Clevis).