关键是要完成签名链的可信传递,即同时满足UEFI固件和Linux内核层的签名要求:UEFI层需验证引导程序或直接加载的内核映像(如efistub或UKI),内核层则要求vmlinuz、initramfs及所有模块均被可信密钥签名,并通过MOK或PK机制将公钥注入信任链。

要让自定义编译的内核在启用 Secure Boot 的 UEFI 环境下正常启动,关键不是“绕过”验证,而是让固件和内核都认可你的内核映像——即完成签名链的可信传递。这需要同时满足 UEFI 层和 Linux 内核层的签名要求。
确认当前启动模式与 Secure Boot 状态
先验证系统是否运行在 UEFI 模式且 Secure Boot 已启用:
- 运行
ls /sys/firmware/efi—— 若目录存在,说明是 UEFI 启动; - 运行
mokutil --sb-state或sudo dmesg | grep -i "secure boot"—— 查看 Secure Boot 当前是否 enabled; - 检查内核是否强制模块签名:
zcat /proc/config.gz | grep CONFIG_MODULE_SIG_FORCE(若为y,则未签名模块完全拒载)。
选择签名策略:MOK 还是平台密钥(PK)?
普通用户推荐使用 Machine Owner Key(MOK),无需修改固件信任根,操作安全可逆;企业或嵌入式场景可考虑替换平台密钥(PK),但风险高、需物理接触固件界面。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
-
MOK 方式:用
openssl生成私钥/公钥对 → 编译时用私钥签名内核和模块 → 用mokutil将公钥导入 MOK 列表 → 重启后进入 MOK 管理界面确认导入; - Pk 方式:需进入 UEFI 设置禁用默认 PK → 导入自签 CA 公钥作为新 PK → 所有后续签名必须由该 CA 签发;此方式影响整个固件信任体系,不建议初学者尝试。
签名内核映像(vmlinuz)
UEFI 是否验证内核,取决于你如何加载它:
- 若使用 GRUB 加载内核(主流方式):GRUB 本身需被 Secure Boot 验证(发行版已预签名),内核由 GRUB 在运行时加载,不直接受 UEFI 验证,但需满足内核自身的模块签名策略;
- 若使用 efistub 直接启动(如 systemd-boot):
vmlinuz必须单独签名成 EFI 映像,命令示例:sbsign --key MOK.priv --cert MOK.crt --output vmlinuz.signed vmlinuz; - 若使用 Unified Kernel Image(UKI)(如 systemd-boot + ukify):整个 UKI 文件(含内核、initramfs、cmdline)需整体签名,签名后才能被 UEFI 加载。
签名内核模块并注入信任链
即使内核能启动,未签名模块仍会被拒绝加载(报 Required key not available)。需同步签名所有自编译模块:
- 编译模块时启用签名:在
make modules前设置环境变量:KBUILD_EXTRA_SYMBOLS=/lib/modules/$(uname -r)/build/Module.symversCONFIG_MODULE_SIG=y且CONFIG_MODULE_SIG_ALL=y(编译时自动签名); - 手动签名已有模块:
sign-file sha256 MOK.priv MOK.crt ./your-module.ko; - 确保内核密钥环包含你的公钥:
sudo cp MOK.crt /usr/share/kernel-signing-certs/(路径依发行版而异),或通过keyctl padd动态注入(仅临时有效)。
配置完成后,重启触发 MOK 导入流程(若选 MOK 方式),通过 UEFI 图形界面确认信任。此后,签名过的内核与模块即可在 Secure Boot 全启用状态下稳定运行——既保持硬件级启动安全,又保留深度定制能力。

















