在保持安全启动的同时安装VirtualBox

我正在尝试在Ubuntu 16.04上安装VirtualBox,同时保持安全启动。 当我通过Synaptic安装它时,我被要求删除SecureBoot,我说不。

我按照这些说明操作: 升级到Ubuntu 16.04后无法加载’vboxdrv’(我想保持安全启动)和https://stegard.net/2016/10/virtualbox-secure-boot-ubuntu-fail/两者都是几乎一样(我把MOK文件留在/ root目录中,就像在第二个链接中一样)。 一切似乎工作正常,我重新启动,再次输入我的密码,重新启动。 都好

但是当我尝试使用VirtualBox时,它仍然无法工作。 如果我从终端运行它我得到:

 WARNING: The character device /dev/vboxdrv does not exist. Please install the virtualbox-dkms package and the appropriate headers, most likely linux-headers-generic. You will not be able to start VMs until this problem is fixed. 

但这两个软件包已经安装并且是最新的。

在另virtualbox-dkms文章的顶部答案中的评论中说,在遵循这些说明之前重新安装virtualbox-dkms 。 我试过了,同样的结果。

我在这里尝试了答案: VirtualBox的安装问题我再次提示我问我是否要禁用安全启动,我说不,然后回到原点。

如果我运行modprobe我得到: modprobe: ERROR: could not insert 'vboxdrv': Required key not available

关于如何让VirtualBox与SecureBoot一起使用的任何想法(请不要告诉我删除它……)?

谢谢

我没有尝试过这些程序。 但是,我确实以不同的方式做到这一点 – 但这是一种非常繁琐的方法。 这个描述会让它看起来比这更容易,因为我指的是我写的一个大页面,涵盖了最糟糕的部分。 我的程序是:

  1. 控制安全启动 – 在我的情况下,我已经配置了我的计算机,以便将自己的安全启动公钥嵌入固件中。 这样我就不需要使用Shim或MOK了。 我已经删除了Microsoft的密钥,并将我自己和Canonical的密钥添加到我使用此过程的计算机上,但您可以使用您喜欢的任何密钥设置自己的密钥。 出于问题的目的,关键部分是您必须包含您生成的密钥并使用您保留的私钥使其生效。 您还需要用于签署标准组件的密钥 – Canonical的密钥,Microsoft的公共市场密钥或两者。 如果使用Windows双启动,则需要Microsoft用于签署自己的引导加载程序的公钥。 有关所有血腥细节的信息,请参阅我的这一页 – 但请注意,这是一个繁琐且挑剔的程序,因此您可能需要花费很长时间才能使这部分工作。 请注意,大多数UEFI使恢复标准密钥集变得非常容易,因此尝试此过程所涉及的风险很低。
  2. 签署VirtualBox模块 – 下一步是签署VirtualBox内核模块。 这与您链接描述的页面几乎完全相同; 但是,我有一个脚本来帮助自动化这个过程(见下文)。
  3. 加载VirtualBox模块 – 签署模块后,必须加载它们。 这应该在重启时自动发生; 但是如果要在不重新启动的情况下使用VirtualBox,则必须为每个模块( vboxdrvvboxnetfltvboxpcivboxnetadp )明确使用modprobe
  4. 每次内核更新后重复步骤2-3 – 内核更新后,必须重复步骤#2和#3。

为方便起见,我编写了一个脚本,在一个命令中执行步骤#2和#3。 我称之为sign-vbox 。 这里是:

 #!/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) 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 /etc/refind.d/keys/refind_local.key /etc/refind.d/keys/refind_local.cer $path_to_modules/vboxdrv.ko $sign_file sha256 /etc/refind.d/keys/refind_local.key /etc/refind.d/keys/refind_local.cer $path_to_modules/vboxnetadp.ko $sign_file sha256 /etc/refind.d/keys/refind_local.key /etc/refind.d/keys/refind_local.cer $path_to_modules/vboxnetflt.ko $sign_file sha256 /etc/refind.d/keys/refind_local.key /etc/refind.d/keys/refind_local.cer $path_to_modules/vboxpci.ko modprobe vboxdrv modprobe vboxnetflt modprobe vboxpci modprobe vboxnetadp echo "Loaded vbox modules:" lsmod | grep vbox fi 

要使用此脚本,只需键入其名称即可。 它签署了与当前运行的内核关联的VirtualBox模块。 如果你传递一个内核版本号,它应该签署与该内核版本相关的内核,但是在指定内核版本号时没有错误的余地。 (它期望与内核运行时uname -r相同的格式。)

请注意,该脚本希望在refind_local.key找到private( refind_local.key )和public( refind_local.cer )键。 除非使用rEFInd并使用本地密钥,否则您必须为自己的系统更改该位置。 私钥文件应该尽可能安全,例如具有0400( -r-------- )权限。 限制对目录本身的访问也可能有所帮助。 更好的是,将它放在只有在运行此命令时插入的USB闪存驱动器上。

另外,我写这个脚本供我个人使用。 它可能有错误,特别是如果以我不期望的方式使用。 当然,如果没有安装必要的内核源文件,它会失败。

可以想象,如果您将生成的密钥文件指向您加载到MOK中的公共文件,则此脚本将与您尝试使用的基于MOK的方法一起使用。 我不能保证这一点,当然,你的问题可能是由于内核模块签名不正确或者Shim / MOK端有问题。 仅当您的内核模块未正确签名时,才使用此脚本。