以下是一份完整的 Secure Boot 模块签名教程,保存备用,下次给其他模块签名时直接照着做。


环境要求

  • Ubuntu 22.04+(或其他使用 shim/MOK 的发行版)
  • 内核版本 5.4+(使用 uname -r 查看)
  • Secure Boot 处于 enabled 状态

第一步:创建签名密钥(只需做一次)

1
2
3
4
5
6
7
8
9
10
mkdir -p ~/mok && cd ~/mok

# 生成 2048 位 RSA 密钥对,有效期 100 年
openssl req -new -x509 -newkey rsa:2048 \
-keyout MOK.priv \
-outform DER \
-out MOK.der \
-nodes \
-days 36500 \
-subj "/CN=Custom Kernel Module Signing/"

生成的两个文件:

文件 用途 保密级别
MOK.priv 私钥,用于签名模块 绝对保密,不要外传
MOK.der 公钥,导入到 UEFI MOK 数据库 可以公开

第二步:将公钥导入 MOK 数据库

1
sudo mokutil --import MOK.der
  • 会提示你设置一个 MOK 密码(8-16 位,纯数字即可,如 12345678
  • 记住这个密码,重启后需要在蓝色 MOK Manager 界面输入

第三步:重启,在 MOK Manager 中确认导入

  1. 重启电脑
  2. 出现 蓝色 MOK Manager 界面
  3. 选择 Enroll MOKContinueYes → 输入刚才设置的密码 → Reboot

如果蓝色界面没出现,说明 shim 没有触发 MOK 注册,检查 mokutil --sb-state 确认 Secure Boot 确实开启。


第四步:给内核模块签名

通用签名命令

1
2
3
4
5
6
7
8
9
10
11
# 变量定义(每次签名时替换模块路径)
MODULE_PATH="/lib/modules/$(uname -r)/kernel/drivers/.../xxx.ko"
PRIV_KEY="$HOME/mok/MOK.priv"
PUB_KEY="$HOME/mok/MOK.der"

# 执行签名
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file \
sha256 \
"$PRIV_KEY" \
"$PUB_KEY" \
"$MODULE_PATH"

常用模块签名示例

示例 1:Realtek r8125 网卡驱动

1
2
3
4
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
~/mok/MOK.priv \
~/mok/MOK.der \
/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/r8125.ko

示例 2:NVIDIA 闭源驱动(如果你手动安装过)

1
2
3
4
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
~/mok/MOK.priv \
~/mok/MOK.der \
/lib/modules/$(uname -r)/kernel/drivers/video/nvidia.ko

示例 3:VirtualBox 内核模块

1
2
3
4
5
6
for mod in vboxdrv vboxnetadp vboxnetflt; do
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
~/mok/MOK.priv \
~/mok/MOK.der \
/lib/modules/$(uname -r)/misc/${mod}.ko
done

示例 4:自己编译的任意 out-of-tree 模块

1
2
3
4
5
# 假设你编译的模块在 /path/to/your-module.ko
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
~/mok/MOK.priv \
~/mok/MOK.der \
/path/to/your-module.ko

第五步:加载模块并验证

1
2
3
4
5
6
7
8
# 重新加载模块
sudo modprobe 模块名

# 验证是否加载成功
lsmod | grep 模块名

# 查看内核日志确认没有 "Key was rejected"
sudo dmesg | tail -n 10

关键注意事项

问题 说明
密钥只需创建一次 MOK 导入成功后,同一对密钥可以给任意模块签名
每次编译新模块都要重新签名 签名和模块内容绑定,重新编译后必须重新签名
私钥 MOK.priv 必须妥善保管 泄露后别人可以用你的密钥签名恶意模块
MOK 密码不是系统密码 是你在 mokutil --import 时单独设置的,仅用于 MOK Manager 验证
同一密钥可以导入多台机器 MOK.der 复制到其他机器重复步骤 2-3 即可

快速检查清单(每次签名时对照)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 确认 Secure Boot 状态
mokutil --sb-state # 应输出 "SecureBoot enabled"

# 2. 确认密钥存在
ls ~/mok/MOK.priv ~/mok/MOK.der

# 3. 确认 sign-file 工具存在
ls /usr/src/linux-headers-$(uname -r)/scripts/sign-file

# 4. 签名
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
~/mok/MOK.priv ~/mok/MOK.der /path/to/module.ko

# 5. 验证签名是否成功
modinfo /path/to/module.ko | grep sig
# 应输出类似 "sig_key: ..." 和 "sig_hashalgo: sha256"

# 6. 加载测试
sudo modprobe 模块名

备份建议

~/mok/ 目录备份到安全位置(如加密 U 盘或密码管理器):

1
tar czf ~/mok_backup.tar.gz ~/mok

下次换机器或重装系统时,只需要用 MOK.der 重新导入即可,不需要重新生成密钥。