Истёк 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-запись не включает нужный УЦ; либо домен теперь вообще указывает на другой сервер.
Сертификат от коммерческого УЦ
- Сгенерируйте новый ключ и 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"
- Отправьте CSR, пройдите проверку домена (по почте, DNS-записью или файлом по HTTP), скачайте сертификат и цепочку промежуточных сертификатов.
- Перечислите в поле 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.