Наверное, кто-то ещё помнит историю о том, как появлялся 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 же ситуация более жёсткая. Использование неподписанного ядра просто недопустимо и система просто не загружается (либо показывая логотип, или чёрный экран или вываливая ошибку). Что же делать?
Два варианта:
- Отключить режим secure boot
- Подписать свежеустановленное ядро
Мы пойдём по второму и более сложному пути из академического, например, интереса. Оригинал решения описан в публикации от 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 – это и есть наш пациент.
Возможно, обратили внимание и на то, что я использую для подтверждения повышения привилегий сканер отпечатка пальца. Об этом я рассказал ранее.
Подписывание нового ядра линукс
После того, как новое ядро было установлено: подпишите его, скопируйте 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. Мало ли, что-то пойдёт не так..