В любой цепочке поставки веба TLS похож на фундамент: его обычно не видно, пока что-то не пойдёт не так. Падает рейтинг в браузерах, клиенты видят предупреждения, боты мониторинга шлют алерты, а платежи не проходят. Хорошая новость: в 90% случаев корневая причина находится за 10–15 минут, если дисциплинированно пройтись по чек‑листу и грамотно использовать инструменты openssl s_client и testssl.sh.
Что именно диагностируем в TLS
Практически все инциденты сводятся к нескольким классам проблем:
- Неполная или некорректная certificate chain (нет промежуточного CA, неверный порядок, вложен корневой).
- Ошибка соответствия имени (SAN/CN) или неправильный виртуальный хост из-за SNI.
- Истёкшие или ещё не начавшие действовать сертификаты/интермедиаты.
- Проблемы с OCSP stapling ("revocation status: unknown/NO"), откуда следуют предупреждения.
- Несогласованные версии TLS/наборы шифров, ALPN и HTTP/2.
- Несоответствие приватного ключа и сертификата.
Базовая стратегия отладки: сначала убедиться, что сервер отдаёт правильный сертификат для конкретного имени (SNI), затем проверить полноту цепочки, сроки и содержание SAN, после — протоколы/шифры/ALPN и OCSP.
Быстрый старт с openssl s_client
openssl s_client — универсальный зонд, показывающий, что сервер реально отправляет в рукопожатии: сертификаты, цепочку, версию TLS, ALPN, OCSP stapling. Несколько базовых сценариев:
1) Проверьте, что сервер отдаёт нужный vhost (SNI)
openssl s_client -connect example.com:443 -servername example.com -brief
Ключ -servername активирует SNI: без него вы увидите сертификат дефолтного виртуального хоста, и это типичный источник ложных выводов. Полезно сразу добавить расширенную печать:
openssl s_client -connect example.com:443 -servername example.com -showcerts -tlsextdebug -alpn h2,http/1.1 -status -verify_return_error
На что смотрим в выводе:
SSL-Sessionи строка сProtocol— какая версия TLS (ожидаем TLSv1.2/TLSv1.3).ALPN protocol— согласованы лиh2илиhttp/1.1.OCSP response— есть ли stapling и валиден ли статус.- Цепочка
Certificate chainи секцииdepth=с верификацией.
2) Явная проверка имени хоста и цепочки
Современный OpenSSL (1.1.1+) умеет проверять соответствие имени и верифицировать цепочку локально:
openssl s_client -connect example.com:443 -servername example.com -verify_hostname example.com -verify 5 -verify_return_error
Если цепочка неполная или имя не сходится, вы увидите verify error с кодом. Частые ошибки:
verify error:num=20:unable to get local issuer certificate— не хватает промежуточного CA в цепочке.verify error:num=62:Hostname mismatch— имя не найдено в SAN.verify error:num=10:certificate has expired— просрочен сертификат (или промежуточный).
3) Извлечь и прочитать сертификаты
Часто полезно сохранить сертификаты на диск и посмотреть их содержимое:
# Получить всю цепочку и сохранить в файл
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null > chain.pem
# Разобрать содержимое
openssl x509 -in chain.pem -noout -subject -issuer -dates -fingerprint -sha256
# Показать SAN
openssl x509 -in chain.pem -noout -ext subjectAltName
Если в файле несколько сертификатов, повторите команду для каждого разделённого блока -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----.
4) Протоколы/шифры/ALPN
Диагностика совместимости со старыми клиентами или наоборот — запрет устаревших протоколов:
# Принудительно TLS 1.2
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -cipher 'HIGH:!aNULL:!MD5'
# Принудительно TLS 1.3
openssl s_client -connect example.com:443 -servername example.com -tls1_3 -ciphersuites 'TLS_AES_256_GCM_SHA384'
# Проверка ALPN
openssl s_client -connect example.com:443 -servername example.com -alpn h2,http/1.1 -brief
Если HTTP/2 не согласуется, смотрите настройки ALPN на сервере и наличие совместимых шифров.
5) OCSP stapling
Проверить, шьёт ли сервер OCSP-статус в рукопожатие:
openssl s_client -connect example.com:443 -servername example.com -status -brief
Валидный ответ выглядит как OCSP Response Status: successful и Cert Status: good. Если no response sent — смотрим на конфигурацию OCSP stapling и доверенные цепочки для валидации ответа.
testssl.sh: быстрая сводка всего
testssl.sh автоматизирует рутину: проверяет протоколы, наборы шифров, цепочку, SNI, ALPN, резюме по уязвимостям и даёт чёткие пометки OK/VULNERABLE/NOT ok. Удобно запускать на девелоперских ноутбуках и CI.
./testssl.sh --sneaky --fast --warnings batch example.com
Ключи:
--sneakyи--fastускоряют проверку и снижают шум.--warnings batchделает вывод компактнее для логов.-pможно указать порт, а-S— SNI-имя, если оно отличается.
На что обратить внимание в выводе:
- Chain issues: "none" — отлично; "incomplete" — отсутствуют интермедиаты; "contains anchor" — в цепочку включён корневой, чего делать не нужно.
- Protocols и Ciphers: откровенный мусор (TLS 1.0/1.1, RC4/3DES) должен быть выключен.
- ALPN/NPN: для HTTP/2 ждём ALPN: h2.
- OCSP stapling: должен быть
offeredиgoodпо статусу.

Типовые ошибки certificate chain и как их чинить
1) Отсутствует промежуточный сертификат
Симптомы: unable to get local issuer certificate в openssl s_client, жалобы только от некоторых клиентов/ботов. В браузерах иногда работает благодаря AIA-фетчу (браузер сам скачивает недостающий intermediate), но не все клиенты так делают.
Исправление: собрать правильный fullchain. Порядок имеет значение — сначала листовой сертификат (ваш), затем все промежуточные от нижнего к верхнему. Корневой не добавлять.
# Пример сборки fullchain
cat server.crt intermediate-1.crt intermediate-2.crt > fullchain.pem
Проверьте локально:
# Верификация с указанием корневых (CAfile) и незакреплённой цепочкой
openssl verify -CAfile cacerts.pem -untrusted intermediate-1.crt server.crt
2) Неверный порядок сертификатов
Симптомы: у некоторых клиентов верификация может падать даже при наличии всех файлов. Сервер обязан отдавать листовой первым, далее — цепочку вверх.
Исправление: переупорядочить и пересобрать fullchain в корректной последовательности.
3) Включён корневой сертификат в цепочку
Симптомы: testssl.sh пишет contains anchor. Технически многие клиенты проигнорируют корневой, но это нарушение практики и иногда ломает OCSP stapling.
Исправление: убрать корневой из файла, который сервер отдаёт клиентам.
4) Микс кросс-подписанных цепочек
Симптомы: у части устройств (часто старые Android) ошибки валидации, у новых — всё ок. Причина — выбор неправильного пути построения цепочки к неподдерживаемому корню.
Исправление: использовать рекомендуемый вендором набор интермедиатов, иногда — alternate‑цепочку. Проверить с testssl.sh и openssl s_client на TLS 1.2/1.3.
5) Несоответствие имени (SAN) и SNI
Симптомы: Hostname mismatch на проверке, в браузере предупреждение, но при запросе на другой домен всё работает. Часто причина — сервер без SNI-роутинга или неправильный дефолтный vhost.
Диагностика:
- Проверьте с и без
-servername— видите ли вы разные сертификаты. - Если по IP отдаётся другой сертификат, настройте корректный дефолтный серверный блок.
- Проверьте, содержит ли SAN точное имя (в т.ч. IDN) и нужные wildcard-паттерны.
Исправление: скорректировать виртуальные хосты и использовать верный fullchain для соответствующего server_name. При необходимости — перевыпустить сертификат с нужными SAN. Если требуется выпуск, продление или замена, оформляйте SSL-сертификаты.
6) Проблемы с OCSP stapling
Симптомы: no response sent или OCSP Response Status: unauthorized. Сервер не может получить или провалидировать ответ от OCSP-провайдера.
Исправление: у сервера должен быть доступ в сеть к OCSP-ресурсам, а также корректно настроен файл доверенных сертификатов для валидации ответа. Проверьте, что конфигурация использует trusted‑цепочку (например, отдельный файл с интермедиатами для проверки OCSP).
7) Неверная пара ключ/сертификат
Симптомы: сервер не стартует, в логах — PEM routines или SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch.
Диагностика локально:
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5
Хэши должны совпасть.
8) Истёкший intermediate
Симптомы: листовой сертификат ещё валиден, а клиенты ругаются. В выводе openssl s_client встречается verify error:num=10:certificate has expired на одном из уровней depth.
Исправление: заменить устаревший intermediate в fullchain на актуальный из того же семейства CA.
Если вы параллельно обновляете политику шифров и протоколов, пригодится наше руководство Лучшие практики TLS в 2025. Для автоматизации выпусков и продления см. настройку Certbot и HSTS.
Диагностика на уровне сети и окружения
- IPv4/IPv6: проверяйте оба стека. Иногда AAAA указывает на другой бэкенд с иной конфигурацией TLS.
- По IP без SNI: проверьте, что дефолтный сертификат не экспонирует внутренние имена. Команда:
openssl s_client -connect 203.0.113.10:443. - Прокси/CDN: убедитесь, что смотрите именно на edge, а не на origin — иногда TLS завершается на периметре.
- Порты не-HTTPS: для SMTP/IMAP/POP используйте
-starttls.
# SMTP
openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com -status
# IMAP
openssl s_client -connect mail.example.com:993 -servername mail.example.com -status
Правильная подача цепочки в популярных серверах
Nginx
ssl_certificate— файл, который сервер отдаёт клиентам. Это должен быть fullchain (листовой + интермедиаты).ssl_certificate_key— приватный ключ.ssl_trusted_certificate— цепочка, которой Nginx доверяет для валидации OCSP. Часто это тот же набор интермедиатов, но без корней клиентов.
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/example/fullchain.pem;
ssl_certificate_key /etc/ssl/example/privkey.pem;
ssl_trusted_certificate /etc/ssl/example/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE+AESGCM:ECDHE+CHACHA20';
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
}

Apache HTTP Server
SSLCertificateFile— листовой сертификат или fullchain в новых версиях.SSLCertificateKeyFile— приватный ключ.SSLCertificateChainFile— для старых версий требуется отдельно указать интермедиаты.
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/ssl/example/fullchain.pem
SSLCertificateKeyFile /etc/ssl/example/privkey.pem
</VirtualHost>
Для OCSP stapling настройте доверенные CA и включите SSLUseStapling, если нужно.
Разбор типичных сообщений об ошибках
verify error:num=20:unable to get local issuer certificate— клиент не смог построить цепочку, сервер не отдал intermediate. Решение: добавьте intermediate в fullchain.self signed certificate in certificate chain— в цепочке оказался корневой или самоподписанный промежуточный. Удалите его.certificate has expired— просрочка. Проверяйте и листовой, и интермедиаты.Hostname mismatch— имя не соответствует SAN. Перевыпустить сертификат или исправить SNI/виртуальный хост.no peer certificate available— сервер не представил сертификат (бывает при неверной конфигурации порта/контекста).
Мини‑чек‑лист перед релизом
- Проверить SNI:
openssl s_client -connect <host>:443 -servername <host>. - Убедиться в полноте цепочки:
-showcertsиtestssl.shне видитChain issues. - Проверить SAN: есть все необходимые домены, включая IDN/wildcard.
- Проверить сроки действия: листовой и все интермедиаты.
- ALPN: согласуется
h2там, где нужен HTTP/2. - OCSP stapling:
goodстатус или отключено осознанно. - Совместимость TLS 1.2/1.3: оба режиссируемы по политике безопасности.
Трюки для глубокого debug
- Сравнить разные адреса: один и тот же домен может резолвиться в разные IP — проверяйте каждый узел.
- Проверка конкретного пути: запрашивайте ресурсы с разным ALPN, чтобы понять, влияет ли HTTP/2.
- Принудительное SNI: при бэктрекинге через балансировщик указывайте
-servernameимя внутреннего upstream, если TLS завершается там. - Диагностика renegotiation: некоторые старые клиенты ломаются — в продакшене она обычно отключена.
Частые организационные причины сбоев
- Файлы fullchain/privkey перепутаны между несколькими сайтами.
- Переезд на новый сервер без переноса актуальных интермедиатов.
- Регламент продления не учитывает промежуточные сертификаты.
- IPv6 конфигурирован иначе, чем IPv4 (разные версии Nginx/Apache, разные файлы).
Итоги
Быстрая и точная отладка TLS держится на двух столпах: корректной интерпретации вывода openssl s_client и автоматизированной сверке через testssl.sh. Начинайте с проверки SNI и имени, затем переходите к цепочке, срокам, OCSP, ALPN и протоколам. Держите под рукой правильные fullchain‑файлы, отдельный набор доверенных сертификатов для OCSP и чек‑лист перед релизом — это экономит часы на инцидентах и избавляет пользователей от предупреждений.


