Почему Let's Encrypt не спасает
Автообновление Certbot — отлично, пока работает. Но оно ломается тихо:
- DNS поменялся — challenge не проходит
- Порт 80 занят другим сервисом
- Nginx/Apache не перезапустился после обновления
- Deploy hook не сработал
- Сервер переехал, а cron с certbot renew остался на старом
Результат: через 90 дней сертификат истекает, браузеры показывают «Не защищено», API начинают отклонять TLS, пользователи уходят.
Проверка одного домена
#!/bin/bash
# /usr/local/bin/nerve-ssl-check.sh
export NERVE_DSN="nerve://TOKEN:[email protected]"
DOMAIN="yoursite.ru"
WARN_DAYS=14
EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "$EXPIRY" ]; then
echo "SSL НЕ ДОСТУПЕН: $DOMAIN" | nerve send --severity critical
exit 1
fi
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
if [ "$DAYS_LEFT" -le 0 ]; then
echo "SSL ИСТЁК: $DOMAIN (${DAYS_LEFT#-} дней назад)" | nerve send --severity critical
elif [ "$DAYS_LEFT" -le "$WARN_DAYS" ]; then
echo "SSL ИСТЕКАЕТ: $DOMAIN через $DAYS_LEFT дней" | nerve send --severity alert
fi
# Проверка раз в день в 8 утра
0 8 * * * /usr/local/bin/nerve-ssl-check.sh
Несколько доменов
#!/bin/bash
export NERVE_DSN="nerve://TOKEN:[email protected]"
WARN_DAYS=14
DOMAINS=(
"yoursite.ru"
"api.yoursite.ru"
"admin.yoursite.ru"
"staging.yoursite.ru"
)
for DOMAIN in "${DOMAINS[@]}"; do
EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "$EXPIRY" ]; then
echo "SSL НЕДОСТУПЕН: $DOMAIN" | nerve send --severity critical
continue
fi
DAYS_LEFT=$(( ($(date -d "$EXPIRY" +%s) - $(date +%s)) / 86400 ))
if [ "$DAYS_LEFT" -le 0 ]; then
echo "SSL ИСТЁК: $DOMAIN" | nerve send --severity critical
elif [ "$DAYS_LEFT" -le "$WARN_DAYS" ]; then
echo "SSL ИСТЕКАЕТ: $DOMAIN через $DAYS_LEFT дн." | nerve send --severity alert
fi
done
Уведомление после certbot renew
Deploy hook Certbot — узнать сразу, что обновление прошло (или не прошло):
# /etc/letsencrypt/renewal-hooks/deploy/nerve-notify.sh
#!/bin/bash
export NERVE_DSN="nerve://TOKEN:[email protected]"
echo "SSL обновлён: $RENEWED_DOMAINS на $(hostname)" | nerve send
chmod +x /etc/letsencrypt/renewal-hooks/deploy/nerve-notify.sh
Проверить что Certbot вообще работает
# Когда последний раз обновлялся?
LAST_RENEW=$(stat -c %Y /etc/letsencrypt/live/yoursite.ru/cert.pem 2>/dev/null || echo "0")
DAYS_SINCE=$(( ($(date +%s) - LAST_RENEW) / 86400 ))
if [ "$DAYS_SINCE" -gt 80 ]; then
echo "CERTBOT: сертификат не обновлялся ${DAYS_SINCE} дней ($(hostname))" | nerve send --severity alert
fi
FAQ
Как узнать что сертификат истекает?
Cron проверяет дату через openssl s_client и шлёт push если осталось меньше 14 дней.
Let's Encrypt обновляется сам, зачем проверять?
Автообновление ломается тихо. Этот скрипт ловит failed renewal до реального истечения.