3. UEFI安全启动

好,咱们进入第三章。这一章聊的是UEFI安全启动,也就是Secure Boot。说实话,这是整个可信启动链条里最容易被忽视、但又最容易出问题的一环。我见过太多项目,BIOS设置没配好,密钥没注册对,结果系统死活起不来,最后查了半天发现是Secure Boot在“捣乱”。

咱们今天就把这事彻底讲透。从BIOS设置开始,到原理,再到密钥管理,一步到位。

3.1 UEFI BIOS设置:你得先找到门

先说说BIOS设置。很多人觉得这步简单,不就是进BIOS改几个选项吗?其实不然。不同厂商的BIOS界面千差万别,但核心逻辑是一样的。

我个人习惯,拿到一台新机器,第一件事就是进BIOS,把Secure Boot相关的选项全部过一遍。你想想看,如果连门都没找到,后面的事根本无从谈起。

常见的设置路径有这些:

  • Boot 菜单下,找 Secure Boot 选项
  • Security 菜单下,找 Secure Boot Configuration
  • 有些厂商放在 Authentication 或 Advanced 里

嗯,这里要注意:很多BIOS默认是关闭Secure Boot的。你得手动把它从 Disabled 改成 Enabled。但别急着改,先看看下面的原理。

警告: 在启用Secure Boot之前,请确保你的操作系统和引导加载程序支持它。否则,改完直接黑屏,别怪我没提醒你。

3.2 Secure Boot原理:说白了就是“验签”

Secure Boot的原理,说白了就是一句话:只允许运行经过签名的代码。

从按下电源键开始,UEFI固件会检查每一个要执行的二进制文件——引导加载程序、驱动、甚至Option ROM——看它们有没有合法的数字签名。没有?对不起,拒绝执行。

为什么会这样?因为恶意软件可能会篡改引导加载程序,在系统启动前就注入恶意代码。Secure Boot就是防这个的。

我曾在项目中遇到过一台服务器,怎么都起不来。查了半天,发现是网卡的Option ROM没有签名。UEFI固件检测到未签名的代码,直接罢工。嗯,从那以后,我再也不敢忽略Option ROM的签名问题了。

整个流程可以概括为:

  1. 固件加载引导加载程序(如shim.efi)
  2. 检查其签名是否在允许的数据库中
  3. 通过则执行,不通过则拒绝
  4. 引导加载程序再检查内核签名
  5. 内核再检查模块签名

这就是一条信任链,环环相扣。

3.3 密钥管理与注册:这才是核心

密钥管理是Secure Boot里最复杂、也最容易出错的部分。我建议你把它想象成一个“白名单”系统。

UEFI固件里维护了几个关键的数据库:

数据库名称 作用 说明
PK (Platform Key) 平台密钥 最高权限,用于管理其他密钥
KEK (Key Exchange Key) 密钥交换密钥 用于更新签名数据库
db (Signature Database) 允许签名数据库 存放允许执行的签名
dbx (Revoked Signature Database) 吊销签名数据库 存放被吊销的签名

你看,这其实就是一个层级结构。PK在最顶层,KEK在中间,db和dbx在最底层。注册密钥的顺序也有讲究:先注册PK,再注册KEK,最后注册db。

我曾经犯过一个错误:先注册了db,再注册PK。结果PK注册失败,整个Secure Boot配置全乱了。最后只能清空CMOS,从头再来。所以,顺序很重要。

核心要点: 注册密钥的顺序必须是 PK → KEK → db。千万别搞反。

实际操作中,注册密钥通常通过以下方式:

  • 使用厂商工具:如微软的SignTool,或者Linux下的efi-updatevar
  • 手动导入:在BIOS设置界面里,选择“Enroll Key”或“Add Key”
  • 自动注册:有些操作系统安装程序会自动注册其签名

举个例子,在Linux下注册一个自定义密钥:

# 生成密钥对
openssl req -new -x509 -newkey rsa:2048 -keyout my.key -out my.crt -days 3650

# 转换为EFI签名列表格式
cert-to-efi-sig-list my.crt my.esl

# 注册到db数据库
efi-updatevar -e my.esl db

嗯,这里要注意:efi-updatevar 需要在内核启动参数中启用 efi=debug 才能正常工作。否则你会看到“Permission denied”的错误。

3.4 避坑指南:我踩过的那些坑

最后,分享几个我亲身经历过的坑,希望能帮你少走弯路。

  • 坑一:忘记备份原始密钥。我曾经在注册新密钥前,没有备份原始的Microsoft密钥。结果系统更新后,新内核的签名不在我的自定义数据库里,系统直接无法启动。从那以后,我每次操作前都会先导出所有密钥。
  • 坑二:误吊销了关键签名。有一次,我不小心把Microsoft的签名加到了dbx(吊销数据库)里。结果所有Windows系统都无法启动。嗯,那次折腾了整整一天。
  • 坑三:忽略固件更新。有些固件更新会重置Secure Boot配置。我建议在更新固件后,重新检查一遍密钥状态。
小技巧: 在启用Secure Boot前,先用 mokutil --sb-state 检查当前状态。如果显示 SecureBoot disabled,再开始配置。

好了,这一章的内容就到这里。Secure Boot说难不难,说简单也不简单。关键在于理解它的原理,然后按部就班地操作。记住,密钥管理是核心,顺序是命门。

UEFI安全启动核心逻辑 UEFI固件 验证签名(db / dbx) 引导加载程序(shim.efi) 操作系统内核 PK KEK db / dbx 最高权限 密钥交换 签名数据库