4. Bootloader阶段
大家好,我是你们的系统安全工程师。今天我们来聊聊可信启动链中非常关键的一环——Bootloader阶段。说白了,这是操作系统启动前最后一道防线,也是整个信任链传递的枢纽。我个人习惯把这一阶段称为“承上启下的守门员”。
你想想看,UEFI固件验证了Bootloader,Bootloader再去验证内核,一环扣一环。如果Bootloader本身被篡改了,那后面的一切都是白搭。所以,这一章的内容,我建议你认真消化。
核心要点:Bootloader阶段的核心任务,就是确保引导加载程序本身是可信的、未被篡改的,并且能够安全地将控制权交给下一个阶段(内核)。
4.1 GRUB2的安装与配置
GRUB2,全称GRand Unified Bootloader version 2,是目前Linux世界最主流的引导加载程序。嗯,这里要注意,它不仅仅是启动菜单那么简单。
安装GRUB2
在UEFI系统上安装GRUB2,我一般会这样做:
# 安装GRUB2到EFI系统分区
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
# 生成配置文件
grub-mkconfig -o /boot/grub/grub.cfg
我在项目中遇到过一个问题:有人直接复制了grub.cfg文件,结果启动时菜单乱码。为什么?因为grub-mkconfig会根据当前系统状态动态生成配置,包括内核版本、磁盘UUID等。手动复制很容易出错。
配置要点
GRUB2的配置文件是/boot/grub/grub.cfg,但我不建议你直接编辑它。正确的做法是修改/etc/default/grub,然后重新生成。比如:
# 设置超时时间
GRUB_TIMEOUT=5
# 设置默认启动项
GRUB_DEFAULT=0
# 启用加密(如果你需要)
GRUB_ENABLE_CRYPTODISK=y
改完后,记得运行grub-mkconfig -o /boot/grub/grub.cfg。这个习惯我保持了很多年,从来没出过问题。
4.2 GRUB2的签名与验证
GRUB2本身支持签名验证。说白了,就是给GRUB2的二进制文件加上数字签名,UEFI固件在加载它之前会验证这个签名。
签名流程
我曾经帮一家企业做过安全加固,他们的做法是这样的:
- 生成一个用于签名的密钥对
- 使用私钥对GRUB2的EFI文件签名
- 将公钥注册到UEFI固件或MOK中
# 使用sbsign工具签名
sbsign --key my.key --cert my.crt --output /boot/efi/EFI/GRUB/grubx64.efi.signed /boot/efi/EFI/GRUB/grubx64.efi
这里有个坑:签名后的文件必须放在EFI系统分区中,并且文件名要对应。我曾经见过有人签名后忘了改名,结果固件找不到文件,直接启动失败。
注意事项:签名密钥一定要妥善保管!如果私钥泄露,攻击者就可以用你的密钥签名恶意代码。我建议使用硬件安全模块(HSM)或至少使用强密码保护私钥文件。
4.3 shim引导加载程序
shim是什么?它其实是一个小型的、经过微软签名的引导加载程序。为什么需要它?因为很多Linux发行版无法直接获得微软的签名,所以它们通过shim来间接实现安全启动。
shim的工作流程是这样的:
- UEFI固件加载并验证shim(shim有微软签名)
- shim验证GRUB2(使用MOK或内嵌证书)
- GRUB2验证内核
说白了,shim就是一个“信任代理”。它本身是可信的,然后它再去验证下一个组件。
我记得有一次,一个客户升级了内核后无法启动。排查了半天,发现是shim版本太旧,不认识新的GRUB2签名算法。升级shim后问题解决。所以,shim也要保持更新。
4.4 MOK(机器所有者密钥)管理
MOK,全称Machine Owner Key。它是你机器自己的密钥库,用来管理那些不在UEFI固件数据库中的证书。
MOK的管理工具
我常用的工具是mokutil和shim-signed。比如:
# 查看已注册的MOK
mokutil --list-enrolled
# 注册一个新的MOK
mokutil --import my-cert.der
# 删除一个MOK
mokutil --delete my-cert.der
注册MOK后,需要重启并进入MOK管理界面(通常按任意键进入),确认操作。这个步骤很多人会忽略,结果注册了却不起作用。
小技巧:如果你需要批量部署多台机器,可以预先生成好MOK证书,通过kickstart或preseed脚本自动导入。我在自动化部署项目中就是这么做的,省了不少时间。
4.5 PreLoader与HashTool
PreLoader是另一种引导加载程序,它的思路和shim类似,但更轻量。HashTool则是用来管理哈希列表的工具。
PreLoader的工作原理
PreLoader会维护一个哈希白名单。只有哈希值在白名单中的程序才能被加载。这个白名单可以通过HashTool来管理。
我曾经在一个嵌入式项目中用过PreLoader,因为它的体积小,适合资源受限的设备。但要注意,哈希白名单的管理比较麻烦——每次更新内核或GRUB2,都需要重新计算哈希并更新白名单。
HashTool的使用
HashTool通常在PreLoader启动时自动运行。你可以通过它:
- 查看当前白名单中的哈希值
- 添加新的哈希值
- 删除旧的哈希值
嗯,这里要提醒一下:HashTool的操作界面是文本模式的,没有鼠标支持。我第一次用的时候还不太习惯,但用多了就发现其实挺高效的。
知识体系总览
为了让你更直观地理解整个Bootloader阶段的知识结构,我画了一张图:
从这张图你可以看到,整个Bootloader阶段是一个层层递进的信任链。每一层都依赖上一层来验证自己的可信性。shim和PreLoader是两种不同的实现方式,但目标一致——确保GRUB2是可信的。
好了,这一章的内容就到这里。记住,Bootloader阶段是整个可信启动链的基石,一定要打好基础。
可可精品资料库