Ошибки SSL-сертификата в браузере: причины и диагностика
Браузер может показать предупреждение о проблеме SSL по десяткам разных причин: сертификат просрочен, выпущен не для того имени, сервер отдаёт неполную цепочку, DNS ведёт на старый IP, а на VPS отвечает соседний виртуальный хост. Внешне всё выглядит одинаково — вместо сайта пользователь получает страницу «Подключение не защищено» или код вида NET::ERR_CERT_....
Поэтому начинать с перевыпуска сертификата — плохая стратегия. Если браузер попадает на другой сервер или Cloudflare показывает свой edge-сертификат, новый файл на VPS вообще ничего не изменит. Сначала нужно выяснить две вещи: к какому узлу подключился клиент и какой сертификат он фактически получил через порт 443.
Диагностику удобнее вести сверху вниз: браузер, DNS, CDN или reverse proxy, IP:443, TLS/SNI, виртуальный хост, сертификат и его цепочка, затем конфигурация Nginx или Apache. Такой порядок быстро отсеивает рабочие уровни и не заставляет менять несколько настроек одновременно.
Команды ниже рассчитаны прежде всего на Linux, VPS и серверы с Nginx или Apache. Владельцу сайта без SSH-доступа всё равно пригодится первая половина проверок: код браузера, сведения о сертификате, DNS и сравнение результата с другого устройства или сети.
Что означает конкретная ошибка SSL в браузере и с чего начинать проверку
Точный код ошибки уже заметно сужает поиск. Фраза «SSL не работает» почти бесполезна для диагностики, а NET::ERR_CERT_DATE_INVALID или NET::ERR_CERT_COMMON_NAME_INVALID сразу указывает, какой параметр проверять первым.
Chrome, Edge и другие Chromium-браузеры используют одни обозначения, Firefox — другие. Формулировки могут отличаться, поэтому важнее определить класс проблемы: срок действия, имя домена, доверие к центру сертификации или сам TLS-handshake.
| Ошибка | Что проверять первым | Инструмент |
|---|---|---|
NET::ERR_CERT_DATE_INVALID |
Срок сертификата и часы на устройстве | Браузер, OpenSSL |
NET::ERR_CERT_COMMON_NAME_INVALID |
Имя сайта и SAN сертификата | Браузер, OpenSSL |
NET::ERR_CERT_AUTHORITY_INVALID |
Цепочка доверия и тип сертификата | OpenSSL |
SEC_ERROR_UNKNOWN_ISSUER |
Intermediate CA и fullchain | OpenSSL |
MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT |
Не используется ли self-signed сертификат | Браузер, OpenSSL |
ERR_SSL_PROTOCOL_ERROR |
TLS-handshake и сервис на порту 443 | OpenSSL, ss, логи веб-сервера |
Дальнейшая ветка обычно определяется сразу. Ошибка DATE ведёт к датам сертификата и системным часам. NAME — к SAN, SNI и DNS. AUTHORITY — к цепочке и доверенному CA. PROTOCOL — к порту 443, TLS и конфигурации сервиса.
Перед изменениями откройте сведения о сертификате в браузере и запишите домен, издателя, даты действия и код ошибки. Если проблема проявляется только у одного пользователя, полезнее получить скриншот страницы предупреждения и сведений о сертификате, чем сообщение «у меня красный замок».
Сначала снимаем симптом, потом меняем конфигурацию. Один точный тест здесь полезнее пяти случайных действий.
Почему NET::ERR_CERT_DATE_INVALID появляется даже у недавно установленного сертификата
NET::ERR_CERT_DATE_INVALID означает, что браузер не принимает временной интервал действия сертификата. Сертификат может быть уже просрочен, ещё не вступить в действие либо время на компьютере пользователя сильно отличается от реального.
Как проверить Not Before и Not After
У сертификата есть два временных ограничения: notBefore и notAfter. Первое показывает, с какого момента сертификат действителен, второе — когда его действие заканчивается. Проверить сертификат, который сервер отдаёт сейчас, можно так:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates
Типичный вывод содержит две строки:
notBefore=Sep 1 00:00:00 2026 GMT
notAfter=Nov 30 23:59:59 2026 GMT
Если notAfter уже в прошлом, причина найдена. Если даты нормальные, проверьте часы устройства, на котором появляется ошибка. Именно клиент сравнивает текущее время с периодом валидности сертификата.
Почему после продления браузер может видеть старый сертификат
Файл на сервере мог успешно обновиться, но это ещё не доказывает, что веб-сервер его загрузил. Например, автоматическое продление Let's Encrypt записало новый fullchain.pem, а последующий reload Nginx завершился ошибкой. Рабочие процессы продолжают обслуживать соединения со старой конфигурацией.
Обычно путаница начинается именно здесь: в панели уже виден новый сертификат, а через 443 всё ещё приходит старый serial. Сертификат на диске и сертификат в сокете — не всегда одно и то же.
Нужно ли проверять время на VPS
Для проверки сертификата браузером критичнее часы клиентского устройства. Время VPS само по себе не изменяет notBefore и notAfter, но сильный рассинхрон способен мешать автоматическому выпуску, обновлению сертификатов и другим операциям вокруг TLS.
date
timedatectl
Если срок сертификата нормальный, часы клиента правильные, а браузер всё равно показывает DATE_INVALID, проверьте сертификат непосредственно на порту 443. Там нередко и находится старый экземпляр.
Почему браузер пишет, что SSL-сертификат выпущен не для этого домена
NET::ERR_CERT_COMMON_NAME_INVALID обычно означает, что имя в адресной строке не входит в список имён сертификата. Второй сценарий — сертификат сам по себе правильный, но запрос попал в чужой виртуальный хост и сервер отдал сертификат соседнего сайта.
example.com и www.example.com проверяются отдельно
Сертификат для example.com не обязан автоматически покрывать www.example.com. Чтобы оба варианта работали, оба имени должны присутствовать в Subject Alternative Name, если их не покрывает подходящий wildcard.
Посмотреть SAN можно в браузере либо через OpenSSL:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
openssl x509 -noout -ext subjectAltName
Если установленная версия OpenSSL не поддерживает вывод отдельного extension, используйте полный просмотр:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
openssl x509 -noout -text
В полном выводе нужен блок X509v3 Subject Alternative Name. Сравнивать нужно именно имена SAN с hostname в адресной строке.
Как работает wildcard-сертификат
| Имя | Покрывает ли *.example.com |
|---|---|
www.example.com |
Да |
shop.example.com |
Да |
example.com |
Нет |
a.b.example.com |
Нет |
Wildcard закрывает один уровень поддоменов. Если нужен и корневой домен, его добавляют в сертификат отдельным SAN.
Что происходит при открытии сайта по IP
Если в сертификате указано example.com, открытие https://203.0.113.10/ приведёт к несовпадению имени. Для корректного подключения непосредственно по IP сам IP должен присутствовать в сертификате как соответствующий SAN. Для обычного сайта такой сценарий чаще всего не нужен.
Если SAN содержит правильное имя, а браузер всё равно жалуется на домен, посмотрите subject фактически полученного сертификата. Если там другой сайт, копать выпуск сертификата уже нет смысла: проверяйте DNS, SNI, CDN и virtual host.
Как проверить, какой SSL-сертификат сервер реально отдаёт пользователю
Самая полезная проверка при спорной SSL-ошибке — посмотреть сертификат непосредственно на порту 443. Панель управления показывает настройку. OpenSSL показывает, что реально получил TLS-клиент.
openssl s_client -connect example.com:443 -servername example.com
Параметр -servername передаёт имя сайта через SNI. Для сервера, где на одном IP размещено несколько HTTPS-сайтов, без этого параметра результат может быть совсем другим.
Чтобы получить только основные поля сертификата:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
openssl x509 -noout -subject -issuer -dates -serial
- subject — какому сертификату вы подключились;
- issuer — кто его выпустил;
- notBefore / notAfter — период действия;
- serial — удобный идентификатор для сравнения старого и нового сертификата;
- SAN — какие имена покрывает сертификат.
HTTPS-запрос целиком удобно проверить через curl:
curl -Iv https://example.com/
curl покажет IP подключения, TLS-сессию и HTTP-ответ. Если OpenSSL показывает ожидаемый сертификат, а curl подключается к другому IP, это уже повод вернуться к DNS, IPv6 или прокси.
Как точно сравнить сертификат на диске и сертификат через сеть
Когда даты и subject совпадают, но нужно убедиться, что это один и тот же сертификат, сравните SHA-256 fingerprint.
Для файла:
openssl x509 -in cert.pem -noout -fingerprint -sha256
Для сертификата на порту 443:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
openssl x509 -noout -fingerprint -sha256
Одинаковый fingerprint означает, что через сеть приходит именно тот сертификат, который вы проверили на диске. Разные значения — сервер, proxy или CDN отдаёт другой экземпляр.
| Команда | Что помогает проверить |
|---|---|
openssl s_client |
TLS-handshake, сертификат, SNI, цепочку |
curl -Iv |
IP подключения, TLS и HTTP-ответ |
curl --resolve |
Конкретный сервер в обход DNS |
dig A |
IPv4-адрес домена |
dig AAAA |
IPv6-адрес домена |
nginx -t |
Синтаксис и загрузку конфигурации Nginx |
apachectl configtest |
Конфигурацию Apache |
Полезная модель диагностики: файл сертификата на диске, сертификат в конфигурации веб-сервера и сертификат, полученный браузером, — три разные точки проверки. Совпасть должны все три.
Почему без SNI сервер показывает SSL-сертификат другого сайта
На одном IP может быть десять HTTPS-сайтов. Запустили openssl s_client по IP без имени — и получили сертификат соседнего домена. Паниковать рано: такой тест сам мог попасть в default vhost.
При TLS-соединении клиент передаёт hostname через Server Name Indication — SNI. Современные браузеры делают это автоматически, а ручная проверка без -servername может показать сертификат виртуального хоста по умолчанию.
Сравните подключение с SNI и без него
openssl s_client -connect 203.0.113.10:443
Теперь тот же IP, но с нужным hostname:
openssl s_client -connect 203.0.113.10:443 -servername example.com
Если во втором случае появляется правильный сертификат, а в первом — чужой, сам HTTPS сайта может быть настроен нормально. Первый тест просто не передал SNI.
Если и с -servername example.com приходит сертификат соседнего сайта, проверяйте virtual host.
Что смотреть в Nginx
nginx -T
Найдите блок, который слушает 443 и содержит нужный server_name. В нём же проверьте ssl_certificate и ssl_certificate_key. Если одно имя описано в нескольких конфигурациях или домен попал в неожиданный default_server, результат может отличаться от того, что показывает панель управления.
Что смотреть в Apache
apachectl -S
Команда показывает виртуальные хосты и помогает увидеть, какой VirtualHost обслуживает имя и порт. На Debian/Ubuntu вместо apachectl также используется apache2ctl.
После правки снова проверяйте соединение с правильным -servername. Для нужного hostname должен приходить его сертификат. Если так и есть, ветку SNI можно закрывать.
Как DNS может привести к правильному домену, но неправильному SSL-сертификату
SSL может быть безупречно настроен на нужном VPS, но пользователь всё равно увидит старый или чужой сертификат, если DNS отправляет его на другой узел. Сертификат в таком случае вообще не виноват.
Проверьте A и AAAA отдельно
dig example.com A
dig example.com AAAA
dig www.example.com A
dig www.example.com AAAA
Если A уже указывает на новый VPS, а забытая AAAA всё ещё ведёт на старый сервер, клиенты с рабочим IPv6 могут получать совершенно другой сайт и сертификат. На устройствах без IPv6 ошибка при этом не воспроизводится.
Ситуация после миграции выглядит знакомо: A уже исправили, сайт у администратора открывается, а часть пользователей продолжает жаловаться. AAAA в таком случае стоит проверить раньше кеша браузера.
Проверьте HTTPS отдельно по IPv4 и IPv6
Одного dig недостаточно, если нужно увидеть реальное HTTPS-подключение по каждому стеку.
curl -4 -Iv https://example.com/
curl -6 -Iv https://example.com/
Если IPv4 проходит нормально, а IPv6 получает другой сертификат или вообще не устанавливает TLS, проблема уже локализована. Проверяйте AAAA, IPv6-адрес сервера, firewall и HTTPS-конфигурацию на этом адресе.
Корневой домен и www тоже могут расходиться
example.com и www.example.com — отдельные DNS-имена. Один адрес может идти через Cloudflare, второй напрямую на VPS. Один может иметь свежий сертификат, второй — старый.
curl -Iv https://example.com/
curl -Iv https://www.example.com/
В начале соединения curl показывает адрес назначения. Если он не совпадает с ожидаемой инфраструктурой, разбираться с Nginx на нужном VPS пока рано.
| Симптом | Куда смотреть | Почему |
|---|---|---|
| Часть пользователей видит старый сертификат | A и AAAA | IPv4 и IPv6 могут вести на разные серверы |
| example.com работает, www — нет | DNS и SAN для обоих имён | Это разные hostname |
| На телефоне ошибка есть, на ПК нет | Сеть, IPv6, DNS | Маршрут может отличаться |
| Сертификат принадлежит другому серверу | IP назначения | Запрос приходит не туда |
После изменения DNS учитывайте TTL и кеш резолверов, но не списывайте любое несоответствие на «DNS ещё обновляется». dig, curl -4, curl -6 и проверка конкретного IP позволяют увидеть состояние маршрутов прямо сейчас.
Почему после переноса сайта или смены сервера продолжает открываться старый SSL-сертификат
После миграции типичный симптом выглядит так: новый VPS уже обслуживает сайт, сертификат на нём свежий, но периодически браузер показывает прежний сертификат. В этой ситуации почти всегда нужно искать второй узел, который всё ещё участвует в обработке запросов.
Им может оказаться старый IP в DNS, забытая AAAA-запись, CDN, балансировщик, второй backend или сам новый сервер, который не перечитал обновлённый сертификат.
Проверяйте серверы в обход DNS
Одна из самых полезных команд при миграции — curl --resolve:
curl --resolve example.com:443:203.0.113.10 https://example.com/ -Iv
Она заставляет curl подключиться к указанному IP, но сохраняет hostname example.com для HTTPS и SNI. Так можно проверить конкретный сервер, не меняя публичный DNS и локальный hosts.
Например, отдельно проверьте старый и новый адрес:
curl --resolve example.com:443:198.51.100.20 https://example.com/ -Iv
curl --resolve example.com:443:203.0.113.10 https://example.com/ -Iv
Если старый IP отдаёт прежний сертификат, а новый — свежий, нужно выяснить, почему часть запросов всё ещё приходит на старый узел. Если оба IP отдают старый сертификат, проблема уже не только в DNS.
После обновления файлов проверьте reload
Для Nginx:
nginx -t
systemctl reload nginx
Для Apache:
apachectl configtest
systemctl reload apache2
Имя сервиса Apache зависит от дистрибутива: встречаются apache2 и httpd. Не копируйте команду перезапуска вслепую — сначала посмотрите фактическое имя службы.
После reload повторите внешний openssl s_client. Если serial и даты изменились, новый сертификат действительно вышел в сеть. Именно этот тест отделяет «файл заменили» от «пользователи уже получают новый сертификат».
Почему SSL ломается при использовании Cloudflare, CDN или reverse proxy
В браузере сертификат может быть совершенно нормальным, а Cloudflare при этом не устанавливает HTTPS до VPS. В такой ситуации смотреть только сертификат в Chrome почти бесполезно: браузер и origin участвуют в двух разных TLS-соединениях.
Браузер
|
| HTTPS
v
Cloudflare / CDN
|
| HTTPS или HTTP — зависит от режима
v
Origin VPS
Публичный сертификат относится к участку браузер → CDN. Сертификат на VPS — к участку CDN → origin. Ошибка на одном участке не доказывает проблему на другом.
Flexible, Full и Full (strict): где именно проверяется сертификат
| Режим | Браузер → Cloudflare | Cloudflare → Origin | Что происходит с сертификатом origin |
|---|---|---|---|
| Flexible | HTTPS | HTTP | Для соединения с origin SSL-сертификат не используется |
| Full | HTTPS | HTTPS | TLS используется, но строгая проверка валидности origin-сертификата не выполняется |
| Full (strict) | HTTPS | HTTPS | Origin должен предъявить подходящий, непросроченный и доверенный для этого режима сертификат |
Flexible иногда маскирует отсутствие рабочего HTTPS на VPS: посетитель видит HTTPS до Cloudflare, но Cloudflare идёт к сайту по HTTP. Это также может приводить к циклам редиректов, если приложение на origin постоянно пытается вернуть клиента на HTTPS.
Full уже требует TLS на origin, но сам факт установления HTTPS ещё не означает строгую проверку сертификата. В Full (strict) проблемы с именем, сроком или доверием origin-сертификата становятся критичными.
Что означают Cloudflare 525 и 526
Коды 525 и 526 относятся именно к Cloudflare и помогают разделить два типа проблем.
- 525 SSL handshake failed — Cloudflare не смог завершить TLS-handshake с origin. Проверяйте порт 443, TLS-конфигурацию, SNI, поддерживаемые параметры соединения и состояние веб-сервера.
- 526 Invalid SSL certificate — Cloudflare дошёл до проверки origin-сертификата, но не смог принять его как валидный в строгом режиме. Проверяйте срок, hostname, chain и тип сертификата.
Код 525 не означает автоматически «сертификат просрочен», а 526 не означает, что нужно менять edge-сертификат Cloudflare. Ошибка находится на участке CDN → origin.
Проверьте origin напрямую
Публичное соединение:
curl -Iv https://example.com/
Теперь тот же hostname непосредственно на IP origin:
curl --resolve example.com:443:203.0.113.10 https://example.com/ -Iv
Если через Cloudflare сайт работает, а прямой запрос к origin падает на TLS, edge можно временно вычеркнуть из списка подозреваемых. Если origin напрямую работает, а Cloudflare получает 525 или 526, сравнивайте требования режима Cloudflare с реальной TLS-конфигурацией VPS.
Отдельно смотрите hostname. Origin может отдавать валидный сертификат, но для другого домена. Без правильного SNI такая конфигурация легко проходит незамеченной при тесте только по IP.
Reverse proxy тоже может сломать TLS на внутреннем участке
Ещё один вариант — внешний Nginx принимает HTTPS нормально, но к backend обращается не тем протоколом. Например, upstream слушает обычный HTTP, а proxy пытается установить с ним HTTPS. Или наоборот.
Смысл такой конфигурации:
proxy_pass http://backend:8080;
и такой:
proxy_pass https://backend:8443;
совершенно разный. Если backend не поддерживает тот протокол, который указан в proxy, клиентская SSL-ошибка может быть лишь верхушкой проблемы. Сначала определите, на каком именно участке не собирается соединение.
Почему ERR_SSL_PROTOCOL_ERROR не всегда означает проблему сертификата
ERR_SSL_PROTOCOL_ERROR может появиться ещё до того, как браузер получил сертификат и начал проверять его срок или имя. Если TLS-handshake до peer certificate вообще не дошёл, перевыпуск SSL пока не следующий шаг.
Проверьте, есть ли слушающий процесс на 443
ss -lntp | grep ':443'
Если вывода нет, на сервере никто не слушает TCP/443. Если порт занят неожиданным процессом, сначала выясните, должен ли именно он обслуживать HTTPS.
Посмотрите, начинается ли TLS-handshake
openssl s_client -connect example.com:443 -servername example.com
При рабочем TLS OpenSSL показывает сертификат и параметры сессии. Если соединение ломается раньше, текст ошибки помогает определить следующий тест, хотя сам по себе не всегда даёт стопроцентный диагноз.
Как читать типовые ошибки openssl s_client
| Вывод или симптом | Что подозревать | Следующая проверка |
|---|---|---|
wrong version number |
На ожидаемом TLS-участке может отвечать plain HTTP или proxy/backend использует неправильный протокол | Проверить listener и схему proxy |
Connection refused |
Порт не слушается либо соединение отклоняется до приложения | ss -lntp, firewall, состояние сервиса |
no peer certificate available |
Handshake завершился до получения сертификата | Логи веб-сервера и TLS-конфигурация |
handshake failure |
Общая ошибка согласования TLS, SNI или серверной конфигурации | Повторить тест с SNI, проверить логи и настройки TLS |
unexpected eof |
Удалённая сторона оборвала соединение раньше ожидаемого | Проверить proxy, backend и журнал сервиса |
wrong version number особенно полезен как подсказка, когда HTTPS случайно направили на обычный HTTP-порт. Похожая проблема возникает, если reverse proxy пытается говорить с upstream по HTTPS, хотя backend принимает только HTTP.
Проверьте конфигурацию и журнал
Для Nginx:
nginx -t
systemctl status nginx
journalctl -u nginx --since "15 minutes ago"
Для Apache:
apachectl configtest
systemctl status apache2
journalctl -u apache2 --since "15 minutes ago"
Формулировки зависят от версии и дистрибутива, но в журнале можно встретить сообщения о невозможности загрузить сертификат, ошибке чтения файла, несовпадающем ключе или занятом порту. Например:
cannot load certificate
BIO_new_file() failed
key values mismatch
bind() to 0.0.0.0:443 failed
Это не шаблон, который обязан появиться именно в таком виде. Смотрите сообщения рядом с моментом старта или reload сервиса и путь к файлу, на который указывает ошибка.
Если OpenSSL получает peer certificate и handshake завершается, а браузер продолжает показывать ERR_SSL_PROTOCOL_ERROR, проверьте промежуточные proxy, другую сеть и клиентское устройство. Если s_client тоже не устанавливает TLS, проблема уже воспроизводится вне браузера.
Какие ошибки конфигурации Nginx и Apache чаще всего ломают HTTPS
Когда DNS указывает на правильный сервер, а сертификат на диске существует, следующий уровень — конфигурация веб-сервера. Здесь чаще всего встречаются неверные пути, неправильный fullchain, несовпадающий приватный ключ и сертификат либо неуспешный reload.
Nginx: сначала configtest, потом reload
nginx -t
Успешный результат выглядит примерно так:
syntax is ok
test is successful
Только после успешной проверки:
systemctl reload nginx
Если nginx -t возвращает ошибку, reload делать бессмысленно. Исправьте строку, которую указывает Nginx, затем повторите тест.
Для анализа активной конфигурации:
nginx -T
Команда помогает увидеть случаи, когда нужный server_name описан дважды или сертификат подключается из другого файла, чем ожидалось.
Apache: проверьте конфигурацию и VirtualHost
apachectl configtest
apachectl -S
Первая команда проверяет конфигурацию, вторая показывает структуру виртуальных хостов. Если нужный домен привязан не к тому VirtualHost *:443, браузер может получить сертификат другого сайта.
Как проверить, что приватный ключ относится к этому сертификату
Проблема особенно вероятна после ручного копирования файлов между серверами. Для RSA раньше часто сравнивали modulus, но универсальнее сравнить публичные ключи.
Для сертификата:
openssl x509 -in cert.pem -pubkey -noout | \
openssl pkey -pubin -outform PEM | sha256sum
Для приватного ключа:
openssl pkey -in privkey.pem -pubout -outform PEM | sha256sum
Хеши должны совпасть. Если они разные, этот приватный ключ не соответствует сертификату.
Не выводите содержимое приватного ключа в тикет, чат или публичный лог. Для диагностики достаточно проверки соответствия и прав доступа к файлу. Команды с приватным ключом выполняйте только на доверенном сервере.
Почему файл обновился, а сайт продолжает отдавать старый сертификат
Веб-сервер читает сертификаты при загрузке конфигурации. Если новый файл появился на диске, но reload не состоялся, рабочие процессы могут продолжать использовать старый сертификат из памяти.
- проверить новые файлы;
- выполнить configtest;
- сделать reload;
- проверить внешний порт 443 через OpenSSL.
Последний пункт и подтверждает, что изменение дошло до клиента.
Почему ошибка SSL видна только на одном компьютере или только в одном браузере
Если сайт нормально открывается на нескольких независимых устройствах, а предупреждение стабильно появляется на одном ноутбуке, сервер всё равно стоит проверить извне, но основная ветка поиска уже смещается к клиенту и его сети.
| Проверка | Если ошибка остаётся | Что это подсказывает |
|---|---|---|
| Другой браузер на том же ПК | Да | Вероятнее системная или сетевая причина |
| Другой ПК в том же Wi-Fi | Да | Проверить сеть, DNS, proxy |
| Телефон в том же Wi-Fi | Да | Проблема может быть общей для сети |
| Телефон через мобильную сеть | Нет | Проверять домашнюю/офисную сеть и DNS |
| Несколько независимых устройств и сетей | Да | Вероятнее сервер, DNS или CDN |
Сравните не только ошибку, но и сам сертификат
На рабочем и проблемном устройстве откройте сведения о сертификате и сравните issuer, serial и срок действия. Если serial различается, устройства фактически получают разные сертификаты. Это уже не «особенность браузера» — нужно искать различие в DNS, IPv4/IPv6, proxy или HTTPS inspection.
Если serial одинаковый, но только один клиент считает сертификат недоверенным, проверяйте локальный trust store, системное время и ПО, которое вмешивается в HTTPS.
Сначала проверьте системное время
Неверные дата, время и часовой пояс способны превратить нормальный сертификат в «просроченный» или «ещё не действующий». Это одна из немногих локальных причин, которую можно исключить за минуту.
Антивирус и корпоративный proxy могут подменять сертификат
Некоторые средства HTTPS inspection расшифровывают соединение локально и выпускают для посещаемого сайта собственный сертификат. Браузер должен доверять локальному корневому CA такого продукта. Если доверие сломалось, пользователь увидит ошибку, хотя публичный сертификат сайта полностью исправен.
Посмотрите issuer на проблемном компьютере. Если вместо ожидаемого публичного CA там указано название антивирусного продукта, корпоративного шлюза или внутреннего центра сертификации, направление поиска меняется сразу: соединение перехватывается между браузером и сайтом.
Старое устройство может не доверять нормальной цепочке
На давно не обновлявшейся ОС или в старом браузере хранилище корневых сертификатов может отличаться от современного. В такой ситуации актуальные устройства открывают сайт нормально, а старое получает UNKNOWN_ISSUER или похожую ошибку.
Сначала убедитесь, что сервер действительно отдаёт полный chain. Если с серверной стороны всё корректно и проблема воспроизводится только на устаревшем клиенте, бесконечно перестраивать fullchain под одно устройство не стоит — проверяйте обновления ОС, браузера и доверенных CA.
DNS, IPv6 и HSTS — разные ветки
Два устройства в одной сети не обязательно идут к сайту одинаковым маршрутом. Одно использует IPv6, другое — IPv4; одно получает корпоративный DNS, другое — публичный. Здесь полезны curl -4 и curl -6, если они доступны на проблемной системе.
HSTS тоже способен влиять на поведение браузера, например принудительно отправлять запрос на HTTPS, но HSTS сам по себе не делает валидный сертификат недействительным. Не смешивайте проблему принудительного HTTPS с ошибкой доверия, имени или срока сертификата.
После сравнения устройства, сети и самого сертификата обычно остаётся одна ветка. Вот её и нужно исправлять.
Как за 10 минут определить, где именно возникает ошибка SSL
Большинство типовых SSL-проблем можно локализовать короткой последовательностью проверок. Задача не в том, чтобы выполнить все команды подряд, а в том, чтобы найти первое место, где реальный результат отличается от ожидаемого.
- Запишите точный код браузера. DATE_INVALID, COMMON_NAME_INVALID, AUTHORITY_INVALID и PROTOCOL_ERROR ведут в разные ветки диагностики.
- Откройте сертификат в браузере. Сверьте имя, issuer, serial и даты действия.
- Проверьте SAN. Убедитесь, что в сертификате есть именно тот hostname, который открыт в адресной строке.
- Получите сертификат через OpenSSL. Так вы увидите то, что сервер реально отдаёт через 443.
- Проверьте цепочку. Используйте
-showcerts, посмотритеCertificate chainи результат verify. - Проверьте A и AAAA. Все адреса должны вести в актуальную инфраструктуру.
- При странной разнице между клиентами сравните IPv4 и IPv6. Используйте
curl -4иcurl -6. - Если серверов несколько, используйте curl --resolve. Это отделяет DNS от состояния конкретного узла.
- При наличии CDN разделите edge и origin. Для Cloudflare учитывайте режим Flexible, Full или Full (strict).
- Проверьте SNI и virtual host. Особенно если сервер показывает сертификат соседнего домена.
- Если TLS не стартует, проверьте порт 443 и логи. До сертификата handshake может вообще не дойти.
- Запустите configtest Nginx или Apache. После исправления выполните reload.
- Повторите проверку извне. Не закрывайте задачу только потому, что сайт открылся в одном браузере.
Минимальный набор команд
openssl s_client -connect example.com:443 -servername example.com
openssl s_client -connect example.com:443 \
-servername example.com -showcerts
curl -Iv https://example.com/
curl -4 -Iv https://example.com/
curl -6 -Iv https://example.com/
dig example.com A
dig example.com AAAA
curl --resolve example.com:443:203.0.113.10 \
https://example.com/ -Iv
ss -lntp | grep ':443'
nginx -t
apachectl configtest
Как читать результаты как одну цепочку
Браузер показывает старый сертификат. dig A уже возвращает новый IP, но dig AAAA показывает старый IPv6. Причина найдена на уровне DNS. В Nginx нового VPS пока копать нечего.
Другой вариант: DNS полностью правильный, но OpenSSL с -servername получает сертификат соседнего домена. Поиск смещается к SNI и virtual host.
Третий сценарий: сервер отдаёт правильный leaf, но openssl s_client -showcerts не показывает нужный intermediate. Исправляйте fullchain.
И ещё один вариант: OpenSSL вообще не получает peer certificate. Значит, проблема находится раньше — порт 443, TLS-listener, reverse proxy или конфигурация веб-сервера. Перевыпуск сертификата здесь пока ничего не решает.
Правило диагностики: не меняйте пять настроек сразу. После каждого теста должна отпасть хотя бы одна гипотеза или появиться конкретный следующий уровень проверки.
Когда сертификат уже исправлен, но нужно проверить HTTPS целиком
Исчезновение предупреждения в одном Chrome ещё не означает, что HTTPS полностью исправлен. У сайта могут отдельно обслуживаться example.com, www.example.com, IPv4, IPv6, поддомены и CDN. Каждый маршрут способен привести к другой TLS-конфигурации.
После исправления проверьте все адреса, которыми реально пользуются посетители:
https://example.com/;https://www.example.com/;- рабочие поддомены;
- IPv4 и IPv6, если опубликована AAAA-запись;
- origin напрямую, если перед сайтом стоит CDN;
- редирект с HTTP на HTTPS.
Редиректы удобно проверить через:
curl -I http://example.com/
curl -I https://example.com/
Первый запрос в типовой конфигурации должен перенаправить посетителя на HTTPS, второй — вернуть нормальный HTTP-ответ уже через TLS. Сам по себе 200, 301 или 302 ещё ничего не доказывает: смотрите, куда ведёт Location и нет ли цикла.
Затем повторите проверку сертификата:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
openssl x509 -noout -subject -issuer -dates -serial
Для сайта с IPv6 полезно отдельно выполнить:
curl -4 -Iv https://example.com/
curl -6 -Iv https://example.com/
Если используется CDN, проверьте публичный edge и origin раздельно. Для Cloudflare в строгом режиме убедитесь, что origin-сертификат соответствует hostname, не просрочен и собирает корректную цепочку.
| Контрольная точка | Что должно совпасть |
|---|---|
| example.com | Правильный сертификат, SAN и срок |
| www.example.com | Имя присутствует в сертификате или корректно редиректится |
| IPv4 | Актуальный сервер или CDN |
| IPv6 | Актуальный сервер и тот же рабочий HTTPS |
| CDN edge | Действующий публичный сертификат |
| Origin | Рабочий TLS согласно режиму CDN |
| Certificate chain | Передаются нужные intermediate-сертификаты |
| HTTP → HTTPS | Нет цикла и переход ведёт на правильный hostname |
Закрывать такую задачу лучше после внешней контрольной проверки, а не после сообщения «у меня уже открылось». Если браузер, OpenSSL и curl независимо получают ожидаемый сертификат, DNS ведёт на актуальные узлы, IPv4 и IPv6 не расходятся, цепочка доверия собирается, а остальные hostname не выпадают из HTTPS, проблему можно считать действительно устранённой.
WordPress хостинг

