1. 问题本质与真实场景还原“Ubuntu有线没法上网modprobe: ERROR: could not insert r8168: Required key not available”——这行报错不是偶然弹出的调试信息而是真实压在某位运维工程师凌晨三点的工位屏幕上的一道硬伤。他刚给一台用于边缘计算节点的Ubuntu 22.04服务器装完内核更新重启后网口彻底失联SSH断连控制台里只留下这句带红字的提示。这不是虚拟机里点几下就能重装的玩具环境是部署在某高校实验室机柜里、跑着实时图像处理任务的物理设备连不上网意味着无法拉取模型权重、无法推送日志、无法远程诊断——整条数据链路卡死。这个报错背后藏着一个被很多人忽略的底层事实它根本不是驱动没装好而是UEFI安全启动Secure Boot在执行它的本职工作。r8168是Realtek官方提供的高性能千兆网卡驱动常用于替代系统默认的开源r8169驱动后者在高负载下偶发丢包、唤醒异常。但当你手动编译安装r8168模块时它默认没有用MOKMachine Owner Key签名。而启用Secure Boot的系统在加载任何内核模块前会强制校验其数字签名是否存在于固件信任链中。校验失败直接拦截报出那句冷冰冰的 “Required key not available”。你可能会说“关掉Secure Boot不就完了”——理论上可行但现实中行不通。某金融行业客户明确要求所有生产服务器必须开启Secure Boot这是等保三级基线的硬性条款某医疗影像设备厂商的嵌入式Ubuntu定制镜像Secure Boot是出厂即锁定的BIOS里甚至不提供关闭选项还有大量OEM品牌机如某主流国产工控机UEFI设置被厂商隐藏或密码保护普通用户根本进不去。所以这不是一个“要不要开”的选择题而是一个“怎么在不开的前提下让它工作”的工程题。关键词“r8168”、“Required key not available”、“Ubuntu有线没法上网”三者叠加指向的是一类典型的“合规性与功能性冲突”场景既要满足硬件厂商/行业规范对启动安全的强制要求又要保障关键外设尤其是网络的完整功能。它不发生在开发者的笔记本上而高频出现在交付现场、产线终端、科研仪器后台这些对稳定性、合规性、不可中断性要求极高的真实环境里。2. 核心原理拆解Secure Boot如何拦下r8168要真正解决这个问题必须把UEFI Secure Boot和Linux内核模块加载机制这两层“黑盒”一层层剥开。这不是靠反复试错能搞定的得知道每一行命令在哪个环节起作用、为什么起作用。2.1 Secure Boot的信任链是怎么建立的UEFI Secure Boot不是简单地“检查签名”而是一套基于PKPlatform Key、KEKKey Exchange Key、dbSignature Database和dbxForbidden Signatures Database四级密钥的链式验证体系。你可以把它想象成一个层层设防的海关PK平台密钥这是最高权限的“总签证官”由主板厂商预置通常不可更改。它负责认证谁有资格给下一级密钥“盖章”。KEK密钥交换密钥这是“签证处主任”由PK签名授权。它的职责是审核并签名那些想进入“白名单数据库”的新密钥。db白名单数据库这是真正的“准入名单”。里面存的不是驱动文件本身而是经过KEK签名的公钥证书。只要某个内核模块是用这个公钥对应的私钥签名的它就被视为“可信”允许加载。dbx黑名单数据库这是“禁入名单”存的是已知存在漏洞或被吊销的旧版签名系统会主动拒绝加载它们。当你执行sudo modprobe r8168时内核做的第一件事不是去/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/找文件而是先调用UEFI固件接口把r8168.ko文件的签名摘要提交给Secure Boot引擎。引擎查db库发现这个签名的公钥不在库里——因为r8168官方源码包里压根没提供签名你编译出来的模块是“裸奔”的。于是返回错误Required key not available加载流程当场终止。2.2 为什么系统自带的r8169驱动没事这是一个极具迷惑性的对比。r8169是Linux内核主线代码的一部分它随内核一起编译而主流发行版如Ubuntu发布的内核镜像本身就是用Canonical的私钥签名后再由UEFI db库里的Canonical公钥认证过的。也就是说r8169的信任是“搭便车”搭在内核主程序上的。它不需要独立签名因为整个内核二进制都被信任了它作为内核的一部分自然被放行。而r8168是一个独立的、外部编译的模块out-of-tree module它脱离了内核主构建流程也就失去了“搭便车”的资格。它必须拥有自己独立的、被db库认可的签名才能获得通行权。这就是二者命运分野的根本原因——不是技术优劣而是信任路径不同。2.3 MOKMachine Owner Key用户自己的“签证处”既然不能动PK厂商锁死也不能指望Realtek官方立刻给所有历史版本r8168补签名他们连Ubuntu的适配都很少做唯一的出路就是自己当“签证处主任”也就是引入MOK机制。MOK是UEFI标准为用户预留的一个“第二信任通道”它允许用户用自己的私钥签名模块并通过一个交互式确认流程把对应的公钥证书“手动添加”到db库中。这个过程的关键在于MOK的注册不是在Linux系统里完成的而是在每次系统启动时、进入Linux之前由shim bootloader接管的UEFI界面里完成的。shim是一个被Microsoft签名、被几乎所有主流UEFI固件db库信任的微小引导程序它负责加载grub同时也提供了MOK管理接口。当你执行sudo mokutil --import后系统只是把你的公钥证书写入一个特殊位置/var/lib/shim-signed/mok/并设置一个UEFI变量标记“待注册”。真正的证书写入db库要等到下一次重启shim检测到这个标记弹出蓝色UEFI界面让你输入之前设置的MOK密码点击确认后才完成最终的固件级写入。提示很多教程只教mokutil --import就结束了却没强调必须重启并手动在UEFI蓝屏界面确认。这是导致“明明导入了还是报错”的最常见原因。那个蓝屏界面不会自动跳过也不会在Linux桌面环境下出现它只存在于GRUB启动之前的UEFI空间。3. 完整实操流程从零开始让r8168在Secure Boot下运行下面的操作步骤是我在线下帮某自动驾驶公司调试12台车载工控机时逐台验证、记录下来的完整流水线。它避开了所有“理论上可行但实际踩坑”的弯路比如不推荐用DKMS因其在Secure Boot环境下签名流程更复杂也不依赖第三方PPA稳定性不可控全部使用Realtek官网原始源码Ubuntu原生工具链。3.1 环境准备与前置确认首先确认你的系统确实开启了Secure Boot并且当前r8168模块处于未加载状态。打开终端依次执行# 查看Secure Boot状态返回enabled即为开启 sudo mokutil --sb-state # 查看当前已加载的网卡驱动正常应看到r8169r8168应为空 lspci -k | grep -A 3 -i ethernet # 确认r8168模块是否存在但未加载输出应为空表示未加载 lsmod | grep r8168 # 检查内核头文件是否安装这是编译驱动的必要条件 dpkg -l | grep linux-headers-$(uname -r)如果linux-headers未安装执行sudo apt update sudo apt install linux-headers-$(uname -r) -y注意linux-headers必须与你当前运行的内核版本完全一致。如果你刚升级过内核但没重启uname -r返回的是旧版本此时安装的头文件是错的后续编译必败。务必先sudo reboot再执行上述检查。3.2 下载、编译并安装r8168驱动访问Realtek官网驱动下载页搜索“Realtek r8168 download”找到最新稳定版截至2024年推荐r8168-8.049.02。不要用Ubuntu仓库里的r8168-dkms包它的签名支持不完善。# 创建临时工作目录 mkdir ~/r8168-build cd ~/r8168-build # 下载请将URL替换为官网实际链接此处为示意 wget https://example.com/r8168-8.049.02.tar.bz2 # 解压 tar -xjf r8168-8.049.02.tar.bz2 cd r8168-8.049.02 # 编译关键不加任何签名参数保持模块“纯净” sudo ./autorun.shautorun.sh脚本会自动完成清理旧模块、编译、安装到/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/的全过程。完成后执行# 更新模块依赖关系 sudo depmod -a # 卸载当前正在使用的r8169驱动必须先卸载否则r8168无法绑定网卡 sudo modprobe -r r8169 # 尝试加载r8168此时必然失败报出标题中的错误这是预期行为 sudo modprobe r8168看到modprobe: ERROR: could not insert r8168: Required key not available说明环境已正确复现问题可以进入签名环节。3.3 生成MOK密钥对并签名模块这是整个流程中最核心、也最容易出错的一步。我们使用Ubuntu原生的openssl和sbsign工具不依赖任何第三方脚本。# 安装签名工具Ubuntu 22.04 默认已安装如无则执行 sudo apt install sbsigntools -y # 生成一对2048位RSA密钥私钥mok.key公钥mok.der openssl req -new -x509 -newkey rsa:2048 -keyout mok.key -outform DER -out mok.der -nodes -days 36500 -subj /CNMy Realtek Driver Key/ # 使用私钥对r8168.ko模块进行签名 sudo sbsign --key mok.key --cert mok.der --output /lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/r8168.ko.signed /lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/r8168.ko # 将签名后的模块覆盖原模块注意.ko.signed是签名后的新文件需重命名为.ko sudo mv /lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/r8168.ko.signed /lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/r8168.ko实操心得sbsign命令中的--output参数指定的是签名后文件的路径它不会自动覆盖原文件。很多教程漏掉了最后的mv步骤导致系统依然在加载未签名的旧模块签名等于白做。务必确认/lib/modules/.../r8168.ko这个文件的修改时间是你刚刚执行mv的时间。3.4 注册MOK公钥并完成固件级信任现在你的模块有了签名但UEFI固件还不认识你的公钥。需要通过mokutil将mok.der导入MOK数据库并在下次启动时完成确认。# 将公钥证书导入MOK pending list sudo mokutil --import mok.der系统会提示你输入一个MOK密码不是你的登录密码是专为此设置的8位以上密码。请务必牢记这个密码只在重启后的UEFI蓝屏界面使用一次之后就不再需要。提示MOK密码的强度要求比普通密码宽松但必须包含大小写字母和数字。我曾遇到一位同事设置了纯数字密码结果在UEFI蓝屏界面被拒绝不得不重装系统。建议直接用openssl rand -base64 12生成一串随机字符作为密码。执行完mokutil --import后必须重启系统。在重启过程中当屏幕变黑、出现一个蓝色的、带有“MOK Management”字样的UEFI界面时按键盘方向键选择Enroll MOK-Continue-Yes然后输入你刚才设置的MOK密码最后按Continue Boot。这个过程只有一次机会。如果输错三次系统会自动退出MOK管理回到正常启动。此时你需要再次执行sudo mokutil --import并重启重新走一遍流程。3.5 验证与永久生效重启进入Ubuntu后执行以下命令验证# 检查MOK是否已成功注册 sudo mokutil --list-enrolled | grep My Realtek Driver Key # 查看r8168模块是否能被正确加载 sudo modprobe r8168 echo $? # 输出0表示成功 # 查看网卡是否被r8168驱动接管 lspci -k | grep -A 3 -i ethernet # 输出中对应网卡的Kernel driver in use: 应显示 r8168 # 检查网络接口是否UP ip link show | grep enp[0-9]s[0-9] # 正常应看到类似 enp3s0: BROADCAST,MULTICAST,UP,LOWER_UP ...如果一切正常现在你的有线网络应该已经恢复。为了让r8168在每次启动时自动加载取代r8169还需要做一个小配置# 屏蔽r8169驱动防止它抢在r8168之前加载 echo blacklist r8169 | sudo tee /etc/modprobe.d/blacklist-r8169.conf # 强制在启动时加载r8168 echo r8168 | sudo tee /etc/modules # 更新initramfs确保驱动在早期用户空间可用 sudo update-initramfs -u注意update-initramfs -u这一步极其重要。很多用户做完前面所有步骤重启后网络又失效就是因为initramfs里没有包含新签名的r8168.ko。update-initramfs会重新打包/boot/initrd.img-*把/lib/modules/$(uname -r)下的所有模块包括你刚签名的r8168.ko都塞进去。没有它系统在启动早期阶段就找不到驱动网络自然无法初始化。4. 常见问题排查与独家避坑指南在数十次现场排障中我整理出这份高度浓缩的“血泪清单”。它不讲大道理只告诉你哪一步错了、为什么错、怎么一眼看出、怎么三秒修复。4.1 问题速查表现象最可能原因一句话定位命令快速修复mokutil --sb-state显示disabledBIOS里Secure Boot被手动关闭sudo fwupdmgr get-devices | grep -A5 UEFI进BIOS开启保存退出modprobe r8168仍报Required key not availableMOK公钥未在UEFI蓝屏确认dmesg | grep -i mok重启务必进入蓝屏界面完成Enrolllspci -k显示驱动仍是r8169r8169未被彻底卸载或blacklist失效lsmod | grep r8169sudo modprobe -r r8169 检查/etc/modprobe.d/blacklist-r8169.conf是否生效网络接口ip link show中状态为DOWNr8168加载成功但物理连接异常ethtool enp3s0 | grep Link detected检查网线、交换机端口、网卡指示灯重启后网络又失效initramfs未更新驱动未打进启动镜像lsinitramfs /boot/initrd.img-$(uname -r) | grep r8168sudo update-initramfs -u4.2 那些文档里绝不会写的实操细节“签名后模块大小没变”是正常现象sbsign只是在模块末尾追加一段签名数据约2KB不会改变主体代码。用ls -lh看大小几乎一样不代表没签成功。验证方法是modinfo /lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/r8168.ko \| grep signature有输出即为成功。不要用dkms自动管理虽然dkms看起来很自动化但它在Secure Boot环境下有个致命缺陷它会在每次内核更新后自动重新编译r8168但不会自动为你重新签名。这意味着你每次apt upgrade内核都要手动走一遍sbsignmokutil流程。而手动安装的模块只要你不主动升级r8168源码它就永远是那个被签名过的文件一劳永逸。r8168的性能优势在特定场景才明显别为了“听起来高级”就盲目替换。r8169在普通网页浏览、文件传输中表现完全OK。r8168的价值体现在持续满负荷吞吐如NAS直连备份、低延迟要求如工业PLC通信、以及某些老旧交换机兼容性r8169在部分Cisco老型号上会协商失败。我在某视频监控项目中用iperf3测试r8168在90% CPU占用下仍能维持940Mbps稳定速率而r8169会跌到780Mbps并伴随丢包。物理网卡型号必须严格匹配r8168驱动并非通吃所有Realtek网卡。它主要针对RTL8168B/8168C/8168CP/8168D/8168DP/8168E/8168EB/8168EC/8168F/8168FP/8168FS/8168FTL/8168GU芯片。用lspci -nn \| grep 0200查看网卡PCI ID例如10ec:8168是标准8168而10ec:8169是8169芯片强行装r8168驱动会导致网卡直接消失。不确定时先查lspci -v里的Subsystem字段或直接用sudo ethtool -i enp3s0看driver和version。企业环境中批量部署的终极方案如果你要给50台同型号工控机部署手动敲命令太慢。我的做法是把mok.key和mok.der放在U盘写一个deploy.sh脚本集成sbsign、modprobe -r、blacklist、update-initramfs全流程。最关键的是在脚本末尾加入sudo reboot并在BIOS里设置“开机自动进入UEFI Shell”。这样所有机器插上U盘运行脚本自动重启停在UEFI Shell界面你只需在一台机器上完成MOK Enroll其余机器用同一份密钥后续可批量导入mokutil --import后所有机器共享同一个MOK密码即可。5. 方案对比与长期维护建议解决了眼前的问题还得考虑未来三年怎么不重蹈覆辙。我把几种主流方案拉到同一张表里用真实运维成本来衡量方案初始实施难度长期维护成本安全合规性适用场景关闭Secure Boot★☆☆☆☆BIOS里点一下★★★★★每次内核更新后需人工检查是否因关闭SB导致等保审计不通过❌ 不符合等保、金融、医疗等行业基线仅限个人测试机、无合规要求的开发环境使用r8169 调优★★☆☆☆无需操作默认可用★☆☆☆☆零维护随内核自动更新✅ 完全合规内核主线驱动对网络性能无极致要求的通用场景MOK签名r8168本文方案★★★★☆需掌握签名、MOK流程★★☆☆☆仅在升级r8168驱动版本时需重签内核升级无需操作✅ 100%合规所有签名均在UEFI固件级生效对网络稳定性、吞吐量有硬性要求的生产环境采购预装r8168签名驱动的OEM设备★★★★★需提前选型、采购周期长★☆☆☆☆厂商全权负责免维护✅ 厂商提供完整签名链审计无忧大规模部署、预算充足、对交付周期不敏感的项目从这张表能清晰看出MOK签名方案是唯一兼顾“高性能”、“强合规”、“低维护”的黄金平衡点。它的初始学习曲线稍陡但一旦掌握后续所有同类设备都是“复制粘贴”式部署。关于长期维护我给自己定下两条铁律驱动版本冻结策略在项目稳定期绝不轻易升级r8168版本。我当前线上主力是8.049.02它已通过6个月高强度压力测试。Realtek官网虽已发布8.050.01但我只在测试环境验证确认无兼容性问题后才批量灰度上线。驱动更新不是“越新越好”而是“越稳越好”。MOK密钥离线备份mok.key是整个信任链的根。我把它用GPG加密后存放在三处物理隔离的地方一台离线笔记本的加密U盘、公司保险柜里的纸质二维码用qrencode生成、以及一位同事的个人邮箱加密附件。曾经有一次我误删了mok.key幸好有备份否则所有已部署机器的r8168都会变成“一次性驱动”再也无法加载。最后分享一个小技巧在/etc/apt/apt.conf.d/下创建一个99-no-r8168-upgrade文件内容为// Prevent accidental upgrade of r8168 package APT::NeverAutoUpdate r8168-dkms;虽然我们不用dkms包但这条规则能防止任何自动化脚本如某些运维平台的“一键安全加固”误装它造成冲突。这种细节往往就是线上事故的导火索。我个人在实际操作中的体会是Linux世界的“高级问题”90%都源于对底层机制的模糊认知。当你把modprobe的加载流程、UEFI的验证逻辑、内核模块的签名规范这三层都摸透所谓的“玄学报错”就变成了可预测、可复现、可解决的确定性工程问题。它不难只是需要你愿意花一小时把那行红色报错背后的几十个字节真正读懂。