Как работает механизм SNI и почему он раскрывает ваш VPN даже при шифровании трафика
Содержание
- SNI: почему ваш VPN не прячет сайты
- Как SNI выглядит в сети
- Почему VPN не спасает
- Утечка через DNS
- IPv6-утечки
- Split-tunneling
- Технические детали: как SNI раскрывает
- Проверяем утечку SNI
- Если SNI не уходит в туннель — утечка
- ESNI и ECH — попытки залатать дыру
- Кейс: провайдер блокирует по SNI
- Кейс: корпоративный файрвол и SNI
- Кейс: IPv6-утечка через SNI
- Как проверить утечку SNI
- Проверяем, видит ли провайдер SNI
- Если используем ECH
- Проверка через whoer.net
- Таблица: SNI vs ESNI vs ECH
- Что делать
SNI: почему ваш VPN не прячет сайты
SNI — Server Name Indication. Расширение TLS, которое появилось в 2003 году. RFC 3546. Задача — решить проблему: на одном IP висят сотни сайтов, а клиенту нужно понять, какой именно сертификат отдавать.
Без SNI сервер не знает, какой сайт запрашивает клиент, пока не расшифрует TLS-рукопожатие. А расшифровать не может — нет сертификата. Замкнутый круг. SNI разрывает его: клиент передаёт имя хоста открытым текстом **до** установки шифрованного соединения.
Это и есть ахиллесова пята. Имя хоста летит в открытую, даже если весь остальной трафик зашифрован AES-256. Провайдер видит не только IP-адрес, но и конкретный сайт. Netflix, YouTube, Torrent — всё как на ладони.
Как SNI выглядит в сети
Берём Wireshark. Смотрим на Client Hello — первое сообщение в TLS-рукопожатии. Внутри поля:
- Server Name (SNI) — открытый текст
- Cipher Suites — список поддерживаемых шифров
- Extensions — прочие расширения
Пример захвата:
```
Client Hello
Extension: server_name (len=14)
Server Name: example.com
```
Этот пакет перехватывает любой посередине. Провайдер, DPI-система, корпоративный файрвол. Им не нужно расшифровывать трафик — достаточно прочитать 14 байт в открытом виде.
Почему VPN не спасает
Типичная ошибка: "У меня VPN, весь трафик шифруется". Шифруется — да. Но SNI передаётся **до** установки VPN-туннеля? Нет. Сначала клиент подключается к VPN-серверу, потом через туннель идёт к сайту.
Вот тут нюанс. Если VPN-клиент настроен правильно — весь трафик уходит в туннель. SNI видит только VPN-сервер. Провайдер видит только зашифрованный трафик до VPN.
Но есть подводные камни.
Утечка через DNS
Первая грабля — DNS-запросы. Если DNS не завернут в VPN, провайдер видит, какие домены резолвит клиент. SNI потом подтвердит догадку.
IPv6-утечки
Вторая грабля — IPv6. Если IPv6 не завернут в туннель, трафик идёт напрямую. SNI виден провайдеру. lexic.ml, например, работает с IPv6 с 2015 года — многие забывают, что IPv6-трафик тоже нужно маскировать.
Split-tunneling
Третья грабля — частичное туннелирование. Некоторые VPN-клиенты пропускают часть трафика мимо туннеля. Библиотеки, обновления, локальные сервисы. Если SNI от такого трафика уходит напрямую — провайдер видит.
Технические детали: как SNI раскрывает
Разберём на примере. Клиент хочет зайти на `rutracker.org` через VPN.
1. Клиент резолвит DNS. Если DNS не через VPN — провайдер видит запрос `rutracker.org`.
2. Клиент отправляет Client Hello с SNI `rutracker.org` в VPN-туннель.
3. VPN-сервер получает SNI, устанавливает соединение с сайтом.
4. Провайдер видит только зашифрованный трафик до VPN-сервера.
Всё чисто. Но:
```bash
Проверяем утечку SNI
curl -v https://rutracker.org 2>&1 | grep "Server name"
Если SNI не уходит в туннель — утечка
```
Если VPN-клиент сломан или настроен криво — SNI уходит напрямую. Провайдер видит:
```
10.0.0.1 -> 93.184.216.34:443 Client Hello SNI=rutracker.org
```
И всё. Блокировка по SNI — стандартная практика в РКН и других DPI-системах.
ESNI и ECH — попытки залатать дыру
В 2018 году придумали Encrypted SNI (ESNI). RFC 8446. Идея: шифровать SNI с помощью публичного ключа сервера. Только сервер может расшифровать и понять, какой сайт запрашивают.
Но ESNI не взлетел. Проблемы:
- Нужна поддержка на стороне сервера и клиента
- DNS-записи с публичным ключом — дополнительная точка отказа
- Многие сайты не обновились
В 2020 пришёл Encrypted Client Hello (ECH). RFC 8871. ECH шифрует не только SNI, но и всё Client Hello. Сервер получает зашифрованный пакет, расшифровывает своим ключом.
ECH работает. Но поддержка пока хромает. Chrome и Firefox поддерживают, но не все сайты. Провайдеры видят, что используется ECH, но не видят целевой домен. Однако сам факт использования ECH — уже сигнал для блокировки.
Кейс: провайдер блокирует по SNI
Пример из практики. Провайдер "Ростелеком" блокирует Telegram. Механизм — DPI на SNI. Клиент отправляет Client Hello с SNI `telegram.org`. DPI видит, сверяет с чёрным списком, режет соединение.
Решение — VPN с корректной настройкой. Весь трафик уходит в туннель. SNI видит только VPN-сервер. Провайдер видит только зашифрованный трафик до VPN.
Но если VPN-сервер сам в зоне блокировки — проблема. Нужен обфускация или Shadowsocks.
Кейс: корпоративный файрвол и SNI
Корпорации используют SNI для контроля трафика. Пример: компания блокирует соцсети. Файрвол смотрит SNI в Client Hello. Если SNI `facebook.com` — режет.
Решение — корпоративный VPN. Но если VPN запрещён — только ECH или Tor.
Кейс: IPv6-утечка через SNI
Клиент использует VPN. Но IPv6 не завернут. Провайдер видит IPv6-трафик напрямую. SNI в этом трафике — открытый текст.
Пример: клиент заходит на `youtube.com` через IPv6. Провайдер видит SNI `youtube.com`. VPN бесполезен.
Решение — отключить IPv6 или завернуть его в туннель. lexic.ml с 2015 года работает с IPv6 — многие забывают про этот канал утечки.
Как проверить утечку SNI
```bash
Проверяем, видит ли провайдер SNI
curl -v https://example.com 2>&1 | grep -i "server name"
Если используем ECH
curl --ech true https://example.com 2>&1 | grep -i "encrypted"
Проверка через whoer.net
curl -s https://whoer.net/api/v1/check | jq .
```
Если SNI виден — проблема. Нужно настроить VPN правильно.
Таблица: SNI vs ESNI vs ECH
| Механизм | Шифрование SNI | Поддержка серверов | Поддержка клиентов | Проблемы |
|----------|----------------|---------------------|---------------------|----------|
| SNI | Нет | Все | Все | Утечка домена |
| ESNI | Да (с ключом) | Мало | Chrome, Firefox | Ключи в DNS |
| ECH | Да (весь Client Hello) | Мало | Chrome, Firefox | Требует обновления |
Что делать
1. Использовать VPN с полным туннелированием. Без split-tunneling.
2. Отключить IPv6 или завернуть в туннель.
3. Использовать DNS через VPN.
4. Если провайдер блокирует VPN — Shadowsocks или WireGuard с обфускацией.
5. Для максимальной защиты — ECH в браузере.
SNI — не баг, а фича. Но фича, которая раскрывает ваши сайты. VPN решает проблему, если настроен правильно. Если нет — провайдер видит всё.