在Fedora中全自动签名英伟达驱动内核模块以支持安全启动
前言
目前新出厂的电脑UEFI会默认开启安全启动(Secure Boot),以阻止不受信任的引导加载程序启动,可以在一定程度上防御RootKit病毒,不过同样会阻止一些未经微软签名的Linux发行版的安装和运行,比如Arch Linux。虽然可以直接选择在主板设置中关闭安全启动来解决一系列麻烦,但就在近期微软公布的Windows11最低硬件标准中可以看到,安全启动被微软看的越来越重。所以掌握让自己常用的Linux发行版支持安全启动的方法是有必要的。然而,让Linux本身支持安全启动,最重要的是让发行商对该Linux的内核与引导加载器进行签名。本文就已经通过安全启动认证的比较受欢迎的一个Linux发行版——Fedora,来讲解常见的英伟达驱动签名问题。
至于为什么有这个教程,是因为如果在Fedora上通过自带软件源一键安装官方的英伟达驱动,会造成这些驱动的内核模块未签名,导致在Linux启动过程中因为安全启动校验签名的存在,被阻止加载这些模块,进而无法正常驱动显卡。用过Ubuntu的伙伴们应该知道,在安全启动开启的情况下 ,Ubuntu安装程序会自动用自签密钥签名英伟达驱动内核模块,并在开机过程中自动将该自签密钥导入MOK List(安全启动机器主人信任密钥列表)。而Fedora只会保证自身内核签名有效,对后期安装的第三方内核模块签名问题不予理会,导致无法正常加载英伟达驱动。
本教程参考这里并实现,感谢该博客作者
本教程已在Fedora 36 Beta版本上测试通过,理论上向下兼容,具体是否有效请自测。注意备份重要数据!笔者仅为分享经验,不对您的任何操作造成的任何后果而负责!
最新测试显示,本教程方法仅适用于Fedora 36 Beta及以下版本,Fedora 36正式版不再适用,官方支持通过特定工具一键生成安全启动密钥并导入,具体请参考这里
前提条件
在开始之前,您的电脑必须满足以下条件
- 主板必须在已经开启安全启动的情况下安装Fedora
- 必须确保任何来源、任何版本的英伟达驱动从未被安装过 (如果已经安装过,请搜索有关彻底卸载的相关教程,或者直接重装系统。因为笔者在试验时发现卸载完后再继续进行以下步骤仍然会导致驱动模块无法被签名)
具体步骤
打开终端,按步骤分别执行以下命令(本教程通用性强,无需考虑命令中的路径与环境变量问题)。
1.将系统更新到最新并重启Fedora
1 | sudo dnf update |
2.安装Mok工具(mokutil)和密钥生成工具(openssl)
1 | sudo dnf install mokutil openssl |
3.生成内核驱动模块的自签安全启动密钥
1 | sudo openssl req -new -x509 -newkey rsa:2048 -keyout ~/driver-signing.key -outform DER -out ~/driver-signing.der -nodes -days 36500 -subj "/CN=Private Driver Signing" |
4.将刚刚自签的安全启动密钥进行注册(导入进主板)
此操作会让Linux内核信任由该自签密钥签名过的任何内核模块。
1 | sudo mokutil --import ~/driver-signing.der |
执行完此命令后,控制台会让您设置一个密码,该密码的作用是用来导入并注册自签自签密钥,只会在第6步用到一次,合理设置即可,建议8位。
5.重启电脑
1 | sudo reboot |
6.导入并注册自签密钥
在第5步键入完命令并重启时,系统启动之前会出现一个蓝色界面(标题为MOK Manager)。在安全启动的条件下安装过Ubuntu的您可能会熟悉。按照以下选项导入密钥即可:
注意:以下几个步骤要小心,任何一步误操作,都必须从第4步开始重做。
通过方向键选择“Enroll MOK”
选择“Continue”
选择“Yes”
此时输入在第4步时设置的密码并回车(输入过程中密码不会显示)
成功后选择“Reboot”
此时,电脑会再次重启,等待进入Fedora即可。
7.启用两个第三方仓库,以便于安装修改过的内核工具进行模块签名
(感谢Elia Geretto提供的仓库)
1 | sudo dnf copr enable egeretto/kmodtool-secureboot |
1 | sudo dnf copr enable egeretto/akmods-secureboot |
8.修改仓库优先级,让修改过的内核工具优先于官方原版安装
以ROOT权限打开文件管理器,修改以下两个文件,每个文件均增加一行:priority=1,然后保存退出。
执行以下命令刷新软件源:
1 | sudo dnf update --refresh |
9.安装修改过的内核工具(kmodtool与akmods)
1 | sudo dnf install kmodtool akmods |
注意控制台中的此处,查看这两个软件包是否来自于刚刚添加的第三方仓库
输入y同意导入仓库公钥:
10.移动证书至正确的位置以便于内核工具能识别到
依次执行以下命令即可:
1 | sudo mv ~/driver-signing.der /etc/pki/akmods/certs/public_key.der |
1 | sudo chown root:akmods /etc/pki/akmods/certs/public_key.der |
1 | sudo chmod 640 /etc/pki/akmods/certs/public_key.der |
1 | sudo mv ~/driver-signing.key /etc/pki/akmods/private/private_key.priv |
1 | sudo chown root:akmods /etc/pki/akmods/private/private_key.priv |
1 | sudo chmod 640 /etc/pki/akmods/private/private_key.priv |
11.安装英伟达驱动
执行以下命令即可:
1 | sudo dnf install gcc kernel-headers kernel-devel akmod-nvidia xorg-x11-drv-nvidia xorg-x11-drv-nvidia-libs xorg-x11-drv-nvidia-libs.i686 |
12.编译并签名驱动内核模块
1 | sudo akmods --force |
13.更新内核启动镜像
1 | sudo dracut --force |
14.重启电脑
1 | sudo reboot |
15.查看英伟达驱动是否正确加载
执行以下命令,查看是否有如图所示的类似结果,并查看英伟达控制面板是否正常显示。
教程结束