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.