SSL: автоматичне оновлення
Хостинг із DirectAdmin — сертифікат оновлюється сам
Задача cron раз на добу забирає свіжий сертифікат і ставить його в DirectAdmin через API за ключем входу, якому дозволено лише SSL. Пароль не потрібен.
Оновлюється сам
Підходить для хостингу з панеллю DirectAdmin: NIC.UA, Tucha та багато інших. Ознака DirectAdmin — адреса входу закінчується на :2222, у меню є Account Manager, Advanced Features, System Info & Files.
Як це працює: скрипт раз на добу забирає сертифікат за посиланням і, якщо він новий, передає його панелі разом із вашим ключем — так само, як ви вставили б його руками в SSL Certificates. До панелі він заходить не паролем, а окремим ключем входу (Login Key), якому дозволена лише одна дія — встановити сертифікат. Ваш пароль від панелі і від хостингу ми не просимо й не бачимо.
Що знадобиться
- Посилання на сертифікат із кабінету:
https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН. - Закритий ключ, з яким замовляли сертифікат. Якщо CSR створював кабінет ZRAZU — це файл, який ви тоді зберегли.
- Розділ Cron Jobs у панелі (є на більшості тарифів) або будь-який сервер Linux із
curlіopenssl. - 15 хвилин.
Крок 1. Перше встановлення (якщо сертифікат ще не стоїть)
У Account Manager → SSL Certificates оберіть Paste a pre-generated certificate and key, вставте в одне поле спершу ключ, під ним — сертифікат, збережіть. Потім Click Here to paste a CA Root Certificate, вставте ланцюжок (chain.pem з картки сертифіката), позначте Use a CA Cert і збережіть. Подробиці — у заміні сертифіката в панелі вручну.
Крок 2. Ключ входу лише для SSL
Account Manager → Login Keys → Create Key (у старих темах — Login Keys на головній):
- Key Name —
zrazu-ssl; - Key Value — натисніть Random і скопіюйте значення: його покажуть лише раз;
- Expires On — Never (ключ потрібен щодня);
- Commands — позначте лише
CMD_API_SSL; без цього ключ відкриває всю панель; - Allowed IPs — IP, з якого запускатиметься скрипт. Якщо це cron самого хостингу — IP сервера (System Info & Files → System Information). Поле порожнє — ключ діє з будь-якої адреси;
- Current Password — ваш пароль від панелі, щоб підтвердити створення.
Якщо пункту Login Keys немає — хостинг вимкнув цю можливість. Тоді лишається ручна заміна, ми нагадаємо про неї заздалегідь.
Крок 3. Файли в домашньому каталозі
У System Info & Files → File Manager створіть у домашньому каталозі (над domains і public_html) папку .zrazu і в ній три файли:
key.pem— закритий ключ разом із рядками-----BEGIN … PRIVATE KEY-----і-----END … PRIVATE KEY-----;login— один рядок у лапках: ім'я користувача панелі, двокрапка, значення ключа входу:
user = "ІМ'Я_КОРИСТУВАЧА:ЗНАЧЕННЯ_КЛЮЧА"zrazu-ssl.sh— скрипт нижче. Змініть у ньому лише рядокPANEL— адреса, за якою ви заходите в панель, з:2222, без шляху.
Усім трьом файлам поставте права 600 (Permissions у File Manager): читати їх може лише ваш обліковий запис.
#!/bin/sh
# ZRAZU: оновлення SSL-сертифіката в DirectAdmin за особистим посиланням. Запускається cron раз на добу.
# Ключ лишається у вас; у панель сертифікат іде, лише якщо він підходить до ключа.
set -eu
PATH=/usr/local/bin:/usr/bin:/bin
PULL="https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
DOMAIN="example.com"
PANEL="https://server.example.com:2222"
DIR="$HOME/.zrazu"
KEY="$DIR/key.pem"
# Ім'я і ключ входу — у файлі, а не в рядку запуску: так їх не видно іншим користувачам сервера.
LOGIN="$DIR/login"
umask 077
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT
TAG=""
[ -f "$DIR/$DOMAIN.etag" ] && TAG=$(cat "$DIR/$DOMAIN.etag")
CODE=$(curl -fsS --retry 3 --max-time 60 -o "$WORK/full.pem" -D "$WORK/hdr" -w '%{http_code}' -H "If-None-Match: $TAG" "$PULL/fullchain.pem")
if [ "$CODE" = "304" ]; then echo "ZRAZU: сертифікат не змінився"; exit 0; fi
grep -q "BEGIN CERTIFICATE" "$WORK/full.pem" || { echo "ZRAZU: за посиланням не сертифікат" >&2; exit 1; }
# Перший сертифікат у файлі — сайту, решта — ланцюжок.
awk -v d="$WORK" '/BEGIN CERTIFICATE/{n++} n==1{print > (d "/cert.pem")} n>1{print > (d "/chain.pem")}' "$WORK/full.pem"
if [ "$(openssl x509 -in "$WORK/cert.pem" -noout -pubkey | openssl sha256)" != "$(openssl pkey -in "$KEY" -pubout | openssl sha256)" ]; then
echo "ZRAZU: сертифікат випущено на інший ключ — нічого не міняю, покладіть новий ключ у $KEY" >&2
exit 1
fi
openssl x509 -in "$WORK/cert.pem" -noout -checkend 0 >/dev/null || { echo "ZRAZU: сертифікат уже не діє" >&2; exit 1; }
# Панель приймає ключ і сертифікат одним полем: спершу ключ, під ним сертифікат.
cat "$KEY" "$WORK/cert.pem" > "$WORK/paste.pem"
api() {
OUT=$(curl -sS --max-time 60 -K "$LOGIN" "$PANEL/CMD_API_SSL" -d "domain=$DOMAIN" -d action=save "$@") || true
case "$OUT" in
error=0*) ;;
*) echo "ZRAZU: панель не прийняла: $(printf '%s' "$OUT" | head -c 300)" >&2; exit 1 ;;
esac
}
api -d type=paste -d request=no --data-urlencode "certificate@$WORK/paste.pem"
if [ -s "$WORK/chain.pem" ]; then
api -d type=cacert -d active=yes --data-urlencode "cacert@$WORK/chain.pem"
fi
# Метка — лише після того, як панель прийняла: не вдалося — наступний запуск спробує ще раз.
sed -n 's/^[Ee][Tt][Aa][Gg]: *//p' "$WORK/hdr" | tr -d '\r' > "$DIR/$DOMAIN.etag"
echo "ZRAZU: новий сертифікат встановлено, діє до $(openssl x509 -in "$WORK/cert.pem" -noout -enddate | cut -d= -f2)"Скрипт нічого не міняє, якщо сертифікат не змінився, якщо за посиланням не сертифікат, якщо сертифікат не підходить до вашого ключа чи вже не діє. Панель відповідає error=0, коли прийняла сертифікат; будь-яка інша відповідь — помилка, і наступного дня скрипт спробує ще раз.
Крок 4. Розклад
Advanced Features → Cron Jobs → Create Cron Job: Minute 17, Hour 4, решта полів — *, команда:
/bin/sh $HOME/.zrazu/zrazu-ssl.sh >> $HOME/.zrazu/log.txt 2>&1Хвилину можна взяти будь-яку — краще не рівно 00. Щоб перевірити одразу, тимчасово поставте час на дві хвилини вперед, а після запуску відкрийте .zrazu/log.txt: має бути «новий сертифікат встановлено».
Свій сервер Linux замість cron хостингу — той самий скрипт із HOME на свій каталог, рядок crontab -e: 17 4 * * * /bin/sh $HOME/.zrazu/zrazu-ssl.sh >> $HOME/.zrazu/log.txt 2>&1, а в Allowed IPs ключа — IP цього сервера.
Перевірка
Відкрийте https://zrazu.com/tools/ssl/example.com/ — має бути сертифікат ZRAZU з новою датою закінчення.
Щоб хостинг не замінив наш сертифікат
Якщо для домену увімкнено безкоштовний сертифікат (Free & automatic certificate from Let's Encrypt у SSL Certificates), панель сама поновлюватиме його і може замінити наш. Скрипт ставить сертифікат як вставлений вручну, і панель перестає поновлювати безкоштовний; перевірте після першого запуску, що в SSL Certificates обрано вставлений сертифікат.
Якщо не вийшло
Це нова інструкція: на живій панелі ми її ще не перевірили. Не спрацювало — напишіть нам у кабінеті (Звернення) чи на пошту з текстом із .zrazu/log.txt, виправимо інструкцію того ж дня.
- «панель не прийняла» і в відповіді HTML зі словами
Cannot Execute Your Request— ключ входу не має права наCMD_API_SSLабо запуск іде з IP поза Allowed IPs. Перевірте крок 2. error=1іtext=…— панель пояснила причину вtext: найчастіше домен записано не так, як у панелі (без*.і безwww).curl: (60)чиSSL certificate problem— уPANELадреса, на яку в панелі інший сертифікат. Візьміть адресу точно з рядка браузера, коли заходите в панель.openssl: not found— на цьому хостингу немаєopenssl; запускайте скрипт зі свого сервера Linux.curl: (22) … 404— посилання вимкнене чи замінене: створіть нове в картці сертифіката і замініть рядокPULL.