certbot в systemd: почему не обновляются сертификаты
Обновление сертификатов в systemd делает таймер certbot.timer, а не служба. Типичная беда не в том, что что-то падает, а в том, что сбой никто не замечает: сертификат истекает через 90 дней, и проблему обнаруживают по ошибке в браузере.
О службе
Пакет certbot ставит таймер, который дважды в сутки запускает попытку обновления. Сама попытка почти всегда завершается успешно и ничего не делает: срок ещё не подошёл. Поэтому важно смотреть не последний запуск, а результат последнего реального обновления.
Проверка владения доменом требует либо доступного порта 80 (способ http-01), либо правки записей DNS. Если порт 80 занят или перекрыт, обновление не проходит. При работающем веб-сервере используют способ через каталог в корне сайта: он не требует остановки сервера.
После обновления сертификат нужно применить: веб-сервер держит старый в памяти. Для этого в certbot есть перехватчики (--deploy-hook), которые перезагружают службу. Без них сертификат обновлён на диске, а браузеры видят прежний до перезапуска.
Как устроена
| Что в автозапуске | certbot.timer, а не служба; проверять надо его состояние |
|---|---|
| Проверка обновления | certbot renew --dry-run — полный прогон без выпуска |
| Срок сертификата | 90 дней, обновление начинается за 30 дней до истечения |
| Применение сертификата | перехватчик --deploy-hook с перезагрузкой веб-сервера |
| Частая поломка | занятый или закрытый порт 80 при способе проверки http-01 |
Частые ошибки
9 записей базы отмечены за этой службой.
Таймеры, сокеты, монтирование
- Таймер срабатывает, но задача падает незаметноТаймер работает исправно, а задача каждый раз завершается ошибкой, и об этом никто не узнаёт. Как настроить оповещение через OnFailure.
- Таймер не работает после перезагрузкиТаймер работал, пока его запускали вручную, но после перезагрузки не активен: не выполнено включение или нет WantedBy=timers.target.
Сообщения журнала
- Address already in use при запуске службыПорт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Connection refused в журнале службыСоединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- certificate verify failed в журнале службыПроверка сертификата не прошла: истёк срок, неполная цепочка, неверное имя, нет доверенных корневых сертификатов.
- Служба не читает закрытый ключ TLSПрава на закрытый ключ: как дать доступ службе, не открывая ключ всем. Группы и каталоги сертификатов.
Коды выхода
- status=1/FAILURE в systemdКод 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
Ошибки служб
- certbot: проверка владения доменом не проходитОбновление сертификата не удаётся: занят порт 80, недоступен каталог проверки, перехвачен редиректом.
- nginx: ошибки сертификата при запуске (SSL_CTX_use_PrivateKey)nginx не запускается из-за сертификата: не совпадает ключ, неполная цепочка, файл повреждён, нет прав на чтение ключа.
Коды выхода этой службы
Числа в status=N ниже 200 назначает сама программа, 200 и выше — systemd, когда не смог подготовить запуск.
| status | Что означает у этой службы | Куда смотреть |
|---|---|---|
1/FAILURE |
проверка владения доменом не прошла или недоступен сервис выдачи сертификатов. | разбор |
Диагностика
Включён ли таймер и когда была последняя попытка.
systemctl list-timers certbot.timer --no-pagerПолная проверка обновления без расхода лимитов выдачи.
sudo certbot renew --dry-runСписок сертификатов с датами истечения: главный показатель.
sudo certbot certificatesИстория попыток за месяц: видно, когда обновление перестало проходить.
journalctl -u certbot --since "30 days ago" --no-pager | grep -iE "error|fail|renew" | tail -20Параметры unit, которые тут важны
- OnCalendar=расписание попыток обновления
- Persistent=догон пропущенной попытки после включения машины
- RandomizedDelaySec=разброс по времени: без него все серверы стучатся одновременно
Частые вопросы
Сертификат обновился, а сайт отдаёт старый. Почему?
Веб-сервер держит сертификат в памяти. Нужен перехватчик после обновления, который выполняет systemctl reload для вашего сервера.
Источники
- Документация certbot
- systemd.timer(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)