← Назад в блогРуководства

Истёк SSL-сертификат: что делать и как это предотвратить

Истёк срок действия SSL-сертификата? Как убедиться в этом через openssl, продлить и установить сертификат с цепочкой, перезагрузить сервер и автоматизировать.

Опубликовано: · 6 мин чтения

Истёкший сертификат выводит сайт из строя не хуже упавшего сервера. Браузеры показывают предупреждение на всю страницу (NET::ERR_CERT_DATE_INVALID в Chrome, SEC_ERROR_EXPIRED_CERTIFICATE в Firefox), а если сайт использует HSTS, нет даже ссылки «всё равно перейти». API-клиенты, мобильные приложения, вебхуки и платёжные уведомления просто перестают работать. Ниже о том, что делать в первые полчаса и как добиться, чтобы это не повторилось.

Шаг 1. Убедитесь, в чём именно проблема

Не всякая ошибка с датой означает, что на вашем сервере истёк сертификат. Проверяйте с машины, часам которой доверяете:

$ openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
    | openssl x509 -noout -subject -issuer -dates
subject=CN = example.com
issuer=C = XX, O = Example CA, CN = Example CA R3
notBefore=Jun 20 08:00:00 2026 GMT
notAfter=Sep 18 08:00:00 2026 GMT

Если notAfter в прошлом, диагноз подтверждён. Что выглядит похоже, но является другим:

  • Неправильные часы у клиента. Ноутбук с севшей батарейкой, уверенный, что на дворе 2019 год, отвергает любой сертификат. Если на ошибку жалуется один-единственный посетитель, сначала спросите про часы.
  • Истёкший промежуточный сертификат в цепочке, которую отдаёт сервер, при том что конечный в порядке.
  • Старый сертификат только на одном из нескольких серверов. За балансировщиком или CDN проверяйте каждый узел, а исходный сервер (origin) отдельно от пограничного.
  • Другой сервис на том же имени. Порт 443 обновили, а у почты (:465, :993, :587 со STARTTLS) остался старый файл:
$ openssl s_client -connect mail.example.com:587 -starttls smtp </dev/null 2>/dev/null \
    | openssl x509 -noout -enddate

Параметр -servername важен: без SNI многие серверы отдают сертификат по умолчанию, а вовсе не тот, который видят браузеры.

Шаг 2. Продлите сертификат: зависит от того, откуда он взялся

ACME (Let's Encrypt и аналоги)

Сертификат должен был продлиться сам; выясните, почему этого не произошло.

$ sudo certbot certificates          # что известно certbot и когда истекает каждый
$ sudo certbot renew --dry-run       # пробный прогон продления
$ sudo certbot renew                 # продлить всё, чему пришёл срок
$ systemctl list-timers | grep -i certbot

Обычные причины: после переезда сервера пропал таймер или задание cron; порт 80 закрыт или перенаправляется так, что ломается проверка HTTP-01; токен DNS API для DNS-01 был перевыпущен; запись AAAA указывает на машину, которая на проверку не отвечает; строгая CAA-запись не включает нужный УЦ; либо домен теперь вообще указывает на другой сервер.

Сертификат от коммерческого УЦ

  1. Сгенерируйте новый ключ и CSR. Не используйте старый ключ повторно просто по привычке.
$ openssl req -new -newkey rsa:2048 -nodes \
    -keyout example.com.key -out example.com.csr \
    -subj "/CN=example.com" \
    -addext "subjectAltName=DNS:example.com,DNS:www.example.com"
  1. Отправьте CSR, пройдите проверку домена (по почте, DNS-записью или файлом по HTTP), скачайте сертификат и цепочку промежуточных сертификатов.
  2. Перечислите в поле SAN все нужные имена хостов. example.com не покрывает www.example.com, а wildcard *.example.com не покрывает ни сам домен без поддомена, ни a.b.example.com.

Сертификатом управляет хостинг, CDN или балансировщик

Загляните в панель провайдера. Управляемые сертификаты не продлеваются, как правило, по одной причине: домен перестал проходить проверку. Изменили DNS-запись, которая указывала на провайдера, удалили CNAME, нужный для валидации, или CAA-запись блокирует УЦ провайдера.

Шаг 3. Установите сертификат с полной цепочкой

Сервер должен отдавать конечный сертификат, а за ним промежуточный (или несколько). Корневой не отправляется. У certbot это файл fullchain.pem:

# nginx
ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Отсутствующий промежуточный сертификат коварен: настольные браузеры часто скрывают проблему, потому что сами загружают или кэшируют промежуточные сертификаты, а curl, приложения на Android и другие серверы падают с ошибкой. Проверяйте строгим клиентом:

$ curl -sSI https://example.com >/dev/null && echo chain ok

Убедитесь, что сертификат и ключ соответствуют друг другу:

$ openssl x509 -noout -pubkey -in fullchain.pem | openssl sha256
$ openssl pkey -pubout -in privkey.pem | openssl sha256

Оба хеша должны совпасть.

Шаг 4. Перезагрузите сервис

Самая частая причина жалобы «я продлил, а он всё ещё истёкший»: веб-сервер по-прежнему держит в памяти старый сертификат.

$ sudo nginx -t && sudo systemctl reload nginx
$ sudo apachectl configtest && sudo systemctl reload apache2

Для ACME-клиентов сделайте перезагрузку частью продления, например certbot renew --deploy-hook "systemctl reload nginx". То же самое относится к Postfix, Dovecot, HAProxy и всему остальному, что читает этот файл.

Шаг 5. Проверьте снаружи

Повторите команду openssl s_client из шага 1 и посмотрите на новое значение notAfter. Затем проверьте:

  • и example.com, и www.example.com, и все прочие используемые имена;
  • IPv4 и IPv6 по отдельности (openssl s_client -4 / -6), если публикуете оба;
  • каждый узел за балансировщиком;
  • почтовые и прочие порты с TLS.

Браузер может какое-то время держать открытое соединение; прежде чем решить, что ничего не получилось, проверьте в новом приватном окне.

Почему это повторяется: сроки действия сокращаются

С сентября 2020 года срок действия публично доверенных SSL/TLS-сертификатов ограничен 398 днями, а Let's Encrypt с самого начала выпускает сертификаты на 90 дней. В апреле 2025 года CA/Browser Forum принял график дальнейшего сокращения максимума: 200 дней с 15 марта 2026 года, 100 дней с 15 марта 2027 года и 47 дней с 15 марта 2029 года. Сокращается и период, в течение которого можно повторно использовать уже пройденную проверку домена.

На практике это значит вот что: напоминание в календаре и ручное продление раз в год — процесс, дни которого сочтены. Сертификаты на 47 дней никто не продлевает руками. Учтите также, что в 2025 году Let's Encrypt перестал рассылать письма с предупреждениями об истечении срока, так что и этой страховки больше нет.

Чек-лист профилактики

  • Автоматизируйте выпуск и продление через ACME везде, где платформа это позволяет. Многие коммерческие УЦ тоже поддерживают ACME.
  • Продлевайте заранее. По умолчанию ACME-клиенты продлевают сертификат, когда остаётся примерно треть срока, так что на обнаружение сбоя есть недели.
  • Следите снаружи, независимо от механизма продления. Проверка должна смотреть на сертификат, который сервер предъявляет, а не на файл на диске. Оповещения — за 21, 14 и 7 дней.
  • Составьте перечень всех точек: поддомены, почтовые серверы, VPN-шлюзы, внутренние инструменты, исходный сервер за CDN. Истекает тот, о котором забыли.
  • Проверьте deploy hook. Продление без перезагрузки — это авария, которая всего лишь отложена.
  • Поддерживайте валидацию в рабочем состоянии: порт 80 доступен для HTTP-01, учётные данные DNS API действительны для DNS-01, в CAA-записях перечислены ваши УЦ.
  • Отправляйте оповещения на общий адрес команды, а не в ящик одного человека.

Частые ошибки

  • Продлить сертификат и не перезагрузить сервер.
  • Установить конечный сертификат без промежуточного.
  • Забыть в списке SAN www или сам домен без www.
  • Продлить сертификат на стороне CDN, пока сертификат исходного сервера тихо истекает; в зависимости от режима CDN это приводит не к предупреждению в браузере, а к ошибкам 5xx от пограничного узла.
  • Советовать пользователям «просто нажать и пройти дальше». Это воспитывает ровно ту привычку, на которую рассчитывают злоумышленники.
  • «Временно» отключить проверку сертификата в API-клиенте.
  • Искать проблему в сертификате, когда настоящая причина в изменении DNS, которое отправило пользователей на другой сервер. Если предъявленный сертификат принадлежит кому-то другому, сначала проверьте, куда указывает имя.

Проверьте в OrbitProbe

Проверка SSL-сертификата в OrbitProbe подключается к вашему имени хоста и сообщает о сертификате, который сервер предъявляет на самом деле: издатель, даты действия и число оставшихся дней, покрываемые имена хостов, согласованная версия протокола TLS, доверенная ли цепочка и есть ли HSTS. Запускайте её после каждого продления: один раз для домена без www и один раз для www. Если в том же инциденте замешана почта, сторона TLS и DNS в доставке писем разобрана в чек-листе DNS для писем, попадающих в спам. А перед тем как менять записи, на которые опирается валидация, вспомните, что такое TTL в DNS.