Nginx 502: SSL routines: ssl/tls alert handshake failure — Решение
При попытке перенаправления трафика на защищенный HTTPS-бэкенд Nginx завершает запрос ошибкой 502. В логе error.log регистрируется сбой криптографического согласования: SSL: error:0A000410:SSL routines::ssl/tls alert handshake failure while SSL handshaking to upstream.
| Причина сбоя | Механизм возникновения | Индикатор ошибки OpenSSL |
|---|---|---|
| Отсутствие SNI | Upstream требует Server Name Indication, но Nginx его не шлет | ssl/tls alert handshake failure |
| Несовпадение версий TLS | Бэкенд требует TLSv1.3, Nginx пытается согласовать TLSv1.2/1.1 | no protocols available / alert handshake |
| Самоподписанный сертификат | Включена строгая проверка proxy_ssl_verify on | certificate verify failed |
| Несовместимые Cipher Suites | Нет общего набора алгоритмов шифрования | no shared cipher |
- Прямое открытие URL бэкенда в браузере работает успешно.
- Сбой возникает только при проксировании запроса схемой
proxy_pass https://....
- Включите передачу имени хоста через механизм SNI (Server Name Indication) в директивах Nginx:
location / { proxy_pass https://backend.internal.domain; # Критически важные директивы для успешного TLS Handshake: proxy_ssl_server_name on; proxy_ssl_name $proxy_host; } - Задайте поддерживаемые протоколы TLS и стойкие наборы шифров для прокси-соединений:
proxy_ssl_protocols TLSv1.2 TLSv1.3; proxy_ssl_ciphers HIGH:!aNULL:!MD5; - Если целевой upstream использует самоподписанный или корпоративный сертификат, укажите доверенный CA или временно отключите проверку:
# Для корпоративного CA: proxy_ssl_trusted_certificate /etc/ssl/certs/internal-ca.crt; proxy_ssl_verify on; # Либо временное отключение проверки (только в закрытых контурах!): proxy_ssl_verify off; - Проверьте параметры и выполните перезагрузку сервиса:
sudo nginx -t sudo systemctl reload nginx
proxy_ssl_server_name выключена (off). Это означает, что Nginx не передает поле SNI в запросе Client Hello, из-за чего Cloudflare, AWS ALB и виртуальные хосты на upstream сбрасывают рукопожатие.Частые вопросы (FAQ)
Что делает директива proxy_ssl_server_name on?
Она заставляет Nginx передавать имя домена бэкенда в расширении TLS Server Name Indication (SNI) при отправке Client Hello пакета целевому серверу.
Почему openssl s_client подключается к бэкенду, а Nginx выдает 502?
Утилита openssl по умолчанию отправляет SNI, а Nginx без явного указания proxy_ssl_server_name on не использует SNI, что приводит к разрыву сессии бэкендом.
Как указать кастомный клиентский SSL-сертификат для аутентификации на upstream (mTLS)?
Используйте директивы proxy_ssl_certificate /path/to/client.crt; и proxy_ssl_certificate_key /path/to/client.key;.
Безопасно ли использовать proxy_ssl_verify off?
Это допустимо исключительно внутри изолированных защищенных подсетей (VPC/LAN). В публичном интернете отключение верификации делает трафик уязвимым к атакам Man-in-the-Middle (MITM).