sadrix logoSadriX
Минцифры готовит обязательную регистрацию IMEI смартфонов, купленных за границей
Гайды

Как обновить и настроить автопродление сертификата Let's Encrypt через Certbot

Полный разбор renew, dry-run, таймеров systemd и диагностики сбоев продления SSL

08 060 просмотров6 мин
0
Поделиться:TelegramVK

Зачем вообще думать о продлении заранее

Сертификаты 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 перестанет быть источником сюрпризов.

Читайте также

Комментарии

Комментарии доступны только зарегистрированным пользователям. Войти

  • Пока нет комментариев. Будьте первым.