Как обновить и настроить автопродление сертификата Let's Encrypt через Certbot
Полный разбор renew, dry-run, таймеров systemd и диагностики сбоев продления SSL
Зачем вообще думать о продлении заранее
Сертификаты Let's Encrypt живут 90 дней. Это компромисс: короткий срок снижает риски компрометации ключа, но требует автоматизации. Certbot по умолчанию ставит задачу автопродления при установке, однако на практике она ломается по десятку причин: сменился IP, закрылся 80-й порт, переехал сайт, обновился пакет Python, изменился конфиг nginx. Если не проверять механизм продления, сайт однажды встретит посетителей ошибкой NET::ERR_CERT_DATE_INVALID.
В этом гайде разберём, как обновить сертификат вручную, как убедиться, что автопродление реально работает, как настроить его с нуля через systemd-таймер или cron и что делать, если certbot renew падает с ошибкой.
Требования и исходные условия
Linux-сервер (Ubuntu/Debian, CentOS/RHEL, AlmaLinux — команды почти идентичны).
Установленный Certbot (пакет
certbotилиpython3-certbot-nginx/python3-certbot-apache).Root-доступ или sudo.
Действующий сертификат, выпущенный ранее (иначе сначала нужно выполнить
certbot certonlyилиcertbot --nginx).Открытые порты для валидации: 80/tcp для HTTP-01 или 443/tcp для TLS-ALPN-01.
Работающий веб-сервер (nginx, apache) либо режим
--standalone.
Проверить версию и наличие Certbot:
certbot --version
which certbotШаг 1. Посмотрите, какие сертификаты уже есть
Certbot хранит данные в /etc/letsencrypt/live/. Список выданных сертификатов и дат истечения:
certbot certificatesВ выводе будут имена (Certificate Name), домены (SAN), дата истечения и путь к файлам fullchain.pem и privkey.pem. Запомните имя — оно понадобится для точечного обновления.
Альтернативно можно посмотреть напрямую:
ls -l /etc/letsencrypt/live/
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -datesШаг 2. Ручное обновление: certbot renew
Основная команда обновления — renew. Она проходит по всем сертификатам и обновляет только те, что истекают в ближайшие 30 дней (по умолчанию). Принудительно обновить всё:
certbot renew --force-renewalОбновить конкретный сертификат:
certbot renew --cert-name example.comПолезные флаги:
--dry-run— тестовый прогон без реального обновления (использует staging-сервер Let's Encrypt).--quiet— минимум вывода, удобно для cron.--deploy-hook "systemctl reload nginx"— выполнить команду только после успешного обновления.--post-hook— выполняется после каждой попытки renew (даже неуспешной).--pre-hook— перед попыткой (например, остановить standalone-сервер).
Важно: --force-renewal не стоит запускать в цикле — можно упереться в лимиты Let's Encrypt (5 дубликатов в неделю на набор доменов).
Шаг 3. Тестовый прогон dry-run — обязательный этап
Перед тем как доверять автопродлению, прогоните его вхолостую:
certbot renew --dry-runЧто должно быть в выводе: строки вида Congratulations, all simulated renewals succeeded для каждого сертификата. Если видите Failed authorization procedure или Timeout during connect — автопродление не сработает, и нужно разбираться до наступления критической даты.
Dry-run использует staging-окружение и не расходует лимиты продакшена. Запускайте его после любого изменения конфигурации nginx/apache, смены DNS или переезда сервера.
Шаг 4. Проверьте, включён ли таймер systemd
На современных дистрибутивах Certbot ставит systemd-таймер certbot.timer, который дважды в сутки запускает certbot renew. Проверить:
systemctl list-timers | grep certbot
systemctl status certbot.timerЕсли таймер активен (active (waiting)), следующий запуск отображается в колонке NEXT. Посмотреть юнит:
systemctl cat certbot.timer
systemctl cat certbot.serviceЕсли таймера нет (старые системы или установка из snap без сервиса), включите его:
systemctl enable --now certbot.timerЛоги последних запусков:
journalctl -u certbot.service --since "7 days ago"Шаг 5. Настройка cron как альтернатива
Если systemd-таймера нет или вы предпочитаете cron, добавьте задачу. Откройте crontab root:
sudo crontab -eСтрока для запуска дважды в сутки со случайной минутой (чтобы не бить по серверам Let's Encrypt в одну секунду со всем интернетом):
17 3,15 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"Не ставьте одновременно и cron, и systemd-таймер — двойные запуски создают лишнюю нагрузку и могут конфликтовать при обновлении файлов.
Шаг 6. Хуки: перезагрузка веб-сервера после обновления
Certbot обновляет файлы в /etc/letsencrypt/live/, но работающий nginx или apache продолжает держать в памяти старый сертификат. Нужен reload. Три способа:
1. Флаг в команде renew: --deploy-hook "systemctl reload nginx". 2. Скрипт в /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh с правом на выполнение — Certbot выполнит его автоматически после успешного обновления любого сертификата. 3. Глобальные хуки в /etc/letsencrypt/cli.ini.
Пример скрипта:
#!/bin/sh
systemctl reload nginxНе забудьте chmod +x. Проверить, что хук отработал, можно по логам journalctl -u certbot.service или /var/log/letsencrypt/letsencrypt.log.
Шаг 7. Диагностика: почему renew падает
Типичные причины и как их ловить:
Порт 80 закрыт файрволом. Проверьте
ufw status,firewall-cmd --list-all, правила облачного security group. HTTP-01 требует доступностиhttp://домен/.well-known/acme-challenge/.Неверный DNS.
dig +short example.comдолжен возвращать IP этого сервера. Если домен за Cloudflare в режиме «Proxied», HTTP-01 может не пройти — используйте DNS-01 или временно отключите проксирование.Редирект на HTTPS ломает валидацию. Certbot обычно справляется, но если у вас жёсткий редирект с нестандартной логикой — добавьте исключение для
/.well-known/acme-challenge/.Конфликт с standalone. Если сертификат выпускался в режиме
--standalone, а теперь на 80-м порту висит nginx, renew упадёт. Перевыпустите сертификат в режиме--webrootили--nginx.Устаревший плагин. После обновления nginx/apache плагин Certbot может не находить конфиг. Обновите
python3-certbot-nginx.Исчерпаны лимиты. Сообщение
too many certificates already issued— подождите неделю или используйте staging для тестов.
Логи всегда смотрите в /var/log/letsencrypt/letsencrypt.log — там подробная причина отказа.
Шаг 8. Проверка срока действия после обновления
После успешного renew убедитесь, что сертификат действительно обновился и веб-сервер отдаёт новый:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -datesСравните дату notAfter с той, что показывает certbot certificates. Если даты расходятся — reload не сработал, проверьте хуки.
Шаг 9. Мониторинг: как узнать о проблеме заранее
Автопродление — это не «настроил и забыл». Минимальный набор:
Внешний мониторинг срока сертификата (uptime-сервисы, Zabbix, Prometheus blackbox_exporter) с алертом за 14 дней до истечения.
Еженедельный
certbot renew --dry-runв cron с отправкой письма при ошибке.Проверка
journalctl -u certbot.serviceраз в месяц.
Простой скрипт-алерт на bash: получить дату окончания через openssl, сравнить с текущей, отправить письмо, если осталось меньше 20 дней.
Шаг 10. Обновление самого Certbot
Старый Certbot — источник половины проблем. Обновляйте его вместе с системой:
Debian/Ubuntu:
apt update && apt install --only-upgrade certbot python3-certbot-nginx.RHEL/Alma:
dnf upgrade certbot python3-certbot-nginx.Snap-установка:
snap refresh certbot.
После обновления обязательно прогоните certbot renew --dry-run.
Типичные ошибки
1. Запуск `--force-renewal` по cron. Приводит к исчерпанию лимитов и блокировке на неделю. В cron должен быть только renew без force. 2. Отсутствие deploy-hook. Сертификат обновлён, но nginx отдаёт старый — классика. 3. Дублирование cron и systemd-таймера. Лишние запросы и гонки при записи файлов. 4. Валидация через закрытый порт. Проверяйте файрвол и security groups после каждого переезда. 5. Cloudflare Proxy. Оранжевое облако мешает HTTP-01; либо DNS-01, либо серое облако на время выпуска. 6. Забытый `--dry-run` после правок конфига. Изменения в nginx ломают валидацию незаметно до дня X. 7. Редирект без исключения для ACME. /.well-known/acme-challenge/ должен отдаваться по HTTP.
FAQ
Как часто запускать renew? Certbot сам обновляет только сертификаты, истекающие в течение 30 дней, поэтому запускать можно хоть каждый день — лишних запросов к Let's Encrypt не будет. Стандарт — дважды в сутки.
Можно ли обновить сертификат без простоя сайта? Да. При webroot/nginx-плагине сайт продолжает работать, файлы подменяются атомарно, а reload nginx не рвёт соединения.
Что делать, если сертификат уже истёк? certbot renew отработает и для истёкшего сертификата, но если валидация сломана — сначала почините доступность домена, затем запускайте renew. При критических проблемах поможет certbot certonly --force-renewal с явным указанием метода.
Где хранятся логи? /var/log/letsencrypt/letsencrypt.log, а также journalctl -u certbot.service для systemd.
Нужно ли перезапускать сервер после обновления? Полный restart не нужен, достаточно reload. Для nginx — systemctl reload nginx, для apache — systemctl reload apache2 (или httpd).
Как обновить только один домен из нескольких? certbot renew --cert-name example.com — обновит только этот сертификат, не трогая остальные.
Итог
Автопродление Certbot — это три вещи: работающий таймер (systemd или cron), корректный метод валидации (webroot/nginx/dns) и deploy-hook на reload веб-сервера. Плюс регулярная проверка через certbot renew --dry-run и внешний мониторинг срока. Настройте это один раз и проверяйте после каждого изменения инфраструктуры — тогда 90-дневный цикл Let's Encrypt перестанет быть источником сюрпризов.
Читайте также
Комментарии
Комментарии доступны только зарегистрированным пользователям. Войти
- Пока нет комментариев. Будьте первым.



