Эта статья описывает политику упаковки и сопровождения официальных ядер Linux в дистрибутивах ROSA Fresh/Chrome платформы rosa2021.1
.
Исходники пакетов с ядрамя находятся здесь:
Каждое ядро собирается в отдельный пакет, в название которого включается:
Примеры названий пакетов с ядрами:
Примеры названий пакетов с заголовочными файлами и исходниками ядра (необходимы для сборки модулей ядра):
В пакете kernel-headers находятся относящиеся не к конкретной версии ядра заголовочные файлы, его не следует путать с devel-пакетом от конкретного ядра.
Пример пути к модулям ядра: /lib/modules/5.15.67-generic-1rosa2021.1-x86_64
Пример uname ядра: 5.15.67-generic-1rosa2021.1-x86_64
Пакетный менеджер dnf обеспечивает одновременную установку нескольких (по умолчанию — трех) минорных версий ядра несмотря на одинаковые названия пакетов:
$ dnf config-manager --dump | grep installonly installonly_limit = 3 installonlypkgs = kernel, kernel-PAE, installonlypkg(kernel), installonlypkg(kernel-module), installonlypkg(vm), multiversion(kernel) $ rpm -q --whatprovides 'installonlypkg(kernel)' <...> kernel-5.15-generic-5.15.53-1.x86_64 kernel-5.15-generic-5.15.65-1.x86_64 kernel-5.15-generic-5.15.67-1.x86_64
Используются официальные релизы выбранной ветки ядра (например, 5.10, 5.15) с kernel.org. По мере выхода новых минорных версий производится обновление пакета с ядром, которые проходят стандартное для всех обновлений тестирование. Задачи как можно быстрее обновлять пакет при выходе новой версии ядра не стоит. Основной упор делается на обеспечение стабильной работы. При выходе исправлений уязвимостей обновления производятся быстрее.
Существует несколько способов поставки сторонних модулей ядра:
Первые 2 способа не вызывают вопросов и требуют наличия исходников, но некоторые разработчики модулей ядра не хотят поставлять их в виде исходников. У сопровождающих пакета с ядром получился такой выбор:
Второе представляется меньшим злом. Мы не гарантируем стабильность ABI. По мере появления сторонних модулей от технологических партнеров, возможно, будет проводиться какой-то контроль ABI исходя из используемых ими интерфейсов. Ядро собрано с CONFIG_MODVERSIONS=y, при загрузке модулей ядра не проверяется соответствие исходного и текущего ядер, а сверяются хеш-суммы прототипов используемых функций ABI в загружаемом модуле и в текущем ядре, которые должны совпадать для загрузки модуля.
В пакетах с ядром есть симлинк /lib/modules/5.15.67-generic-1rosa2021.1-x86_64/zzz-5.15-rosa-flow-abi[1] на /lib/modules/5.15-rosa-flow-abi. Таким образом, сторонние модули ядра, лежащие в /lib/modules/5.15-rosa-flow-abi, будут подгружаться всеми ядрами 5.15.х в дистрибутивах ROSA Fresh/Chrome. Разработчикам бинарных модулей, которые не готовы поставлять их в виде исходных текстов, рекомендуется класть их в /lib/modules/5.15-rosa-flow-abi.
Каталог /lib/modules/5.15-rosa-flow-abi принадлежит пакету kernel-5.15-rosa-flow-abi, который содержит только ее.
Рекомендуем разработчикам сторонних модулей поставлять связываемую с ядром часть в виде исходников, как Nvidia.
В ОС РОСА (далее — Роса) имеется механизм проверки валидности подписей модулей ядра.
При сборке ядра создается ключевая пара (далее — «рандомный ключ»), закрытым ключом подписываются все входящие в состав ядра модули, а открытый ключ встраивается в ядро. Закрытая часть этой ключевой пары нигде не сохраняется.
Также в ядро встраиваются несколько дополнительных открытых ключей, закрытые части которых хранятся у Росы (далее — «дополнительные ключи»).
При загрузке модуля ядра выполняется проверка валидности его подписи. Если модуль подписан одним из ключей, открытая часть которых встроена в ядро, а подпись валидна, то проверка подписи модуля считается пройденной успешно.
В ОС ROSA Fresh/Хром по умолчанию разрешена загрузка неподписанных модулей ядра, а для ее запрета необходимо добавить в cmdline ядра: module.sig_enforce=1
.
В ОС ROSA Никель по умолчанию запрещена загрузка неподписанных модулей ядра, а для ее разрешения необходимо добавить в cmdline ядра: module.sig_enforce=0
.
Из предыдущего раздела следует, что проверка подписи модуля ядра может быть проведена успешно только в следующих случаях:
Сторонний модуль с непубличным исходным кодом не может быть собран и подписан во время сборки ядра, т.к. это требует свободного распространения его кода. Закрытая часть одного из дополнительных ключей могла бы быть передана разработчику стороннего модуля, однако это представляется неправильным, поскольку доверие к таким модулям не может быть более или равным доверию к поставляемым разработчиком ОС модулям, а системный администратор не будет иметь возможности ограничить доверие к сторонним разработкам, в т.ч. в случае компроментации выданного таким образом закрытого ключа.
Предлагается следующий механизм:
Нужно создать ключевую пару и подписанный этим ключом запрос на сертификат.
Можно использовать как ГОСТ-алгоритмы, так и RSA или эллиптические кривые.
RSA:
openssl req -new -nodes -newkey rsa:2048 -keyout privatekey.key -out certificatesigningrequest.csr
По ГОСТ:
libressl req -new -nodes -newkey gost2001 -pkeyopt dgst:streebog512 -pkeyopt paramset:A -streebog512 -days 109500 -keyout privatekey.key -out certificatesigningrequest.csr
(для ГОСТ требуется libressl с патчами Росы (или иное средство), который есть в репозитории Росы или может быть собран отдельно; лучше использовать пока что RSA)
Generating a 2048 bit GOST2001 private key writing new private key to 'privatekey.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. -----
Указываем страну:
Country Name (2 letter code) []:RU
Указываем субъект РФ (республику/область/иное):
State or Province Name (full name) []:Orlovskaya region
Указываем город или иной населенный пункт (для городов федерального значения значение этих двух полей может совпадать, например, в обоих Moscow):
Locality Name (eg, city) []:Oryol
Заполняем информацию об организации, OUN можно пропустить:
Organization Name (eg, company) []:Roga i kopyta Ltd. Organizational Unit Name (eg, section) []: Common Name (eg, fully qualified host name) []:roga-i-kopyta.ru Email Address []:info@roga-i-kopyta.ru
Можно использовать пароль, можно не использовать, оставив поле пустым и просто нажав Enter:
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:
Было создано 2 файла:
Отправьте CSR (файл certificatesigningrequest.csr) в Росу.
Выпускаем подписанный сертификат:
certtool --generate-certificate --load-request certificatesigningrequest.csr --load-ca-privkey встроенный_в_ядро_ключ.pem --load-ca-certificate встроенный_в_ядро_ключ.pem --outfile /tmp/t1.pem
где /tmp/t1.pem — необходимый результат операции.
Необходимо конвертировать ключ в формат der (это может сделать как сотрудник Росы, так и РСМ сам):
openssl x509 -outform der -in /tmp/t1.pem -out /tmp/t1.der
Подписывание производится с помощью scripts/sign-file из состава исходных кодов ядра Linux. Для удобства использования эта утилита опакечена в Росе (в ОС Никель имеется на диске разработчика), ее можно установить с помощью пакетного менеджера:
sudo dnf install sign-file
Эта утилита в варианте из репозитория поддерживает ГОСТ-ключи и работает через libressl вместо openssl.
Далее подписать модуль ядра:
sign-file sha256 privatekey.key t1.pem file.ko
В случае ГОСТ заменить sha* на streebog256 / streebog512.
Использование именно этой утилиты рекомендуется, но не обязательно.
Выше описано, в какой каталог рекомендуется положить модуль ядра (*.ko*).
В /lib/modules/keys/*.der
необходимо положить подписанный ключом Росы публичный ключ. Имя файла рекомендуется сделать таким: имя_пакета.der, однако технически имя файла может быть любым.
Все ключи из этого каталога добавляются в ядро из initrd (dracut). Пакет dracut должен быть версии не ниже 053-0.git5eb736.16.