Ansible Sign#

Ansible Sign – это инструмент командной строки, позволяющий обеспечить надежную передачу содержимого Ansible от разработчиков к пользователям с помощью цифровой подписи. Это простой способ обеспечить защиту содержимого, исключающий возможность его несанкционированного изменения и повышающий надежность автоматизации, особенно в критически важных или многопользовательских средах.

Для создания и проверки цифровой подписи Ansible Sign использует GPG – набор утилит от проекта GNU, реализующих протокол OpenGPG.

Примечание

Подробности использования GPG доступны на сайте проекта The GNU Privacy Guard, а описание протокола OpenPGP в RFC 4880.

Применение Ansible Sign для контроля целостности проекта показано на схеме:

../../../_images/ansible-sign-workflow.svg
  1. Разработчик публикует проект Ansible в SCM-системе, например, в репозитории GitFlic.

  2. SCM-система подписывает содержимое приватным ключом GPG.

  3. Пользователь синхронизирует содержимое с SCM-системой.

  4. Пользователь запускает проверку целостности полученного проекта, используя публичный ключ GPG. Утилита Ansible Sign проверяет цифровую подпись и контрольные суммы файлов.

    Проверка может быть выполнена следующими способами:

    • вручную;

    • автоматически.

    Для автоматической проверки в Automation Controller или контроллере EDA создайте полномочие типа «Публичный ключ GPG». Если проверка целостности не будет успешной, Automation Controller и контроллер EDA заблокируют использование содержимого.

Установка#

Для установки Ansible Sign выполните следующие действия:

  1. Подключите репозиторий Astra Automation.

    Инструкция по подключению репозитория
    1. В каталоге /etc/apt/sources.list.d/ создайте файл astra-automation.list со ссылкой на репозиторий Astra Automation:

      deb https://dl.astralinux.ru/aa/aa-debs-for-alse-1.8 <version> main
      

      Вместо <version> необходимо подставить версию устанавливаемой платформы, например, 1.2.

      Доступные версии продукта опубликованы в таблице История обновлений.

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

      sudo apt update
      
  2. Установите пакет ansible-sign:

    sudo apt install ansible-sign --yes
    

Установка при отсутствии доступа к интернету описана в документе Средства разработки.

Создание хранилища и ключей#

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

  1. Проверьте наличие хранилища ключей:

    gpg --list-secret-keys
    

    Если хранилище не существует, утилита создаст его, о чем свидетельствует следующий вывод в терминал:

    gpg: создан каталог '/home/<user>/.gnupg'
    gpg: создан щит с ключами '/home/<user>/.gnupg/pubring.kbx'
    gpg: /home/<user>/.gnupg/trustdb.gpg: создана таблица доверия
    

    Если хранилище существует, но не содержит ключей, вывод утилиты будет пустым.

    Если в хранилище уже существуют ключи, утилита выводит информацию о них, например:

    gpg: проверка таблицы доверия
    gpg: marginals needed: 3  completes needed: 1  trust model: pgp
    gpg: глубина: 0  достоверных:   1  подписанных:   0  доверие: 0-, 0q, 0n, 0m, 0f, 1u
    gpg: срок следующей проверки таблицы доверия 2035-02-04
    /home/<user>/.gnupg/pubring.kbx
    --------------------------------
    sec   rsa4096 2025-02-06 [SC] [   годен до: 2035-02-04]
          6CE032B47A1EA571A25FC228455114CAF74D0C6E
    uid         [  абсолютно ] Example User (Astra Automation Example GPG Key) <user@example.com>
    ssb   rsa4096 2025-02-06 [E] [   годен до: 2035-02-04]
    
  2. Для создания пары ключей выполните команду:

    gpg --full-generate-key
    

    В терминал выводится приглашение для выбора типа ключа:

    gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    Выберите тип ключа:
       (1) RSA и RSA (по умолчанию)
       (2) DSA и Elgamal
       (3) DSA (только для подписи)
       (4) RSA (только для подписи)
      (14) Имеющийся на карте ключ
      (14) GOST R34.10-2001 (sign only) OBSOLETE
      (15) GOST R34.10-2012 (sign only)
    Ваш выбор?
    
  3. Для выбора нужного типа ключа укажите число, стоящее в скобках рядом с названием, и нажмите Enter.

    Совет

    Рекомендуется использовать ключи типа RSA и RSA.

    В терминал выводится приглашение для выбора длины ключа:

    длина ключей RSA может быть от 1024 до 4096.
    Какой размер ключа Вам необходим? (3072)
    
  4. Введите нужную длину ключа и нажмите Enter.

    Совет

    Рекомендуется использовать ключи длиной не менее 4096 бит.

    В терминал выводится приглашение для ввода срока действия ключа:

    Выберите срок действия ключа.
             0 = не ограничен
          <n>  = срок действия ключа - n дней
          <n>w = срок действия ключа - n недель
          <n>m = срок действия ключа - n месяцев
          <n>y = срок действия ключа - n лет
    Срок действия ключа?
    
  5. Укажите срок действия ключа и нажмите Enter.

    В терминал выводится запрос на подтверждение корректности выбранного срока действия ключа:

    Срок действия ключа не ограничен
    Все верно? (y/N)
    
  6. Для подтверждения корректности выбранного срока действия ключа введите y и нажмите Enter.

    В терминал выводится приглашение ко вводу вашего полного имени:

    GnuPG должен составить идентификатор пользователя для идентификации ключа.
    
    Ваше полное имя:
    
  7. Введите латиницей ваше полное имя, например, John Dow, и нажмите Enter.

    В терминал выводится приглашение ко вводу адреса электронной почты:

    Адрес электронной почты:
    
  8. Введите адрес электронной почты и нажмите Enter.

    В терминал выводится приглашение ко вводу примечания.

  9. Введите текст примечания и нажмите Enter.

    В терминал выводится запрос на подтверждение корректности введенных данных, например:

    Ваше полное имя: John Dow
    Адрес электронной почты: johndow@example.com
    Примечание: John Dow GPG Key
    Вы выбрали следующий идентификатор пользователя:
        "John Dow (John Dow GPG Key) <johndow@example.com>"
    
    Сменить (N)Имя, (C)Примечание, (E)Адрес; (O)Принять/(Q)Выход?
    
  10. Чтобы подтвердить корректность введенных данных, введите O и нажмите Enter.

    В терминал выводится диалоговое окно для ввода пароля для защиты ключа:

    ┌────────────────────────────────────────────────────────┐
    │ Введите фразу-пароль                                   │
    │ для защиты нового ключа                                │
    │                                                        │
    │ Фраза-пароль: ________________________________________ │
    │                                                        │
    │        <OK>                         <Отмена (C)>       │
    └────────────────────────────────────────────────────────┘
    
  11. Введите пароль и нажмите Enter.

    В терминал выводится диалоговое окно для ввода подтверждения пароля:

    ┌────────────────────────────────────────────────────────┐
    │ Повторите фразу-пароль:                                │
    │                                                        │
    │ Фраза-пароль: ________________________________________ │
    │                                                        │
    │        <OK>                         <Отмена (C)>       │
    └────────────────────────────────────────────────────────┘
    
  12. Введите пароль еще раз и нажмите Enter.

    В терминал выводится сообщение о необходимости получения множества случайных чисел:

    Необходимо получить много случайных чисел. Желательно, чтобы Вы
    в процессе генерации выполняли какие-то другие действия (печать
    на клавиатуре, движения мыши, обращения к дискам); это даст генератору
    случайных чисел больше возможностей получить достаточное количество энтропии.
    Необходимо получить много случайных чисел. Желательно, чтобы Вы
    в процессе генерации выполняли какие-то другие действия (печать
    на клавиатуре, движения мыши, обращения к дискам); это даст генератору
    случайных чисел больше возможностей получить достаточное количество энтропии.
    
  13. Для увеличения энтропии случайным образом двигайте мышь и нажимайте клавиши на клавиатуре до тех пор, пока в терминал не выводится сообщение о создании ключей и сертификата, например:

    gpg: ключ A92BB253E671651D помечен как абсолютно доверенный
    gpg: сертификат отзыва записан в '/home/<user>/.gnupg/openpgp-revocs.d/A90B44D4C5967DDF9280A737A92BB253E671651D.rev'.
    открытый и секретный ключи созданы и подписаны.
    
    pub   rsa4096 2025-02-06 [SC]
          A90B44D4C5967DDF9280A737A92BB253E671651D
    uid                      John Dow (John Dow GPG Key) <johndow@example.com>
    sub   rsa4096 2025-02-06 [E]
    

Распространение публичного ключа#

Чтобы подготовить публичный ключ GPG к передаче пользователям, выполните следующие действия:

  1. Получите список существующих ключей:

    gpg --list-secret-keys
    

    Команда выводит в терминал список ключей и их отпечатков (fingerprints), например:

    sec   rsa4096 2025-02-06 [SC]
          A90B44D4C5967DDF9280A737A92BB253E671651D
    uid         [  абсолютно ] John Dow (John Dow Personal GPG key) <johndow@example.com>
    ssb   rsa4096 2025-02-06 [E]
    

    Здесь A90B44D4C5967DDF9280A737A92BB253E671651D – отпечаток ключа.

  2. Выполните команду экспорта публичной части ключа:

    gpg --export --armor <fingerprint> > <file>
    

    Здесь:

    • <fingerprint> – отпечаток ключа;

    • <file> – путь к файлу для сохранения публичного ключа. Как правило, такие файлы имеют расширение .asc. Например, файл с ключом GPG, которым подписаны файлы в APT-репозиториях PostgreSQL, имеет название ACCC4CF8.asc.

  3. Любым удобным способом передайте файл с публичным ключом пользователям содержимого Ansible.

    Чтобы использовать публичный ключ GPG для автоматической проверки содержимого при использовании в Automation Controller или контроллере EDA, выполните следующие действия:

    1. Используйте файл с публичным ключом GPG для создания полномочия типа «Открытый ключ GPG» (GPG Public Key).

    2. В настройках проекта заполните поле Учетные данные для проверки подписи содержимого (Content Signature Validation Credential), указав созданное полномочие.

    3. Синхронизируйте проект с источником.

    Примечание

    Инструкции по созданию полномочий, настройке и синхронизации проектов приведены в соответствующих разделах.

Импорт ключей#

Импорт ключей необходим для проверки целостности полученного содержимого Ansible. По умолчанию ключи импортируются в стандартное хранилище – файл ~/.gnupg/trustdb.gpg. В некоторых случаях целесообразно использовать отдельное хранилище для ключей GPG. Чтобы импортировать ключ GPG в отдельное хранилище, в аргументах команды gpg укажите опции --no-default-keyring и --keyring.

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

  1. Загрузите ключ в формате .asc на компьютер.

  2. Создайте хранилище ключей и импортируйте в него загруженный ключ:

    gpg \
        --no-default-keyring \
        --keyring path/to/custom-keyring.gpg \
        --import path/to/public/key.asc
    

    Здесь:

    • --no-default-keyring – запрет использования стандартного хранилища;

    • --keyring – путь к хранилищу, в которое импортируется ключ;

    • --import – путь к файлу ключа.

  3. Убедитесь, что ключ успешно импортирован:

    gpg \
        --no-default-keyring \
        --keyring path/to/custom-keyring.gpg \
        --list-keys
    

    Если импорт выполнен успешно, в терминал выводится список ключей.

  4. Чтобы использовать импортированные ключи для проверки целостности содержимого, укажите путь к хранилищу в опции --keyring команды ansible-sign:

    ansible-sign project gpg-verify . --keyring path/to/custom-keyring.gpg
    

Подписывание содержимого#

Процесс подписывания содержимого Ansible состоит из двух этапов:

  1. Создание файла MANIFEST.in.

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

  2. Запуск утилиты ansible-sign.

    Утилита ansible-sign выполняет следующие операции:

    1. Формирует список файлов проекта на основе содержимого файла MANIFEST.in.

    2. Рассчитывает контрольные суммы указанных файлов.

    3. Создает в каталоге проекта подкаталог .ansible-sign/, содержащий следующие файлы:

      • sha256sum.txt – контрольные суммы файлов;

      • sha256sum.txt.sig – цифровая подпись файла с контрольными суммами.

Создание файла MANIFEST.in#

В корневом каталоге проекта создайте файл MANIFEST.in. В этом файле укажите директивы, управляющие списком файлов для расчета контрольных сумм.

Директивы#

В файле MANIFEST.in допускается использование следующих директив:

  • include <templates>#

    Включает размещенные в корневом каталоге проекта файлы, названия которых удовлетворяют шаблонам <templates>.

    Например, так можно включить все файлы с расширениями .yaml и .md в корневом каталоге:

    include *.yaml *.md
    
    recursive-include <directory> <templates>#

    Рекурсивно включает из каталогов, названия которых удовлетворяют шаблону <directory>, все файлы, названия которых удовлетворяют шаблонам <templates>.

    Например, так можно включить все файлы с расширениями .yaml и .md, размещенные в каталоге roles/:

    recursive-include roles/ *.yaml *.md
    
    global-include <templates>#

    Включает все файлы, названия которых удовлетворяет указанным шаблонам, независимо от каталога, в котором они находятся.

    Например, так можно включить все файлы с расширением .yaml:

    global-include *.yaml
    
    exclude <templates>#

    Исключает размещенные в корневом каталоге проекта файлы, названия которых удовлетворяют указанным шаблонам <templates>.

    Например, так можно исключить файлы .log в корневом каталоге:

    exclude *.log
    
    recursive-exclude <directory> <templates>#

    Исключает из каталога <directory> и его подкаталогов все файлы, названия которых удовлетворяют шаблонам. Например, так можно исключить все файлы с расширением .bak, размещенные в каталоге src/ и его подкаталогах:

    recursive-exclude src/ *.bak
    
    global-exclude <templates>#

    Исключает все файлы проекта, названия которых удовлетворяют указанным шаблонам. Например, так можно исключить все файлы с расширениями .tmp и .log:

    global-exclude *.tmp *.log
    
    grafs <templates>#

    Рекурсивно включает содержимое каталогов, названия которых удовлетворяют указанному шаблону.

    prune <templates>#

    Рекурсивно исключает содержимое каталогов, названия которых удовлетворяют указанному шаблону.

Ansible Sign обрабатывает символы в шаблонах следующим образом:

  • * – любой символ любое количество раз.

  • ? – любой символ.

  • [chars] – любой символ из перечисленных.

    Чтобы задать диапазон символов, используйте дефис, например:

    global-exclude *.py[cod]
    

    Эта директива исключит из списка подписываемых все файлы с расширениями .pyc, .pyo и .pyd.

Названия каталогов рассчитываются относительно корневого каталога проекта.

Директивы обрабатываются в порядке следования в файле MANIFEST.in, например:

graft tests
global-exclude *.py[cod]

Директива graft включит в список все содержимое каталога tests/ и его подкаталогов. Следующая после нее директива global-exclude исключит из списка файлы с расширениями .pyc, .pyo и .pyd.

Запуск ansible-sign#

Чтобы подписать проект, в его корневом каталоге выполните команду:

ansible-sign project gpg-sign .

Чтобы использовать для подписывания проекта определенный приватный ключ, укажите его отпечаток в опции --fingerprint:

ansible-sign project gpg-sign . --fingerprint <fingerprint>

Подробное описание аргументов утилиты ansible-sign см. в справочнике.

Проверка целостности#

Проверка целостности содержимого Ansible может быть выполнена вручную или автоматически.

Ручная проверка целостности#

Для ручной проверки целостности содержимого Ansible выполните в корневом каталоге проекта команду:

ansible-sign project gpg-verify .

В терминал выводятся результаты проверки, например:

[OK   ] GPG signature verification succeeded.
[OK   ] Checksum validation succeeded.

Если контрольная сумма хотя бы одного файла не соответствует ожидаемой, в терминал выводится соответствующее сообщение:

[OK   ] GPG signature verification succeeded.
[ERROR] Checksum validation failed.
[ERROR] Checksum mismatch: README.md

Автоматическая проверка целостности#

Automation Controller и контроллер Event-Driven Ansible выполняют проверку целостности содержимого Ansible автоматически, если с проектом связано полномочие типа «Публичный ключ GPG» (GPG public key).

Инструкции по созданию полномочия:

Примеры#

Изучите использование Ansible Sign на примере подписывания файлов проекта.

  1. Если у вас нет хранилища и пары ключей GPG, создайте их согласно инструкции.

  2. В корневом каталоге проекта создайте файл MANIFEST.in, например:

    include README.md
    recursive-include playbooks *.yml
    prune .git
    
  3. Выполните команду:

    ansible-sign project --gpg-sign .
    

    В терминал выводится диалоговое окно для ввода пароля секретного ключа OpenPGP:

    ┌───────────────────────────────────────────────────────────────────────┐
    │ Введите фразу-пароль для разблокировки секретного ключа OpenPGP:      │
    │ "Example User (Astra Automation Example GPG Key) <user@example.com>"  │
    │ 4096-битный ключ RSA, идентификатор 455114CAF74D0C6E,                 │
    │ создан 2025-02-06.                                                    │
    │                                                                       │
    │                                                                       │
    │ Фраза-пароль: _______________________________________________________ │
    │                                                                       │
    │          <OK>                                    <Отмена (C)>         │
    └───────────────────────────────────────────────────────────────────────┘
    
  4. Введите пароль секретного ключа OpenPGP и нажмите Enter.

    В терминал будут выведены сообщения о ходе и результатах расчета контрольных сумм:

    [OK   ] GPG signing successful!
    [NOTE ] Checksum manifest: ./.ansible-sign/sha256sum.txt
    [NOTE ] GPG summary: signature created