Привет, Хабр! Недавно делал одну интересную задачу, связанную с актуализацией просроченных сертификатов (открытых ключей), используемых для подписания и шифрования файлов при помощи Криптопро 5. Решил поделиться опытом. Возможно, это поможет сэкономить время при решении похожей задачи или будет просто интересным чтивом для вас.
Дисклеймер
Я буду очень рад вашим замечаниям и предложениям по оптимизации bash скрипта, генерирующего сервисный json с информацией о сроке годности сертификатов. Так же буду рад услышать советы по оптимизации Dockerfile. Заранее спасибо.
Что будет в статье
подготовка скрипта для сбора данных о состоянии сертификатов
сборка Docker образа с Криптопро 5 на основе Fedora 38
загрузка сертификатов в контейнер
Подготовка скрипта для сбора данных о состоянии сертификатов
Основная проблема сотрудников организации, для которой я делал эту доработку, заключалась в том, что они имели в распоряжении большое количество сертификатов, используемых для подписания и шифрования файлов. У сертификатов, разумеется, были разные сроки действия, и было очень трудно отслеживать просроченные сертификаты для того, чтобы своевременно выпустить новую версию.
Чтобы решить эту проблему, было принято решение разработать небольшое дополнение к Криптопро 5, которое помогло актуализировать информацию об имеющихся сертификатах.
#!/usr/bin/env bash CERTS_CHECK="$(certmgr -list | grep -E "Subject ")" # check if certs exists if [[ $CERTS_CHECK == *"Subject "* ]]; then touch ./result.json else echo "[]" > ./result.json exit 0 fi COUNTER=1 # prepare data from certmgr certmgr -list | grep -E "Subject " | awk -F'CN=' '{ print $2 }' | tr -d '"' > ./names.txt certmgr -list | grep -E "Subject " | awk -F'E=' '{ print $2 }' | cut -d "," -f 1 | tr -d '"' > ./emails.txt certmgr -list | grep -E "Not valid after" | cut -d ":" -f 2 | cut -d " " -f 2 | tr -d '"' > ./valid_to.txt # count certs qty CERTS_QTY=$(wc -l < names.txt) # prepare result json echo "[" > ./result.json while (($COUNTER <= $CERTS_QTY )) do echo ' {' >> ./result.json echo ' "name": "'"$(cat ./names.txt | tail -n $COUNTER | head -n 1)"'",'>> ./result.json echo ' "e-mail": "'"$(cat ./emails.txt | tail -n $COUNTER | head -n 1)"'",' >> ./result.json echo ' "valid-to": "'"$(cat ./valid_to.txt | tail -n $COUNTER | head -n 1)"'"' >> ./result.json echo ' }' >> ./result.json echo " ," >> ./result.json COUNTER=$((COUNTER + 1)) done sed -i '$ d' ./result.json echo "]" >> ./result.json # remove tmp files rm -f ./names.txt rm -f ./emails.txt rm -f ./valid_to.txt # print result if [[ $CERTS_CHECK == *"Subject "* ]]; then cat ./result.json fi
Результатом работы скрипта является файл result.json, содержащий информацию о сроке действия сертификатов, электронной почте владельцев сертификатов и CN.

Также скрипт выводит в консоль содержание файла result.json, если в Криптопро установлены сертификаты или предупреждение об отсутствии сертификатов, если их нет.

Сборка Docker образа с Криптопро 5 на основе fedora 38
Здесь все просто, как пять копеек. Качаем rpm дистрибутив, делаем Dockerfile и собираем образ. Дистрибутив доступен по этой ссылке - https://www.cryptopro.ru/products/csp.
Обратите внимание, что есть возможность выбрать и deb и rpm дистрибутив.

Содержимое Dockerfile:
FROM fedora:38 WORKDIR /usr/src/cryptopro COPY ./distr ./distr RUN yes Y | ./distr/install.sh kc1 RUN ln -s /opt/cprocsp/sbin/amd64/cpconfig /usr/bin/cpconfig RUN ln -s /opt/cprocsp/bin/amd64/certmgr /usr/bin/certmgr RUN ln -s /opt/cprocsp/bin/amd64/cryptcp /usr/bin/cryptcp COPY ./src/certs_info /usr/bin/certs_info CMD [ "tail", "-f", "/dev/null" ]
Папка distr содержит распакованный архив с дистрибутивом Криптопро 5. Папка src содержит исполняемый скрипт certs_info, который был описан ранее.
Обратите внимание, что после установки нужно сделать soft link на исполняемые файлы, чтобы не указывать полный путь до них каждый раз, когда запускаете ту или иную команду. В этом примере используются только три исполняемые команды: cpconfig, certmgr и cryptcp. Если вам нужны другие команды, не забудьте их добавить в этот перечень.
Чтобы собрать образ, нужно выполнить команду docker build.
docker build -t cryptopro5 .
Чтобы запустить контейнер, нужно выполнить команду docker run.
docker run -v ./cer:/cer -d --name cryptopro5 cryptopro5
Обратите внимание на расшареную директорию сer. Она понадобится для установки сертификатов.
Чтобы проверить статус лицензии, нужно выполнить команду в запущенном контейнере.
docker exec cryptopro5 cpconfig -license -view

Загрузка сертификатов в контейнер
В целях упрощения тестирования на сайте Криптопро есть возможность загрузить тестовые сертификаты. Они доступны по этой ссылке - http://testca2012.cryptopro.ru/ui/.

Чтобы установить корневой сертификат, нужно воспользоваться параметром -store со значением root. Также обратите внимание, что в процессе установки сертификата утилита ожидает ответа от пользователя, ответ не буква Y а буква o.
docker exec cryptopro5 bash -c "yes o | certmgr -install -store root -file /cer/rootca.cer"
Чтобы установить сторонний сертификат, параметр -store не нужен.
docker exec cryptopro5 certmgr -install -file /cer/subca.cer
Теперь можно проверить состояние сторонних сертификатов при помощи написанного ранее скрипта.
docker exec cryptopro5 certs_info
Заключение
Дальнейшие шаги по автоматизации процесса обновления сертификатов выполнялись при помощи SOAR, они включали в себя периодический опрос контейнера с Криптопро на предмет устаревающих сертификатов (здесь как раз использовался json сформированный скриптом), формирование предупреждающих уведомлений до того как сертификат просрочиться и отправку инструкций по замене сертификата на электронную почту ответственных лиц.
