Вопрос или проблема
У меня есть система (22.04.1 LTS) с картой Nvidia и включенной безопасной загрузкой EFI.
Virtualbox отказывается запускать виртуальную машину и утверждает, что
если в системе включена безопасная загрузка EFI, вам также может понадобиться подписать модули ядра (vboxdrv, vboxnetflt, vboxnetapd, vboxpci)
также
VERR_VM_DRIVER не установлен
Как мне подписать эти модули?
Во-первых, проблема не в EFI; она в Secure Boot, который является всего лишь одной из специфических функций UEFI. Безопасная загрузка может быть включена или отключена и даже отсутствует на некоторых (в основном старых) реализациях EFI/UEFI. Я упоминаю это, потому что, если вы сможете изменить название вопроса, это будет полезно другим.
Во-вторых, чтобы ответить на ваш вопрос, сначала вам нужно установить в вашем компьютере ключ владельца машины Secure Boot (MOK) или ключ базы данных Secure Boot. Для этого вам необходимо установить обе программы openssl
и mokutil
(из пакетов openssl
и mokutil
, соответственно). Вкратце:
-
Используя оболочку (программу терминала или текстовый вход), создайте и перейдите в каталог.
-
Создайте MOK. Это делается путем выполнения двух команд:
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=Ваше Имя/" 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 в список MOK в NVRAM. Когда закончите, перезагрузитесь в 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
. Если она не установлена, вам следует установить пакет linux-headers
. Вы также можете воспользоваться find
, чтобы определить, где находятся модули VirtualBox, если вы этого еще не знаете.
После того как модули будут подписаны, вы можете загрузить их с помощью modprobe
или перезагрузить компьютер.
Я делаю это достаточно часто, чтобы написать скрипт для автоматизации части процесса подписки. Этот скрипт не автоматизирует создание MOK. Вот мой скрипт:
#!/bin/bash
# скрипт sign-vbox, авторские права (c) 2017 Род Смит
# Распространяется на условиях GPLv3
if [ "$#" -ne 1 ] && [ "$#" -ne 0 ]; then
echo "Использование: $0 [ {версия-ядра} ]"
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 "Не удалось найти бинарный файл sign-file! Завершение!"
exit 1
else
path_to_modules="/lib/modules/$kernel_version/updates/dkms"
if [ ! -f $path_to_modules/vboxdrv.ko ]; then
echo "Не удалось найти $path_to_modules/vboxdrv.ko!"
echo "Правильная ли версия ядра?"
exit 1
fi
echo "Подписываю модули для $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 "Загружены модули vbox:"
lsmod | grep vbox
fi
Чтобы использовать скрипт, сначала сохраните его в файл и сделайте его исполняемым (chmod a+x sign-vbox
, например, если это имя файла, которое вы используете). Затем выполните скрипт от имени root
, как в sudo ./sign-vbox
. Это подпишет модули VirtualBox текущего ядра. (Если вы хотите подписать модули другого ядра, вы можете передать его номер версии в качестве параметра.) Кроме того, в скрипте используется зашитое местоположение для файлов ключей, что приводит нас к….
Имейте в виду, что файл MOK.key
(или как бы вы его ни назвали) потенциально довольно чувствителен. Если злоумышленник получит этот ключ, он сможет подписывать модули ядра или загрузчики и использовать его для получения низкоуровневого доступа к вашему компьютеру. Вот почему этот скрипт получает доступ к файлам ключей в /mnt/keys
; идея заключается в том, чтобы поместить их на съемный диск и монтировать этот диск только тогда, когда он нужен. Храните все ключи, созданные ранее с помощью openssl
, таким образом. Настройте скрипт по необходимости для того места, где вы хранили свои ключи.
Я только что переустановил пакет dkms VirtualBox из терминала с помощью:
sudo apt-get install virtualbox-dkms --reinstall
Установщик предложил мне создать сертификат, установить пароль для MOK и дал четкие инструкции (перезагрузиться и зарегистрировать сертификат в MOK).
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/
# для иллюстрации
cd
# установить модули
apt-get install virtualbox-dkms --reinstall
# создать сертификат
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=Ваше Имя/"
openssl x509 -in MOK.crt -out MOK.cer -outform DER
# перейти в каталог с модулями
cd $(dirname $(modinfo -n vboxdrv))
# они сжаты, вы не можете подписать это
# распакуйте
# возможно, вам нужно будет делать это по одному, без подстановочных знаков
sudo zstd -d --rm vbox*
# подписать модули (сертификаты находятся в $HOME, в этом случае)
# вам, возможно, придется подписывать их по одному, без подстановочных знаков
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/MOK.key ~/MOK.cer ./vbox*
# обновить информацию о модулях
sudo depmod
# установить этот MOK в NVRAM вашего компьютера
sudo mokutil -i MOK.cer # запомните пароль
перезагрузите
# нажмите клавишу для входа в управление MOK, добавьте MOK,
# введите пароль, который вы запомнили ранее
На Linux Mint я просто удалил Virtualbox и переустановил его, и всё заработало.
Ответ или решение
Для решения проблемы запуска VirtualBox на системе с включённой безопасной загрузкой (Secure Boot) и ошибками, связанными с подписями модулей ядра, вам необходимо выполнить несколько шагов. Ниже представлено полное руководство по подписыванию модулей VirtualBox в среде Ubuntu 22.04.1 LTS и выше.
Шаги для подписывания модулей VirtualBox
-
Установка необходимых пакетов:
Убедитесь, что у вас установлены пакетыopenssl
иmokutil
. Если они отсутствуют, установите их:sudo apt-get install openssl mokutil
-
Создание ключа MOK (Machine Owner Key):
Откройте терминал и выполните следующие команды для генерации ключа и сертификата:openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=Ваше имя/" openssl x509 -in MOK.crt -out MOK.cer -outform DER
-
Установка ключа MOK в NVRAM:
Установите созданный сертификат с помощьюmokutil
:sudo mokutil -i MOK.cer
Вы будете запрошены ввести новый пароль для MOK. Запомните его, так как он понадобится позже.
-
Перезагрузка и управление MOK:
Перезагрузите компьютер. При загрузке вам будет предложено управлять MOK. Нажмите соответствующую клавишу, и введите пароль, который вы установили ранее. Это добавит ваш MOK в NVRAM. -
Подписание модулей VirtualBox:
Чтобы подписать необходимые модули VirtualBox, сначала найдите позицию программыsign-file
, которая обычно находится в заголовках вашего ядра:find /usr/src -iname sign-file
Теперь подпишите модули. Если вы не уверены в их местоположении, используйте команду
modinfo
для определения их пути:cd /lib/modules/$(uname -r)/updates/dkms/
Подпишите модули:
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/MOK.key ~/MOK.cer vboxdrv.ko sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/MOK.key ~/MOK.cer vboxnetadp.ko sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/MOK.key ~/MOK.cer vboxnetflt.ko sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/MOK.key ~/MOK.cer vboxpci.ko
-
Обновление информации о модулях:
После подписания модулей обновите кэш модулей:sudo depmod
-
Загрузка подписанных модулей:
После выполнения всех шагов, загрузите модули:sudo modprobe vboxdrv sudo modprobe vboxnetflt sudo modprobe vboxnetadp sudo modprobe vboxpci
Примечание
Если вы используете сжатые модули (например, zstd), вам нужно сначала разжать их перед подписанием:
sudo zstd -d --rm vbox*
Скрипт автоматизации (необязательно)
Существует возможность создания скрипта, который будет автоматизировать процесс подписания модулей. Однако не забудьте управлять безопасностью ключей и сертификатов, чтобы избежать несанкционированного доступа.
Если вы столкнетесь с трудностями или если скомпилированные модули не находятся, убедитесь, что вы установили virtualbox-dkms
:
sudo apt-get install virtualbox-dkms --reinstall
Заключение
Следуя указанным шагам, вы сможете успешно подписать модули VirtualBox для работы с включенной безопасной загрузкой в системе. Это решение обеспечит правильную работу VirtualBox на вашем устройстве.