Блог "Дети ОИТа"
/поиск

TLS Server Name Indication (SNI) на практике: совместимость, безопасность и диагностика

Практическое руководство по SNI: совместимость, риски приватности, диагностика через OpenSSL/curl, настройка на Nginx/Apache/HAProxy и чек-лист.

TLS Server Name Indication (SNI) на практике: совместимость, безопасность и диагностика

Зачем нужен SNI

SNI (RFC 6066) позволяет одному IP-адресу обслуживать множество HTTPS-хостов с разными сертификатами. Это основа современного shared-хостинга, SaaS и multi-tenant инфраструктур. Ошибки в SNI приводят к предупреждениям безопасности, недоступности сервисов и проблемам с аудитом.

Как работает TLS Handshake с SNI

  1. ClientHello содержит extension ‘server_name’ с целевым hostname.
  2. Сервер выбирает сертификат и цепочку под этот hostname.
  3. Если SNI не совпадает с сертификату — разрыв или предупреждение (в зависимости от клиента/сервера).
  4. При отсутствии SNI (старые клиенты) сервер отдаёт default certificate.

Совместимость

  • Поддержка: практически все современные клиенты (браузеры, curl, wget, языки) поддерживают SNI.
    | Клиент/Язык | SNI по умолчанию | Особенности |
    |---|---|---|
    | Браузеры | Да | |
    | curl | Да; можно отключить --tls-sni | Полезно для диагностики |
    | OpenSSL s_client | Требует -servername | |
    | Java (JSSE) | Да; важен правильный HostnameVerifier | |
    | Go | Да; настраивается через ServerName в tls.Config | |
    | Python (requests/urllib3) | Да | |

  • Проблемы: старые устройства/ОС (Windows XP, старые embedded), нестандартные клиенты без SNI.

Безопасность и приватность

  • SNI раскрывает запрашиваемый hostname в открытом виде в ClientHello. Это метаданные.
  • ECH (Encrypted Client Hello, RFC 9460) решает проблему, но требует поддержки на клиенте и сервере (DoH/DoT, совместимые прокси/CDN).
  • Риски: утечка структуры доменов, профилирование трафика.
  • Меры: ECH при возможности; иначе — минимизация числа wildcard и чёткое разделение tenant по endpoint’ам.

Диагностика

OpenSSL

# С SNI
openssl s_client -connect host:443 -servername example.com -tlsextdebug < /dev/null
# Без SNI
openssl s_client -connect host:443 -noservername < /dev/null

curl

# Явно задать SNI/Host
curl -vI https://example.com --resolve example.com:443:1.2.3.4 --header "Host: example.com"
# Отключить SNI для теста
curl -vI https://1.2.3.4 --connect-to ::1.2.3.4 --header "Host: example.com" --tls-sni 0

nmap

nmap --script ssl-cert,ssl-enum-ciphers -p 443 host

Серверные платформы

  • Nginx: server_name и отдельные server {} блоки; default_server для fallback.
  • Apache: NameVirtualHost и VirtualHost с ServerName/ServerAlias.
  • HAProxy: sni req.ssl_sni в frontend/backend, ACL по SNI.
  • CDN/WAF: корректно проксируйте SNI; следите за сохранением Host и consistency сертификатов.

Чек-лист внедрения

  • Для каждого tenant/hostname — свой сертификат или корректный SAN/UCC.
  • Настроен default сертификат для клиентов без SNI.
  • Проверены legacy-пути (если поддерживаются) и их изоляция.
  • Включён мониторинг ошибок TLS (handshake_failure, unknown_name).
  • Проверена консистентность сертификатов на всех endpoint’ах (HA/CDN).
  • Оценена применимость ECH; при невозможности — документирован риск раскрытия SNI.

Теги

TLS, SNI, SSL, безопасность, диагностика, совместимость, ECH, HTTPS, Nginx, HAProxy

Категории

Безопасность, Системное администрирование