4、GRUB2引导加载器:安装、签名与密码保护

好,咱们继续往下走。上一章我们把UEFI Secure Boot的框架搭起来了,但说实话,那只是第一道门。真正跟操作系统内核打交道的,是GRUB2这个引导加载器。它负责把内核从磁盘里拽出来,然后交棒给系统。如果GRUB2被人动了手脚,那前面所有的安全措施都白费了。

这一章,我带你搞定三件事:GRUB2的安装与配置、GRUB2的签名与验证、以及GRUB2的密码保护。这三步走完,你的引导链才算真正有了“可信”的根基。

4.1 GRUB2安装与配置

先说说安装。很多同学觉得GRUB2安装就是敲个grub-install完事。嗯,确实能启动,但离“可信”还差得远。我个人习惯,安装之前先想清楚:你的启动分区是啥格式? 内核参数要不要加安全选项?

最基本的安装命令长这样:

# 假设你的EFI分区挂载在 /boot/efi
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB

但这里有个坑——默认安装的GRUB2可能不包含你需要的模块。比如,你要用LUKS全盘加密,就得确保cryptodisk和luks模块被装进去了。我在项目中遇到过,装完系统重启,发现GRUB2根本不认识加密分区,直接卡在grub rescue界面。后来怎么解决的?手动指定模块列表:

grub-install --target=x86_64-efi --efi-directory=/boot/efi \
  --bootloader-id=GRUB --modules="part_gpt part_msdos cryptodisk luks gcry_rijndael gcry_sha256 ext2"

配置方面,核心文件是/etc/default/grub。改完这个文件,记得跑update-grub(或者grub-mkconfig -o /boot/grub/grub.cfg)。我个人建议,至少把下面几个参数加上:

  • GRUB_CMDLINE_LINUX:内核启动参数,比如quiet splash可以去掉,方便看启动日志。
  • GRUB_ENABLE_CRYPTODISK=y:如果你用了全盘加密,这个必须开。
  • GRUB_TIMEOUT:倒计时秒数,我一般设成5秒,既不会等太久,也来得及手动干预。
小提示: 如果你在虚拟机里测试,记得把EFI分区格式化成FAT32,别用ext4。UEFI固件只认FAT32,这是个老生常谈的坑了。

4.2 GRUB2签名与验证

好,安装配置完了。但你想过没有——怎么保证你加载的GRUB2是原装的? 如果有人偷偷替换了你的grubx64.efi文件,系统照样能启动,但内核可能已经被植入了后门。

这就是签名验证要解决的问题。说白了,就是用私钥给GRUB2的EFI文件打个戳,然后在UEFI固件里只认这个戳。别人改过的文件,签名对不上,直接拒绝启动。

具体怎么做?分三步:

  1. 生成你自己的签名密钥对(如果你还没有的话)。
  2. 用私钥对GRUB2的EFI文件签名。
  3. 把公钥注册到UEFI的MOK(Machine Owner Key)列表里。

签名命令示例:

# 假设你的私钥是 MOK.key,公钥是 MOK.der
sbsign --key MOK.key --cert MOK.der --output /boot/efi/EFI/GRUB/grubx64.efi.signed /boot/efi/EFI/GRUB/grubx64.efi

然后,把签名后的文件替换掉原来的:

cp /boot/efi/EFI/GRUB/grubx64.efi.signed /boot/efi/EFI/GRUB/grubx64.efi

注册公钥到MOK:

mokutil --import MOK.der

重启后,系统会提示你输入密码确认导入。嗯,这一步别跳过,否则签名等于白做。

警告: 签名用的私钥一定要保管好!我曾经有个客户,把私钥存在了CI/CD服务器的共享目录里,结果被内部人员泄露了。整个产线的签名信任链都得重建,那叫一个折腾。建议用HSM(硬件安全模块)或者至少用加密U盘单独存放。

验证是否生效也很简单:

sbverify --cert MOK.der /boot/efi/EFI/GRUB/grubx64.efi

如果输出Signature verification OK,那就稳了。

4.3 GRUB2密码保护

签名验证解决的是“文件被篡改”的问题。但还有一个场景:物理接触。如果有人能直接按键盘,在GRUB2菜单里按e编辑启动参数,他就能绕过你的密码、甚至直接进单用户模式。你想想看,这多可怕。

所以,GRUB2密码保护是必须的。它分两种:

  • 普通密码:启动时直接输密码才能进系统。
  • 超级用户密码:只有输了这个密码,才能编辑菜单项、进命令行。

我个人建议,至少设置超级用户密码。因为普通用户密码会影响自动化重启(比如无人值守更新),而超级用户密码只在你需要手动干预时才用。

设置方法:

grub-mkpasswd-pbkdf2

它会让你输两次密码,然后生成一串哈希。把这段哈希复制下来,加到/etc/grub.d/40_custom文件里:

set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.XXXXXXXXXXXXXXXX...YYYYYY

然后更新GRUB配置:

update-grub

重启后,你按e编辑菜单项时,就会弹出密码框了。

核心要点: GRUB2密码保护不是用来防“黑客”的,而是用来防“物理接触”的。如果有人能摸到你的机器,他就能用U盘启动、拆硬盘、甚至用调试器。密码保护只是增加一道门槛,让普通操作员没法乱改启动参数。

知识体系总览

下面这张图,把GRUB2可信部署的核心逻辑串起来了。你可以把它当成一个检查清单:

GRUB2可信部署核心逻辑 安装与配置 签名与验证 密码保护 grub-install + 模块选择 /etc/default/grub 参数调优 update-grub 生成配置 生成密钥对 (MOK) sbsign 签名 EFI 文件 mokutil 注册公钥 grub-mkpasswd-pbkdf2 生成哈希 配置 superusers 和密码 防止物理篡改启动参数 三者缺一不可,构成完整可信引导链

这张图你看懂了吗?从左到右,安装配置是基础,签名验证是防篡改,密码保护是防物理接触。三者缺一不可。我在实际项目中见过不少团队,只做了签名验证,觉得万事大吉了。结果机房运维人员不小心按了e键,把ro改成了rw,系统直接以读写模式启动了……嗯,从那以后,我每次部署都会把密码保护加上。

避坑指南: 我曾经在批量部署时,用脚本自动生成了GRUB2密码哈希。结果发现,所有机器的密码都一样!这等于没设。后来我改成每台机器单独生成,并记录到密钥管理系统中。记住:密码保护不是摆设,密码本身也要保护好。

好了,这一章的内容就这些。GRUB2这块,说难不难,说简单也不简单。关键是把“安装-签名-密码”这三步走扎实。下一章,我们会深入内核层面,看看怎么给内核也加上签名验证。但那是后话了,先把GRUB2搞定再说。


可可精品资料库