SSL: автоматичне оновлення
Сервер Linux — nginx, Apache, Caddy, HAProxy, Docker
Скрипт для nginx, Apache, Caddy, HAProxy і Docker раз на добу забирає свіжий сертифікат, звіряє його з вашим ключем і перезапускає вебсервер без простою.
Оновлюється сам
Підходить, якщо у вас є доступ до сервера по SSH і права root (VPS, виділений сервер, свій комп'ютер у стійці). Потрібні curl і openssl — вони є майже в кожному Linux.
Що знадобиться
- Посилання на сертифікат із кабінету:
https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН. - Закритий ключ, з яким замовляли сертифікат (файл
key.pemчи схожий). Якщо CSR створював кабінет ZRAZU — це файл, який ви тоді зберегли. - 10 хвилин.
Крок 1. Покладіть ключ на сервер
sudo mkdir -p /etc/ssl/zrazu/example.com
sudo chmod 700 /etc/ssl/zrazu/example.com
sudo nano /etc/ssl/zrazu/example.com/key.pem
sudo chmod 600 /etc/ssl/zrazu/example.com/key.pemУ nano вставте весь текст ключа разом із рядками -----BEGIN … PRIVATE KEY----- і -----END … PRIVATE KEY-----, збережіть (Ctrl+O, Enter) і вийдіть (Ctrl+X). Ключ без пароля: якщо ваш ключ запаролений, зніміть пароль командою openssl pkey -in старий.key -out /etc/ssl/zrazu/example.com/key.pem.
Крок 2. Скрипт оновлення
Створіть файл sudo nano /usr/local/bin/zrazu-ssl-example.com.sh, вставте текст нижче і змініть лише рядок RELOAD під свій вебсервер:
- nginx —
nginx -t && systemctl reload nginx(так стоїть); - Apache (Debian, Ubuntu) —
apachectl configtest && systemctl reload apache2; Apache (CentOS, Rocky, Alma) —apachectl configtest && systemctl reload httpd; - Caddy —
systemctl reload caddy; - HAProxy —
systemctl reload haproxyіCOMBINED=1(HAProxy читає сертифікат і ключ одним файломcombined.pem); - nginx у Docker —
docker exec НАЗВА_КОНТЕЙНЕРА nginx -s reload(каталог/etc/ssl/zrazuпідключіть у контейнер як том).
#!/bin/sh
# ZRAZU: оновлення SSL-сертифіката за особистим посиланням. Запускається cron раз на добу.
set -eu
# cron дає короткий PATH без /usr/sbin, а nginx і apachectl лежать саме там.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PULL="https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
DIR="/etc/ssl/zrazu/example.com"
KEY="$DIR/key.pem"
RELOAD="nginx -t && systemctl reload nginx"
COMBINED=0
umask 077
tmp=$(mktemp "$DIR/.new.XXXXXX")
trap 'rm -f "$tmp"' EXIT
curl -fsS --retry 3 --max-time 60 -o "$tmp" "$PULL/fullchain.pem"
grep -q "BEGIN CERTIFICATE" "$tmp" || { echo "ZRAZU: за посиланням не сертифікат"; exit 1; }
if [ -f "$DIR/.applied" ] && cmp -s "$tmp" "$DIR/.applied"; then
echo "ZRAZU: сертифікат не змінився"
exit 0
fi
cert_pub=$(openssl x509 -in "$tmp" -noout -pubkey | openssl sha256)
key_pub=$(openssl pkey -in "$KEY" -pubout | openssl sha256)
if [ "$cert_pub" != "$key_pub" ]; then
echo "ZRAZU: сертифікат випущено на інший ключ — нічого не міняю, покладіть новий ключ у $KEY"
exit 1
fi
openssl x509 -in "$tmp" -noout -checkend 0 >/dev/null || { echo "ZRAZU: сертифікат уже не діє"; exit 1; }
chmod 644 "$tmp"
mv -f "$tmp" "$DIR/fullchain.pem"
if [ "$COMBINED" = 1 ]; then
cat "$DIR/fullchain.pem" "$KEY" > "$DIR/combined.pem.new"
mv -f "$DIR/combined.pem.new" "$DIR/combined.pem"
fi
sh -c "$RELOAD"
cp "$DIR/fullchain.pem" "$DIR/.applied"
echo "ZRAZU: новий сертифікат встановлено, діє до $(openssl x509 -in "$DIR/fullchain.pem" -noout -enddate | cut -d= -f2)"Скрипт нічого не міняє, якщо вебсервер уже працює з цим сертифікатом, якщо файл за посиланням не сертифікат, якщо сертифікат не підходить до вашого ключа чи вже не діє. Конфігурацію вебсервера він перевіряє перед перезапуском, тож зламаний конфіг сайт не покладе; а якщо перезапуск не вдався, наступного дня скрипт спробує ще раз.
Зробіть файл виконуваним і запустіть один раз руками:
sudo chmod 700 /usr/local/bin/zrazu-ssl-example.com.sh
sudo /usr/local/bin/zrazu-ssl-example.com.shМає з'явитися «новий сертифікат встановлено» і файл /etc/ssl/zrazu/example.com/fullchain.pem.
Крок 3. Вкажіть файли у вебсервері (один раз)
nginx — у блоці server сайту:
ssl_certificate /etc/ssl/zrazu/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/zrazu/example.com/key.pem;Apache 2.4.8 і новіший — у <VirtualHost *:443>:
SSLCertificateFile /etc/ssl/zrazu/example.com/fullchain.pem
SSLCertificateKeyFile /etc/ssl/zrazu/example.com/key.pemCaddy — у блоці сайту tls /etc/ssl/zrazu/example.com/fullchain.pem /etc/ssl/zrazu/example.com/key.pem. HAProxy — у bind :443 ssl crt /etc/ssl/zrazu/example.com/combined.pem.
Перевірте конфіг (nginx -t чи apachectl configtest) і перезапустіть вебсервер.
Крок 4. Розклад
echo "17 4 * * * root /usr/local/bin/zrazu-ssl-example.com.sh >> /var/log/zrazu-ssl.log 2>&1" | sudo tee /etc/cron.d/zrazu-ssl-example.comСкрипт запускатиметься щодня о 04:17 за часом сервера. Хвилину можна взяти будь-яку — краще не рівно 00.
Перевірка
sudo tail /var/log/zrazu-ssl.log— завтра там з'явиться «сертифікат не змінився»: розклад працює.- Сайт віддає наш сертифікат:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -enddateабо сторінка https://zrazu.com/tools/ssl/example.com/. - У кабінеті, у картці сертифіката, видно, що сервер забрав чинний сертифікат.
Якщо не вийшло
curl: (22) … 404— посилання вимкнене чи замінене. У картці сертифіката створіть нове і замініть рядокPULLу скрипті.curl: (22) … 429— забагато запитів (понад 60 на годину). Раз на добу — з великим запасом.- «сертифікат випущено на інший ключ» — сертифікат перевипускали з новим ключем. Покладіть новий ключ у
key.pemі запустіть скрипт ще раз. nginx: [emerg]після перезапуску — помилка в конфігурації сайту, не в сертифікаті; старий сертифікат лишається в роботі, доки помилку не виправите.