Хостинг

Как продлить сертификат Let’s Encrypt и найти ошибку Certbot

Проверяем таймер Certbot, запускаем пробное продление и сверяем сертификат Nginx с тем, который видит посетитель.

Круговая стрелка вокруг щита с сертификатом рядом с сервером

При ошибке продления Let’s Encrypt начните с расписания Certbot, затем проверьте подтверждение домена и сертификат, который отдаёт веб-сервер. Таймер может срабатывать, хотя проверка домена завершается ошибкой. На диске может лежать свежий сертификат, а Nginx продолжать отдавать предыдущий.

Проверить сертификат снаружи

Подставьте свой домен. Запускайте команды с другой машины, чтобы увидеть тот же TLS, что и посетитель.

host=example.com
curl -sSI --max-time 15 "https://$host/"
openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null |
  openssl x509 -noout -dates -issuer -serial -ext subjectAltName

curl проверяет доверие и имя хоста. OpenSSL показывает даты, SAN и серийный номер предъявленного сертификата. Запишите notAfter и serial. При CDN внешний TLS может завершаться на стороне CDN. Тогда сертификаты edge и origin проверяют отдельно, учитывая доверие к цепочке на каждом звене.

Уточнить, какой Certbot работает по расписанию

command -v certbot
certbot --version
systemctl list-timers --all | grep -Ei 'certbot|letsencrypt'
sudo systemctl show certbot.service -p ExecStart -p Result -p ExecMainStatus
sudo journalctl -u certbot.service -n 60 --no-pager

Пакет Ubuntu, snap и отдельная установка могут использовать разные команды и unit-файлы. Если в выводе есть snap.certbot.renew.timer, смотрите связанный unit. Если таймера нет, проверьте настройки расписания пакета и задания cron. inactive (dead) у службы типа oneshot между запусками может быть обычным состоянием. Смотрите результат предыдущего запуска и следующий запуск таймера.

Подставьте исполняемый файл из рабочего задания. Узнайте точное Certificate Name, которое Certbot использует для выбора сертификата. Имя может оканчиваться на -0001.

sudo certbot certificates

Запустить пробное продление

Проверьте существующие pre/post hooks и способ проверки домена. В режиме standalone Certbot может освобождать порт через hook, поэтому сначала оцените влияние на обслуживаемые сайты. Для проверки выберите один сертификат.

name=example.com
sudo certbot renew --cert-name "$name" --dry-run

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

Устранить ошибку проверки домена

Для HTTP-01 запрос начинается на TCP-порту 80. Проверьте ответы A и AAAA, правила firewall, попадание в нужный vhost и путь /.well-known/acme-challenge/. Если в DNS опубликован IPv6, убедитесь, что он также обслуживает проверяемое имя. Инструкции по проверке записей есть в разборе DNS домена.

dig +short example.com A
dig +short example.com AAAA

При webroot согласуйте каталог, в который пишет Certbot, с root или alias в Nginx. Для проверки положите одноразовый файл с безобидным содержимым в .well-known/acme-challenge/ внутри этого каталога. С внешней машины откройте точный HTTP-адрес файла и сравните тело ответа. Удалите файл после проверки. Главная страница со статусом 200 не проверяет этот маршрут. Если ответом стала HTML-страница входа, проверьте, не перехватывают ли путь авторизация, приложение или CDN.

Для DNS-01 проверьте TXT на _acme-challenge у актуальных авторитетных серверов. Учитывайте делегирование и время публикации. Если раньше добавляли TXT вручную, для автоматического продления нужен поддерживаемый DNS-плагин или hook, который создаёт и убирает запись. Выдавайте ключу DNS только права, нужные для этой операции.

Сравнить файл на сервере и ответ Nginx

Если Certbot сообщил о новом сертификате, а внешний serial остался прежним, проверьте, какой файл подключён к нужному vhost. Путь возьмите из вывода certbot certificates.

sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem \
  -noout -serial -dates
sudo nginx -T 2>/dev/null | grep -E 'server_name|ssl_certificate '
sudo nginx -t && sudo systemctl reload nginx

В ssl_certificate для типовой установки Nginx используется fullchain.pem. Проверьте соответствие имени в server_name и пары с ssl_certificate_key. Если файл выбран правильно, настройте reload после успешного продления через deploy hook с проверкой конфигурации. После reload повторите внешний curl и сравните serial. При CDN сопоставьте значения для edge и origin по отдельности.

Если сертификат ещё не выпущен, начните с инструкции по первому подключению HTTPS. Повторные боевые запросы без устранения причины могут упереться в лимиты центра сертификации.

На Hostfera мы проверили этот способ сравнения: серийный номер сертификата в публичном TLS-ответе совпал с номером в файле на сервере.

Первоисточники

Нашли неточность?

Сообщите адрес статьи и фрагмент через контакты редакции.