)
不关Secure Boot用mokutil永久解决Linux内核模块签名问题附自动化脚本在企业级Linux运维中Secure Boot作为UEFI固件的重要安全功能能有效防止恶意软件在启动过程中加载未经验证的代码。但当我们尝试加载自行编译或第三方内核模块时常会遇到Key was rejected by service的错误提示。本文将深入解析MOK机制的工作原理并提供一套完整的自动化解决方案。1. Secure Boot与内核模块签名的技术本质Secure Boot并非简单的开关功能而是构建在PKI体系上的完整信任链。当UEFI固件启用Secure Boot时系统只会加载经过微软或发行版厂商数字签名的组件。这种设计虽然提升了安全性却给开发者加载自定义内核模块带来了挑战。传统解决方案中关闭Secure Boot虽然简单直接但会带来三个显著问题系统启动完整性检查被完全禁用丧失对恶意rootkit的防护能力不符合企业安全合规要求MOKMachine Owner Key机制则提供了更优雅的解决方案。其核心原理是允许终端用户将自己的公钥注入系统信任链该密钥与厂商证书处于不同信任层级签名验证时系统会同时检查两级信任关系# 信任链验证流程伪代码 verify_signature() { if (signature vendor_cert) return ALLOW; else if (signature mok_cert mok_enrolled) return ALLOW; else return REJECT; }2. 完整MOK配置流程详解2.1 环境准备与依赖安装在Ubuntu/Debian系系统上需要确保以下软件包已安装sudo apt update sudo apt install -y mokutil openssl shim-signed关键组件说明mokutilMOK管理工具openssl证书生成工具shim-signedSecure Boot兼容层2.2 密钥对生成最佳实践建议在安全目录下生成密钥对并设置严格的权限控制sudo mkdir -p /etc/secureboot/keys cd /etc/secureboot/keys sudo openssl req -new -x509 -newkey rsa:4096 \ -keyout MOK.priv -outform DER -out MOK.der \ -nodes -days 3650 -subj /CN$(hostname)/ sudo chmod 600 MOK.priv参数优化建议RSA密钥长度从2048升级到4096位有效期延长至10年3650天使用主机名作为证书CN字段3. 自动化签名解决方案3.1 智能签名脚本实现以下脚本自动处理密钥生成、MOK注册和模块签名全过程#!/bin/bash # auto_sign_module.sh - Automated kernel module signing solution KEYS_DIR/etc/secureboot/keys MODULE$1 [ -z $MODULE ] { echo Usage: $0 module.ko; exit 1; } init_keys() { [ -d $KEYS_DIR ] || sudo mkdir -p $KEYS_DIR [ -f $KEYS_DIR/MOK.der ] return sudo openssl req -new -x509 -newkey rsa:4096 \ -keyout $KEYS_DIR/MOK.priv -outform DER -out $KEYS_DIR/MOK.der \ -nodes -days 3650 -subj /CN$(hostname)/ sudo chmod 600 $KEYS_DIR/MOK.priv } register_mok() { if ! sudo mokutil --test-key $KEYS_DIR/MOK.der 2/dev/null; then echo Registering MOK key... read -sp Set MOK enrollment password: password echo sudo mokutil --import $KEYS_DIR/MOK.der $password echo Key enrolled, please reboot to complete MOK registration exit 0 fi } sign_module() { local kernel_version$(uname -r) local sign_file/usr/src/linux-headers-$kernel_version/scripts/sign-file [ -f $sign_file ] || { echo Error: sign-file script not found for kernel $kernel_version exit 1 } sudo $sign_file sha256 $KEYS_DIR/MOK.priv $KEYS_DIR/MOK.der $MODULE echo Module $MODULE signed successfully } init_keys register_mok sign_module3.2 内核更新自动触发机制通过DKMS和systemd服务实现自动化签名创建DKMS配置钩子# /etc/kernel/postinst.d/sign_modules #!/bin/bash KERNEL_VERSION$1 find /lib/modules/$KERNEL_VERSION -name *.ko -exec /usr/local/bin/auto_sign_module.sh {} \;注册systemd服务监控内核更新# /etc/systemd/system/module-signing.path [Unit] DescriptionWatch for kernel updates [Path] PathChanged/lib/modules/ [Install] WantedBymulti-user.target4. 企业级部署注意事项4.1 安全审计与密钥管理对于生产环境建议实施以下安全措施安全措施实施方法风险控制密钥轮换每12个月更新MOK密钥新旧密钥并行期30天访问控制密钥目录权限750root专属访问日志审计记录所有签名操作syslog集中收集4.2 常见问题诊断当遇到EFI variables are not supported错误时检查以下项目确认系统以UEFI模式启动[ -d /sys/firmware/efi ] echo UEFI || echo BIOS虚拟机需启用EFI支持VMware: 虚拟机设置 → 选项 → 高级 → 固件类型VirtualBox: 系统 → 主板 → 启用EFI物理机检查BIOS设置确保UEFI Boot已启用CSM Support应设为Disabled5. 高级应用场景扩展5.1 多主机统一签名方案在服务器集群环境中可通过以下方式实现集中管理生成统一的CA证书openssl genrsa -out cluster-ca.key 4096 openssl req -new -x509 -key cluster-ca.key \ -out cluster-ca.crt -days 3650 -subj /CNClusterCA/为每台主机签发子证书openssl genrsa -out node01.key 4096 openssl req -new -key node01.key -out node01.csr \ -subj /CNnode01/ openssl x509 -req -in node01.csr -CA cluster-ca.crt \ -CAkey cluster-ca.key -CAcreateserial -out node01.crt -days 3650部署脚本自动识别主机证书# 在auto_sign_module.sh中添加 NODE_CERT/etc/secureboot/keys/$(hostname).crt NODE_KEY/etc/secureboot/keys/$(hostname).key5.2 内核模块完整性验证签名后可通过以下方式验证模块完整性# 检查模块签名信息 modinfo module.ko | grep ^sig_ # 验证签名有效性 sudo cat /proc/keys | grep Module signature典型输出示例signer: myhost sig_key: A1:B2:C3:... sig_hashalgo: sha256