制作含额外模块的MOK签名GRUB时遭遇启动验证失败的问题求助
我现在碰到一个和Wake-on-LAN相关的GRUB配置难题:想让GRUB通过网络请求(比如用load_env (http,192.168.1.123)/grubenv)来判断是否要启动Windows,这样我就能在唤醒机器前写入这个文件来控制启动选项。但Ubuntu默认的签名GRUB缺少http、tftp这类模块,而且开启Secure Boot后,它会拒绝从磁盘加载这些未签名的模块。
我本来以为注册MOK并签名一个独立版本的GRUB就能解决问题,但现在启动时会弹出shim的蓝色文本对话框,提示:
Verification failed: (0x1A) Security Violation
之后会出现"Shim UEFI key management"对话框,我尝试注册grubx64.efi的哈希值,但奇怪的是,注册完成后下次启动还是同样的错误,而且对话框里显示的哈希和我直接对grubx64.efi或者/boot/efi里其他文件做sha256sum得到的结果都不匹配。
我的MOK证书包含X509v3 Extended Key Usage: Code Signing, 1.3.6.1.4.1.311.10.3.6,不像发行版生成的证书那样带有1.3.6.1.4.1.2312.16.1.2这个仅用于内核模块签名的限制ID。
我的具体操作步骤:
- 创建初始GRUB配置文件
grub-initial.cfg:
cat >grub-initial.cfg <<EOF search.fs_uuid [……/boot uuid……] root set prefix=($root)/grub configfile $prefix/grub.cfg EOF
- 定义需要包含的GRUB模块列表:
MODULES="tpm part_gpt lvm ext2 fat chain linux efifwsetup \ efi_uga efi_gop efinet configfile normal gzio gfxterm ls cat \ test echo http gfxterm_background png gfxterm_menu gfxmenu \ sleep videoinfo gettext loadenv search luks password_pbkdf2 \ extcmd terminal play linuxefi search_fs_uuid search_label \ search_fs_file regexp reboot halt memdisk lsefi"
- 生成未签名的独立GRUB镜像:
grub-mkstandalone --compress=xz -O x86_64-efi -o grubx64.unsigned \ --install-modules="$MODULES" --modules="$MODULES" --themes="" \ --locales="en@quot" boot/grub/grub.cfg=grub-initial.cfg
- 用我的MOK密钥对GRUB镜像进行签名:
sbsign --key /etc/keys/MOK.priv --cert /etc/keys/MOK.pem \ --output grubx64.efi grubx64.unsigned
- 验证MOK证书已经注册:
mokutil --test-key /etc/keys/MOK.der # 输出结果:/etc/keys/MOK.der is already enrolled
- 验证签名后的GRUB镜像有效性:
sbverify --cert /etc/keys/MOK.pem /boot/efi/EFI/bifrost/grubx64.efi # 输出结果:Signature verification OK
- 在ESP分区创建新目录并复制相关文件:
mkdir /boot/efi/EFI/bifrost cp grubx64.efi /boot/efi/EFI/bifrost/ cp /boot/efi/EFI/ubuntu/{shimx64.efi,mmx64.efi} /boot/efi/EFI/bifrost/
- 创建新的UEFI启动项:
efibootmgr -c -d /dev/nvme0n1p1 -L "bifrost auto select" -l "\EFI\bifrost\shimx64.efi"
- 确认启动项创建成功:
efibootmgr -v # 输出片段: # Boot0001* bifrost auto select HD(1,GPT,[……ESP uuid……],0x800,0x82000)/File(\EFI\BIFROST\SHIMX64.EFI) # Boot0002* ubuntu HD(1,GPT,[……ESP uuid……],0x800,0x82000)/File(\EFI\UBUNTU\SHIMX64.EFI)..BO
完成以上操作后,我手动选择新的启动项重启,就遇到了开头提到的验证失败错误。
我对问题的一些猜测:
正常启动默认GRUB的流程是:Boot0002 -> Ubuntu shim -> Ubuntu GRUB -> Linux或Windows
而启动我自制GRUB的流程是:Boot0001 -> 复制的Ubuntu shim -> 拒绝我的GRUB,但我不知道具体原因
可能的原因方向:
- 是不是不小心启动了其他位置的shim文件?
- 复制的Ubuntu shim是不是没有加载同目录下的grubx64.efi,而是尝试加载了其他文件?
- 复制的Ubuntu shim依赖的密钥集合和mokutil管理的不是同一套?
- 最有可能的是,我对Secure Boot、shim和GRUB签名的整个流程存在理解误区?
备注:内容来源于stack exchange,提问作者Chris Boyle

