Secure Boot — механизм UEFI, который блокирует выполнение любого кода на этапе загрузки, если его подпись не подтверждена доверенным ключом. В Linux цепочка доверия проходит через несколько звеньев: прошивка проверяет shim, shim проверяет GRUB, GRUB проверяет ядро, а ядро проверяет каждый загружаемый модуль. Если на любом этапе подпись не проходит валидацию — загрузка останавливается.
Прошивка хранит несколько наборов ключей в энергонезависимой памяти (NVRAM):
Большинство x86-систем поставляются с сертификатами Microsoft в db. Именно это позволяет Linux-дистрибутивам использовать модель shim: бинарник shim подписан ключом Microsoft, который уже доверен прошивке.
Прошивка определяет, что загружать, через переменные NVRAM:
При включении Secure Boot прошивка читает переменную
Shim — минимальный pre-bootloader, подписанный Microsoft. Прошивка валидирует его подпись по сертификату из db и передаёт управление.
Внутри shim встроена собственная база доверия, содержащая сертификат дистрибутива (например, Canonical для Ubuntu). Это позволяет shim проверять подписи GRUB, ядра и MokManager без необходимости добавлять сертификат каждого дистрибутива в прошивку.
После валидации shim загружает второй этап — либо GRUB (штатная загрузка), либо MokManager (управление ключами).
GRUB подписан ключом дистрибутива. Shim проверяет эту подпись и передаёт управление. GRUB читает конфигурацию с раздела
Ядро в режиме Secure Boot представляет собой самодостаточный EFI-бинарник, подписанный ключом дистрибутива. GRUB проверяет подпись ядра перед передачей управления. Если подпись невалидна — загрузка прерывается.
Важный нюанс: initrd не проверяется. Это известное ограничение цепочки доверия — содержимое initramfs остаётся за пределами криптографической верификации на этапе загрузки.
После загрузки ядро отключает Boot Services прошивки и переходит в пользовательский режим, где доступ к UEFI-переменным становится read-only.
Модули ядра обладают широкими привилегиями — фактически это код, работающий в ring 0. Поэтому механизм Secure Boot распространяется и на них.
Подсистема подписи модулей (module signing facility) использует X.509-сертификаты. Поддерживаются алгоритмы RSA, NIST P-384 ECDSA и NIST FIPS-204 ML-DSA. Хеш-алгоритмы для RSA и ECDSA: SHA-2 и SHA-3 с размерами 256, 384 и 512 бит.
Проверка выполняется целиком внутри ядра — userspace-компоненты не участвуют. Модули загружаются через
При
Если
Модуль с некорректно сформированным блоком подписи отклоняется в любом режиме.
Публичные ключи для проверки подписей хранятся в keyring
Дополнительные ключи можно добавить командой
Архитектурный код может также импортировать публичные ключи из аппаратного хранилища — например, из базы ключей UEFI.
MOK — механизм, позволяющий пользователю добавлять собственные ключи доверия без модификации прошивки. Это основной способ подписывать сторонние модули (DKMS-драйверы, проприетарные модули NVIDIA и т. п.).
При установке или обновлении системы, если требуются сторонние модули:
Пароль, заданный пользователем, действителен только для одного запуска shim и MokManager. После завершения или отмены процесса он очищается.
Начиная с shim 15.4, ключи MOK, помеченные OID
Приватный ключ MOK хранится на файловой системе как обычный файл с правами root. Это осознанный компромисс: наличие root-доступа и так даёт полный контроль над системой, но администраторам стоит учитывать, что MOK на диске фактически стирает границу между root и kernel mode.
Для ручной подписи используется утилита
Если приватный ключ защищён паролем или PIN-кодом, его передают через переменную окружения
Генерация пары ключей через OpenSSL:
Полученный файл
На любом этапе цепочки неподписанный или некорректно подписанный бинарник блокируется.
Если необходимо загрузить неподписанное ядро или модуль без собственной подписи:
Утилита
Для диагностики проблем с загрузкой модулей полезно обращаться к
Проверить, какие ключи находятся в системном keyring, можно через
Для систем, где Secure Boot управляется через UEFI-прошивку, состояние можно также проверить через EFI-переменные, доступные в
Поддержка Secure Boot в Ubuntu развивалась поэтапно:
Пакеты
Если в системе уже существует зарегистрированный MOK, установка нового DKMS-модуля (стороннего драйвера) автоматически подписывает собранный модуль этим ключом. Взаимодействие с пользователем не требуется.
Если MOK отсутствует или не зарегистрирован, система автоматически создаёт новый ключ непосредственно перед подписью и предлагает пользователю зарегистрировать его при следующей перезагрузке через MokManager.
При обновлении системы пакеты
Базы ключей в UEFI-прошивке
Прошивка хранит несколько наборов ключей в энергонезависимой памяти (NVRAM):
- PK (Platform Key) — корневой ключ платформы. Определяет, кто имеет право изменять остальные базы. Обычно принадлежит производителю оборудования.
- KEK (Key Exchange Key) — ключи, уполномоченные обновлять базы данных подписей.
- db (Signature Database) — список доверенных сертификатов и хешей. Бинарник, подписанный ключом из db, считается доверенным.
- dbx (Forbidden Signature Database) — список отозванных сертификатов и хешей. Даже если подпись есть в db, наличие в dbx блокирует загрузку.
Большинство x86-систем поставляются с сертификатами Microsoft в db. Именно это позволяет Linux-дистрибутивам использовать модель shim: бинарник shim подписан ключом Microsoft, который уже доверен прошивке.
Переменные загрузки NVRAM
Прошивка определяет, что загружать, через переменные NVRAM:
BootXXXX(например,Boot0000,Boot0001) — содержат путь к EFI-бинарнику и параметры.
BootOrder— задаёт приоритет записейBootXXXX.
При включении Secure Boot прошивка читает переменную
BootOrder, находит первую активную запись и пытается загрузить указанный EFI-файл, предварительно проверив его подпись.Shim: мост между Microsoft и дистрибутивом
Shim — минимальный pre-bootloader, подписанный Microsoft. Прошивка валидирует его подпись по сертификату из db и передаёт управление.
Внутри shim встроена собственная база доверия, содержащая сертификат дистрибутива (например, Canonical для Ubuntu). Это позволяет shim проверять подписи GRUB, ядра и MokManager без необходимости добавлять сертификат каждого дистрибутива в прошивку.
После валидации shim загружает второй этап — либо GRUB (штатная загрузка), либо MokManager (управление ключами).
GRUB и загрузка ядра
GRUB подписан ключом дистрибутива. Shim проверяет эту подпись и передаёт управление. GRUB читает конфигурацию с раздела
/boot, находит образ ядра и initrd.Ядро в режиме Secure Boot представляет собой самодостаточный EFI-бинарник, подписанный ключом дистрибутива. GRUB проверяет подпись ядра перед передачей управления. Если подпись невалидна — загрузка прерывается.
Важный нюанс: initrd не проверяется. Это известное ограничение цепочки доверия — содержимое initramfs остаётся за пределами криптографической верификации на этапе загрузки.
После загрузки ядро отключает Boot Services прошивки и переходит в пользовательский режим, где доступ к UEFI-переменным становится read-only.
Подпись модулей ядра
Модули ядра обладают широкими привилегиями — фактически это код, работающий в ring 0. Поэтому механизм Secure Boot распространяется и на них.
Как устроена проверка
Подсистема подписи модулей (module signing facility) использует X.509-сертификаты. Поддерживаются алгоритмы RSA, NIST P-384 ECDSA и NIST FIPS-204 ML-DSA. Хеш-алгоритмы для RSA и ECDSA: SHA-2 и SHA-3 с размерами 256, 384 и 512 бит.
Проверка выполняется целиком внутри ядра — userspace-компоненты не участвуют. Модули загружаются через
insmod, modprobe, init_module() или finit_module() без дополнительной обработки на стороне пользователя.Ключевые параметры конфигурации ядра
| Параметр | Назначение |
|---|---|
CONFIG_MODULE_SIG | Включает проверку подписей модулей |
CONFIG_MODULE_SIG_FORCE | Запрещает загрузку неподписанных модулей и модулей с неизвестным ключом |
CONFIG_MODULE_SIG_ALL | Автоматически подписывает модули на этапе modules_install |
CONFIG_MODULE_SIG_KEY | Путь к PEM-файлу с приватным ключом и сертификатом (по умолчанию certs/signing_key.pem) |
CONFIG_SYSTEM_TRUSTED_KEYS | PEM-файл с дополнительными сертификатами для системного keyring |
Режимы enforcement
При
CONFIG_MODULE_SIG_FORCE=y (или параметре командной строки module.sig_enforce=1) ядро загружает только модули с валидной подписью, для которой у него есть публичный ключ. Попытка загрузить неподписанный модуль завершается ошибкой.Если
CONFIG_MODULE_SIG_FORCE выключен (permissive-режим), неподписанные модули загружаются, но ядро помечается как tainted, а модуль получает флаг E.Модуль с некорректно сформированным блоком подписи отклоняется в любом режиме.
Встроенный keyring
Публичные ключи для проверки подписей хранятся в keyring
.builtin_trusted_keys. Просмотреть его содержимое можно через /proc/keys:
Код:
cat /proc/keys | grep builtin_trusted_keys
Дополнительные ключи можно добавить командой
keyctl padd, но только если новый ключ подписан ключом, уже находящимся в .builtin_trusted_keys.Архитектурный код может также импортировать публичные ключи из аппаратного хранилища — например, из базы ключей UEFI.
Machine Owner Keys (MOK)
MOK — механизм, позволяющий пользователю добавлять собственные ключи доверия без модификации прошивки. Это основной способ подписывать сторонние модули (DKMS-драйверы, проприетарные модули NVIDIA и т. п.).
Генерация и регистрация
При установке или обновлении системы, если требуются сторонние модули:
- Автоматически генерируется пара ключей MOK.
- Пользователю предлагается задать пароль (потребуется при следующей загрузке).
- Сторонние модули подписываются сгенерированным MOK.
- При перезагрузке MokManager выводит текстовый интерфейс с предложением зарегистрировать ключ.
- Пользователь выбирает «Enroll MOK», подтверждает отпечаток сертификата и вводит пароль.
- Ключ записывается в trust-базу shim, система перезагружается.
Пароль, заданный пользователем, действителен только для одного запуска shim и MokManager. После завершения или отмены процесса он очищается.
Ограничения MOK
Начиная с shim 15.4, ключи MOK, помеченные OID
1.3.6.1.4.1.2312.16.1.2 (Module-signing only), принимаются ядром для проверки модулей, но игнорируются shim и GRUB при валидации загрузочных образов. Это означает, что MOK нельзя использовать для подписи собственного загрузчика или ядра — только для модулей.Приватный ключ MOK хранится на файловой системе как обычный файл с правами root. Это осознанный компромисс: наличие root-доступа и так даёт полный контроль над системой, но администраторам стоит учитывать, что MOK на диске фактически стирает границу между root и kernel mode.
Подпись собственного модуля
Для ручной подписи используется утилита
scripts/sign-file из дерева исходников ядра. Она принимает четыре аргумента: хеш-алгоритм, путь к приватному ключу, путь к сертификату и путь к модулю.
Bash:
scripts/sign-file sha512 kernel-signkey.priv kernel-signkey.x509 module.ko
Если приватный ключ защищён паролем или PIN-кодом, его передают через переменную окружения
KBUILD_SIGN_PIN.Генерация пары ключей через OpenSSL:
Bash:
openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
-config x509.genkey -outform PEM \
-out kernel_key.pem -keyout kernel_key.pem
Полученный файл
kernel_key.pem содержит и приватный ключ, и сертификат. Путь к нему указывают в CONFIG_MODULE_SIG_KEY.Особенности подписанного модуля
- Подпись добавляется в конец файла. Маркер
~Module signature appended~.подтверждает наличие подписи, но не её валидность.
- Подписанный модуль нельзя strip — подпись покрывает весь ELF-файл, включая отладочную информацию.
- Хеш-алгоритм при подписи не обязан совпадать с настроенным в ядре, но должен быть либо встроен в ядро, либо загружаться без зависимостей.
Что происходит при сбое валидации
| Этап | Поведение при невалидной подписи |
|---|---|
| Прошивка → shim | Загрузка не начинается, firmware выводит ошибку |
| shim → GRUB | shim останавливает процесс |
| GRUB → ядро | GRUB отказывается передавать управление |
| Ядро → модуль | insmod/modprobe возвращает ошибку, модуль не загружается |
На любом этапе цепочки неподписанный или некорректно подписанный бинарник блокируется.
Отключение Secure Boot и обходные пути
Если необходимо загрузить неподписанное ядро или модуль без собственной подписи:
sudo mokutil --disable-validation— отключает проверку на уровне shim (требуется пароль и перезагрузка). Secure Boot в прошивке остаётся включённым, но shim перестаёт валидировать образы.
- Отключение Secure Boot в настройках UEFI — полностью убирает проверку подписей на уровне прошивки.
- Подпись собственного ядра или загрузчика ключом, зарегистрированным через MokManager (без OID module-signing-only).
Практическая проверка состояния Secure Boot
Утилита
mokutil предоставляет интерфейс для взаимодействия с MOK и проверки состояния Secure Boot на уровне shim. В частности, она позволяет отключить валидацию (--disable-validation) и управлять регистрацией ключей.Для диагностики проблем с загрузкой модулей полезно обращаться к
dmesg: при попытке загрузить неподписанный модуль в enforce-режиме ядро выводит сообщение об ошибке с указанием имени модуля. В permissive-режиме модуль загрузится, но в выводе dmesg и в /proc/sys/kernel/tainted появится отметка о tainted-состоянии с символом E.Проверить, какие ключи находятся в системном keyring, можно через
/proc/keys — там отображаются все асимметричные ключи, включая сертификат дистрибутива и зарегистрированные MOK.Для систем, где Secure Boot управляется через UEFI-прошивку, состояние можно также проверить через EFI-переменные, доступные в
/sys/firmware/efi/efivars/. Если каталог существует и содержит переменную SecureBoot, система загружена в UEFI-режиме.Эволюция Secure Boot в Ubuntu
Поддержка Secure Boot в Ubuntu развивалась поэтапно:
- Ubuntu 12.04 LTS — первое появление Secure Boot: enforcing для загрузчика, non-enforcing для ядра.
- Ubuntu 18.04 LTS — полная верификация: загрузчик, ядро и модули.
- Ubuntu 20.04 LTS — добавлена поддержка
grub-efi-arm64-signedдля ARM64.
- Ubuntu 21.04 — shim 15.4 с ограничением MOK-ключей только для подписи модулей.
Пакеты
shim-signed и grub-efi-amd64-signed (или grub-efi-arm64-signed) содержат подписанные бинарники, распространяемые через основной архив Ubuntu.Автоматическая подпись DKMS-модулей
Если в системе уже существует зарегистрированный MOK, установка нового DKMS-модуля (стороннего драйвера) автоматически подписывает собранный модуль этим ключом. Взаимодействие с пользователем не требуется.
Если MOK отсутствует или не зарегистрирован, система автоматически создаёт новый ключ непосредственно перед подписью и предлагает пользователю зарегистрировать его при следующей перезагрузке через MokManager.
При обновлении системы пакеты
shim и shim-signed обновляются, генерируется новый MOK, сторонние модули пересобираются под новое ядро и подписываются. После перезагрузки MokManager предлагает зарегистрировать обновлённый ключ и, при необходимости, повторно включить валидацию shim.
