Автоматическое продление SSL-сертификатов Let's Encrypt в Nginx с Certbot | AdminWiki

Автоматическое продление SSL-сертификатов Let's Encrypt в Nginx с Certbot

07 августа 2026 9 мин. чтения

Что понадобится и что получится в итоге

  • Сертификат Let's Encrypt, уже выпущенный для Nginx.
  • Сервер на Ubuntu 24.04 или Debian 12 с правами root или доступом через sudo.
  • Открытые порты 80 и 443, если используется HTTP-01 верификация.

В результате Certbot будет автоматически запускать certbot renew, продлевать сертификаты до истечения срока и выполнять systemctl reload nginx только после успешного обновления. Новые сертификаты применяются без простоя и разрыва установленных соединений. Работу настройки можно проверить через --dry-run, статус timer или логи cron и Certbot.

Почему автоматизация продления сертификатов критически важна

Сертификаты Let's Encrypt действительны 90 дней. Это осознанное решение центра сертификации, стимулирующее автоматизацию. Ручное обновление четырежды в год кажется простым, пока вы не пропустите срок. Просроченный сертификат означает, что браузеры клиентов покажут предупреждение о небезопасном соединении. Пользователи уйдут, API-интеграции оборвутся, репутация пострадает.

Человеческий фактор - главный враг стабильности. Отпуск администратора, болезнь, высокая загрузка или сбой в почтовом напоминании от Let's Encrypt приводят к простою. Автоматизация решает эту проблему: сертификаты продлеваются без участия человека. Certbot предоставляет два встроенных механизма - cron и systemd timer. Оба запускают certbot renew по расписанию, а renew-hook перезагружает Nginx для применения новых сертификатов только после фактического обновления.

В этом руководстве мы настроим автоматическое продление двумя способами, проверим его через dry-run, настроим безопасную перезагрузку Nginx без разрыва соединений и наладим мониторинг. Все основные команды проверены на Ubuntu 24.04 и Debian 12 в 2026 году. Если вам нужна базовая настройка HTTPS с нуля, обратитесь к полной инструкции по получению сертификатов Let's Encrypt для Nginx и Apache.

Предварительные требования и проверка окружения

Перед настройкой автоматизации убедитесь, что сертификаты уже выпущены и корректно работают. Проверьте список установленных сертификатов:

sudo certbot certificates

Вывод покажет домены, путь к файлам сертификатов и дату истечения. Если список пуст, сертификаты не выпущены. Вернитесь к первичной настройке - автоматическое продление без действующих сертификатов бессмысленно.

Проверьте версии ПО. Минимальные требования: Certbot 1.0 и Nginx 1.14. Более старые версии могут не поддерживать флаг --renew-hook или корректную перезагрузку. Узнать версии можно командами:

certbot --version
nginx -v

Убедитесь, что у процесса, который будет запускать продление, есть права на запись в каталог /etc/letsencrypt/. Оба способа - cron и systemd timer - мы настроим от root. Это стандартная практика, поскольку сертификаты и приватные ключи должны быть защищены от чтения непривилегированными пользователями.

Порты 80 и 443 должны быть открыты на файрволе и доступны из интернета. Certbot использует HTTP-01 верификацию, которая требует входящего соединения на порт 80. Проверьте правила iptables или ufw:

sudo ufw status verbose

Если вы используете CDN или прокси-сервер перед Nginx, метод HTTP-01 может не сработать. В таких случаях применяется DNS-01 верификация, но это тема отдельного руководства. Для стандартной конфигурации с прямым доступом к серверу HTTP-01 работает без дополнительных настроек.

Способ 1: Автоматическое продление через cron

Cron - классический планировщик задач в Unix-подобных системах. Для автоматического продления сертификатов мы создадим задание, которое ежедневно запускает certbot renew и перезагружает Nginx только при фактическом обновлении.

Настройка cron-задачи для certbot renew

Certbot не продлевает сертификаты при каждом запуске. Команда renew проверяет срок действия всех установленных сертификатов и обновляет только те, у которых до истечения осталось менее 30 дней. Ежедневный запуск безопасен и не создаёт лишней нагрузки на инфраструктуру Let's Encrypt.

Откройте crontab пользователя root:

sudo crontab -e

Добавьте строку:

0 0 * * * certbot renew --quiet --renew-hook "systemctl reload nginx"

Пять полей расписания 0 0 * * * означают запуск ежедневно в полночь. certbot renew проверяет все сертификаты. Флаг --quiet подавляет стандартный вывод, а --renew-hook выполняет указанную команду только после успешного обновления хотя бы одного сертификата.

Альтернативный вариант - разместить скрипт в каталоге /etc/cron.daily/. Создайте файл /etc/cron.daily/certbot-renew:

#!/bin/bash
certbot renew --quiet --renew-hook "systemctl reload nginx"

Сделайте его исполняемым:

sudo chmod +x /etc/cron.daily/certbot-renew

Скрипты в /etc/cron.daily/ выполняются анакроном - подсистемой, которая гарантирует запуск пропущенных задач, если сервер был выключен в запланированное время. Это даёт небольшое преимущество перед классическим cron.

Безопасная перезагрузка Nginx через --renew-hook

Ключевой момент автоматизации - перезагрузка Nginx только после фактического обновления сертификатов. Флаг --renew-hook выполняется исключительно после успешного обновления. Если продление не потребовалось, Nginx продолжает работать без вмешательства.

Почему reload, а не restart? Команда systemctl reload nginx отправляет мастер-процессу сигнал SIGHUP. Nginx перечитывает конфигурацию и применяет новые сертификаты без разрыва установленных соединений. Клиенты не замечают перезагрузки. Команда restart полностью останавливает и запускает сервер, поэтому активные соединения обрываются. Для production-среды разница критична. Если вы углубляетесь в тему безопасности Nginx, рекомендуем готовую конфигурацию с TLS 1.3 и усиленными параметрами безопасности.

Способ 2: Автоматическое продление через systemd timer

Systemd timer - современная альтернатива cron в дистрибутивах с systemd, включая Ubuntu 24.04 и Debian 12. Таймеры systemd предоставляют детальное логирование через journald, гарантируют запуск пропущенных задач после простоя сервера и позволяют контролировать состояние unit-файла.

Создание unit-файла сервиса certbot-renew.service

Создайте файл сервиса, который будет выполнять продление:

sudo nano /etc/systemd/system/certbot-renew.service

Содержимое файла:

[Unit]
Description=Certbot Renew Service
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"

Директива Type=oneshot указывает systemd, что сервис выполняет однократное действие и завершается. After=network.target задаёт порядок запуска после инициализации сети. Обратите внимание на полные пути к исполняемым файлам: /usr/bin/certbot и /bin/systemctl.

Создание unit-файла таймера certbot-renew.timer

Таймер определяет расписание запуска сервиса. Создайте второй файл:

sudo nano /etc/systemd/system/certbot-renew.timer

Содержимое:

[Unit]
Description=Certbot Renew Timer
Requires=certbot-renew.service

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Директива OnCalendar=daily запускает задачу раз в сутки. Можно указать точное время: OnCalendar=*-*-* 03:00:00 - ежедневно в 3 часа ночи. Persistent=true запускает задачу после загрузки, если плановый запуск был пропущен из-за выключения сервера.

Активируйте таймер:

sudo systemctl daemon-reload
sudo systemctl enable --now certbot-renew.timer

Проверьте статус и ближайшее срабатывание:

sudo systemctl status certbot-renew.timer
sudo systemctl list-timers --all | grep certbot

Статус active (waiting) означает, что таймер запущен и ожидает следующего срабатывания. После планового запуска результат самого сервиса проверяйте отдельно:

sudo systemctl status certbot-renew.service
sudo journalctl -u certbot-renew.service --since "1 week ago"

Так можно убедиться, что systemd timer реально запускал certbot renew, а не только включён в конфигурации.

Сравнение cron и systemd timer: что выбрать

Оба метода выполняют задачу. Systemd timer удобнее для мониторинга: запуски сервиса попадают в journald, доступны через journalctl -u certbot-renew.service и поддерживают Persistent=true. Cron проще настроить, но его сообщения обычно попадают в syslog вместе с другими событиями.

Cron остаётся актуальным для legacy-систем без systemd, включая Alpine Linux и старые версии CentOS Stream, а также для администраторов, которым нужен единый crontab. Если у вас современный Ubuntu или Debian, используйте systemd timer для детального контроля и логирования.

Для комплексной защиты веб-сервера после настройки сертификатов изучите руководство по SSL/TLS и HTTPS в Nginx с настройкой HSTS и reverse proxy.

Мониторинг и уведомления о сбоях

Автоматизация без мониторинга - чёрный ящик. Проверьте работу настройки сразу после внедрения и заранее настройте уведомления, чтобы ошибка продления не обнаружилась только после истечения сертификата.

Анализ логов Certbot и Nginx

Certbot пишет подробный лог в /var/log/letsencrypt/letsencrypt.log. Проверьте последние записи:

sudo tail -50 /var/log/letsencrypt/letsencrypt.log

Успешное продление содержит строки:

Successfully renewed certificate for example.com
Running renew-hook command: /bin/systemctl reload nginx

Для systemd timer логи доступны в journald:

sudo journalctl -u certbot-renew.service --since "1 week ago"

Для cron проверьте сообщения планировщика в syslog. Конкретный путь зависит от настроек системы, например:

sudo grep certbot /var/log/syslog

Эти проверки показывают, запускался ли certbot renew, завершился ли он успешно и выполнялся ли reload nginx.

Настройка уведомлений при ошибках продления

Certbot поддерживает флаг --renew-hook для успешного обновления, но для ошибок прямого хука нет. Решение - обернуть вызов в скрипт, который проверяет код возврата.

Создайте скрипт /usr/local/bin/certbot-renew-notify.sh:

#!/bin/bash
/usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"
if [ $? -ne 0 ]; then
    echo "Certbot renewal failed on $(hostname) at $(date)" | mail -s "SSL Renewal FAILED" admin@example.com
fi

Замените admin@example.com на ваш email. Сделайте скрипт исполняемым и укажите его в cron или systemd-сервисе вместо прямого вызова certbot. Альтернатива для систем мониторинга - проверка срока действия сертификата с отправкой метрики в Zabbix, Prometheus или Datadog. Настройте алерт за 14 дней до истечения.

Типичные ошибки и их решение

Даже правильно настроенная автоматизация иногда ломается. Разберём частые ошибки и способы их исправления.

Ошибка: не удается подключиться к порту 80

Certbot использует HTTP-01 верификацию. Если порт занят другим процессом или закрыт файрволом, верификация проваливается.

Проверьте, кто слушает порт 80:

sudo ss -tlnp | grep :80

Если порт занят Nginx, это нормально. Certbot умеет работать с Nginx через плагин. Проблема возникает, когда на порту работает другой веб-сервер (Apache, Caddy) или кастомное приложение. Остановите конфликтующий сервис на время продления или настройте DNS-01 верификацию.

Проверьте файрвол:

sudo iptables -L -n | grep :80

Порт 80 должен быть открыт для входящих соединений с любых IP-адресов. Серверы Let's Encrypt используют разные IP, белый список невозможен.

Ошибка: недостаточно прав для записи сертификатов

Каталог /etc/letsencrypt/ и все файлы в нём принадлежат root с правами 700. Если cron-задача или systemd-сервис запущены от непривилегированного пользователя, certbot не сможет обновить файлы.

Для cron используйте sudo crontab -e. Для systemd сервис по умолчанию запускается от root, если не указана директива User=. Проверьте, что в unit-файле нет строки User=someuser.

Если вы вынуждены использовать непривилегированного пользователя, настройте sudo с ограниченными правами. Добавьте в /etc/sudoers.d/certbot:

someuser ALL=(root) NOPASSWD: /usr/bin/certbot renew *

Это разрешит конкретному пользователю запускать certbot renew от root без пароля. Менее безопасно, но приемлемо в контролируемой среде.

Тестирование автоматического продления

Перед тем как положиться на автоматизацию, проверьте её в деле. Certbot предоставляет режим сухого прогона - --dry-run. Он симулирует цикл продления, включая обращение к серверам Let's Encrypt, но не сохраняет рабочие сертификаты.

Выполните тестовый запуск:

sudo certbot renew --dry-run

Успешный вывод содержит строку:

Congratulations, all simulated renewals succeeded

Если видите ошибку, исправьте её до настройки автоматизации. Сухой прогон проверяет достижимость серверов Let's Encrypt, корректность конфигурации плагинов и права доступа.

Для проверки renew-hook можно запустить продление принудительно с флагом --force-renewal:

sudo certbot renew --force-renewal --renew-hook "systemctl reload nginx"
sudo systemctl status nginx | grep "Main PID"

После выполнения убедитесь, что Nginx перезагрузился и сертификаты обновились. Откройте сайт в браузере и проверьте дату сертификата. Принудительный запуск используйте осознанно: он обращается к Let's Encrypt и может расходовать лимиты запросов.

Для systemd timer запустите сервис вручную:

sudo systemctl start certbot-renew.service
sudo systemctl status certbot-renew.service

Статус должен показать успешное завершение с кодом 0. Для cron проверьте результат через лог Certbot и сообщения cron в syslog.

Заключение: полностью автоматизированное управление SSL

Вы настроили автоматическое продление сертификатов Let's Encrypt для Nginx без участия человека. Выбран метод - cron для простоты или systemd timer для детального контроля и логирования. Настроена безопасная перезагрузка Nginx через --renew-hook, которая применяет новые сертификаты без простоя. Налажен мониторинг с оповещениями о сбоях.

Проверьте логи через неделю после настройки. Убедитесь, что certbot renew отрабатывает штатно, timer или cron запускается, а письма о сбоях не приходят. Для дополнительного усиления защиты веб-сервера используйте полное руководство по защите Nginx и Apache с WAF и security-заголовками.

Автоматическое обновление SSL - базовая гигиена современного веб-сервера. Настроив его один раз и проверив через dry-run, вы снижаете риск просрочки сертификатов и сохраняете HTTPS доступным для пользователей и API.

Поделиться:
Сохранить гайд? В закладки браузера