Подпись модулей VirtualBox с включенной безопасной загрузкой EFI

Вопрос или проблема

У меня есть система (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, соответственно). Вкратце:

  1. Используя оболочку (программу терминала или текстовый вход), создайте и перейдите в каталог.

  2. Создайте 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
    
  3. Установите этот MOK в NVRAM вашего компьютера. Это можно сделать несколькими способами, но, вероятно, проще всего использовать mokutil. Вы начинаете с передачи файла MOK.cer в mokutil:

    sudo mokutil -i MOK.cer
    
  4. Имейте в виду, что sudo может запросить пароль вашей учетной записи; затем mokutil запросит новый пароль и его подтверждение.

  5. Перезагрузите компьютер. Если все пройдет хорошо, вам будет предложено нажать клавишу для начала управления 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, поэтому нужны дополнительные шаги для подписки

На основе:

# для иллюстрации
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

  1. Установка необходимых пакетов:
    Убедитесь, что у вас установлены пакеты openssl и mokutil. Если они отсутствуют, установите их:

    sudo apt-get install openssl mokutil
  2. Создание ключа 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
  3. Установка ключа MOK в NVRAM:
    Установите созданный сертификат с помощью mokutil:

    sudo mokutil -i MOK.cer

    Вы будете запрошены ввести новый пароль для MOK. Запомните его, так как он понадобится позже.

  4. Перезагрузка и управление MOK:
    Перезагрузите компьютер. При загрузке вам будет предложено управлять MOK. Нажмите соответствующую клавишу, и введите пароль, который вы установили ранее. Это добавит ваш MOK в NVRAM.

  5. Подписание модулей 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
  6. Обновление информации о модулях:
    После подписания модулей обновите кэш модулей:

    sudo depmod
  7. Загрузка подписанных модулей:
    После выполнения всех шагов, загрузите модули:

    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 на вашем устройстве.

Оцените материал
Добавить комментарий

Капча загружается...