Ошибка при проверке SSL сертификата: 7 частых причин сбоя
Ошибка при проверке SSL-сертификата — не диагноз, а симптом. Браузер сообщает, что не может подтвердить защищённое соединение, но за этим могут стоять разные вещи: истёкший сертификат, неправильное…

Ошибка при проверке SSL-сертификата — не диагноз, а симптом. Браузер сообщает, что не может подтвердить защищённое соединение, но за этим могут стоять разные вещи: истёкший сертификат, неправильное имя хоста, неполная цепочка доверия или часы на клиентском устройстве, которые живут в собственной временной зоне. На сервере при этом всё может выглядеть вполне прилично: сайт отвечает по HTTPS, замок в панели зелёный, а пользователи получают предупреждение.
Сначала нужно выяснить, где ломается проверка: на сервере, в конфигурации конкретного виртуального хоста или на стороне клиента. Отключить проверку сертификата — быстрый способ убрать сообщение и медленный способ создать дыру. Для диагностики нужны код ошибки, имя хоста и данные сертификата, который сервер действительно отдаёт при подключении.
1. Сервер не отдал промежуточный сертификат
Сертификат сайта обычно не подписан корневым сертификатом напрямую. Между ними есть промежуточный сертификат, а иногда и несколько. Вместе они образуют цепочку доверия: клиент проверяет подпись сайта, затем поднимается по цепочке к центру сертификации, которому доверяет операционная система или браузер.
Если веб-сервер отдаёт только сертификат сайта, клиенту может не хватить данных для проверки. Один браузер иногда достроит цепочку из уже сохранённых сертификатов, другой — нет. В результате один пользователь видит сайт, а другой ловит SEC_ERROR_UNKNOWN_ISSUER или похожую ошибку. Это не делает конфигурацию «почти правильной». Просто у части клиентов есть удачный кеш.
Частый источник проблемы — в настройке указан файл с leaf-сертификатом вместо полного набора. В Nginx, например, директива ssl_certificate обычно должна ссылаться на файл, в котором сертификат сайта расположен вместе с нужными промежуточными сертификатами. В панель управления хостингом могли загрузить только один файл из комплекта, а промежуточный оставить лежать рядом без дела. Сервер не читает файлы из жалости.
Проверять нужно не то, что лежит на диске, а то, что сервер отдаёт клиенту. На результат влияют конфигурация виртуального хоста, выбранный сертификат, SNI и балансировщик перед приложением. Если TLS завершается на CDN или reverse proxy, править сертификат на backend-сервере может быть бессмысленно: пользователь до него вообще не доходит.
Если ошибка проявляется не у всех, не записывайте это в «капризы браузера». Разные клиенты часто просто по-разному переживают неполную цепочку.
После изменения конфигурации проверьте именно нужное доменное имя: один IP-адрес может обслуживать несколько сайтов, и без корректного SNI сервер отдаст не тот сертификат. Если используется CDN, проверять следует внешний endpoint, а не только origin.
2. Сертификат истёк или ещё не начал действовать
Ошибка даты — самый понятный случай и не всегда самый простой в ремонте. Сертификат может закончить срок действия, а автоматическое продление — тихо не сработать из-за проблем с DNS, HTTP challenge, правами на каталог или доступом к серверу. Для пользователя это часто выглядит как NET::ERR_CERT_DATE_INVALID или SEC_ERROR_EXPIRED_CERTIFICATE.
Бывает и обратная ситуация: сертификат ещё не вступил в силу. Например, системное время устройства сильно отстаёт. Браузер сравнивает текущую дату с периодом действия сертификата и делает ровно то, что должен: отказывается считать его валидным. Неверные часы встречаются и на сервере, особенно в виртуальных машинах с проблемной синхронизацией времени. Проверка сертификата не обязана подстраиваться под устройство, которое решило, что сейчас прошлый вторник.
Разделить эти случаи можно по датам сертификата и по системным часам. Если даты сертификата корректны, а предупреждение появляется у одного пользователя, проверьте время, часовой пояс и синхронизацию устройства. Если срок действительно закончился — проверяйте продление и то, какой сертификат установлен на точке, принимающей HTTPS-соединение. Нередко новый файл уже выпущен, но Nginx продолжает отдавать старый: конфиг не перечитан, путь ведёт не туда или TLS завершается на другом узле.
Само наличие таймера автоматического продления ещё ничего не гарантирует. Нужны успешный выпуск, установка сертификата и перезагрузка или reload сервиса. А ещё — мониторинг срока действия с проверкой снаружи, по доменному имени. Лог задания cron, в котором написано «успешно», не доказывает, что пользователю отдают нужный сертификат.
3. Сертификат выписан не на тот домен
Сертификат проверяется не «для сайта вообще», а для конкретного имени хоста. Если запрос идёт на shop.example.test, а сертификат покрывает только example.test, клиент может сообщить SSL_ERROR_BAD_CERT_DOMAIN. Корневой домен и поддомен — разные имена, если только сертификат явно не охватывает оба.
Здесь часто всплывают мелкие, но дорогие расхождения:
- в сертификат добавили
www, но забыли версию безwww, или наоборот; - DNS ведёт на старый сервер, где установлен сертификат другого проекта;
- балансировщик или CDN отдаёт сертификат не для того hostname;
- приложение перенаправляет на домен, которого нет в сертификате;
- тестируют IP-адрес, хотя сертификат выпущен на доменное имя.
Последний пункт регулярно порождает ложные выводы. Открыть сайт по IP и увидеть ошибку имени — не доказательство, что сертификат сломан. Клиент сравнивает имя, к которому подключился, с именами в сертификате. Подключение по IP требует, чтобы соответствующий IP был предусмотрен сертификатом; для обычного веб-сайта это не типовой сценарий.
При диагностике указывайте точное имя хоста и сохраняйте SNI. Запрос к адресу сервера без имени может попасть в дефолтный виртуальный хост. Тот честно отдаст сертификат другого сайта — и вот уже появляется «непонятная ошибка SSL», хотя причина в том, что проверяли не тот endpoint.
4. На публичном сайте установлен самозаверяющий сертификат
Самозаверяющий сертификат подписан не доверенным удостоверяющим центром, а собственным ключом. Для внутреннего тестового стенда это бывает уместно: инфраструктура может распространять свой корневой сертификат на управляемые устройства. Для публичного сайта это обычно заканчивается предупреждением ERROR_SELF_SIGNED_CERT или сообщением о неизвестном издателе.
Технически соединение может быть зашифровано. Но шифрование и проверка подлинности — не одно и то же. Сам факт, что трафик зашифрован, не подтверждает клиенту, что он подключился именно к нужному сайту, а не к узлу, который подменил ответ. Браузер не доверяет подписи просто потому, что сервер уверенно показывает сертификат.
Внутренний центр сертификации — отдельный вариант, но он работает только там, где его корневой сертификат установлен и считается доверенным. Если часть сотрудников работает с личных устройств, а часть — через управляемый браузер, поведение будет различаться. Это уже вопрос политики доверия, а не настройки кнопки в браузере.
Не обходите предупреждение инструкцией «нажмите продолжить». Для публичного ресурса нужен сертификат от доверенного центра и правильно настроенная цепочка. Для закрытой инфраструктуры — осознанно распространённый корневой сертификат и контроль его срока действия. Остальное — костыль, который прячет проблему только от тех, кто согласился нажать кнопку.
5. Антивирус или прокси перехватывает HTTPS
Некоторые антивирусы, корпоративные прокси и фильтры трафика анализируют HTTPS-соединения. Для этого они могут завершить исходное TLS-соединение, проверить трафик и создать новое соединение до сайта. На клиентском устройстве такой посредник предъявляет сертификат, подписанный своим локальным или корпоративным центром.
Если этот центр доверия не установлен, повреждён или заменён политикой устройства, браузер не сможет подтвердить сертификат. Пользователь видит ошибку, хотя сервер сайта может отдавать корректную цепочку. В такой ситуации сертификат, показанный в браузере, способен принадлежать не сайту, а перехватывающему узлу.
Показательный признак — ошибка возникает только в одной сети, на одном устройстве или при включённом конкретном защитном ПО. Сравните результат из другой сети и проверьте издателя сертификата. Это помогает локализовать проблему, но не даёт основания постоянно отключать проверку HTTPS в антивирусе. Если вмешивается корпоративный прокси, исправлять нужно доверенную цепочку на управляемых устройствах или конфигурацию прокси. Если перехват включило стороннее ПО — разбираться с его настройками и сертификатами.
Сертификат, который пользователь видит в браузере, может принадлежать не сайту, а перехватывающему узлу. Менять сертификат на сервере, не посмотрев, что именно получил клиент, — типовая попытка чинить прод по описанию из чата.
Не путайте этот сценарий с ошибкой на сервере. Если ошибка воспроизводится только в одной сети или на одном устройстве — сначала исключите посредника, и только потом лезьте в конфигурацию веб-сервера.
6. Веб-сервер отдаёт разные сертификаты на разных узлах
Один домен может указывать на несколько IP-адресов, работать через балансировщик, CDN или несколько региональных узлов. Если сертификат обновили только на части инфраструктуры, результат будет зависеть от точки подключения. Один запрос проходит, другой получает просроченный сертификат или сертификат соседнего хоста.
Похожая картина возникает после миграции. DNS уже указывает на новый сервер, но часть клиентов ещё попадает на старый адрес из кеша. Или внешний прокси обслуживает TLS сам, а на origin оставили прежнюю конфигурацию. Важен тот сертификат, который видит клиент на публичном адресе и порту 443, а не тот, который администратор только что открыл в каталоге /etc/ssl.
Проверяйте каждый адрес отдельно, сохраняя имя хоста для SNI. Если проблема плавающая, сопоставьте ошибки с IP, регионом, балансировщиком и временем запроса. Сравните Subject Alternative Name, издателя и даты действия сертификата на разных узлах. Тогда «иногда не работает» превращается в конкретное наблюдение: например, один backend отдаёт старую цепочку.
Для Nginx после обновления конфигурации обычно требуется проверить синтаксис и сделать reload, а не бездумно перезапускать весь сервер. Но сначала убедитесь, что конфигурация действительно указывает на новый файл и что процесс имеет к нему доступ. Иначе reload лишь аккуратно применит старую ошибку ещё раз.
7. Старая конфигурация TLS или неверные параметры handshake
TLS handshake может завершиться не только из-за сертификата. Клиент и сервер должны договориться о версии протокола и наборе параметров соединения. Если конфигурация веб-сервера отключает совместимые версии или оставляет устаревшие настройки, часть клиентов не сможет подключиться. SSL 3.0 — давно устаревшая версия протокола: включать её ради сомнительной совместимости — плохой ремонт, а не настройка.
При этом сообщение «ошибка SSL» не всегда означает, что нужно переписывать TLS-конфиг. Сначала отделите сбой handshake от ошибки проверки сертификата. В первом случае соединение может оборваться до того, как клиент проверит цепочку. Во втором TLS-соединение дошло до этапа проверки, но клиент не доверяет полученным данным. Логи прокси и веб-сервера здесь полезнее гадания по скриншоту браузера.
Ищите точный момент и источник сбоя. Если ошибка воспроизводится только на старом клиенте, проверьте его поддержку протоколов и криптографических параметров. Если падают разные клиенты, а в логах виден один и тот же сертификатный сбой, возвращайтесь к имени хоста, цепочке и срокам. Не включайте все версии TLS подряд ради того, чтобы «заработало»: это не совместимость, а археология с открытым портом.
Как проверить сертификат с сервера
Базовая проверка начинается с внешнего запроса, в котором передано правильное имя хоста. openssl s_client показывает сертификат, цепочку и результат проверки. Опция -servername важна: она передаёт SNI, чтобы сервер выбрал виртуальный хост по имени, а не отдал сертификат по умолчанию. В выводе найдите сертификаты, которые сервер отправил клиенту, и итог проверки цепочки.
Чтобы увидеть даты, издателя и альтернативные имена сертификата в читаемом виде, сохраните его в файл через ту же утилиту и разберите командой openssl x509 -noout -subject -issuer -dates -ext subjectAltName. Этого хватает для быстрой проверки, но не заменяет проверку всех узлов за балансировщиком. Повторите запрос для каждого публичного IP, сохраняя SNI: у одного и того же домена часто живёт несколько backend-ов с разной конфигурацией.
Для проверки именно HTTPS-запроса пригодится curl -Iv https://example.com/. Флаг -k отключает проверку сертификата и годится только как временный диагностический приём — чтобы выяснить, отвечает ли endpoint при обходе валидации. Он не исправляет TLS и не подтверждает безопасность соединения, поэтому в постоянных сценариях ему не место.
Если подозрение падает на системное время, проверьте его на клиенте и сервере. На Linux обычно начинают с date -u и timedatectl status — это покажет текущее время, часовой пояс и состояние синхронизации. Расхождение даже в несколько часов достаточно, чтобы валидный сертификат превратился в «просроченный».
Дальше диагностика идёт по конкретному коду и месту обрыва — собирайте всё в таблицу соответствий, чтобы не перебирать причины наугад.
| Код ошибки | Что проверять в первую очередь |
|---|---|
NET::ERR_CERT_DATE_INVALID, SEC_ERROR_EXPIRED_CERTIFICATE | Срок сертификата и системное время на устройстве |
SSL_ERROR_BAD_CERT_DOMAIN | Hostname запроса и список имён в subjectAltName |
SEC_ERROR_UNKNOWN_ISSUER | Издателя и полноту цепочки, отдаёт ли сервер промежуточные |
ERROR_SELF_SIGNED_CERT | Установлен ли публичный сертификат или внутренний самоподписанный |
| Ошибка только в одной сети или на одном устройстве | Прокси, антивирусный HTTPS-фильтр и локальные доверенные центры |
Причины сбоя SSL-соединения редко требуют магии. Обычно достаточно перестать смотреть на зелёный значок в панели хостинга и проверить сертификат снаружи, по тому же hostname, который использует пользователь. Сначала локализуйте узел и этап сбоя. Потом меняйте конфигурацию. В обратном порядке получается особенно дорогой костыль.
Настройте мониторинг срока действия сертификатов и проверяйте резервные копии конфигурации. Сертификат продлевается автоматически ровно до того момента, когда автоматика перестаёт работать. Бэкапы тоже: делайте их и проверяйте восстановление, а не только наличие файлов на диске.