На Хабре вышла моя статья про настройку Secure Boot для запуска FreeBSD. Здесь её расширенная версия.

Введение

Secure Boot — это технология, предназначенная для загрузки только доверенного кода. Она была создана как ответ на буткиты — вирусы, записывающие свой код в главную загрузочную запись, Master Boot Record, MBR.

Цифровая подпись в очень сильно упрощённом виде работает так:

  1. Вы генерируйте пару огромных простых чисел, их ещё называют открытым и закрытым ключами шифрования.

    Открытый ключ распространяете между абонентами.

    Приватный ключ храните в надёжном месте и никому не показываете. Для надёжности его ещё часто защищают паролем.

  2. Теперь вы создаёте цифровую подпись — вычисляете контрольную сумму нужных файлов, сохраняете это всё в файл, а уже его шифруете приватным ключом.

  3. Любой человек, у которого есть публичный ключ, может убедиться, что файлы отправлены именно вами — достаточно сделать следующее:

    1. Расшифровать файл с контрольными суммами с помощью публичного ключа.

    2. Сравнить фактические контрольные суммы с теми, что записаны в расшифрованном файле.

Применительно к Secure Boot это работает так:

  1. Вы записываете в NVRAM, энергонезависимую память материнской платы, открытые ключи шифрования, или MOK (Machine Owner Key). Далее я буду называть их просто MOK.

  2. На основе приватного ключа создаёте сертификат.

  3. Подписываете загрузчики и драйверы с помощью сертификата.

  4. Secure Boot при попытке выполнить загрузчик или драйвер сначала проверит его цифровую подпись с помощью MOK, который хранится в NVRAM. Если проверка будет успешной, UEFI выполнит код загрузчика или драйвера.

В чём сложность с FreeBSD

Корпорация Microsoft добилась того, чтобы в подавляющем большинстве современных компьютеров в NVRAM уже есть ключи, позволяющие загрузчику Windows успешно пройти проверку Secure Boot. Это позволяет использовать Windows, не требуя от пользователей дополнительных действий.

С другими ОС немного сложнее. Им нужно как-то добавить свой ключ в NVRAM. Чтобы не усложнять жизнь пользователей, разработчики популярных дистрибутивов пошли на сделку с Microsoft: на начальном этапе для запуска Linux используется загрузчик shim-loader, подписанный той же цифровой подписью, что и загрузчик Windows.

Так работают, например, Ubuntu Linux и Debian Linux.

Разработчики FreeBSD ни на какие сделки не пошли, поэтому для запуска этой ОС в режиме Secure Boot необходимо:

  1. Создать пару ключей.

  2. Записать публичный ключ в NVRAM.

  3. Подписать загрузчик.

Далее эти этапы рассматриваются более подробно.

Создание ключей

Ключи можно создать и в Linux, и во FreeBSD, достаточно наличия на компьютере OpenSSL:

  1. Создайте пару ключей:

     openssl req \
          -new \
          -x509 \
          -newkey rsa:2048 \
          -keyout MOK.priv \
          -outform DER \
          -out MOK.der \
          -days 36500 \
          -subj "/CN=My Machine Owner Key/"
    

    Здесь:

    • -new — запрос на создание нового ключа.

    • -x509 — стандарт.

    • rsa:2048 — алгоритм шифрования и длина ключа в битах. Возможно, ключи длиной 4096 бит тоже поддерживаются, но на моей старой ASUS ROG Strix Z370 не взлетело.

    • MOK.priv — имя файла приватного ключа.

    • MOK.der — имя файла публичного ключа.

    • 36500 — срок действия ключа — 10 лет.

    • subj — описание ключа. Можете вписать что угодно после CN=, главное сделать свой ключ легко узнаваемым.

    Если планируете устанавливать драйверы NVIDIA с сайта производителя, а не из репозиториев Debian / Ubuntu, то не задавайте пароль. Установщик драйвера позволяет пойти двумя путями:

    • Сгенерировать ещё одну пару ключей. А нам точно нужен ещё один ключ в NVRAM? Известны случаи, когда переполнение хранилища приводило к возникновению различных ошибок в работе компьютеров.

    • Использовать для подписи драйверов уже существующую пару ключей. Но если ключ защищён паролем, установщик не предложит его ввести, а выдаст сообщение об ошибке и завершит работу.

  2. Создайте сертификат:

     openssl x509 -inform der -in MOK.der -out MOK.pem
    

    Им мы будем подписывать загрузчик FreeBSD.

  3. Скопируйте ключи на флешку или ещё куда-нибудь. Позже нужно будет получить к ним доступ из FreeBSD.

Создание ключей, альтернативный путь в Linux

Публичный ключ и сертификат можно создать и более простым способом, если у вас Debian Linux или Ubuntu Linux:

sudo dkms generate_mok

Эта команда создаст в каталоге /var/lib/shim-signed/mok два файла:

  • MOK.priv — приватный ключ;

  • MOK.der — MOK.

Создание ключей, альтернативный путь во FreeBSD

Во FreeBSD для генерации ключей можно использовать скрипт uefikeys:

  1. Сделайте скрипт исполняемым:

     chmod +x /usr/share/examples/uefisign/uefikeys
    
  2. Запустите скрипт:

     /usr/share/examples/uefisign/ MOK
    

    Скрипт создаст в текущем каталоге два файла:

    • MOK.pem — MOK;

    • MOK.key — приватный ключ.

  3. Переименуйте MOK.pem в MOK.der.

    Вообще это не обязательно, но далее я использую это имя файла в команде импорта MOK в NVRAM.

Импорт MOK в NVRAM

Тут опять понадобится Linux. Во FreeBSD нет ничего, с помощью чего можно было бы импортировать MOK в NVRAM.

  1. Установите утилиту mokutil:

     sudo apt-get install mokutil --yes
    
  2. Импортируйте ключ:

     sudo mokutil --import /path/to/MOK.der
    
  3. Введите пароль и подтверждение. Не делайте их слишком сложными, они понадобятся всего один раз.

  4. Перезагрузите компьютер. Вместо ядра Linux запустится оболочка для управления ключами MOK.

  5. Выбирайте пункты, которые позволят вам раскатать (enroll) ваш MOK в NVRAM. Если всё сделаете правильно, дойдёте до этапа с перезагрузкой компьютера.

  6. Загрузите Linux снова и проверьте наличие вашего MOK в NVRAM:

     mokutil --list-enrolled | grep "Issuer: CN"
    

    Свой ключ вы узнаете по CN. Если использовали для генерации ключей возможности утилиты dkms, то ваши ключи, созданные в Debian, будут выглядеть так:

     Issuer: CN=Debian Secure Boot CA
     Issuer: CN=DKMS module signing key
    

    Технически MOK это контейнер, а ключей в него можно запихнуть хоть 10 штук, так что не удивляйтесь, что импортировали один ключ, а получили два.

Установка и настройка FreeBSD

Пора переходить к самому интересному — установке FreeBSD.

  1. Убедитесь, что в настройках UEFI загружены ключи по умолчанию.

    Значения в разделах Управление PK, Управление KEK, Управление базами и Управление DBX не должны быть пустыми. В противном случае Windows, например, считает, что Secure Boot выключен, даже если он включен.

  2. В настройках UEFI выключите Secure Boot.

    Эта настройка может называться по-разному. Например, у меня она называется Тип ОС. Чтобы выключить Secure Boot, нужно выбрать Другие ОС.

  3. Запустите установщик FreeBSD и установите ОС в режиме EFI. На этапе разметки диска выберите структуру разделов GPT и обязательно создайте раздел ESP, если его нет.

  4. Сделайте созданные ранее ключи доступными в файловой системе FreeBSD. Способ, которым вы это сделаете, не важен, нужно лишь чтобы вы могли указать путь к файлам.

  5. Удалите из каталога /boot/efi/efi/boot/loader.efi неподписанный загрузчик:

     rm /boot/efi/efi/boot/loader.efi
    
  6. Подпишите загрузчик и скопируйте его в каталог /boot/efi/efi/boot/:

     uefisign \
       -c MOK.der \
       -k MOK.priv \
       -o /boot/efi/efi/boot/bootx64.efi \
       /boot/loader.efi
    

    Имя файла загрузчика имеет значение, поскольку UEFI ищет только файлы с определёнными именами.

  7. Перезагрузите компьютер и в настройках UEFI включите Secure Boot.

    Ваша FreeBSD должна нормально загрузиться.