SSL handshake завершается до передачи HTTP-запроса. Если он падает, причина обычно в сертификате, цепочке доверия, имени домена, версии TLS, SNI или несовместимых настройках клиента и сервера.

Проверьте соединение с указанием домена через openssl s_client и curl, изучите выданную цепочку и серверный лог. Важно тестировать именно тот hostname, который использует клиент.

Коротко: что сделать

  • Проверить срок и имена в сертификате
  • Проверить полную цепочку intermediate CA
  • Проверить SNI и выбранный virtual host
  • Сверить поддерживаемые версии TLS
  • Проверить время на клиенте и сервере

Почему возникает проблема

Сообщение handshake failed общее, а точный этап сбоя виден в коде OpenSSL, журнале прокси или подробном выводе клиента.

  • Сервер отдает неполную цепочку сертификатов
  • Сертификат выпущен не на запрошенный домен
  • Без SNI выбирается сертификат другого сайта
  • Клиент поддерживает только устаревший TLS
  • Reverse proxy проверяет backend по неправильному имени
  • Часы устройства существенно отстают или спешат

Пошаговая диагностика

Проверку лучше проводить на одном воспроизводимом примере и фиксировать результат каждого шага. Так можно быстро отделить первопричину от побочных ошибок и не менять несколько компонентов одновременно.

  • Запустить openssl s_client -connect host:443 -servername host -showcerts
  • Проверить curl -Iv https://host
  • Сравнить результат с подключением по IP без SNI
  • Просмотреть error log Nginx, Apache или балансировщика
  • Проверить конфигурацию CDN и origin certificate
  • Протестировать современный и проблемный клиент отдельно

Как исправить

Исправляйте конкретную точку несовместимости, сохраняя современные безопасные версии TLS.

  • Установить fullchain вместо одного leaf-сертификата
  • Привязать сертификат к правильному server_name
  • Передавать SNI при TLS-соединении к backend
  • Разрешить TLS 1.2 и 1.3 для совместимых клиентов
  • Обновить старую библиотеку TLS на клиенте
  • Настроить автоматическое продление и reload сервера

Как проверить результат

  • Проверить домен через openssl и curl
  • Убедиться, что verify return code равен 0
  • Проверить основной и альтернативные домены
  • Повторить тест через CDN и напрямую к origin
  • Проверить мобильное приложение или интеграцию, где был сбой

Как не допустить повторения

Сертификат нужно контролировать вместе с цепочкой, сроком и фактической конфигурацией прокси.

  • Добавить мониторинг срока сертификата
  • Проверять reload после продления
  • Хранить TLS-конфигурацию в репозитории
  • Тестировать внешние интеграции после смены сертификата

Чего не стоит делать

  • Не отключать проверку сертификата в клиенте
  • Не возвращать TLS 1.0 ради одного старого устройства без оценки риска
  • Не копировать приватный ключ в сторонние сервисы
  • Не проверять HTTPS только в браузере с кэшем сертификатов

Что подготовить для диагностики

  • Домен и порт
  • Точный текст ошибки клиента
  • Вывод openssl s_client
  • Конфигурация TLS-прокси без приватного ключа
  • Схема CDN, балансировщика и backend

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

Почему браузер открывает сайт, а API-клиент нет?

Браузер может достроить цепочку или поддерживать другой TLS-набор, тогда как библиотека API требует полную цепь от сервера.

Что такое SNI?

Это имя домена, передаваемое в начале TLS-соединения, чтобы сервер выбрал правильный сертификат.

Можно ли просто отключить verify?

Нет. Это скрывает ошибку и делает соединение уязвимым для подмены.

Когда стоит обратиться за помощью

Помощь особенно нужна при связке CDN, reverse proxy, нескольких доменов и внутренних HTTPS-сервисов, где сертификат может быть корректен на одном участке и ошибочен на другом.

Итог

Диагностика SSL handshake строится по цепочке клиент — прокси — origin с проверкой имени, SNI и доверия. Настроить HTTPS без отключения защиты можно через @rabotator_support.