
近年来,TPM 2.0 模块已经从一个硬件谜团变成了任何具有 UEFI 和安全启动的现代计算机的常见组成部分。 本文解释了 /dev/tpm0 和 /dev/tpmrm0 是什么以及如何使用 tpm2_pcrread 和 tpm2_pcrextend。 (以及它在 tpm2-tools 中的实际命令),并解释它们如何适应 Linux 中的测量启动、磁盘加密和签名 PCR 策略。
有用的文档存在,但它分散在 systemd 手册页、wiki 条目和非常密集的帖子中; 我们在这里收集所有关键信息(PCR、实际示例、风险和防御) 这样,即使技术人员不是 TPM 专家,也可以使用这些工具,而不会迷失在晦涩的细节中。
什么是 TPM 2.0 以及您为何关心
可信平台模块是一种位于主板上(或 CPU 内部,如 fTPM/Intel PTT)的安全芯片,可充当系统的安全存储、随机数生成器和信任根。 它是被动的:如果你不使用它,它就不会做任何事情。,但是当您将其集成到您的启动流程和磁盘加密中时,它会提供完整性验证和硬件保护密钥。
实际上,TPM 2.0 允许您在磁盘加密中使用两种主要模式:a)生成/保存强密钥,并使用具有防暴力破解锁的 PIN 保护其使用;b)激活所谓的测量启动,其中 每个启动组件都以 PCR 记录进行测量,因此,只有当系统未被篡改(并且可选地使用预启动 PIN)时,密钥才会被“解开”。
/dev/tpm0 和 /dev/tpmrm0:区别以及何时使用它们
在 Linux 上,当 TPM 2.0 可用时,您将看到两个字符设备。 /dev/tpm0 是 TPM 的“原始”接口而 /dev/tpmrm0 通过资源管理器公开访问 (一个可以增加客户端、管理会话和资源的管理器),在大多数情况下是 tpm2-tools 推荐的管理器。
如果您不确定 TPM 是否存在,您可以对其进行热测试。 如果 /sys/class/tpm/ 为空或 wiki 命令未返回任何内容,没有可见的 TPM:它可能在物理上不存在,或者可能在固件中被禁用。
# ¿Hay TPM 2.0?
ls /sys/class/tpm/
cat /sys/class/tpm/tpm*/tpm_version_major
# Dispositivos
ls -l /dev/tpm*
当两个设备节点都存在时,tpm2-tools 通常会检测 /dev/tpmrm0 并自动使用它。 如果您需要强制使用设备,大多数工具都接受 –tcti 或者使用 TCTI 环境变量,但对于常见任务通常没有必要。
TPM PCR:工作原理和测量内容
平台配置寄存器是存储每个启动阶段关键组件状态的哈希值(通常为 SHA-256)的记录。 它们在上电周期被初始化为零,并且只能“延长”:永不重写或擦除(PCR 16 等调试情况除外)。
基本操作是扩展: 新值 = SHA256(当前值 || SHA256(数据))这就是将测量链接在一起,避免机会性重置的方法。此模式用于测量固件、配置、安全启动、内核、initrd 和内核参数等。
在现代设备上,您将看到 24 个 PCR(0-23)。 在 UEFI 引导中使用 systemd 时最相关的是:
– PCR 0:固件代码。
– PCR 1:固件配置(UEFI 设置)。
– PCR 7:安全启动状态及其信任的证书。
– PCR 9:内核测量的 initrd。
– PCR 11:通过 systemd-stub/systemd-pcrphase 的 UKI(统一内核映像)和阶段标记。
– PCR 12:内核命令行。
使用 tpm2-tools 读取和扩展 PCR:tpm2_pcrread 和 tpm2_pcr_extend
在 tpm2-tools 中,读取操作如下: tpm2_pcr读取 以及扩展 tpm2_pcrextend。有时,您会看到“tpm2_pcr_extend”被称为扩展的概念操作,但 实际套件命令是 tpm2_pcrextend.
检查 PCR 的当前状态 SHA-256,它很简单:
# Leer PCRs en SHA-256 (ejemplos de índices habituales)
sudo tpm2_pcrread sha256:0,1,7,9,11,12
# O todos los PCRs SHA-256 disponibles
tpm2_pcrread sha256:all
要使用任意数据的哈希值扩展 PCR(作为教学示例,/etc/passwd 的哈希值),请计算 SHA-256 并对其进行扩展。 请记住:TPM 不会接收巨大的数据,但它的哈希值,受限制和设计。
# 1) Guardar el hash de /etc/passwd
echo -n $(sha256sum /etc/passwd | cut -d' ' -f1) > passwd.sha
# 2) Extender PCR 7 (ejemplo) con el hash previo
sudo tpm2_pcrextend 7:sha256=$(cat passwd.sha)
# 3) Ver el nuevo valor del PCR 7
tpm2_pcrread sha256:7
如果你想在 TPM 之外重现扩展数学, 将当前 PCR 值(二进制)与新的哈希值连接起来 然后再次应用 SHA-256 来检查结果。
PCR 可以重置吗?
在正常情况下,不会。 其理念是,PCR 只会随着延伸而增长有一个例外:PCR 16 通常保留用于“调试”,并且可以在某些流程中重置,但它不能用作策略的安全根。
测量启动、LUKS 和 systemd-cryptenroll:将各个部分整合在一起
当您将 TPM 集成到磁盘加密中时,您可以将密钥解锁“绑定”到一组 PCR。 如果在当前启动中这些 PCR 具有与注册密钥时相同的值,TPM 解封,LUKS 卷自动打开(有或没有预启动 PIN,取决于您的配置)。
使用 systemd-cryptenroll 和 systemd-cryptsetup 可以很好地完成此操作。 其目的是创建您的卷,注册 TPM 密钥,并添加恢复密钥。 因此,如果测量结果发生变化(例如,更新固件或内核后),您就不会被排除在外。
# Ejemplo: crear LUKS, matricular TPM y añadir recuperación (pseudoflujo)
# 1) Crear el volumen con contraseña temporal
sudo cryptsetup luksFormat /dev/nvme0n1p2
# 2) Matricular TPM en LUKS usando PCRs concretos y PIN
sudo systemd-cryptenroll \
--tpm2-device=auto \
--tpm2-with-pin=yes \
--tpm2-pcrs=1+2+3+4 \
--wipe-slot=empty \
/dev/nvme0n1p2
# 3) Añadir clave de recuperación aleatoria
sudo systemd-cryptenroll --recovery-key /dev/nvme0n1p2
# 4) Abrir con TPM o con recovery cuando proceda
systemd-cryptsetup attach root /dev/nvme0n1p2 - tpm2-device=auto
如果你强迫出现差异(例如, 你故意延长 PCR 4),TPM 将不再释放密钥,您需要使用恢复密钥。您可以稍后使用新的当前值重新注册 TPM,方法是: –wipe-slot=tpm2 以及另一次 systemd-cryptenroll 的执行。
选择哪种 PCR 以及原因
您链接的相关 PCR 越多,您减少的表面积就越大,但在合法更改之后,您需要重新注册的次数就越多。 一些实用的标准:
– PCR 7(安全启动):如果您的键盘设置没有改变,应该非常稳定。
– PCR 0/1(固件和配置):这些很少改变;它们需要在更新固件或更改 BIOS/UEFI 后重新注册。
– PCR 9/11/12(内核、initrd、UKI 和 cmdline):如果您不使用 UKI 或稳定签名/策略,这些会经常更改。
在某些环境中,它只链接 PCR 7,依靠安全启动来验证内核和 initrd(如果它们作为签名的 UKI 启动),并使用 systemd-boot SB 处于活动状态时不允许编辑内核参数。这是可行的,但如果您的安全启动依赖于第三方密钥(例如 Microsoft 第三方),则更容易安排保留 PCR 7 的备用启动,因此 这不是最严格的选择.
UKI和PCR政策签署:稳定而不失安全
避免每次更新内核时重新注册的一个实用解决方案是使用 UKI(统一内核映像)和签名的 PCR 策略您生成一个密钥对,在注册时将公钥绑定到 TPM,并在每次更新后签署您的 UKI。TPM 信任该签名,即使特定内核哈希发生变化,也允许解锁。
systemd-measure 工具和 systemd-ukify 助手使这变得简单: ukify 将内核、initrd 和 cmdline 打包到 UKI 中 (通常在 PCR 11 中测量)并使用 systemd-measure 签署策略。使用 mkinitcpio 可以集成 ukify,以便 安装后 签名自行执行。
# Esquema típico (pseudocomandos)
# 1) Crear claves para política PCR firmada
openssl genpkey -algorithm RSA -out /etc/kernel/pcr-initrd.key.pem -pkeyopt rsa_keygen_bits:3072
openssl req -new -x509 -key /etc/kernel/pcr-initrd.key.pem -out /etc/kernel/pcr-initrd.pub.pem -subj "/CN=UKI PCR Policy"
# 2) Configurar ukify/mkinitcpio para generar UKI y firmar política
# (consultar man ukify y systemd-measure para parámetros)
# 3) Matricular en LUKS atando PCRs y clave pública de la política
sudo systemd-cryptenroll \
--tpm2-device=auto \
--wipe-slot=tpm2 \
--tpm2-with-pin=yes \
--tpm2-pcrs=0+1+2+7 \
--tpm2-public-key=/etc/kernel/pcr-initrd.pub.pem \
--tpm2-public-key-pcrs=11 \
/dev/nvme0n1p2
这样, 只要您继续使用密钥签署 UKI,您的政策就能保持稳定,不受内核/initrd 变化的影响。如果您更新密码或更改 PCR 集,则需要重新注册。
使用 systemd 的测量链示例
在启动期间,systemd-stub 和 systemd-pcrphase 会在特定时间延长 PCR。 例如,“enter-initrd”记录在PCR 11中,允许解锁仅在 initrd 内有效(减少攻击者稍后尝试重用密钥的向量)。
在有 UKI 的系统中,UKI 内容在 PCR 11 中测量;在没有 UKI 的系统中, 内核在 PCR 9 中测量 initrds 并且引导加载程序可以测量 PCR 12 中的 cmdline。请确保在策略中涵盖 initrd 和 cmdline,否则有人可能会 后门 使用恶意命令行启动 initrd 或 boot,例如 初始化=/bin/bash.
真正的风险:冷启动、TPM 嗅探等
可能出现什么问题?建模威胁时需要了解的几点。 冷启动攻击 仍然有效:如果解锁是全自动的,攻击者可以无限次尝试。一个明显的缓解措施是要求预启动 PIN (PBA),将尝试次数减少到每次开机一次。
另一类是 TPM总线嗅探攻击CPU 请求密钥,TPM 发送密钥;如果链接被窃听,密钥可能会泄露。为此,systemd 实现了“参数加密”,以便对交换过程进行加密;或者,使用 fTPM/Intel PTT 或加密内存可以减少泄露。目前有一些相对经济实惠的公开演示(甚至使用微控制器)展示了在主流品牌笔记本电脑上的可行性。
学术和实践上也存在一些漏洞: TPM-Fail,故障TPM(对AMD有显著影响) 和案件 bitpixie(CVE-2023-21563)这并不意味着 TPM 没有用,但您应该保持固件为最新版本,了解您的威胁模型,而不是盲目信任它。
BitLocker 针对这些威胁的状态
在 Windows 世界中,部署最广泛的磁盘加密是 BitLocker。现在有消息称 其默认配置(仅使用 TPM 自动解锁) 由于它没有实现 systemd 风格的参数加密,因此很容易受到冷启动和 TPM 通道嗅探的攻击。这使得某些公司计算机在几分钟内就容易受到攻击。
建议 预启动身份验证 通过策略/注册表或 CLI 进行操作,但普通用户对此了解甚少。此外,请务必检查恢复密钥的存储位置:它通常位于用户的 Microsoft 帐户中, 这是另一个风险角度 如果不加以控制。
攻防技巧:替换 LUKS 根目录以强制获取密码
当没有预启动身份验证时,有一个有趣的向量。攻击者可以克隆真正的 LUKS 分区, 用另一个具有相同 UUID 和他知道的密码的 LUKS 替换它,然后启动计算机。由于 PCR 测量结果匹配,TPM 会释放密钥,但密钥与伪造的 LUKS 不匹配,因此 initrd 会提示输入“恢复”密钥。输入攻击者已知的密码后,您的系统将在 initrd 中以 root 身份运行,然后您就可以策划窃取原始密钥(例如,通过网络挂载真正的副本并使用 systemd-cryptsetup)。
明确的缓解措施: 激活预启动身份验证,利用 systemd-pcrphase 将解锁严格绑定到 initrd 阶段,并考虑测量/绑定目标 LUKS 卷(需要仔细设计以避免恶性循环)。
选择分区和第二个键:最佳实践
保持 恢复密钥 这是强制性的:如果 TPM 或主板坏了,绑定到 TPM 的密钥就失效了。LUKS 允许多个插槽(TPM 使用一个,恢复使用另一个)。此外,将 / 和 /home 分区分开还有好处:你可以应用 采用 TPM a/ 进行严格测量 并对 /home 使用强密钥或 FIDO2/YubiKey 设备,降低对单一机制的整体信任。
更新固件或内核时会发生什么?
如果您更改固件或触摸 UEFI 选项,PCR(如 0/1)将会改变,并且 TPM 将不会释放密钥,直到您重新注册。 为 内核和 initrd,变化频繁如果您使用的 UKI 未包含签名政策,每次更新都可能强制您使用恢复选项,并在之后重新注册。如果您使用的 UKI 已签名,则只需签名即可。
社区笔记和观察
在某些发行版的流行指南中,它被推荐 使用 UKI 和 systemd-boot 时仅绑定 PCR 7,依赖于安全启动的安全措施以及无法编辑命令行。虽然可以正常工作,但依赖第三方工具存在风险。过去也记录过一个 bug,解锁后按下 Enter 键会弹出恢复 shell;为了避免意外情况,最好保持版本更新。
2025/06 分享了一些有趣的评论: TPM故障继续影响AMD 在某种程度上;wiki 添加了关于签名 PCR 策略的特定部分;并且对提供 FDE 和 TPM 作为实验功能的发行版的安装程序进行了测试,但遇到了一些实际问题(首次启动时需要恢复、依赖快照、双磁盘加密),这个问题 值得更深入的审计.
2025/07 年发布了有关 Windows 磁盘加密的后续文章。 总体结论强化了 PBA 和加密 TPM 通道的必要性。,以及限制对安全启动中的第三方密钥的依赖。
tpm2-tools 和 systemd 的操作技巧
日常使用:安装 tpm2-tools 和 tpm2-tss。 默认使用 /dev/tpmrm0以及 tpm2_pcrread/tpm2_pcrextend 用于测试和实验 PCR。避免使用任意数据扩展生产 PCR:请在实验室中进行此操作或使用 PCR 16 进行测试。
使用 systemd-cryptenroll 注册时: –tpm2-设备=自动 检测TPM; –tpm2-带引脚 添加PBA; –tpm2-pcrs=… 选择您的 PCR; –tpm2-public-key=… 和 –tpm2-public-key-pcrs=… 激活已签名的 PCR 策略(例如,与 UKI 的 PCR 11 绑定)。不要忘记 –擦除槽 当您想要清理前一个插槽时。
如果你没有 TPM,并且 systemd 让你在启动时等待
有时,更新后,即使您的机器上没有可见的 TPM,服务也会尝试使用 TPM,从而导致启动超时。 首先检查没有出现 /dev/tpm* 也不是 /sys/class/tpm 中的条目。
# Verificación rápida
ls /dev/tpm*
ls /sys/class/tpm/
如果没有 TPM,请检查您的 /etc/crypttab 没有像 tpm2-device=auto 这样的选项如果存在,请删除它们并重建 initrd。您也可以在没有 TPM 的计算机上禁用测量阶段:
# 1) Eliminar referencias TPM en /etc/crypttab y regenerar initrd
sudo mkinitcpio -P # (o dracut/rebuildinitrd según distro)
# 2) Evitar carga de módulos TPM si el firmware publica algo extraño
echo -e "blacklist tpm\nblacklist tpm_tis\nblacklist tpm_crb" | sudo tee /etc/modprobe.d/no-tpm.conf
# 3) Opcional: evitar pcrphase si te da problemas
sudo systemctl mask systemd-pcrphase.service
如果您的设备缺少 TPM,这可以消除不必要的等待。 如果您稍后在 BIOS/UEFI 中启用 TPM,删除黑名单并取消屏蔽该设备以恢复测量结果。
良好实践和信任决策
有些人对 TPM 心存疑虑,因为它就像自加密磁盘一样,是个“黑匣子”。这种怀疑是合理的。 评估你的威胁模型 并平衡了可用性、隐私性和维护性。对于许多人来说,TPM+PBA+签名的UKI是一个巨大的安全飞跃,而且不会产生过多的摩擦。
在允许的硬件上,添加 加密内存 避免在安全启动中依赖第三方密钥;尽可能将密钥链限制在您自己的密钥范围内。保持固件和内核更新,以纳入已发布漏洞的缓解措施。
掌握 /dev/tpm0、/dev/tpmrm0 和 tpm2_pcrread/tpm2_pcr_extend 操作为 Linux 中的测量启动和强大的磁盘加密打开了大门;借助 UKI 和签名的 PCR 策略,您可以实现操作稳定性,而添加预启动 PIN 还可以保护您免受更实际的攻击。 关键是要选择好 PCR,对经常更改的内容进行签名,并始终保留良好的恢复密钥。.