Содержание

Введение

Secure Boot (далее SB) — это часть стандарта UEFI, описывающая систему доверенной загрузки. Проверка осуществлятся посредством цепочки сертификатов, главные из которых (корневые) находятся внутри специального хранилища в прошивке UEFI-BIOS. При включённом SB прошивка может загружать и исполнять только бинарники, подписанные доверенным сертификатом. Соответственно, чтобы обеспечить загрузку дистрибутива, требуется наличие загрузчика, который подписан одним из ключей, входящих в базовую цепочку доверия. Обычно в этот список входят сертификаты фирмы-производителя оборудования, производителя прошивки, материнской платы, а также сертификат компании Microsoft, каковая и предоставляет услуги по подписыванию сторонних EFI-файлов.

В дистрибутиве ROSA Desktop Fresh в качестве EFI-загрузчика используется grub2, но поскольку при каждом обновлении его требовалось бы переподписывать заново (что может занять несколько недель), то в качестве доверенного загрузчика была выбрана минималистичная заглушка shim от Matthew Garrett. Shim позволяет добавить в цепочку доверия новые ключи, а также (в комплекте с утилитой MokManager) вручную отметить нужные бинарники как доверенные. В итоге последовательность загрузки выглядит следующим образом:

Чтобы эта схема работала, исполняемые файлы grub2 должны при каждом обновлении переподписываться ключом ROSA. С одной стороны, требуется процедуру подписывания максимально упростить и автоматизировать, с другой стороны, необходимо гарантировать защиту от несанкционированного доступа к подписыванию произвольных файлов. Ниже описана схема инфраструктуры, которую мы реализовали для этих целей, а также приведены инструкции по разворачиванию её с нуля.

Схема инфраструктуры ABF для безопасного подписывания

Здесь описана общая схема работы. Технические подробности о реализации и необходимых взаимосвязях расписаны в следующем разделе.

Инструкция по разворачиванию инфраструктуры

В этом разделе предполагается, что система ABF как таковая уже развёрнута и работоспособна, что дистрибутивные платформы сконфигурированы и т. д.

rpm1-rosa-signer     ansible_ssh_port=22 ansible_ssh_host=192.168.1.22

[abf-worker-rpm-rosa-signer]
rpm1-rosa-signer  abf_token='XXXXXXXXXXXXXXXXXXXX' platform_type='rhel' platform_name='centos'

[abf-worker-rpm-rosa-signer:vars]
file_store_ip     = 195.19.76.233
file_store_domain = file-store.rosalinux.ru
abf_ip1           = 195.19.76.241
abf_domain1       = abf.rosalinux.ru
abf_ip2           = 195.19.76.241
abf_domain2       = abf.io
max_workers_count = 2
vm_x86_64         = 512
vm_i586           = 512
vm_cpus           = 2
use_log_server    = false
use_proxy         = false
proxy_ip          = http://8.8.8.8:8080
scripts_mdv_external_script = '/opt/rosa-signer/auto_sign-macro.args'
scripts_rhel_external_script = 

[abf-worker-rpm:children]
abf-worker-rpm-rosa-signer

[abf-worker-rpm:vars]
log_server_host=0.0.0.0
resque_redis=0.0.0.0:6379


[abf-worker:children]
abf-worker-rpm

[abf-worker:vars]
# ansible_ssh_user=root   Comment because remote_user dont rewrite this

# our public key
airbrake_api_key='3c6209710087bfb53bd9604040a9c6ef'
abf_url='https://abf.rosalinux.ru'
file_store_url='http://file-store.rosalinux.ru'
ansible-playbook -i abf-worker.hosts abf-worker.yml
Эту команду необходимо выполнять каждый раз после перезагрузки сервера, так как сервисы ABF не являются linux-сервисами и не стартуют автоматически.
# yum install nss-tools opensc pesign expect
# mkdir -p /opt/rosa-signer/db
# cd /opt/rosa-signer/db
# export DBDIR=$PWD
# certutil -d $DBDIR -N --empty-password
# modutil -dbdir $DBDIR -add etoken -libfile /usr/lib64/libeToken.so -force
# pkcs11-tool --module /usr/lib64/libeToken.so -L
# cp rosa-signer.pl sign.expect auto_sign-macro.args /opt/rosa-signer/
# cp rosa-signer.service /lib/systemd/system/
# systemctl daemon-reload
# systemctl enable rosa-signer.service
# systemctl start rosa-signer.service

В spec-файлах подпись реализуется макросом %auto_sign, принимающим в качестве аргументов список файлов, которые нужно подписать. Если проект поддерживается несколькими разработчиками, то для удобства отладки может потребоваться его сборка также и на публичных нодах, но поскольку на них нет этого макроса, сборка завершится ошибкой. Чтобы не править spec-файл, постоянно добавляя-удаляя вызов команды подписывания, удобно использовать следующую конструкцию:

%if %{defined auto_sign}
    %auto_sign file1.efi file2.efi ...
%endif

Тогда при наличии макроса файлы будут подписаны, а при его отсутствии пакет будет собран с неподписанными файлами.

(временно) Альтернативное решение

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

В последних версиях osslsigncode тоже добавили поддержку работы с токенами. Поскольку osslsigncode, в отличие от pesign, позволяет подписывать с наложением временно́го сертификата, эта утилита является предпочтительной (если заработает). Предварительные заметки о том, как заставить его работать.

cd /home/user/libp11
./bootstrap
./configure
make
cd /home/user/engine_pkcs11
./bootstrap
LDFLAGS='-L/home/user/libp11/src/.libs/' PKG_CONFIG_PATH=/home/user/libp11/src/ CFLAGS='-I/home/user/libp11/src' ./configure
make
pesign --certdir /opt/rosa-signer/db -t "NTC IT ROSA LLC" -c "NTC IT ROSA LLC" --export-cert=/opt/rosa-signer/cert/rosa.der
openssl x509 -inform der -in /opt/rosa-signer/cert/rosa.der -out /opt/rosa-signer/cert/rosa.pem
/home/user/osslsigncode/osslsigncode sign -pkcs11engine /home/user/engine_pkcs11/src/.libs/engine_pkcs11.so -pkcs11module /usr/lib64/libeToken.so -certs /opt/rosa-signer/cert/rosa.pem -h sha256 -t http://timestamp.digicert.com/ /path/to/grub-unsigned.efi /path/to/grub-signed.efi