Разработка собственного EE для замкнутой программной среды#

Режим замкнутой программной среды (ЗПС) обеспечивает динамический контроль неизменности (целостности) и подлинности файлов. Он предназначен для решения следующих задач:

  • выявление несанкционированного изменения исполняемых и других файлов;

  • предотвращение загрузки и исполнения измененных исполняемых файлов;

  • предотвращение открытия измененных неисполняемых файлов.

Контроль целостности файлов реализован в невыгружаемом модуле ядра Linux digsig_verif и производится путем проверки цифровых подписей файлов.

Особенности режима ЗПС для контейнеров#

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

Режим ЗПС накладывает ряд ограничений на использование исполняемых файлов в контейнерах:

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

  2. Все исполняемые файлы в контейнере должны иметь цифровую подпись. При ее отсутствии ядро операционной системы заблокирует загрузку и выполнение исполняемого файла.

Все исполняемые файлы из состава Astra Linux Special Edition имеют цифровую подпись и корректно работают в режиме ЗПС. Образы среды исполнения, разработанные ПАО Группа Астра и доступные в Automation Hub, могут быть использованы в режиме ЗПС без дополнительных настроек.

Программное обеспечение, исполняемые файлы которого не имеют цифровой подписи ПАО Группа Астра или ее партнеров, далее называется сторонним ПО.

Если вы хотите использовать стороннее ПО в собственных образах среды исполнения, следуйте этой инструкции.

Примечание

В этом руководстве рассматривается создание образа среды исполнения на базе образа aa-minimal-ee, доступного в Automation Hub.

Этапы разработки#

Разработка образа среды исполнения, включающего стороннее ПО и способного работать в режиме ЗПС, состоит из следующих этапов:

  1. Подготовка образа со всеми необходимыми пакетами, независимо от наличия цифровых подписей, и его проверка в окружении с выключенным режимом ЗПС.

    В данном руководстве этот этап не рассматривается. Для получения соответствующих инструкций обратитесь к руководству по Ansible Builder.

  2. Получение ISO-образа с комплектом ключей для подписывания исполняемых файлов.

  3. Подписывание исполняемых файлов, не имеющих цифровой подписи для работы в режиме ЗПС.

    В этом руководстве рассматривается подписывание исполняемых файлов формата ELF (Executable and Linkable Format), распространяемых в составе DEB-пакетов и пакетов Python формата .whl.

  4. Сборка образа среды исполнения с использованием подписанных пакетов. Далее эти шаги представлены более подробно.

Подготовка к работе#

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

  1. Изучите статьи Справочного центра:

  2. Для ISO-образа с комплектом ключей заполните форму на сайте ПАО Группа Астра.

    ISO-образ содержит следующие файлы:

    • ***_pub.key – публичный ключ цифровой подписи;

    • ***_secret.gpg – приватный ключ цифровой подписи;

    • ***_password.txt – пароль приватного ключа цифровой подписи;

    • ***_revoke.rev – сертификат отзыва ключа цифровой подписи.

  3. Обновите список доступных пакетов:

    sudo apt update
    
  4. Установите утилиты, необходимые для подписи файлов и работы с архивами:

    sudo apt install binutils bsign dpkg-dev file unzip zip --yes
    
  5. Установите Ansible Builder, следуя инструкции.

Создание структуры проекта#

Создайте структуру файлов и каталогов проекта:

project/
├── files/
│   ├── signed-deb/
│   └── signed-whl/
└── execution-environment.yml

Здесь:

  • files/signed-deb/ – каталог для размещения подписанных DEB-пакетов;

  • files/signed-whl/ – каталог для размещения подписанных пакетов Python формата .whl;

  • execution-environment.yml – файл определения среды исполнения.

Подписывание файлов#

Чтобы подписать DEB-пакеты и пакеты Python в формате .whl, выполните следующие действия:

  1. Убедитесь, что каталог /media/cdrom/ существует и пуст. Если каталог не существует, для его создания выполните команду:

    sudo mkdir -p /media/cdrom/
    
  2. Смонтируйте ISO-образ с ключами в каталог /media/cdrom:

    sudo mount /path/to/image.iso /media/cdrom -t iso9660 -o ro
    
  3. Сохраните пароль приватного ключа в переменной окружения pass:

    pass=$(cat /media/cdrom/<passfile>)
    

    Здесь <passfile> – название файла с паролем.

  4. Загрузите секрет, которым защищен закрытый ключ:

    echo "$pass" | gpg \
       --batch \
       --yes \
       --pinentry-mode loopback \
       --passphrase-fd 0 \
       --import /media/cdrom/<secret>.gpg
    

    Здесь <secret>.gpg – название файла с секретом.

    Если загрузка секрета выполнена успешно, в терминал выводится набор строк следующего вида:

    gpg: создан каталог '/home/<user>/.gnupg'
    gpg: создан щит с ключами '/home/<user>/.gnupg/pubring.kbx'
    gpg: ключ B0F6B01F548C108D: 1 подпись не проверена за отсутствием ключа
    gpg: /home/<user>/.gnupg/trustdb.gpg: создана таблица доверия
    gpg: ключ B0F6********108D: импортирован открытый ключ "ООО "РусБИТех-Астра" (key for signing) <info@astralinux.ru>"
    gpg: ключ B0F6********108D: импортирован секретный ключ
    gpg: Всего обработано: 1
    gpg:                  импортировано: 1
    gpg:     прочитано секретных ключей: 1
    gpg: импортировано секретных ключей: 1
    gpg: абсолютно доверенных ключей не найдено
    
  5. Загрузите закрытый ключ:

    key=$(gpg --with-colons --list-secret-keys | awk -F: '/fpr:/ {print $10; exit}')
    
  6. Скопируйте DEB-пакеты в каталог files/signed-deb/, а пакеты Python в формате .whl в каталог files/signed-whl.

Подписывание DEB-пакетов#

Чтобы подписать содержимое DEB-пакета, выполните следующие действия:

  1. Создайте временный каталог, например:

    tmp_dir=$(mktemp --directory)
    
  2. Распакуйте содержимое пакета в этот каталог:

    dpkg-deb -R <package>.deb "$tmp_dir"
    
  3. Найдите и подпишите все ELF-файлы во временном каталоге:

    find "$tmp_dir" -exec file {} \; | grep -i -e ELF -e 'shared object' | cut -d":" -f1 | while read file; do
      bsign -s -N --pgoptions "--default-key=$key --passphrase $pass" "$file"
    done
    
  4. Запакуйте содержимое временного каталога в новый DEB-пакет:

    dpkg-deb -b "$tmp_dir" <package>_signed.deb
    
  5. Удалите временный каталог:

    rm -rf "$tmp_dir"
    

Подписывание пакетов Python#

Чтобы подписать содержимое пакета Python в формате .whl, выполните следующие действия:

  1. Создайте временный каталог, например:

    tmp_dir=$(mktemp --directory)
    
  2. Распакуйте содержимое пакета во временный каталог:

    unzip -q <package>.whl -d "$tmp_dir"
    
  3. Найдите и подпишите все ELF-файлы во временном каталоге:

    find "$tmp_dir" -exec file {} \; | grep -i -e ELF -e 'shared object' | cut -d":" -f1 | while read file; do
      bsign -s -N --pgoptions "--default-key=$key --passphrase $pass" "$file"
    done
    
  4. Перейдите во временный каталог:

    cd "$tmp_dir"
    
  5. Запакуйте содержимое временного каталога в новый пакет .whl:

    zip -r -X --symlinks <package>_signed.whl ./*
    
  6. Переместите подписанный пакет в каталог files/signed-whl/:

    mv <package>_signed.whl /path/to/project/files/signed-whl/
    
  7. Удалите временный каталог:

    rm -rf "$tmp_dir"
    

Сборка образа#

Для сборки образа с подписанными файлами выполните следующие действия:

  1. Файл определения среды исполнения заполните по образцу:

    execution-environment.yml#
    ---
    version: 3
    
    images:
      base_image:
        name: hub.astra-automation.ru/aa-1.2/aa-minimal-ee:latest
    
    dependencies: {}
    
    additional_build_files:
      - src: files/
        dest: .
    
    additional_build_steps:
      prepend_base:
        - RUN apt update
        - COPY _build/signed-deb/ /opt/deb/
        - COPY _build/signed-whl/ /opt/whl/
        - RUN dpkg -i /opt/deb/*.deb || apt-get install -f -y && dpkg -i /opt/deb/*.deb
        - RUN pip3 install --no-index --find-links=/opt/whl/ /opt/whl/*.whl
    
  2. Запустите сборку образа как в следующем примере:

    ansible-builder build -t signed-ee:1.0.0
    

Проверка работоспособности образа#

Для проверки работоспособности собранного образа выполните следующие действия:

  1. Если в каталоге /etc/digsig/keys/ не существует подкаталог legacy/keys/, создайте его:

    sudo mkdir -p /etc/digsig/keys/legacy/keys/
    
  2. Скопируйте публичный ключ цифровой подписи в каталог /etc/digsig/keys/legacy/keys/:

    sudo cp /media/cdrom/<pubkey_file> /etc/digsig/keys/legacy/keys/pubkey.gpg
    
  3. Включите режим ЗПС:

    sudo astra-digsig-control enable
    
  4. Перезагрузите компьютер.

  5. Запустите образ в интерактивном режиме, например:

    podman run --rm --tty --interactive signed-ee:1.0.0 /bin/bash
    
  6. Для проверки работоспособности утилит, установленных из DEB-пакетов, запустите их, например:

    cowsay "Testing signing"
    

    Режим ЗПС заблокирует запуск, если у ELF-файлов утилиты нет цифровой подписи.

  7. Для проверки работоспособности пакетов Python выполните следующие действия:

    1. Запустите интерпретатор:

      python3
      
    2. Импортируйте модули, установленные из подписанных пакетов Python, например:

      import pandas
      import numpy
      

      Режим ЗПС заблокирует импорт, а интерпретатор Python выведет сообщения об ошибках, если у ELF-файлов модуля нет цифровой подписи.

    3. Завершите работу с интерпретатором:

      exit()