Server Name Indication (SNI)

Server Name Indication (SNI) - это расширение протокола TLS, которое позволяет клиенту указать имя сервера, к которому он пытается подключиться, в начале процесса рукопожатия.

Проблема, которую решает SNI

В традиционном HTTPS-соединении сервер должен предоставить правильный сертификат до того, как клиент отправит HTTP-заголовок Host. Это создаёт проблему для виртуальных хостов, когда несколько доменов используют один IP-адрес.

Без SNI:
Клиент → Сервер (IP-адрес) → ? Какой сертификат предоставить?

С SNI:
Клиент → Сервер (с указанием доменного имени) → Сервер предоставляет правильный сертификат

Как работает SNI

  1. Клиент инициирует TLS-рукопожатие
  2. В сообщении ClientHello клиент включает расширение SNI с именем хоста
  3. Сервер использует это имя для выбора соответствующего сертификата
  4. Процесс рукопожатия продолжается с выбранным сертификатом

Пример SNI в ClientHello

Extension: server_name Type: server_name (0) Length: 19 Server Name Indication extension Server Name list length: 17 Server Name Type: host_name (0) Server Name length: 14 Server Name: example.com

Важность SNI

Примечание: SNI раскрывает имя хоста в незашифрованном виде во время рукопожатия TLS. Для дополнительной конфиденциальности существуют расширения как Encrypted SNI (ESNI) в TLS 1.3.

Поддержка браузерами

SNI поддерживается всеми современными браузерами. Для старых браузеров (например, IE на Windows XP) может потребоваться fallback-решение.

Настройка SNI на сервере

Пример конфигурации для Nginx:

server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/example.com.crt; ssl_certificate_key /path/to/example.com.key; ... } server { listen 443 ssl; server_name another.com; ssl_certificate /path/to/another.com.crt; ssl_certificate_key /path/to/another.com.key; ... }