# SNI

> Расширение TLS, в котором клиент в начале рукопожатия сообщает имя сайта; позволяет держать много HTTPS-сайтов с разными сертификатами на одном IP-адресе. Передаётся открыто, его шифрует Encrypted Client Hello.

Источник: https://llmdocs.ru/wiki/sni/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Полное название**: Server Name Indication
- **Спецификация**: RFC 3546 (2003), действующая — RFC 6066
- **Где передаётся**: в сообщении ClientHello рукопожатия TLS
- **Назначение**: виртуальный хостинг HTTPS на одном IP-адресе
- **Видимость**: открытым текстом (кроме ECH)
- **Шифрование имени**: Encrypted Client Hello (ECH)
**SNI** (англ. *Server Name Indication* — указание имени сервера) — расширение протокола [TLS](https://llmdocs.ru/wiki/tls.md), с помощью которого клиент в самом первом сообщении рукопожатия (ClientHello) сообщает, к какому доменному имени он подключается. Сервер, обслуживающий много сайтов на одном IP-адресе, по этому имени выбирает нужный сертификат и конфигурацию.[1]

Без SNI каждому HTTPS-сайту требовался бы отдельный IP-адрес. Сегодня SNI отправляют все браузеры и HTTP-клиенты, и именно он позволяет хостингам, [CDN](https://llmdocs.ru/wiki/cdn.md) и [обратным прокси](https://llmdocs.ru/wiki/reverse-proxy.md) обслуживать тысячи доменов на общих адресах.

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

В обычном [HTTP](https://llmdocs.ru/wiki/http.md) сервер узнаёт сайт из заголовка `Host`, поэтому на одном адресе легко размещать много сайтов (*виртуальный хостинг*). В HTTPS заголовок `Host` передаётся уже внутри зашифрованного канала, а чтобы установить канал, сервер должен сначала предъявить сертификат — но какой, если он ещё не знает, какой сайт нужен клиенту? SNI решает это, передавая имя до выбора сертификата.

Расширение описано в RFC 3546 в 2003 году, а сейчас — в RFC 6066.[2] Долгое время массовому использованию мешали старые клиенты — Internet Explorer на Windows XP и ранние версии Android, — но с их уходом SNI стал универсальным.

## Как это выглядит

```bash
# подключиться к IP-адресу, указав имя сайта для SNI
openssl s_client -connect 203.0.113.10:443 -servername example.com </dev/null | head -20

# curl сам отправляет SNI по имени из URL; --resolve подставляет IP
curl -v --resolve example.com:443:203.0.113.10 https://example.com
```

Если не указать `-servername`, сервер вернёт сертификат по умолчанию, и проверка имени, скорее всего, не пройдёт — частая причина недоумения при отладке.

На стороне сервера выбор по SNI происходит автоматически. В [nginx](https://llmdocs.ru/wiki/nginx.md) достаточно нескольких блоков `server` с разными `server_name` и сертификатами на одном порту:[5]

```nginx
server {
    listen 443 ssl;
    server_name shop.example.com;
    ssl_certificate     /etc/ssl/shop.crt;
    ssl_certificate_key /etc/ssl/shop.key;
}
server {
    listen 443 ssl;
    server_name blog.example.com;
    ssl_certificate     /etc/ssl/blog.crt;
    ssl_certificate_key /etc/ssl/blog.key;
}
```

## Приватность: SNI виден всем

SNI передаётся **открытым текстом**: TLS 1.3 зашифровал сертификат сервера и почти всё рукопожатие, но имя в ClientHello осталось видимым.[6] Провайдер, администратор сети или любой наблюдатель видит, на какие сайты ходит пользователь, даже не видя содержимого. Этим пользуются системы фильтрации трафика (DPI) для блокировки отдельных сайтов, корпоративные прокси и системы обнаружения угроз. Тот же эффект дают незашифрованные запросы [DNS](https://llmdocs.ru/wiki/dns.md).

## Encrypted Client Hello

Первая попытка скрыть имя — **ESNI** (2018) — шифровала только расширение SNI. Её заменила более общая схема **Encrypted Client Hello** (ECH): клиент шифрует весь «внутренний» ClientHello с настоящим именем открытым ключом, опубликованным в DNS-записи HTTPS (см. [DNS-записи (A, AAAA, CNAME, MX, TXT)](https://llmdocs.ru/wiki/dns-records.md)), а во «внешнем» ClientHello указывает общее имя фронтенд-сервера.[3] Наблюдатель видит только, что пользователь обращается, например, к CDN, но не к какому из тысяч сайтов за ним.

ECH поддерживают Firefox и Chrome и крупные CDN.[4] Для полной приватности его нужно сочетать с зашифрованным DNS (DoH, DoT), иначе имя утечёт через DNS-запрос.

## Связанные темы

- **Маршрутизация по SNI без расшифровки.** Балансировщики и прокси (HAProxy, nginx `stream` с `ssl_preread`) читают SNI из ClientHello и направляют TCP-соединение на нужный бэкенд, не завершая TLS.
- **Domain fronting** — приём, когда в SNI указан один домен CDN, а в зашифрованном заголовке `Host` — другой; использовался для обхода блокировок, сейчас большинство CDN его запрещают.
- **Несовпадение SNI и сертификата** — браузер покажет ошибку «сертификат выдан для другого имени»; проверьте `server_name` и поле SAN сертификата (см. [Сертификат X.509 и центры сертификации](https://llmdocs.ru/wiki/x509-certificates.md)).

## См. также

- [TLS](https://llmdocs.ru/wiki/tls.md)
- [Сертификат X.509 и центры сертификации](https://llmdocs.ru/wiki/x509-certificates.md)
- [nginx](https://llmdocs.ru/wiki/nginx.md)
- [DNS](https://llmdocs.ru/wiki/dns.md)
- [CDN](https://llmdocs.ru/wiki/cdn.md)

## Источники

1. [RFC 6066 — TLS Extensions: Extension Definitions (Server Name Indication)](https://www.rfc-editor.org/rfc/rfc6066)
2. [RFC 3546 — Transport Layer Security (TLS) Extensions](https://www.rfc-editor.org/rfc/rfc3546)
3. [IETF — TLS Encrypted Client Hello (draft-ietf-tls-esni)](https://datatracker.ietf.org/doc/draft-ietf-tls-esni/)
4. [Cloudflare Blog — Encrypted Client Hello: the last puzzle piece to privacy](https://blog.cloudflare.com/announcing-encrypted-client-hello/)
5. [nginx — Server names](https://nginx.org/en/docs/http/server_names.html)
6. [RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3](https://www.rfc-editor.org/rfc/rfc8446)
