Обновление ядра на Ubuntu 20.04 с активированным режимом UEFI secure boot

Обновление ядра на Ubuntu 20.04 с активированным режимом UEFI secure boot

Наверное, кто-то ещё помнит историю о том, как появлялся UEFI на замену BIOS и том, с какими надуманными сложностями столкнулось Linux-сообщество. Но на текущий момент все они решены и современные дистрибутивы Linux нормально устанавливаются на современные устройства с нормальными настройками в BIOS (без отключенного режима «secure boot» и без включенного режима «legacy mode’).

Но есть некоторые интересные моменты, которые связаны с желанием установить более новые версии ядра на Ubuntu 20.04 (и/или при использовании версии GRUB2 2.02+dfsg1-5ubuntu1 и выше). В предыдущей LTS версии Ubuntu 18.04 вся эта история могла вызывать только предупреждение при загрузке (о том, что версия ядра не является подписанной. Где-то на просторах интернета я встречал сообщения об этом). На Ubuntu 20.04 LTS же ситуация более жёсткая. Использование неподписанного ядра просто недопустимо и система просто не загружается (либо показывая логотип, или чёрный экран или вываливая ошибку). Что же делать?

Два варианта:

  1. Отключить режим secure boot
  2. Подписать свежеустановленное ядро

Мы пойдём по второму и более сложному пути из академического, например, интереса. :) Оригинал решения описан в публикации от 2017 года на официальном блоге Ubuntu.

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

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

Создайте файл mokconfig.cnf, который будет содержать все нужные параметры для генерации сертификата, который используется как ключ:

# This definition stops the following lines failing if HOME isn't defined.
HOME                    = .
RANDFILE                = $ENV::HOME/.rnd 
[ req ]
distinguished_name      = req_distinguished_name
x509_extensions         = v3
string_mask             = utf8only
prompt                  = no

[ req_distinguished_name ]
countryName             = <YOURcountrycode>
stateOrProvinceName     = <YOURstate>
localityName            = <YOURcity>
0.organizationName      = <YOURorganization>
commonName              = Secure Boot Signing Key
emailAddress            = <YOURemail>

[ v3 ]
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer
basicConstraints        = critical,CA:FALSE
extendedKeyUsage        = codeSigning,1.3.6.1.4.1.311.10.3.6
nsComment               = "OpenSSL Generated Certificate"

Раздел [ req_distinguished_name ] заполните на своё усмотрение. Реальными или выдуманными данными. Это пригодится только для того, чтобы проверить и удостовериться, что ключ установился.

Далее генерируем ключ и конвертируем в PEM-формат

openssl req -config ./mokconfig.cnf -new -x509 -newkey rsa:2048 -nodes -days 36500 -outform DER -keyout "MOK.priv" -out "MOK.der"
openssl x509 -in MOK.der -inform DER -outform PEM -out MOK.pem

После того. как ключ сгенерирован и его формат приведён к нужному, заливаем его в UEFI

sudo mokutil --import MOK.der

В процессе импорта ключа требуется ввести пароль, который потребуется просто для подтверждения импорта ключа. Поэтому можно ввести любой.

Далее перезагрузите систему. Первым делом, что вы увидете при загрузке — синий экран. Но это не синий экран смерти ;) а интерфейс инструмента MOKManager.

В пункте меню “Enroll MOK” нажмите  “View key” и убедитесь, что этот ключ тот самый, что был сгенерирован. Завершением установки ключа будет ввод пароля, который был указан ранее. После этого продолжите загрузку системы.

После удачного завершения загрузки системы и авторизации в учётную запись, проверьте на всякий случай, что ключ был успешно импортирован командой:

$  sudo mokutil --list-enrolled
[key 1]
SHA1 Fingerprint: 41:55:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            6b:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=RU, ST=IRK, L=Irkutsk, O=sabinich, CN=Secure Boot Signing Key/emailAddress=vadim@sabini.ch
        Validity...
...

Установка новой версии ядра Линукс

Для обновления ядра без установки всяких непонятных приложений из всяких непонятных репозиториев, я решил использовать такой же непонятный BASH-скрипт ubuntu-mainline-kernel, который поддерживает Ubuntu с 16.04 по 20.04

Для его установки выполните две команды:

wget https://raw.githubusercontent.com/pimlie/ubuntu-mainline-kernel.sh/master/ubuntu-mainline-kernel.sh
sudo install ubuntu-mainline-kernel.sh /usr/local/bin/

Для выяснения доступности последних версий ядер можно выполнить команду проверки локальной версии ядра, наличия ядра и его корректности сборки:

$ ubuntu-mainline-kernel.sh -c 
Finding latest version available on kernel.ubuntu.com: v5.9.11
A newer kernel version (v5.9.11) was found but the build was not successful

На момент написания публикации установить версию ядра 5.9.11 не удавалось. Поэтому пробуем на v5.10.

Установка выполняется так же в одну команду

sudo ubuntu-mainline-kernel.sh -i <VERSION>

В качестве <VERSION> можно указывать v5.10 или 5.10

$ sudo ubuntu-mainline-kernel.sh -i v5.9.10
Положите указательный палец правой руки на считывающее устройство
Downloading index from kernel.ubuntu.com
Will download 6 files from kernel.ubuntu.com:
Downloading amd64/linux-headers-5.9.10-050910-generic_5.9.10-050910.202011221708_amd64.deb: 100%   
Downloading amd64/linux-headers-5.9.10-050910_5.9.10-050910.202011221708_all.deb: 100%   
Downloading amd64/linux-image-unsigned-5.9.10-050910-generic_5.9.10-050910.202011221708_amd64.deb: 100%   
Downloading amd64/linux-modules-5.9.10-050910-generic_5.9.10-050910.202011221708_amd64.deb: 100%   
Downloading amd64/CHECKSUMS: 100%   
Downloading amd64/CHECKSUMS.gpg: 100%   
Signature of checksum file has been successfully verified
Checksums of deb files have been successfully verified with sha256sum
Installing 4 packages
Cleaning up work folder

Обратите внимание на скачивание и установку пакета, содержащее название linux-image-unsigned — это и есть наш пациент.

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

Настройка сканера отпечатков пальцев в Ubuntu 20.04

Подписывание нового ядра линукс

После того, как новое ядро было установлено: подпишите его, скопируйте initrd с новым названием, содержащим «signed» и обновите GRUB

sudo sbsign --key MOK.priv --cert MOK.pem /boot/vmlinuz-<KERNEL-VERSION>-generic --output /boot/vmlinuz-<KERNEL-VERSION>-generic.signed
sudo cp /boot/initrd.img-<KERNEL-VERSION>-generic{,.signed}
sudo update-grub

Где <KERNEL-VERSION> — версия установленного ядра.

Теперь можно перезагрузиться…

После удачной загрузки, убедитесь, что система использует выбранную вами версию ядра командой uname -a, и удалите неподписанные версии. Можно путём переименования unsigned -> signed

sudo mv /boot/vmlinuz-<KERNEL-VERSION>-generic{.signed,}
sudo mv /boot/initrd.img-<KERNEL-VERSION>-generic{.signed,}
sudo update-grub

 

PS: не забудьте сохранить в безопасном месте файлы ключа MOK.*

PPS: и конечно же не забудьте сделать бекапы /boot/uefi. Мало ли, что-то пойдёт не так..

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *