Выберите продукт

Отладка TLS: openssl s_client, testssl.sh и типовые ошибки цепочки

Эта инструкция для админов и девопсов показывает, как быстро и точно диагностировать проблемы TLS на боевых хостах. Разбираем openssl s_client и testssl.sh, ошибки цепочки, SNI, ALPN, OCSP stapling, версии протоколов и шифры, с примерами команд и чек-листами.
Отладка TLS: openssl s_client, testssl.sh и типовые ошибки цепочки

В любой цепочке поставки веба 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 по статусу.

Схема цепочки TLS: листовой, промежуточный, корневой

Типовые ошибки 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.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Диагностика на уровне сети и окружения

  • 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;
}

Настройка SSL в Nginx: сертификаты, цепочка и stapling

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 — сервер не представил сертификат (бывает при неверной конфигурации порта/контекста).

Мини‑чек‑лист перед релизом

  1. Проверить SNI: openssl s_client -connect <host>:443 -servername <host>.
  2. Убедиться в полноте цепочки: -showcerts и testssl.sh не видит Chain issues.
  3. Проверить SAN: есть все необходимые домены, включая IDN/wildcard.
  4. Проверить сроки действия: листовой и все интермедиаты.
  5. ALPN: согласуется h2 там, где нужен HTTP/2.
  6. OCSP stapling: good статус или отключено осознанно.
  7. Совместимость 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 и чек‑лист перед релизом — это экономит часы на инцидентах и избавляет пользователей от предупреждений.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...