помилка підпису модуля та / або необхідний ключ відсутній


11

Я працюю над модулем ядра, який працює чудово. Однак, переглядаючи dmesg, я бачу повідомлення про мій модуль про те, що перевірка модуля не вдалась (підпис перевірки не вдався і / або необхідний ключ відсутній).

Як я можу вирішити цю проблему? Як мені підписати модуль для перевірки?

Дякую.


Відповіді:


3

Все, що вам потрібно, описано тут

КЕРНЕЛЬНИЙ МОДУЛЬ, ЗНАЧАЮЩИЙ МІСЦЕ


ЗМІСТ

  • Огляд
  • Налаштування підпису модуля.
  • Генерування ключів підпису.
  • Відкриті ключі в ядрі.
  • Модулі, що підписуються вручну.
  • Підписані модулі та зачистка.
  • Завантаження підписаних модулів.
  • Недійсні підписи та неподписані модулі.
  • Адміністрація / захист приватного ключа.

ОГЛЯД

Засіб підписання модуля ядра криптографічно підписує модулі під час встановлення, а потім перевіряє підпис при завантаженні модуля. Це дозволяє підвищити безпеку ядра, забороняючи завантажувати неподписані модулі або модулі, підписані недійсним ключем. Підпис модуля підвищує безпеку, ускладнюючи завантаження шкідливого модуля в ядро. Перевірка підпису модуля виконується ядром, так що не потрібно мати довірених бітів простору користувача.

Цей інструмент використовує стандартні сертифікати X.509 ITU-T для кодування відкритих ключів. Підписи самі по собі не кодуються в будь-якому типі промислового стандарту. Наразі об'єкт підтримує лише стандарт шифрування відкритого ключа RSA (хоча він підключається та дозволяє використовувати інші). Можливі хеш-алгоритми, які можна використовувати, - SHA-1, SHA-224, SHA-256, SHA-384 та SHA-512 (алгоритм вибирається за даними підпису).


КОНФІГУРИРОВАННЯ МОДУЛЯ ПІДПИСАННЯ

Засіб підписання модуля вмикається, перейшовши до розділу "Увімкнути підтримку завантажуваного модуля" в налаштуваннях ядра та увімкнувши

CONFIG_MODULE_SIG   "Module signature verification"

Тут є ряд варіантів:

  1. "Потрібно, щоб модулі були дійсно підписані" (CONFIG_MODULE_SIG_FORCE)

    Це визначає, як ядро ​​має поводитися з модулем, який має підпис, для якого ключ не відомий, або модуль, який не підписаний.

    Якщо це вимкнено (тобто "дозвільний"), то модулі, для яких ключ недоступний, і модулі, які не підписані, дозволені, але ядро ​​буде позначено як пошкоджене, а відповідні модулі будуть позначені як заплямовані, показані з символом 'E'.

    Якщо це ввімкнено (тобто "обмежувальний"), завантажуватимуться лише модулі, які мають дійсну підпис, яку можна перевірити відкритим ключем у володінні ядра. Усі інші модулі генерують помилку.

    Незалежно від налаштувань тут, якщо модуль має блок підпису, який неможливо проаналізувати, він буде відхилений поза рукою.

  2. "Автоматично підписувати всі модулі" (CONFIG_MODULE_SIG_ALL)

    Якщо це ввімкнено, модулі будуть автоматично підписані під час фази module_install збірки. Якщо це вимкнено, модулі потрібно підписати вручну, використовуючи:

    scripts/sign-file
    
  3. "З яким алгоритмом хешу слід підписати модулі?"

    Тут представлено вибір того, який алгоритм хешу, етап встановлення підписує модулі:

    CONFIG_MODULE_SIG_SHA1      "Sign modules with SHA-1"
    CONFIG_MODULE_SIG_SHA224    "Sign modules with SHA-224"
    CONFIG_MODULE_SIG_SHA256    "Sign modules with SHA-256"
    CONFIG_MODULE_SIG_SHA384    "Sign modules with SHA-384"
    CONFIG_MODULE_SIG_SHA512    "Sign modules with SHA-512"
    

    Вибраний тут алгоритм також буде вбудований у ядро ​​(а не як модуль), щоб модулі, підписані цим алгоритмом, могли перевіряти свої підписи, не викликаючи циклу залежності.

  4. "Ім'я файлу або PKCS №11 URI ключа підпису модуля" (CONFIG_MODULE_SIG_KEY)

    Якщо встановити цю опцію на щось інше, ніж за замовчуванням "certs / signature_key.pem", вимкніть автогенерацію ключів підпису і дозволить підписати модулі ядра за вибором ключа. Наданий рядок повинен ідентифікувати файл, що містить і приватний ключ, і відповідний йому сертифікат X.509 у формі PEM, або - на системах, де функціонує OpenSSL ENGINE_pkcs11 - URI PKCS # 11, як визначено RFC7512. В останньому випадку URI PKCS №11 повинен посилатися як на сертифікат, так і на приватний ключ.

    Якщо файл PEM, що містить приватний ключ, зашифрований, або якщо маркер PKCS # 11 вимагає PIN-коду, це може бути надано під час створення за допомогою змінної KBUILD_SIGN_PIN.

  5. "Додаткові ключі X.509 для системних брелоків за замовчуванням" (CONFIG_SYSTEM_TRUSTED_KEYS)

    Цю опцію можна встановити на ім'я файлу, кодованого PEM, що містить додаткові сертифікати, які за замовчуванням будуть включені в системний брелок.

Зверніть увагу, що включення підпису модуля додає залежність від пакетів розробки OpenSSL до процесів збирання ядра для інструменту, який виконує підписання.


УЗАГАЛЬНЕННЯ КЛЮЧІВ ПІДПИСУ

Криптографічні ключові пари необхідні для генерування та перевірки підписів. Приватний ключ використовується для створення підпису, а відповідний відкритий ключ використовується для його перевірки. Приватний ключ потрібен лише під час збирання, після чого його можна видалити або надійно зберегти. Відкритий ключ вбудовується в ядро, щоб його можна було перевірити підписи під час завантаження модулів.

У звичайних умовах, коли CONFIG_MODULE_SIG_KEY не змінюється за замовчуванням, збірка ядра автоматично генерує нове ключове слово, використовуючи openssl, якщо такого не існує у файлі:

certs/signing_key.pem

під час створення vmlinux (публічна частина ключа повинна бути вбудована в vmlinux) з використанням параметрів у:

certs/x509.genkey

файл (який також генерується, якщо він ще не існує).

Настійно рекомендуємо надати власний файл x509.genkey.

Найголовніше, що у файлі x509.genkey розділ req_distinguished_name має бути змінено за замовчуванням:

[ req_distinguished_name ]
#O = Unspecified company
CN = Build time autogenerated kernel key
#emailAddress = unspecified.user@unspecified.company

Згенерований розмір ключа RSA також можна встановити за допомогою:

[ req ]
default_bits = 4096

Також можна вручну генерувати ключові приватні / публічні файли, використовуючи файл конфігурації генерації ключів x509.genkey у кореневому вузлі дерева джерел ядра Linux та команду openssl. Нижче наведено приклад для генерації файлів із відкритим / приватним ключем:

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, а сертифікат і ключ в ньому будуть використовуватися замість автоматичної генерації ключа.


ПУБЛІЧНІ КЛЮЧІ В КЕРНЕЛІ

Ядро містить кільце відкритих ключів, яке можна переглянути коренем. Вони знаходяться в брелоку під назвою ".system_keyring", який можна побачити:

[root@deneb ~]# cat /proc/keys
...
223c7853 I------     1 perm 1f030000     0     0 keyring   .system_keyring: 1
302d2d52 I------     1 perm 1f010000     0     0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
...

Крім відкритого ключа, створеного спеціально для підписання модуля, додаткові довірені сертифікати можуть надаватися у файлі, кодованому PEM, на який посилається параметр конфігурації CONFIG_SYSTEM_TRUSTED_KEYS.

Крім того, код архітектури може брати відкриті ключі з магазину апаратних засобів і додавати їх у також (наприклад, з бази даних ключів UEFI).

Нарешті, можна додати додаткові відкриті ключі, виконавши:

keyctl padd asymmetric "" [.system_keyring-ID] <[key-file]

наприклад:

keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509

Однак зауважте, що ядро ​​дозволить додавати ключі до .system_keyring, лише якщо обертка нового ключа X.509 нового ключа буде дійсно підписана ключем, який уже знаходиться в .system_keyring на момент додавання ключа.


РУЧНО ЗАПИСНІ МОДУЛИ

Щоб підписати модуль вручну, використовуйте інструмент скриптів / знакових файлів, доступний у дереві джерела ядра Linux. Сценарій вимагає 4 аргументів:

1.  The hash algorithm (e.g., sha256)
2.  The private key filename or PKCS#11 URI
3.  The public key filename
4.  The kernel module to be signed

Нижче наведено приклад підписання модуля ядра:

scripts/sign-file sha512 kernel-signkey.priv \
    kernel-signkey.x509 module.ko

Використовуваний алгоритм хешу не повинен відповідати налаштованому, але якщо його немає, слід переконатися, що алгоритм хеша або вбудований у ядро, або може бути завантажений, не вимагаючи себе.

Якщо для приватного ключа потрібна парольна фраза чи PIN-код, він може бути наданий у змінній середовища $ KBUILD_SIGN_PIN.


ПІДПИСАНІ МОДУЛИ ТА СТРУПІНГ

Підписаний модуль має цифровий підпис, який просто додається в кінці. Рядок "~ Додано підпис модуля ~." в кінці файлу модуля підтверджується наявність підпису, але він не підтверджує, що підпис дійсний!

Підписані модулі BRITTLE, оскільки підпис знаходиться поза визначеним контейнером ELF. Таким чином, вони НЕ можуть бути позбавлені, коли підпис обчислюється та додається. Зауважте, весь модуль - це підписане корисне навантаження, включаючи будь-яку та всю інформацію про налагодження, наявну на момент підписання.


ЗАВАНТАЖЕННЯ ЗАПИСАНИХ МОДУЛІВ

Модулі завантажуються з insmod, modprobe, init_module () або finit_module (), точно так само, як і для непідписаних модулів, оскільки обробка в просторі користувачів не виконується. Перевірка підпису виконується всередині ядра.


НЕВАЛІДНІ ПІДПИСИ ТА НЕЗНАЧЕННІ МОДУЛИ

Якщо параметр CONFIG_MODULE_SIG_FORCE увімкнено або в командному рядку ядра подано Execucemodulesig = 1, ядро ​​буде завантажувати лише дійсно підписані модулі, для яких у нього є відкритий ключ. Інакше він також завантажить модулі, які не підписані. Будь-який модуль, для якого в ядрі є ключ, але який виявляється невідповідним підписом, завантажуватися не дозволяється.

Будь-який модуль, який має нерозбірливий підпис, буде відхилений


ВПРАВЛІННЯ / ЗАХИСТ ПРИВАТНОГО КЛЮЧА

Оскільки приватний ключ використовується для підписання модулів, віруси та зловмисне програмне забезпечення можуть використовувати приватний ключ для підписання модулів і компрометувати операційну систему. Приватний ключ повинен бути знищений або переміщений у захищене місце і не зберігатися у кореневому вузлі дерева джерела ядра.


Дякую, але я вже абсолютно бачив цей текст. Проблема, з якою я стикаюся, - навіть якщо я можу підписати свій файл, я не можу все-таки завантажувати файл, тому що: "він ядро ​​дозволить додати ключі до. ключ, який вже знаходиться в .system_keyring на момент додавання ключа. "
OmnipotentEntity

Я теж бачив це кілька разів, але це не допомагає. У Ubuntu є помилка, яка впливає на всі материнські плати, які не підтримують uefi: bugs.launchpad.net/ubuntu/+source/linux-lts-xenial/+bug/1656670
musbach

0

Відредагуйте ./include/generated/autoconf.hта змініть рядок

define CONFIG_MODULE_SIG 1

до

define CONFIG_MODULE_SIG 0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.