第 8.1 讲了 TPM 和 PCR——本篇讲怎么把它用起来。Secure Boot(验签防篡改)+ Measured Boot(度量记录)+ IMA(运行时完整性)= Linux 完整可信启动链。
三个机制对比
graph TB
M1[Secure Boot]
M1 --> R1[启动时验签
签名错就拒绝执行]
M2[Measured Boot]
M2 --> R2[启动时记录
哈希进 TPM PCR]
M3[IMA]
M3 --> R3[运行时验证
读文件时检查]
| 机制 |
时机 |
动作 |
失败后果 |
| Secure Boot |
启动 |
验签 |
拒绝启动 |
| Measured Boot |
启动 |
度量记录 |
不阻止启动,但 PCR 不同 |
| IMA |
运行 |
验签 / 度量 |
拒绝执行 / 报警 |
UEFI Secure Boot
graph LR
PK[Platform Key
主板厂家]
KEK[Key Exchange Key
OS 厂家]
DB[DB
允许的签名 / 哈希]
DBX[DBX
禁用的签名 / 哈希]
PK --> KEK --> DB
KEK --> DBX
UEFI Secure Boot 的密钥层次:
1 2 3 4 5 6 7 8 9 10
| PK(Platform Key): 主板厂家,根 KEK(Key Exchange Key): OS 厂家用,可签 DB / DBX DB(Allowed DB): 允许执行的签名 / 哈希列表 DBX(Forbidden DB): 禁用的签名(吊销列表)
启动时验签流程: 1. UEFI 加载 Bootloader 2. 检查 Bootloader 签名是否在 DB 中 3. 是 → 加载执行 4. 否 → 拒绝,停止启动
|
Microsoft 主导的 DB
1 2 3 4 5 6 7 8
| 默认 DB 包含: Microsoft Windows Production CA Microsoft UEFI CA(用于第三方 OS) Linux Bootloader(shim)签名: shim 由 Microsoft UEFI CA 签 shim 内嵌 Linux 厂家公钥 shim 加载 GRUB → GRUB 验签 kernel → kernel 验 module
|
shim 是 Linux 在 Secure Boot 下的”信任桥梁”——所有发行版(RHEL / Ubuntu / SUSE)都用它。
自管 Secure Boot
1 2 3 4 5 6 7 8 9 10 11 12 13
| mokutil --sb-state
mokutil --list-enrolled
mokutil --import my_cert.crt
sbkeysync --pk sbkeysync --keystore /etc/secureboot/keys
|
shim → GRUB → kernel 的验签
1 2 3 4 5 6 7 8 9 10 11 12 13
| shim 启动后: 1. 检查 grubx64.efi 签名(用 shim 内嵌的发行版公钥) 2. 通过 → 加载 GRUB GRUB 启动后: 1. 检查 vmlinuz 签名 2. 通过 → 加载 kernel kernel 启动后: 1. 检查 .ko 模块签名(kernel 模块也要验签) 2. 通过 → 允许加载 任何一步不通过 → 拒绝执行 → 启动失败
|
Secure Boot 的几个重要实践
1 2 3 4 5 6 7 8 9 10
|
bootctl status
mokutil --sb-state efivar -l
sbsign --key MOK.priv --cert MOK.crt --output module.ko.signed module.ko
|
Measured Boot
Secure Boot 是”二选一”——通过或不通过。Measured Boot 是”完整记录”——把每一步都哈希进 TPM。
graph TB
CRTM[CRTM] -->|度量并 Extend| PCR0[PCR 0]
BIOS[BIOS] -->|度量 Bootloader| PCR4[PCR 4]
GRUB[GRUB] -->|度量 kernel/initrd| PCR8[PCR 8]
GRUB -->|度量 cmdline| PCR9[PCR 9]
KER[Kernel] -->|度量初始化| PCR10[PCR 10]
IMA[IMA] -->|度量文件| PCR10b[PCR 10]
启动度量事件日志
UEFI 实现把每次”度量”事件记到日志,开机后 OS 可以看:
1 2 3 4 5 6 7 8 9 10 11 12 13
| sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements
|
事件日志 + 当前 PCR 值 = “可重放”——验证方可以独立验证启动链。
用 PCR 7 还是 PCR 0-4?
1 2 3 4 5 6 7
| PCR 0-4: 度量具体的 BIOS / Bootloader / kernel 哈希 → 任何 BIOS / kernel 升级都改值 → 灵活性差 PCR 7: 仅度量 Secure Boot 状态(PK / KEK / DB / DBX 等) → 升级 kernel 时 PCR 7 不变 → 推荐用 PCR 7 + Secure Boot 组合
|
LUKS + Measured Boot 实战
1 2 3 4 5 6 7 8 9 10 11 12 13
| systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sda3
cryptsetup luksAddKey /dev/sda3 recovery_key.txt
|
IMA:Linux 文件完整性
IMA(Integrity Measurement Architecture)是 Linux 内核的运行时完整性子系统:
graph TB
EXEC[执行 / mmap / open]
EXEC --> IMA[IMA Hook]
IMA --> CHECK{检查策略}
CHECK --> M[度量:写入 measurement list + Extend PCR 10]
CHECK --> A[Appraisal:验证签名 / 哈希]
CHECK --> AUDIT[审计:仅记录]
A --> R{验证通过?}
R -- 是 --> RUN[允许执行]
R -- 否 --> DENY[拒绝]
IMA 的三种模式:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1. 度量(Measurement): - 把文件哈希写入 /sys/kernel/security/ima/ascii_runtime_measurements - 同时 Extend PCR 10 - 不阻止执行 - 用于审计和远程证明 2. 评估(Appraisal): - 验证文件的扩展属性签名 - 不通过 → 拒绝执行 - 严格但需要预先签名
3. 审计(Audit): - 仅写日志
|
IMA 启用
1 2 3 4 5 6 7 8 9 10 11 12
| GRUB_CMDLINE_LINUX="ima_policy=tcb ima_template=ima-ng ima_hash=sha256"
cat /sys/kernel/security/ima/ascii_runtime_measurements | head
tpm2_pcrread sha256:10
|
IMA 度量后每个文件首次访问时都会哈希入 PCR 10——这就让”系统启动以来所有访问的文件”都被记录。
IMA 策略
1 2 3 4 5 6 7
| dont_measure fsmagic=0x9fa0 dont_measure fsmagic=0x62656572 measure func=BPRM_CHECK measure func=FILE_MMAP mask=MAY_EXEC measure func=MODULE_CHECK appraise func=POLICY_CHECK
|
EVM:扩展属性签名
1 2 3 4 5 6 7
| EVM(Extended Verification Module): - 验证文件的扩展属性 xattr(IMA 哈希、SELinux 标签等) - 防止单独篡改 xattr
启用: GRUB_CMDLINE_LINUX="... evm=fix" # 第一次自动签 之后 evm=enforce
|
完整可信启动链的搭建
graph TB
S1[BIOS Secure Boot]
S1 --> S2[Bootloader 验签 kernel]
S2 --> S3[Kernel 验签 module]
S3 --> S4[IMA 度量 + Appraisal]
S4 --> S5[远程证明可达]
S6[Measured Boot 同步进行]
S6 -.- S1 & S2 & S3 & S4
实际部署:
1 2 3 4 5 6 7 8
| 1. BIOS: 启用 Secure Boot + Measured Boot 2. Bootloader: shim + GRUB 签名 3. Kernel: 发行版签的 kernel + 自签 module 4. initrd: 生成时签 5. IMA: 启动 ima_policy=appraise_tcb 6. EVM: 启用 evm 7. LUKS: 密封到 PCR 7 8. 应用: 按需 IMA 度量
|
实战案例:金融业可信服务器
1 2 3 4 5 6 7 8 9 10 11 12
| 某银行核心交易系统: - 物理 TPM 2.0 + Secure Boot - kernel + initrd 内部签 - LUKS 全盘加密 + TPM 密封 PCR 7 - IMA Appraisal 模式 - 远程证明每天定时到中心化平台 - 启动状态异常 → 自动告警 + 隔离
效果: - 任何 BIOS / Bootloader / Kernel 篡改 → 启动失败 - 任何关键二进制篡改 → 拒绝执行 - 物理拆机偷盘 → 数据无法解密(PCR 不对)
|
远程证明实战
1 2 3 4 5 6 7 8 9 10 11 12
|
apt install keylime-agent
keylime_register --addr <verifier> --uuid <uuid>
|
主流远程证明方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| keylime(NCC 出品,CNCF 项目): - 开源 - Bootstrap + Periodic attest - 集成 IMA 度量列表
Microsoft Attestation Service: - Windows Defender Device Health - Azure Attestation Service Intel Trust Authority: - Intel 官方 - 服务化远程证明
国产: - 公安部一所 / 中电科 等可信认证体系 - 工信部"可信云"标准 - 各家 OEM 自家方案
|
几个老坑
坑 1:Secure Boot + 第三方驱动
1 2 3 4 5 6 7 8 9
| NVIDIA / Mellanox 等内核模块: - shim 信任的是发行版公钥 - 第三方模块需要单独签 - 用 mokutil 加用户证书
正确流程: 1. 生成 MOK 密钥对 2. mokutil --import 加证书 3. 装第三方驱动时用 dkms 自动签
|
坑 2:Kernel 升级 PCR 0/4 改变
1 2 3 4 5 6
| LUKS 密封 PCR 0/4 → kernel 升级 → PCR 不一样 → 启动后无法解密
防御: - 升级前 systemd-cryptenroll 重新封装 - 或一直只用 PCR 7(推荐) - 留一把 fallback 密码
|
坑 3:IMA 性能开销
1 2 3 4 5 6 7 8 9
| IMA 默认全度量: - 每次 execve / mmap 都要哈希 - 4 KB 文件哈希 ~10 μs - 大量小文件应用受影响 5-15%
调优: - 用 dont_measure 排除不必要路径 - 用 ima-buf 替代 ima-ng(buffer 模式) - SHA-1 比 SHA-256 快但安全性弱
|
坑 4:BIOS 升级清密钥
1 2 3 4 5 6 7
| BIOS 升级有时候清空 PK / KEK / DB → Secure Boot 关闭 → mokutil 之前导入的全没
防御: - 升级前导出 PK / KEK / DB 备份 - 升级后用 sbkeysync 恢复
|
坑 5:vTPM 状态
1 2 3 4 5
| KVM vTPM 默认 swtpm 持久化: /var/lib/swtpm/<uuid> 迁移 VM: vTPM 状态要同步迁移 否则: 新宿主机的 vTPM 是新的 → PCR 全空 → LUKS 解不开
|
坑 6:IMA Appraisal 启用前没签好
1 2 3 4 5 6 7
| appraisal=enforce 时: 未签的文件不能执行 → 突然启用 → 大量应用启动失败
正确: 1. 先 ima_appraise=fix 一次(自动签) 2. 验证一切正常 3. 再 ima_appraise=enforce
|
坑 7:远程证明引用值管理
1 2 3 4 5 6
| 万级集群每机 PCR 值不同(kernel / 配置略差异): - 集中维护"已知好"哈希列表 - 每次升级都要更新基线 - 大集群运维成本高
→ 这是为什么互联网厂启用率低
|
TPM 与 BIOS 的协议
1 2 3 4 5 6 7 8
| TCG PC Client Profile: - 度量哪些事件(PCR mapping) - 事件日志格式 - 厂家必须遵循
每家 BIOS 实现略有差别: - 同款服务器换 BIOS 厂 PCR 不一样 - 跨厂家集群 PCR 基线管理头疼
|
一些查询命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| mokutil --sb-state
mokutil --list-enrolled
efivar -l efibootmgr -v
tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements tpm2_pcrread sha256:0,1,2,3,4,5,6,7,8,9,10
cat /sys/kernel/security/ima/ascii_runtime_measurements | wc -l
cat /sys/kernel/security/ima/policy
cat /sys/kernel/security/lockdown
|
一些数字直觉
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 启动时间影响: Secure Boot: +50-200 ms Measured Boot: +500-1000 ms IMA 度量: +1-5 秒(按文件数) TPM 解 LUKS: +200-500 ms 运行时性能: IMA Measurement: 5% 性能损失 IMA Appraisal: 10-15% 性能损失 EVM 启用: 额外 5-10% 存储: Measurement 列表: 小集群每天几十 MB Event log: 每机几 MB
|
不同发行版默认情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| RHEL 9: - Secure Boot 默认启用 - shim 已签 - IMA 配置可选 - TPM 工具齐全
Ubuntu 24.04: - Secure Boot 默认启用 - LUKS + TPM 通过 systemd-cryptenroll - IMA 不默认
openEuler 22.03 LTS: - 信创目录默认启用 Secure Boot + Measured Boot - IMA 政企版默认启用 - 与 TCM 集成
麒麟 V10: - 等保 3+ 默认 Secure Boot + IMA - 国密签名(SM2/SM3) - 与 TCM / TPCM 适配
|
小结
- Secure Boot = 启动验签,不通过就拒绝
- Measured Boot = 启动度量记录到 TPM PCR
- IMA = 运行时文件完整性验证
- 三者配合形成完整可信启动链
- 远程证明把启动状态送到验证方
- LUKS + TPM PCR 7 是最常用的全盘加密方案
- 互联网厂启用率低,政企 / 金融 / 关基启用率高
下一篇讲 TEE——SGX、TDX、SEV、TrustZone 等”可信执行环境”。