Привет, Хабр! Недавно делал одну интересную задачу, связанную с актуализацией просроченных сертификатов (открытых ключей), используемых для подписания и шифрования файлов при помощи Криптопро 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 сформированный скриптом), формирование предупреждающих уведомлений до того как сертификат просрочиться и отправку инструкций по замене сертификата на электронную почту ответственных лиц.