С 4 июня 2025 Let’s Encrypt окончательно прекратила email-напоминания о скором истечении сертификатов. Если автоматизация не настроена, сайт внезапно рушится с ERR_CERT_DATE_INVALID — классическая проблема с ssl из-за просроченного сертификата. Решение — полностью полагаться на автообновление ACME + свою автопроверку/алерты (Slack/почта/чат-бот).
Ниже — пошагово для Ubuntu/Debian (Nginx/Apache)
1) Срочно «потушить пожар»: обновить сертификат сейчас
# Проверка статуса Certbot
sudo certbot --version || sudo apt update && sudo apt install -y certbot
# Попытка немедленного продления (скрипт сам решит, у каких доменов срок близок)
sudo certbot renew --force-renewal
# Перезапуск/перечтение веб-сервера (выберите свой)
sudo systemctl reload nginx 2>/dev/null || sudo systemctl reload apache2
Проверьте, что браузер не ругается - https://hstq.net/ssl-check.html при необходимости гляньте сроки:
sudo openssl x509 -in /etc/letsencrypt/live/your-domain/fullchain.pem -noout -dates -issuer -subject
Почему это важно: ошибка ERR_CERT_DATE_INVALID появляется, когда сертификат уже не действителен (или время на сервере/клиенте «уехало»), чаще всего — банально просрочен. 
2) Настраиваем автообновление «по-взрослому»
Вариант A. Стандартный systemd-таймер (проще всего)
На современных Ubuntu/Debian Certbot ставит certbot.timer, который пытается продлевать сертификаты два раза в сутки. Проверьте и включите:
sudo systemctl enable --now certbot.timer
systemctl status certbot.timer --no-pager
sudo certbot renew --dry-run
Добавьте хук на перезагрузку вашего сервиса (один раз — навсегда):
# Хук при успешном обновлении
sudo tee /etc/letsencrypt/renewal-hooks/deploy/00-reload.sh >/dev/null <<'SH'
#!/usr/bin/env bash
set -e
systemctl reload nginx 2>/dev/null || true
systemctl reload apache2 2>/dev/null || true
SH
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/00-reload.sh
Вариант B. Свой таймер для «коротких» сертификатов
Let’s Encrypt ввела 6-дневные короткоживущие сертификаты (опционально). Для них сама CA рекомендует продлевать каждые ≈3 дня, но надёжнее сделать попытки ещё чаще — у нас будет запас на выходные и простои. 
Создадим отдельный service/timer с попыткой обновления каждые 48 часов:
# Сервис
sudo tee /etc/systemd/system/certbot-renew.service >/dev/null <<'UNIT'
[Unit]
Description=Certbot renew (short-lived certs)
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet
ExecStartPost=/bin/sh -c 'systemctl reload nginx 2>/dev/null || true; systemctl reload apache2 2>/dev/null || true'
UNIT
# Таймер (48h)
sudo tee /etc/systemd/system/certbot-renew.timer >/dev/null <<'UNIT'
[Unit]
Description=Run Certbot renew every 48 hours (short-lived certs)
[Timer]
OnBootSec=15m
OnUnitActiveSec=48h
Persistent=true
[Install]
WantedBy=timers.target
UNIT
sudo systemctl daemon-reload
sudo systemctl enable --now certbot-renew.timer
systemctl list-timers | grep certbot-renew
Примечание: обычные 90-дневные сертификаты можно спокойно продлять «раз в сутки» (или через встроенный certbot.timer). Короче говоря, чем короче жизнь сертификата — тем чаще должны идти попытки.
3) Slack-уведомления: бот, который предупредит заранее
Сделаем мини-монитор: он подключится к сайту, вычислит «дней до конца» и пошлёт алерт в Slack, если порог пройден.
3.1. Переменные (задаём один раз)
export DOMAIN=example.com # ваш домен
export SLACK_WEBHOOK="https://hooks.slack.com/services/XXX/YYY/ZZZ" # входящий Webhook в Slack
export THRESHOLD_DAYS=14 # порог для обычных (90d)
export THRESHOLD_DAYS_SHORT=2 # порог для 6-дневных
3.2. Скрипт проверки /usr/local/bin/ssl-expiry-watch.sh
sudo tee /usr/local/bin/ssl-expiry-watch.sh >/dev/null <<'SH'
#!/usr/bin/env bash
set -euo pipefail
DOMAIN="${DOMAIN:-example.com}"
WEBHOOK="${SLACK_WEBHOOK:-}"
THRESHOLD="${THRESHOLD_DAYS:-14}"
SHORT_THRESHOLD="${THRESHOLD_DAYS_SHORT:-2}"
if [ -z "$WEBHOOK" ]; then
echo "SLACK_WEBHOOK not set" >&2
exit 1
fi
# Получаем дату истечения с прод-сервера
end_date="$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)"
# Переводим в UNIX time и считаем дни
end_ts="$(date -d "$end_date" +%s)"
now_ts="$(date +%s)"
days_left=$(( (end_ts - now_ts) / 86400 ))
# Определяем, короткий ли сертификат (<= 7 дней)
# Ловим крайний случай: если осталось мало, это всё равно сработает
short="no"
[ $days_left -le 7 ] && short="maybe"
# Порог в зависимости от типа
use_threshold="$THRESHOLD"
[ "$short" = "maybe" ] && use_threshold="$SHORT_THRESHOLD"
if [ $days_left -le $use_threshold ]; then
msg=":warning: SSL for *$DOMAIN* expires in *$days_left* days. Threshold=$use_threshold. Renew now!"
payload=$(printf '{"text":"%s"}' "$msg")
curl -fsS -X POST -H 'Content-type: application/json' --data "$payload" "$WEBHOOK" >/dev/null
fi
SH
sudo chmod +x /usr/local/bin/ssl-expiry-watch.sh
3.3. Периодический запуск
- Для обычных (90 дней): ежедневно в 09:00
- Для 6-дневных: каждые 12 часов
# Cron: открыть crontab
sudo crontab -e
# Ежедневно 09:00
0 9 * * * DOMAIN=example.com SLACK_WEBHOOK="https://hooks.slack.com/services/XXX/YYY/ZZZ" /usr/local/bin/ssl-expiry-watch.sh
# Для 6-дневных дополнительно в 21:00
0 21 * * * DOMAIN=example.com SLACK_WEBHOOK="https://hooks.slack.com/services/XXX/YYY/ZZZ" THRESHOLD_DAYS_SHORT=2 /usr/local/bin/ssl-expiry-watch.sh
4) Типичные «проблемы с ssl сертификатом» и быстрые проверки
1.Сертификат обновился, а сервер отдаёт старый.
Значит, сервис не перезагружается после renew. Решение: deploy-hook (выше) или --deploy-hook "systemctl reload nginx"/apache2.
2.ACME-проверка падает.
Откройте 80/443, убедитесь, что /.well-known/acme-challenge/ доступен, нет «ораньжевой тучки» (гибридного прокси), нет редиректов на другой хост до прохождения валидации.
3.Несовпадение доменов/SAN.
Проверьте, что все -d перечислены в сертификате, а виртуальный хост слушает именно этот server_name.
4.Nginx/Apache берёт не те пути.
Проверьте конфиг на пути ssl_certificate и ssl_certificate_key — это должны быть файлы из /etc/letsencrypt/live/<domain>/.
5.Часы/таймзона.
Если системное время «убежало», браузер видит бесплатный ssl сертификат для сайта как «не ещё действительный»/«уже истёк». Сверьте NTP.
5) Что меняется с короткими 6-дневными сертификатами
Let’s Encrypt в 2025 запустила short-lived (≈6 дней). Это удобно для повышенной безопасности, но требует частых попыток продления и более агрессивного мониторинга:
- Официально рекомендуют обновлять каждые 3 дня;
- На практике безопаснее пробовать каждые 48 часов (см. наш certbot-renew.timer), чтобы не попасть в «длинные выходные»;
- Мониторинг — каждые 12 часов с порогом 2 дня.
6) Проверка, что всё работает
# Сухой прогон продления
sudo certbot renew --dry-run
# Когда реальное продление произойдёт, certbot вызовет наш deploy-hook:
# - перезагрузит веб-сервер
# - при желании можно добавить отправку в Slack (аналогично чекеру)
# Вручную посмотреть срок на проде
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates -issuer -subject
FAQ: «бесплатный ssl / ssl для сайта бесплатно»
- Let’s Encrypt — это по-настоящему бесплатный SSL-сертификат для сайта. Он живёт 90 дней (или 6 дней для короткого варианта) и требует исправной автоматизации. Именно поэтому CA и отключила email-напоминания: ожидается, что у всех настроена автоматика.
- Как часто «крутить» renewal? Для 90-дневных — раз в день (или штатный certbot.timer 2 раза в сутки). Для 6-дневных — каждые 48 часов (у нас так настроено), при том что рекомендация CA — раз в 3 дня.
- ERR_CERT_DATE_INVALID исчезнет сам? Нет: нужно обновить сертификат и удостовериться, что веб-сервер отдаёт новый (reload/hook). Причина ошибки — истёкший или «не ещё действительный» сертификат.
Если у вас проблемы с ssl сертификатом и нет времени разбираться: HSTQ настроит бесплатный SSL (Let’s Encrypt) под ваш стек, включит автопродление и Slack-алерты, разрулит редиректы/Cloudflare, проверит firewall и HTTP-валидацию, а также возьмёт на 24/7-мониторинг.