我有一台配备 Nvidia 显卡并启用了 EFI 安全启动的系统 (22.04.1 LTS)。Virtualbox
拒绝运行虚拟机,并声称
如果系统启用了 EFI 安全启动,您可能还需要签署内核模块(vboxdrv、vboxnetflt、vboxnetapd、vboxpci)
还
VERR_VM_DRIVER 未安装
我如何签署这些模块?
答案1
首先,问题不在于电喷;它与安全启动,这只是一个特定的 UEFI 功能。安全启动可以启用或禁用,甚至在某些(大多数较旧的)EFI/UEFI 实现中不存在。我提到这一点是因为,如果你可以编辑问题的标题,那么这样做会对其他人有所帮助。
其次,要回答您的问题,您必须首先在计算机上安装安全启动机器所有者密钥 (MOK) 或安全启动数据库密钥。为此,您必须同时安装openssl
和mokutil
程序(分别来自openssl
和mokutil
软件包)。简而言之:
使用 shell(终端程序或文本模式登录),创建并更改临时目录。
创建 MOK。通过发出两个命令即可完成:
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=Your Name/" openssl x509 -in MOK.crt -out MOK.cer -outform DER
将此 MOK 安装到计算机的 NVRAM 中。可以通过多种方式完成此操作,但最简单的方法可能是使用
mokutil
。首先将MOK.cer
文件传递给mokutil
:sudo mokutil -i MOK.cer
请注意,
sudo
可能会要求您输入帐户密码;然后mokutil
会要求新的密码及其确认。重启电脑。如果一切顺利,系统会要求你按下一个键来开始 MOK 管理,然后要求输入密码——输入新的您提供的一个
mokutil
。(在我最近的一些实验中,系统要求密码中包含特定的随机字符,这更令人尴尬。)然后您可以确认将您的 MOK 添加到 NVRAM 的 MOK 列表中。完成后,重新启动进入 Ubuntu。
现在,MOK 已存储在 NVRAM 中,您可以对 VirtualBox 驱动程序二进制文件进行签名。最基本的命令如下:
$path_to_binary/sign-file sha256 MOK.key MOK.cer $path_to_driver/vboxdrv.ko
vboxnetadp.ko
对和重复此操作vboxnetflt.ko
。该sign-file
程序实际上是 Linux 内核源代码的一部分;它不是 Ubuntu 中的标准程序。您可以通过输入 找到它的位置find /usr/src -iname sign-file
。如果未安装,则应安装该软件包。如果您还不知道 VirtualBox 模块的位置,linux-headers
也可以使用它来定位它。find
一旦模块被签名,您就可以加载它们modprobe
或重新启动计算机。
我经常这样做,所以我写了一个脚本来自动执行签名部分。这个脚本将不是不过,要自动创建 MOK。这是我的脚本:
#!/bin/bash
# sign-vbox script, copyright (c) 2017 by Rod Smith
# Distributed under the terms of the GPLv3
if [ "$#" -ne 1 ] && [ "$#" -ne 0 ]; then
echo "Usage: $0 [ {kernel-version} ]"
exit 1
fi
if [ "$#" == 0 ]; then
kernel_version=$(uname -r)
# apt-get install virtualbox-dkms --reinstall
else
kernel_version="$1"
fi
sign_file=$(find /usr/src/ -name sign-file | tail -n 1)
if [ -z $sign_file ]; then
echo "Can't find the sign-file binary! Exiting!"
exit 1
else
path_to_modules="/lib/modules/$kernel_version/updates/dkms"
if [ ! -f $path_to_modules/vboxdrv.ko ]; then
echo "Could not find $path_to_modules/vboxdrv.ko!"
echo "Is the kernel version correct?"
exit 1
fi
echo "Signing modules for $kernel_version"
$sign_file sha256 /mnt/keys/MOK.key /mnt/keys/MOK.cer $path_to_modules/vboxdrv.ko
$sign_file sha256 /mnt/keys/MOK.key /mnt/keys/MOK.cer $path_to_modules/vboxnetadp.ko
$sign_file sha256 /mnt/keys/MOK.key /mnt/keys/MOK.cer $path_to_modules/vboxnetflt.ko
modprobe vboxdrv
modprobe vboxnetflt
modprobe vboxpci
modprobe vboxnetadp
echo "Loaded vbox modules:"
lsmod | grep vbox
fi
要使用该脚本,首先将其存储在一个文件中并使其可执行(chmod a+x sign-vbox
例如,如果这是您使用的文件名)。然后以 执行该脚本root
,如sudo ./sign-vbox
。这将签署当前已启动内核的 VirtualBox 模块。(如果您想要签署另一个内核的模块,您可以将其版本号作为选项传递。)此外,该脚本使用密钥文件的硬编码位置,这将我们带到了……
请注意,该MOK.key
文件(或无论您如何称呼它)可能非常敏感。如果入侵者掌握了该密钥,那么入侵者就可以签署内核模块或引导加载程序,并使用它来获取对您计算机的低级访问权限。这就是此脚本访问 中的密钥文件的原因/mnt/keys
;其想法是将它们放在可移动磁盘上,并仅在需要时安装该磁盘。以这种方式存储之前生成的所有密钥openssl
。根据需要调整脚本以适应您存储密钥的位置。
答案2
我刚刚使用以下命令从终端重新安装了 VirtualBox dkms 包:
sudo apt-get install virtualbox-dkms --reinstall
安装程序提示我创建证书、在 MOK 中设置密码并给出了明确的说明(重新启动并在 MOK 中注册证书)。
答案3
Ubuntu 23.10,virtualbox 安装程序未提示 MOK 安装,virtualbox 模块是 zstd 压缩的,因此需要额外的签名步骤
基于:
- https://askubuntu.com/a/1456158/968164(@rod-smith 回答)
- https://gist.github.com/dublado/d0321da690c633e7799d5d504e3b52c1
- https://blog.unitedheroes.net/archives/p/5625/signing-kernel-modules-under-ubuntu-23-10/
# for illustration purpouses
cd
# install modules
apt-get install virtualbox-dkms --reinstall
# create certificate
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=Your Name/"
openssl x509 -in MOK.crt -out MOK.cer -outform DER
# move to dir with modules
cd $(dirname $(modinfo -n vboxdrv))
# they are compressed, you can't sign that
# decompress
# you might need to do this one by one, without wildcard
sudo zstd -d --rm vbox*
# sign modules (certs lies in $HOME, in this case)
# you might need to sign them one by one, without wildcard
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/MOK.key ~/MOK.cer ./vbox*
# update modules info
sudo depmod
# install this MOK in your computer's NVRAM
sudo mokutil -i MOK.cer # remember password
reboot
# press key to enter MOK management, add MOK,
# type password you'v remembered previously