К основному содержимому

Ошибки SSL в браузере: причины и как исправить

Безопасность · 31.10.2026 · 6 мин чтения
Иллюстрация к статье «Ошибки SSL в браузере: причины и как исправить»

Браузер пишет «Соединение не защищено», «Сертификат сервера не является доверенным» или показывает код NET::ERR_CERT_DATE_INVALID. За такими сообщениями стоит одна из пяти причин, и каждая опознаётся командой openssl за минуту. О том, как просто посмотреть сертификат, написано в статье Как проверить SSL-сертификат. Здесь разбираем причины ошибки и способы починки.

Быстрая диагностика с сервера

Сначала выясните, что именно не нравится проверяющей стороне. Команда ниже подключается к сайту, как это делает браузер, и печатает код проверки, владельца сертификата и издателя.

openssl s_client -connect example.com:443 -servername example.com -verify_hostname example.com </dev/null 2>/dev/null | grep -E "Verify return code|subject=|issuer="

Код в строке Verify return code указывает на причину. Сопоставьте его с таблицей.

ПричинаКод проверки opensslГде проявляется
Срок действия истёк10 (certificate has expired)Везде, у всех посетителей
Самоподписанный сертификат18 (self-signed certificate)Везде, у всех посетителей
Нет промежуточного сертификата20 или 21 (unable to get local issuer certificate / unable to verify the first certificate)Часто только на телефонах, curl и в приложениях
Имя не совпадает с доменом62 (Hostname mismatch)Везде, у всех посетителей
Часы на клиенте сбиты0 (ok) на сервереТолько у одного пользователя или устройства

Причина 1: срок сертификата истёк

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

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -checkend 0

Исправление: перевыпустить сертификат и перезагрузить веб-сервер. Если вы пользуетесь Let's Encrypt, причина почти всегда в сломанном автопродлении. Порядок настройки описан в статье Nginx и Certbot. Проверьте, что продление проходит без ошибок, и перечитайте конфигурацию.

sudo certbot certificates
sudo certbot renew --dry-run
sudo systemctl reload nginx

Причина 2: сертификат самоподписанный

Самоподписанный сертификат выпущен самим сервером и никем не заверен, поэтому в openssl вы увидите код 18, а в блоке subject и issuer будут одинаковые значения. Для тестового стенда или внутренней службы это нормально, для публичного сайта нет: посетители увидят предупреждение.

Исправление для публичного сайта: получить сертификат у доверенного центра сертификации. Различия между видами сертификатов описаны в статье о типах сертификатов DV, OV и EV. Для внутренней службы можно добавить собственный корневой сертификат в доверенные на клиентах.

Причина 3: не прислана промежуточная часть цепочки

Центр сертификации подписывает ваш сертификат не корневым ключом, а промежуточным. Сервер обязан отдать клиенту свой сертификат вместе с промежуточными. Десктопные браузеры нередко достраивают недостающее звено сами, поэтому на компьютере всё открывается, а на телефоне, в curl или в стороннем приложении возникает ошибка.

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | grep -E "^ *[0-9] s:|^ *i:|Verify return code"

В выводе ниже должно быть как минимум два звена: ваш сертификат (строка 0) и промежуточный (строка 1). Если звено одно, а в конце стоит код 20 или 21, цепочка неполная.

  • В Nginx укажите в ssl_certificate файл с полной цепочкой (fullchain.pem), а не один сертификат.
  • В Apache используйте файл цепочки, который выдал центр сертификации, в директиве SSLCertificateChainFile или объедините цепочку в основной файл.
  • После правки перезагрузите службу и повторите команду: код должен смениться на 0.
ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Причина 4: имя в сертификате не совпадает с доменом

Сертификат выпущен на другие имена, чем те, по которым открывают сайт. Типичные случаи: сертификат на example.com, а сайт открывается как www.example.com; сертификат старого домена после переезда; обращение по IP-адресу. Современные клиенты смотрят только поле Subject Alternative Name, а не Common Name.

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName

Исправление: перевыпустите сертификат так, чтобы в нём были все нужные имена, или настройте редирект на то имя, которое покрыто. Порядок установки описан в статье подключения SSL.

Причина 5: часы на клиенте сбиты

Сертификат действует с одной даты по другую. Если на устройстве стоит неверная дата, браузер считает действующий сертификат ещё не начавшимся или уже истёкшим. Признак: ошибка только на одном компьютере или телефоне, а на сервере проверка проходит с кодом 0. Проверить время на самом сервере можно так.

date -u
timedatectl status
  • На клиенте включите автоматическую установку даты и времени и проверьте часовой пояс.
  • На сервере настройте синхронизацию времени, иначе проверки клиентских сертификатов и подписи токенов тоже будут давать сбои.
  • Если ошибка исчезла после исправления часов, сертификат ни при чём.

Частые вопросы

Что значит «сертификат сервера не является доверенным»?

Клиент не смог построить цепочку от сертификата сайта до корневого сертификата, которому он доверяет. Причины: самоподписанный сертификат, отсутствие промежуточного звена или неизвестный центр сертификации. Код проверки в openssl s_client показывает, какой именно из случаев перед вами, и подсказывает исправление. Само предупреждение браузера причину не называет.

Почему на компьютере сайт открывается, а на телефоне ошибка?

Чаще всего сервер не присылает промежуточный сертификат. Десктопный браузер может достроить цепочку из кеша или по ссылке внутри сертификата, а мобильные клиенты, curl и приложения этого не делают. Подключите полную цепочку (fullchain) в настройках веб-сервера и перезагрузите службу. После этого откройте сайт с телефона ещё раз.

Как понять, что сертификат просто истёк?

Выполните openssl x509 с ключом -enddate по ответу сервера или проверьте код 10 в строке Verify return code. Дата окончания в прошлом означает истёкший сертификат. Перевыпустите его и перезагрузите веб-сервер. Если используете автопродление, найдите в журналах причину, по которой оно не сработало, и проверьте пробный запуск продления.

Можно ли просто нажать «всё равно перейти на сайт»?

Для чужого публичного сайта этого делать не стоит: при подмене сертификата трафик может перехватить третья сторона. Для собственного тестового стенда допустимо, но лучше выпустить нормальный сертификат или добавить свой корневой сертификат в доверенные на своих устройствах. Нажатие кнопки обхода ошибку не устраняет.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке