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.