我最近在旧的 SSD 上安装了 Ubuntu,因为我想在不同的操作系统上测试一些软件。安装 Ubuntu(使用debootstrap
、arch-chroot
和apt
)后,我的 EFI 的 NVRAM 启动顺序变得混乱,TPM2 现在不会自动解锁我的 Arch 根分区和交换分区。系统提示我输入恢复密钥或密码。
因此,我知道我需要更新 TPM 中的 PCR 寄存器。但我有几个问题:
- 我应该如何替换旧 TPM2 PCR 插槽中的条目,而不是添加新的条目?
- 有人能解释一下为什么 TPM 芯片现在无法解锁我的分区吗?以及我应该尝试避免在将来再次这样做吗?
我的主要操作系统是 Arch Linux,按照以下几篇文章进行设置:
systemd-boot
用作引导加载程序。
启动时使用 TPM 解锁两个 dm-crypt 分区:
root
swap
(允许暂停和恢复)。
安装 Ubuntu 后,root
和swap
卷都无法使用 TPM 解锁。
如何使 TPM PCR 寄存器无效
我意识到我做错了一件事,就是在安装到 之前先将 Ubuntu 安装到/media/ubuntu
中。因此,在第一次使用 安装 Ubuntu 后,我运行了:/efi
/media/ubuntu/boot/efi
debootstrap
mount --bind /efi /media/ubuntu/boot/efi
arch-chroot /media/ubuntu
apt install grub-efi-amd64
(这将删除grub-pc
)grub-install
因此,我现在有一个/efi
分区,一个/boot
用于 Arch Linux 的加密分区,Ubuntu 分区有一个/boot
文件夹。(还有一个 Windows 引导加载程序,所以是的,很乱……)
grub
无法os-probe
检测到我的 Arch Linux 安装,因此我不得不F11在早期启动时按下 并选择 来重新进入Linux Boot Manager
。此时,systemd
要求我输入根分区的解锁密码或恢复密钥。(我目前都有这两个,因此进入不是问题,除非我远程重启)。
我的设置
我列出了相当长的诊断命令列表,这对于将来诊断类似问题的人(毫无疑问也包括我)应该非常有帮助!
更新: TPM 已注册以解锁 PCR 7 上的加密分区,如下所示:
# Install the TPM tools
pacman -S tpm2-tools
# Check the name of the kernel module for our TPM
systemd-cryptenroll --tpm2-device=list
# Generate a recovery key (not mandatory but strongly recommended)
systemd-cryptenroll --recovery-key /dev/gpt-auto-root-luks
# Generate a key in the TPM2 and add it to a key slot in the LUKS device
systemd-cryptenroll --tpm2-device=auto /dev/gpt-auto-root-luks --tpm2-pcrs=7
# This is the command to use later, to remove the (insecure) initial password
#systemd-cryptenroll /dev/gpt-auto-root-luks --wipe-slot=password
我的分区表非常繁忙:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:16 0 238.5G 0 disk
├─sdb1 8:17 0 128G 0 part /media/ubuntu
├─sdb2 8:18 0 110G 0 part
└─sdb3 8:19 0 527M 0 part
nvme0n1 259:0 0 931.5G 0 disk
├─nvme0n1p1 259:1 0 100M 0 part
├─nvme0n1p2 259:2 0 16M 0 part
├─nvme0n1p3 259:3 0 165.4G 0 part
├─nvme0n1p4 259:4 0 507M 0 part
├─nvme0n1p5 259:5 0 1G 0 part
├─nvme0n1p6 259:6 0 32G 0 part
│ └─swap 254:1 0 32G 0 crypt [SWAP]
├─nvme0n1p7 259:7 0 227G 0 part
│ └─root 254:0 0 227G 0 crypt /
└─nvme0n1p8 259:8 0 505.5G 0 part
└─data 254:3 0 505.5G 0 crypt /var/lib/docker
/media/data
$ sudo fdisk -l /dev/nvme0n1 /dev/sdb
Disk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: Samsung SSD 980 PRO 1TB
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Device Start End Sectors Size Type
/dev/nvme0n1p1 2048 206847 204800 100M EFI System (/efi)
/dev/nvme0n1p2 206848 239615 32768 16M Microsoft reserved
/dev/nvme0n1p3 239616 347119443 346879828 165.4G Microsoft basic data (Win 10)
/dev/nvme0n1p4 347119616 348157951 1038336 507M Windows recovery environment
/dev/nvme0n1p5 348157952 350255103 2097152 1G Linux extended boot (/boot)
/dev/nvme0n1p6 350255104 417363967 67108864 32G Linux swap
/dev/nvme0n1p7 417363968 893417471 476053504 227G Linux root (x86-64) (/)
/dev/nvme0n1p8 893417472 1953523711 1060106240 505.5G Linux filesystem (/media/data)
Disk /dev/sdb: 238.47 GiB, 256060514304 bytes, 500118192 sectors
Disk model: M4-CT256M4SSD2
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 268437503 268435456 128G 83 Linux (/media/ubuntu)
/dev/sdb2 * 268437504 499035680 230598177 110G 7 HPFS/NTFS/exFAT
/dev/sdb3 499036160 500115455 1079296 527M 27 Hidden NTFS WinRE
已安装安全启动,但未启用:
$ sbctl status
Installed: ✓ sbctl is installed
Owner GUID: 1fd4cb4a-55ff-42f6-8dbb-285bfedf56de
Setup Mode: ✓ Disabled
Secure Boot: ✗ Disabled
Vendor Keys: microsoft
我的启动日志显示内核命令行和 TPM 相关条目(显示它已提前加载):
$ sudo journalctl -k --grep='Command line|tpm|TPM'
Aug 30 06:10:03 archlinux kernel: Command line: initcall_blacklist=acpi_cpufreq_init amd_pstate=passive nvidia_drm.modeset=1 nvidia_drm.fbdev=1 ip=:::::eth0:dhcp
Aug 30 06:10:03 archlinux kernel: efi: ACPI=0xbd440000 ACPI 2.0=0xbd440014 TPMFinalLog=0xbd40a000 SMBIOS=0xbde22000 SMBIOS 3.0=0xbde21000 MEMATTR=0xb7f14018 ESRT=0xb7f14898 RNG=0xbcd38f18 INITRD=0xb6d12f18 TPMEvent>
Aug 30 06:10:03 archlinux kernel: ACPI: TPM2 0x00000000BCD50000 00004C (v04 ALASKA A M I 00000001 AMI 00000000)
Aug 30 06:10:03 archlinux kernel: ACPI: Reserving TPM2 table memory at [mem 0xbcd50000-0xbcd5004b]
Aug 30 06:10:03 archlinux kernel: tpm_crb MSFT0101:00: Disabling hwrng
Aug 30 06:10:03 archlinux systemd[1]: systemd 256.5-1-arch running in system mode (+PAM +AUDIT -SELINUX -APPARMOR -IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +K>
Aug 30 06:10:03 archlinux systemd[1]: Starting TPM PCR Barrier (initrd)...
Aug 30 06:13:19 ryzenbeast systemd[1]: systemd 256.5-1-arch running in system mode (+PAM +AUDIT -SELINUX -APPARMOR -IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +>
Aug 30 06:13:19 ryzenbeast systemd[1]: Expecting device /dev/tpm0...
Aug 30 06:13:19 ryzenbeast systemd[1]: Listening on TPM PCR Measurements.
Aug 30 06:13:19 ryzenbeast systemd[1]: Listening on Make TPM PCR Policy.
Aug 30 06:13:19 ryzenbeast systemd[1]: Starting TPM PCR Machine ID Measurement...
Aug 30 06:13:19 ryzenbeast systemd[1]: Starting Early TPM SRK Setup...
内核模块和钩子:
# mkinitcpio.conf
MODULES=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)
HOOKS=(base systemd autodetect microcode modconf keyboard keymap consolefont sd-vconsole block sd-tinyssh encryptssh sd-encrypt filesystems resume fsck)
LUKS 标头键槽:
$ sudo systemd-cryptenroll /dev/disk/by-partlabel/archlinux
SLOT TYPE
0 password
1 recovery
2 tpm2
$ sudo systemd-cryptenroll /dev/disk/by-partlabel/swap
SLOT TYPE
0 password
1 tpm2
已签名的文件:
$ sbctl verify
Verifying file database and EFI images in /efi...
✓ /boot/EFI/Linux/arch-linux-fallback.efi is signed
✓ /boot/EFI/Linux/arch-linux.efi is signed
✗ /efi/EFI/Boot/bootx64.efi is not signed (this became signed after running `bootctl install`)
✓ /efi/EFI/systemd/systemd-bootx64.efi is signed
✓ /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed is signed
✗ /efi/EFI/GRUB/grubx64.efi is not signed
✗ /efi/EFI/Manjaro/grubx64.efi is not signed
✗ /efi/EFI/Microsoft/Boot/Resources/bootres.dll is not signed
✗ /efi/EFI/Microsoft/Boot/Resources/en-US/bootres.dll.mui is not signed
✗ /efi/EFI/Microsoft/Boot/bg-BG/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/bg-BG/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/bootmgfw.efi is not signed
✗ /efi/EFI/Microsoft/Boot/bootmgr.efi is not signed
✗ /efi/EFI/Microsoft/Boot/cs-CZ/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/cs-CZ/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/cs-CZ/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/da-DK/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/da-DK/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/da-DK/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/de-DE/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/de-DE/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/de-DE/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/el-GR/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/el-GR/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/el-GR/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/en-GB/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/en-GB/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/en-US/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/en-US/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/en-US/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/es-ES/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/es-ES/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/es-ES/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/es-MX/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/es-MX/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/et-EE/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/et-EE/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fi-FI/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fi-FI/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fi-FI/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fr-CA/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fr-CA/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fr-FR/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fr-FR/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/fr-FR/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/hr-HR/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/hr-HR/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/hu-HU/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/hu-HU/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/hu-HU/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/it-IT/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/it-IT/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/it-IT/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ja-JP/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ja-JP/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ja-JP/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_10df.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_10ec.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_1137.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_14e4.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_15b3.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_1969.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_19a2.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_1af4.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_02_8086.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_07_1415.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kd_0C_8086.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kdnet_uart16550.dll is not signed
✗ /efi/EFI/Microsoft/Boot/kdstub.dll is not signed
✗ /efi/EFI/Microsoft/Boot/ko-KR/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ko-KR/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ko-KR/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/lt-LT/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/lt-LT/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/lv-LV/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/lv-LV/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/memtest.efi is not signed
✗ /efi/EFI/Microsoft/Boot/nb-NO/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/nb-NO/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/nb-NO/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/nl-NL/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/nl-NL/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/nl-NL/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pl-PL/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pl-PL/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pl-PL/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pt-BR/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pt-BR/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pt-BR/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pt-PT/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pt-PT/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/pt-PT/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/qps-ploc/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ro-RO/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ro-RO/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ru-RU/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ru-RU/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/ru-RU/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sk-SK/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sk-SK/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sl-SI/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sl-SI/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sr-Latn-RS/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sr-Latn-RS/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sv-SE/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sv-SE/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/sv-SE/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/tr-TR/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/tr-TR/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/tr-TR/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/uk-UA/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/uk-UA/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/zh-CN/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/zh-CN/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/zh-CN/memtest.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/zh-TW/bootmgfw.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/zh-TW/bootmgr.efi.mui is not signed
✗ /efi/EFI/Microsoft/Boot/zh-TW/memtest.efi.mui is not signed
✗ /efi/EFI/ubuntu/grubx64.efi is not signed
系统测量
$ sudo /usr/lib/systemd/systemd-measure status
# PCR[11] kernel-boot
11:sha1=<SHA1SUM>
11:sha256=<SHA256SUM>
# PCR[12] kernel-config (NOT SET!)
12:sha1=0000000000000000000000000000000000000000
12:sha256=0000000000000000000000000000000000000000000000000000000000000000
# PCR[13] sysexts (NOT SET!)
13:sha1=0000000000000000000000000000000000000000
13:sha256=0000000000000000000000000000000000000000000000000000000000000000
$ sudo /usr/lib/systemd/systemd-measure calculate --current --bank=sha1 --bank=sha256
# PCR[11] Phase <enter-initrd>
11:sha1=<SHA1SUM_2>
11:sha256=<SHA256SUM_2>
# PCR[11] Phase <enter-initrd:leave-initrd>
11:sha1=<SHA1SUM_3>
11:sha256=<SHA256SUM_3>
# PCR[11] Phase <enter-initrd:leave-initrd:sysinit>
11:sha1=<SHA256SUM_4>
11:sha256=<SHA256SUM_4>
# PCR[11] Phase <enter-initrd:leave-initrd:sysinit:ready>
11:sha1=<SHA256SUM_5>
11:sha256=<SHA256SUM_5>
测试使用 TPM 打开根分区
$ sudo cryptsetup open --test-passphrase /dev/nvme0n1p7
Failed to unseal secret using TPM2: Operation not permitted
Enter passphrase for /dev/nvme0n1p7:
当前 PCR 时段
$ systemd-analyze pcrs
NR NAME SHA256
0 platform-code <SHA256>
1 platform-config <SHA256>
2 external-code <SHA256>
3 external-config <SHA256>
4 boot-loader-code <SHA256>
5 boot-loader-config <SHA256>
6 host-platform <SHA256>
7 secure-boot-policy <SHA256>
8 - 0000000000000000000000000000000000000000000000000000000000000000
9 kernel-initrd <SHA256>
10 ima 0000000000000000000000000000000000000000000000000000000000000000
11 kernel-boot <SHA256>
12 kernel-config 0000000000000000000000000000000000000000000000000000000000000000
13 sysexts 0000000000000000000000000000000000000000000000000000000000000000
14 shim-policy 0000000000000000000000000000000000000000000000000000000000000000
15 system-identity <SHA256>
16 debug 0000000000000000000000000000000000000000000000000000000000000000
17 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
18 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
19 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
20 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
21 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
22 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
23 application-support 0000000000000000000000000000000000000000000000000000000000000000
添加新的 TPM 条目
我知道我可以使用以下命令添加新的 TPM 条目并删除旧的条目:
# Enroll TPM (again).
$ sudo systemd-cryptenroll --tpm2-device=auto /dev/nvme0n1p7`
🔐 Please enter current passphrase for disk /dev/nvme0n1p7:
New TPM2 token enrolled as key slot 3.
# List LUKS unlock slots on my root partition.
$ sudo systemd-cryptenroll /dev/nvme0n1p7
SLOT TYPE
0 password
1 recovery
2 tpm2
3 tpm2
# Wipe the old tpm2 entry
$ sudo systemd-cryptenroll /dev/nvme0n1p7 --wipe-slot=2
Wiped slot 2.
# Test I can open it
$ sudo cryptsetup open --test-passphrase /dev/nvme0n1p7
$
更新:系统日记帐分录
我检查了journalctl -u systemd-cryptsetup@root
一下是否可以在第一次启动失败之前和之后找到更多信息。
启动成功后:
Aug 27 09:46:02 archlinux systemd[1]: Starting Cryptography Setup for root...
Aug 27 09:46:02 archlinux systemd-cryptsetup[407]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/gpt-auto-root-luks.
Aug 27 09:46:02 archlinux systemd-cryptsetup[407]: Automatically discovered security TPM2 token unlocks volume.
Aug 27 09:46:04 archlinux systemd-cryptsetup[407]: Successfully extended PCR index 15 with 'cryptsetup:root:<UUID>' and volume key (banks sha1, sha256).
Aug 27 09:46:04 archlinux systemd[1]: Finished Cryptography Setup for root.
下次启动失败时:
Aug 28 08:09:52 archlinux systemd[1]: Starting Cryptography Setup for root...
Aug 28 08:09:52 archlinux systemd-cryptsetup[403]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/gpt-auto-root-luks.
Aug 28 08:09:52 archlinux systemd-cryptsetup[403]: Automatically discovered security TPM2 token unlocks volume.
Aug 28 08:09:53 archlinux systemd-cryptsetup[403]: Failed to unseal secret using TPM2: Operation not permitted
Aug 28 08:09:53 archlinux systemd-cryptsetup[403]: No valid TPM2 token data found.
Aug 28 08:09:53 archlinux systemd-cryptsetup[403]: No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking.
Aug 28 08:10:21 archlinux systemd-cryptsetup[403]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/gpt-auto-root-luks.
Aug 28 08:10:24 archlinux systemd-cryptsetup[403]: Failed to activate with specified passphrase. (Passphrase incorrect?)
Aug 28 08:10:30 archlinux systemd-cryptsetup[403]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/gpt-auto-root-luks.
Aug 28 08:10:33 archlinux systemd-cryptsetup[403]: Successfully extended PCR index 15 with 'cryptsetup:root:<UUID>' and volume key (banks sha1, sha256).
Aug 28 08:10:33 archlinux systemd[1]: Finished Cryptography Setup for root.
这里提到了 PCR15,解释man systemd-cryptenroll
如下:
systemd-cryptsetup(8) 可选择将激活的 LUKS 卷的卷密钥纳入此 PCR。systemd-pcrmachine.service(8) 将 machine-id(5) 纳入此 PCR。[email protected] (8) 将挂载点、文件系统 UUID、标签、根和 /var/ 文件系统的分区 UUID 纳入此 PCR。
看起来这些测量值会通过(重新)格式化分区而改变,并且足以破坏这个 PCR 寄存器......
悬而未决的问题
现在我已经研究如何解决这个问题并且有效地完成了,但我还有疑问!
- 什么原因导致 TPM 插槽值变得不正确?
- 如果我更新 Ubuntu 的内核或 initrd,这种情况会再次发生吗?
- 如何防止此类事件再次发生?
- 我看到在2023 年 11 月
systemd
引入了pcrlock 工具,但(我认为)它仍处于实验阶段,我不完全了解它,也不知道它是否有帮助。会吗? - 更新:格式化分区后,如何更新 PCR 15?
它的工作原理正好相反。启动过程会更新 PCR 寄存器以表示当前系统状态,而您的 LUKS 密钥槽(由 TPM 密封,但实际上存储在磁盘上的 LUKS 标头内)则绑定到特定的“预期”PCR 值。
那么绑定到 PCR 7 对您没有任何好处,因为它是仅代表安全启动状态的 PCR,因此如果没有 SB,它就无法保护您免受状态变化的影响(例如,未签名的内核仍然有可能被篡改)。
是的,密钥槽仍然与物理硬件绑定,但这是 TPM 密封操作的固有属性 - 即使没有 PCR 绑定,您也可以获得相同的效果。
一般有两个原因:
TPM 中存储的 SRK(存储根密钥)已被替换。
密封期间指定的策略不再符合现实,例如,如果数据被密封为特定的原始 PCR 值,则实时 PCR 不再与预期 PCR 匹配。
理论上,如果没有完全清除 TPM,情况 #1 就不可能发生,但是...我依稀记得最近的 systemd 版本中的某些变化改变了 EC SRK 的生成方式。
(TPM2 SRK 是由种子+模板确定性生成的,因此 RSA SRK 生成一次并存储,而 EC SRK 可以动态生成。如果我没记错的话,早期的 systemd 版本曾经提供不太标准的模板,导致与更高版本相比的 SRK 有所不同。)
案例 #2 取决于使用了哪些 PCR。每个 PCR 都是固件(或引导加载程序,有时是操作系统)写入内存日志的特定事件的滚动哈希值;功能类似于 Git 提交日志。事件日志可以从 Windows 或 Linux 读取,例如使用“tcg-log-parser”。
For PCR 7, the only measurements should be 1) whether Secure Boot is enabled at all, 2) the current state of all the Secure Boot variables (PK/KEK/db/dbx), and 3) the specific db entries used to validate every signed file.
(The latter means that PCR 7 will distinguish Windows and non-Windows boot files, or MS-signed vs custom-signed boot files, so you can actually keep the MS UEFI CA active without it compromising your custom-signed system.)
It's possible that the Secure Boot state changed by Windows or Linux installing a new dbx list (revoked bootloader signatures) through
fwupd
or Windows Update. But only traveling back in time and getting a before/after comparison of the full event log would give you a definite answer. (Or, if you boot Windows often, it keeps a stash of event log archives somewhere in C:\Windows.)Depends on the PCR binding – it should not happen with PCR 7 as long as the Secure Boot configuration doesn't change.
On the other hand, e.g. using PCR 4 (which contains events recording the exact hashes of the bootloader and vmlinuz) or PCR 11 (which contains a hash of the initrd) would make it break after every kernel update; this is why systemd invented its "signed PCR" feature for example.
As above, depends on the PCR bindings. Pcrlock is supposed to predict future PCR values and do the equivalent of re-sealing the LUKS keyslot against them (but with more indirection), so e.g. if you were using PCR 4+11 for exact kernel hashes, it would need to be run after each upgrade to re-seal against the new kernel.
(Since the PCRs are hashes of an event log, it's possible to read and "replay" the same log in memory, feeding each event to SHA256() the same way a TPM would – but upon encountering e.g. the "vmlinuz.efi hash" entry, substitute its value with the hash of the new kernel.)
I've never used systemd-pcrlock (though I've written my own tool that does a similar thing for PCR 4), but it seems like it would help if you did the job of integrating it to your system upgrade process; as with many systemd-related things recently, it's probably slightly over-engineered and very much aimed at distributions making fully-sealed packages, rather than end-users.