Статья обновлена 23.01.2025 г. Это мой вольный перевод статьи Debian Wiki Secure Boot.

В статье рассматривается настройка проприетарного драйвера NVIDIA и модулей ядра VirtualBox для работы в Debian 10 или более новом в режиме SecureBoot. Linux при работе в режиме Secure Boot блокируется исполнение любых модулей ядра, у которых нет цифровой подписи. Алгоритм решения проблемы выглядит следующим образом:

  1. Поменять настройки BIOS / UEFI.
  2. Самостоятельно сгенерировать ключ цифровой подписи (MOK — Machine Owner Key).
  3. Добавить ключ цифровой подписи в список доверенных ключей Secure Boot.
  4. Сгенерированным ключом подписать нужные модули ядра.

Все выполняемые операции требуют привилегий root, поэтому использование sudo для краткости опущено.

Ключ можно сгенерировать один раз и больше не менять в течение длительного времени, а вот модули ядра нужно подписывать при каждом их обновлении. Если сделать описанные в статье настройки, подписывание модулей будет происходить автоматически.

Подготовка к работе

  1. Зайдите в настройки BIOS / UEFI и приведите настройки к следующему виду:

    • Secure bootON.
    • Secure boot modeMicrosoft Windows EFI или аналогичный.

    Начиная с Debian 10 для загрузки ядра используется модуль shim, подписанный ключом Microsoft. Если Secure Boot будет работать в режиме Other OS, будут проблемы с подписыванием модулей ядра.

  2. Убедитесь, что в конфигурационном файле /etc/dkms/framework.conf отсутствует строка:

     sign_tool="/etc/dkms/sign_helper.sh"
    

    Если такая строка там есть, удалите или закоментируйте её.

  3. В каталоге /etc/dkms/framework.conf.d/ создайте файл mok_settings.conf со следующим содержимым:

     mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
     mok_certificate="/var/lib/shim-signed/mok/MOK.der"
    
  4. Включите поддержку каталогов non-free и contrib в репозиториях.

    Для этого добавьте нужные ключевые слова в /et/apt/sources.list (из примера удалены все комментарии):

     deb http://ftp.ru.debian.org/debian/ bullseye main non-free contrib
     deb-src http://ftp.ru.debian.org/debian/ bullseye main non-free contrib
    
     deb http://security.debian.org/debian-security bullseye-security main non-free contrib
     deb-src http://security.debian.org/debian-security bullseye-security main non-free contrib
    
     deb http://ftp.ru.debian.org/debian/ bullseye-updates main non-free contrib
     deb-src http://ftp.ru.debian.org/debian/ bullseye-updates main non-free contrib
    
  5. Обновите список доступных пакетов:

     apt-get update
    
  6. Установите заголовочные файлы ядра, набор средств разработки и утилиту mokutil:

     apt-get install linux-headers-amd64 build-essential make mokutil --yes
    

Генерация ключа

  1. Создайте в каталоге /var/lib/ подкаталог shim-signed/mok:

     mkdir -p /var/lib/shim-signed/mok/
    
  2. Перейдите в созданный каталог:

     cd /var/lib/shim-signed/mok/
    

    Во многих руководствах можно встретить и другие пути к каталогу, в которому нужно создавать MOK. Однако, Debian Wiki говорит, что лучше использовать именно этот каталог, поскольку многое ПО, собранное под Ubuntu Linux, будет искать ключи в первую очередь там.

  3. Сгенерируйте ключ цифровой подписи:

     openssl req \
             -new \
             -x509 \
             -newkey rsa:2048 \
             -keyout MOK.priv \
             -outform DER \
             -out MOK.der \
             -days 36500 \
             -subj "/CN=My Name/"
    
  4. Преобразуйте созданный ключ в формат PEM:

     openssl x509 -inform der -in MOK.der -out MOK.pem
    
  5. Импортируйте в Secure Boot ключ в формате DER:

     mokutil --import MOK.der
    
  6. Перезагрузите компьютер.

    Будет запущена специальная утилита для импорта ключей в Secure Boot.

    1. Выберите пункт Enroll key(s).
    2. Введите пароль ключа.

Драйверы NVIDIA

  1. Установите драйвер NVIDIA и утилиту nvidia-xconfig:

     apt-get install nvidia-driver nvidia-xconfig --yes
    
  2. Перейдите в каталог с модулями для используемой версии ядра, например:

     cd /lib/modules/5.10.0-16-amd64/update/dkms/
    
  3. Подпишите модули ядра сгенерированным ранее ключом, например:

     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der nvidia-current-drm.ko
     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der nvidia-current-modeset.ko
     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der nvidia-current-uvm.ko
     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der nvidia-current.ko
    
  4. Обновите файл /etc/X11/xorg.conf:

     rm /etc/X11/xorg.conf && nvidia-xconfig
    
  5. Обновите конфигурацию загрузчика:

     sudo update-initramfs -u -k all
    
  6. Перезагрузите компьютер.

VirtualBox

  1. Подключите репозиторий VirtualBox:

    Оригинал инструкции по подключению репозитория доступен на сайте VirtualBox.

    1. Импортируйте ключ репозитория:

       wget https://www.virtualbox.org/download/oracle_vbox_2016.asc |\
          sudo gpg --dearmor --yes --output /etc/apt/trusted.gpg.d/oracle.gpg
      
    2. Создайте в каталоге /etc/apt/sources.list.d/ файл virtualbox.list со ссылкой на репозиторий:

       deb https://download.virtualbox.org/virtualbox/debian bullseye contrib
      
  2. Обновите список доступных пакетов:

     apt-get update
    
  3. Установите пакеты VirtualBox:

     apt-get install virtualbox-7.0
    
  4. Перейдите в каталог с модулями для используемой версии ядра, например:

     cd /lib/modules/5.10.0-16-amd64/misc/
    
  5. Подпишите модули ядра, отвечающие за работу VirtualBox:

     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der vboxdrv.ko
     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der vboxnetadp.ko
     /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der vboxnetflt.ko
    
  6. Обновите конфигурацию загрузчика:

     update-initramfs -u -k all
    
  7. Убедитесь, что модуль загружается:

     modprove vboxdrv
    

    Если подписание модулей ядра прошло успешно, команда должна выполниться без вывода каких-либо сообщений.

    После успешного подписания модулей не выполняйте команду /sbin/vboxconfig! Модули будут собраны заново, и их придётся подписывать ещё раз.

Автоматизация

Имеет смысл автоматизировать процессы генерации ключа и подписания модулей ядра. Для этого создайте два скрипта:

  • Скрипт генерации цифровой подписи

      echo "Создание ключей"
    
      mkdir -p /var/lib/shim-signed/mok/
      cd /var/lib/shim-signed/mok/
      openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=My Name/"
      openssl x509 -inform der -in MOK.der -out MOK.pem
    
      echo "Импорт ключа"
      mokutil --import /var/lib/shim-signed/mok/MOK.der
    
  • Скрипт подписывания модулей ядра:

      echo "Подписание модулей"
    
      mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
      mok_certificate="/var/lib/shim-signed/mok/MOK.der"
    
      # Определение версии используемого ядра
      VERSION="$(uname -r)"
      SHORT_VERSION="$(uname -r | cut -d . -f 1-2)"
      MODULES_DIR=/lib/modules/$VERSION
      KBUILD_DIR=/usr/lib/linux-kbuild-$SHORT_VERSION
    
      echo -n "Введите пароль приватного ключа:"
      read -s KBUILD_SIGN_PIN
      export KBUILD_SIGN_PIN
    
      if [ -d "$MODULES_DIR/updates/dkms" ]; then
          echo "Подписание модулей в каталоге ${MODULES_DIR}/updates/dkms/"
    
          cd "$MODULES_DIR/updates/dkms" # For dkms packages
    
          find -name \*.ko | while read i; do
              sudo --preserve-env=KBUILD_SIGN_PIN \
              "$KBUILD_DIR"/scripts/sign-file \
              sha256 \
              $mok_signing_key \
              $mok_certificate \
              "$i" || break
          done
      fi
    
      if [ -d "$MODULES_DIR/misc/" ]; then
          echo "Подписание модулей в каталоге ${MODULES_DIR}/misc"
    
          cd "$MODULES_DIR/misc/"
    
          find -name \*.ko | while read i; do
              sudo --preserve-env=KBUILD_SIGN_PIN \
                  "$KBUILD_DIR"/scripts/sign-file \
                   sha256 \
                   $mok_signing_key \
                   $mok_certificate \
                   "$i" || break
          done
      fi
    
      echo "Обновление параметров ядра"
    
      update-initramfs -u -k all
    

Теперь алгоритм работы в режиме Secure Boot упростился до двух простых шагов:

  1. Запуск первого скрипта, выполняющего генерацию и импорт MOK.

    Этот шаг достаточно выполнить всего один раз.

  2. Запуск второго скрипта по необходимости.