Настройка автоматического обновления сертификатов Let’s Encrypt на веб-сервере

Если вы хотите, чтобы ваш сайт не терял HTTPS каждые 90 дней и вы не получали нервные письма от браузеров — эта инструкция для вас. Я покажу, как настроить автоматическое обновление сертификатов Let’s Encrypt так, чтобы всё работало стабильно и без вашего участия.

Почему это важно и как это работает

Let’s Encrypt выдаёт сертификаты на 90 дней. Это сделано специально — чтобы в случае компрометации ключа ущерб был ограничен по времени. Но это значит, что вам нужно обновлять сертификат примерно раз в три месяца. Вручную — утомительно и легко забыть. Поэтому правильный путь — автоматизировать процесс.

Автоматическое обновление работает через задание в планировщике задач (cron), которое регулярно запускает клиент Let’s Encrypt, проверяет, истекает ли сертификат, и если да — продлевает его. Всё это без вашего участия.

Что понадобится перед началом

Прежде чем настраивать автообновление, убедитесь, что у вас уже есть:

  • Веб-сервер (Nginx, Apache или другой), уже работающий с сертификатом Let’s Encrypt
  • Установленный клиент Certbot (или другой ACME-клиент)
  • Доступ к серверу по SSH с правами root или возможностью запускать команды через sudo
  • Открытый порт 80 (HTTP) — он нужен для проверки домена при выпуске и обновлении сертификата

Если Certbot ещё не установлен, вот команды для популярных систем:

  • Ubuntu/Debian: sudo apt install certbot
  • CentOS/RHEL 7+: sudo yum install epel-release && sudo yum install certbot
  • CentOS/RHEL 8+ / Fedora: sudo dnf install epel-release && sudo dnf install certbot

Если вы используете Nginx, понадобится плагин: sudo apt install python3-certbot-nginx. Для Apache: sudo apt install python3-certbot-apache.

Шаг 1. Проверяем, что сертификат уже получен

Сначала убедимся, что сертификат существует и Certbot его «знает». Выполните:

sudo certbot certificates

Вы должны увидеть список сертификатов с доменами, датой истечения и путём к файлам. Если сертификата нет — сначала получите его вручную:

sudo certbot --nginx -d example.com -d www.example.com

или для Apache:

sudo certbot --apache -d example.com -d www.example.com

Шаг 2. Тестируем обновление вручную

Прежде чем доверять автоматике, проверим, что обновление вообще работает. Запустите тестовое обновление:

sudo certbot renew --dry-run

Ключ --dry-run означает, что Certbot пройдёт все шаги, но не будет выпускать реальный сертификат. Если вы видите сообщение The dry run was successful — всё настроено правильно и можно переходить к автоматизации.

Если появляется ошибка — читайте текст внимательно. Чаще всего проблемы связаны с:

  • Закрытым портом 80 или 443
  • Неправильной конфигурацией веб-сервера
  • DNS-записями, которые не указывают на ваш сервер
  • Ограничениями частоты запросов на стороне Let’s Encrypt

Шаг 3. Настраиваем автоматическое обновление через cron

Certbot поставляется с готовым systemd-таймером на большинстве современных дистрибутивов. Проверьте, активен ли он:

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

Если таймер есть и активен — поздравляю, автоматическое обновление уже настроено. Таймер запускает команду certbot renew дважды в сутки в случайное время. Этого достаточно, потому что Certbot обновляет только те сертификаты, которым осталось меньше 30 дней.

Если таймера нет — создайте cron-задание вручную:

sudo crontab -e

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

0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx" 2>>> /var/log/certbot-renew.log

Давайте разберём, что здесь происходит:

  • 0 3 * * * — запуск каждый день в 3:00 ночи
  • --quiet — не выводить информацию в консоль, если всё прошло успешно
  • --post-hook — команда, которая выполнится после успешного обновления. Она перезагружает Nginx, чтобы сервер начал использовать новый сертификат
  • 2>> /var/log/certbot-renew.log — записываем ошибки в лог, чтобы потом было что читать при проблемах

Если у вас Apache, замените пост-хук на:

--post-hook "systemctl reload apache2"

Для CentOS/RHEL с Apache:

--post-hook "systemctl reload httpd"

Шаг 4. Проверяем, что cron работает

Не ждите 90 дней, чтобы узнать, что что-то пошло не так. Проверьте cron сразу:

  1. Убедитесь, что служба cron запущена: sudo systemctl status cron (или crond на CentOS)
  2. Проверьте, что задание добавлено: sudo crontab -l
  3. Принудительно обнулите дату истечения сертификата для теста — не делайте этого на продакшене, но на тестовом сервере можно проверить полный цикл

Также полезно проверить лог после первого запуска:

cat /var/log/certbot-renew.log

Альтернатива: systemd-таймер вместо cron

Если вы предпочитаете systemd, можно создать свой таймер. Это чуть больше кода, но даёт больше контроля.

Создайте файл сервиса:

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

Содержимое:

[Unit]
Description=Certbot Renewal

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

Теперь создайте таймер:

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

Содержимое:

[Unit]
Description=Run Certbot renewal twice daily

[Timer]
OnCalendar=*-*-* 03:00,15:00
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target

Активируйте и запустите:

sudo systemctl enable --now certbot-renew.timer
sudo systemctl list-timers | grep certbot

Параметр RandomizedDelaySec=3600 добавляет случайную задержку до часа, чтобы все серверы в мире не ломились на Let’s Encrypt одновременно.

Сравнение подходов к автоматизации

Подход Сложность настройки Надёжность Когда выбирать
Встроенный certbot.timer Минимальная Высокая Стандартная установка Certbot на Ubuntu 18.04+ / Debian 10+
Cron-задание Низкая Высокая Любой дистрибутив, максимальная совместимость
Свой systemd-таймер Средняя Высокая Нужен контроль над расписанием и пост-хуками
Docker + cron внутри контейнера Средняя Средняя Если Certbot запускается в контейнере

Что выбрать в зависимости от вашей ситуации

У вас обычный VPS с Ubuntu или Debian, сертификат получен через Certbot с плагином nginx/apache. Скорее всего, вам вообще ничего делать не нужно — таймер уже работает. Просто проверьте systemctl list-timers | grep certbot.

У вас CentOS или вы ставили Certbot вручную. Добавьте cron-задание, как описано выше. Это самый простой и надёжный путь.

У вас Docker. Запускайте Certbot в отдельном контейнере с примонтированным томом /etc/letsencrypt и настройте cron внутри контейнера или используйте оркестратор (в Kubernetes есть cert-manager).

У вас несколько серверов за балансировщиком. Обновляйте сертификаты на одном сервере и копируйте файлы на остальные через rsync в том же пост-хуке. Либо используйте DNS-челлендж вместо HTTP-челленджа — тогда не важно, на каком сервере проходит проверка.

Частые ошибки и как их избежать

Ошибка 1: порт 80 закрыт или занят другим сервисом. Let’s Encrypt по умолчанию использует HTTP-челлендж на порту 80. Если порт недоступен из интернета, обновление упадёт с ошибкой connection refused. Проверьте: curl -I http://your-domain.com/.well-known/acme-challenge/test с внешнего сервера.

Ошибка 2: забыли перезагрузить веб-сервер после обновления. Сертификат обновился на диске, но Nginx/Apache продолжает раздавать старый. Всегда добавляйте --post-hook с командой reload.

Ошибка 3: DNS указывает на другой сервер. Если вы перенесли сайт на новый хостинг, но DNS ещё не обновился или указывает на старый IP — обновление не сработает. Проверьте A-запись домена.

Ошибка 4: лимит запросов Let’s Encrypt. Let’s Encrypt ограничивает количество запросов: 5 дубликатов сертификата в неделю, 50 сертификатов на домен в неделю. Если часто запускаете certbot certbot с одними и теми же доменами — можете упереться в лимит. Используйте --dry-run для тестов, а не реальные запросы.

Ошибка 5: права доступа к файлам сертификатов. Файлы в /etc/letsencrypt принадлежат root. Если веб-сервер работает от другого пользователя, убедитесь, что он может читать эти файлы. Обычно это не проблема, но при нестандартных настройках может быть.

Практические рекомендации

  • Не обновляйте сертификат чаще, чем нужно. Certbot сам проверяет, осталось ли меньше 30 дней. Запуск каждый день — нормально, он просто ничего не сделает, если обновлять нечего.
  • Настройте уведомления по email. Certbot может присылать уведомления при ошибках. Добавьте флаг --email your@email.com при получении сертификата.
  • Логируйте. Всегда перенаправляйте вывод cron в файл. Через три месяца скажете себе спасибо, когда нужно будет понять, почему сертификат не обновился.
  • Проверяйте раз в месяц. Добавьте себе в календарь напоминание проверить sudo certbot certificates. Это занимает 10 секунд, но спасает от внезапного падения сайта.
  • Имейте запасной план. Если Let’s Encrypt недоступен (что бывает крайне редко, но бывает), ваш сайт всё равно должен работать. Убедитесь, что вы понимаете, как вручную продлить сертификат.

Как проверить, что всё работает прямо сейчас

Выполните эту команду и посмотрите на дату истечения:

sudo certbot certificates

Затем проверьте сайт через браузер или командой:

echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Вы увидите даты notBefore и notAfter. Если notAfter меньше чем через 30 дней — что-то пошло не так с автообновлением.

Итог

Автоматическое обновление сертификатов Let’s Encrypt — это буквально одна строка в cron или уже работающий systemd-таймер. Вот что нужно сделать:

  1. Убедиться, что Certbot установлен и сертификат получен
  2. Протестировать обновление через sudo certbot renew --dry-run
  3. Проверить, что работает certbot.timer или добавить cron-задание
  4. Не забыть про --post-hook с перезагрузкой веб-сервера
  5. Настроить логирование и проверить раз в месяц, что всё в порядке

После этих шагов ваш сайт будет автоматически продлевать HTTPS-сертификаты, и вы сможете не думать об этом годами. Если что-то пойдёт не так — вы увидите это в логах до того, как браузеры начнут пугать посетителей красным замком.

Dfncfg.ru