Первое, что нужно решить, это определить место хранения сертификата, доступное с любой дугой машины. Решено было использовать для этого репозиторй на локальном GitLab. Это даёт возможность контролировать версионность файлов и откатить изменения, в случае ошибки, чего не позволяет использование обычного общего smb-ресурса.
Чтобы избежать привязанности репозитория к опеределённому пользователю создадим группу automation, а уже в ней проект ssl, так что путь к этому проекту будет выглядеть так
https://gitlab.oldfag.ru/automation/ssl.gitНа машине, где выпускаются сертификаты создадим каталог repo, в котором будут дополнительные каталоги, соответствующие именам доменов, для которых будут выпускаться сертификаты от Let's Encrypt. Доступ к этому каталогу будет только у пользователя root.
mkdir /repo chmod 700 /repoВ самом репозитории на GitLab для каждого домена будет создана отдельная ветка, имя которой так же будет соответствовать имени домена.
Теперь перейдём непосредственно к скрипту, который будет проверять наличие свежего сертификата.
Логика его работы достаточно проста. При запуске получается список каталогов в /repo, после чего соответствующий каталог ищется в /etc/letsencrypt/live, если каталог найден, то с помощью openssl проверяется количество дней, оставшихся до истчения срока действия сертификата. Если количество дней больше, чем было при прошлом запуске, которое хранится в файле days_counter, то сертификат, его цепочка сертификации и ключ загружаются в соответствующую ветку репозитория.
touch /scripts/ssl_check.sh chmod +x /scripts/ssl_check.shСам скрипт выглядит вот так
#!/bin/bash
# Получаем список всех каталогов в /repo
arr=(/repo/*)
# Удаляем последний слэш у каждого элемента
arr=("${arr[@]%/}")
# Удаляем префикс пути
arr=("${arr[@]##*/}")
# Корневой сертификат DST Root CA X3 (https://www.identrust.com/dst-root-ca-x3)
ca="-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----"
for entry in ${arr[@]}; do
# Проверяем существование соответствующего каталога в /etc/letsencrypt/live
if [ -d "/etc/letsencrypt/live/${entry}" ]; then
counter_file="/repo/${entry}/days_counter"
# Получаем дату окончания срока действия сертификата
exp_date=`echo | openssl x509 -enddate -noout -in "/etc/letsencrypt/live/${entry}/cert.pem" | grep notAfter |cut -d'=' -f2`
let days_left=(`date -d "${exp_date}" +%s` - `date +%s` )/86400
# Если файл счётчика не сущестует в папке, то создаём его, записываем счёчик и ждём следущего запуска
if [ ! -f ${counter_file} ]; then
echo ${days_left} > ${counter_file}
exit
fi
previous_days_counter=$(head -n 1 ${counter_file})
if [ ${previous_days_counter} -lt ${days_left} ]; then
yes | cp -Lr /etc/letsencrypt/live/${entry}/* /repo/${entry}
# Добавляем корневой сертификат в цепочку
echo "${ca[*]}" >> /repo/${entry}/chain.pem
cd /repo/${entry}
# Инициализируем репозиторий, если это не было сделано ранее
if [ ! -d "/repo/${entry}/.git" ]; then
git init
git checkout -b ${entry}
git remote add origin https://gituser:gituserpassword@gitlab.oldfag.ru/automation/ssl.git
echo $'days_counter\nREADME' >> /repo/${entry}/.git/info/exclude
fi
git add .
git commit -m "New certicate issued"
git push -u origin ${entry}
fi
echo ${days_left} > ${counter_file}
fi
done
При инициализации репозитория используется строка с указанием имени пользователя и пароля т.к. репозиторий не является публичным и доступ к нему
ограничен определённым списком пользователей.Теперь добавим задание запуска скрипта в /etc/crontab
# Let's Encrypt certificates check and update repo
00 3 * * * root /scripts/ssl_check.sh
Каждый день в 3 часа будет запускаться скрипт и прверять наличи нового сертификата.В блоге есть пример использования сертификатов, хранимых подобным образом, на Zimbra Collaboration OSE.
Комментариев нет:
Отправить комментарий