Server Name Indication (SNI)
Server Name Indication (SNI) - это расширение протокола TLS, которое позволяет клиенту указать имя сервера, к которому он пытается подключиться, в начале процесса рукопожатия.
Проблема, которую решает SNI
В традиционном HTTPS-соединении сервер должен предоставить правильный сертификат до того, как клиент отправит HTTP-заголовок Host. Это создаёт проблему для виртуальных хостов, когда несколько доменов используют один IP-адрес.
Без SNI:
Клиент → Сервер (IP-адрес) → ? Какой сертификат предоставить?
С SNI:
Клиент → Сервер (с указанием доменного имени) → Сервер предоставляет правильный сертификат
Как работает SNI
- Клиент инициирует TLS-рукопожатие
- В сообщении ClientHello клиент включает расширение SNI с именем хоста
- Сервер использует это имя для выбора соответствующего сертификата
- Процесс рукопожатия продолжается с выбранным сертификатом
Пример 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
- Позволяет размещать несколько HTTPS-сайтов на одном IP-адресе
- Экономит IPv4-адреса
- Стандарт для современных веб-серверов и облачных платформ
Примечание: 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;
...
}