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