SSL/TLS-алерт

Сертификат истекает — уведомление на телефон.

Ежедневная проверка openssl + push за 14 дней до истечения. Поймайте сломанный Certbot renewal до «Не защищено» в браузере.

Почему Let's Encrypt не спасает

Автообновление Certbot — отлично, пока работает. Но оно ломается тихо:

Результат: через 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 до реального истечения.