Как работает Encrypted Client Hello (RFC 9849): внешний и внутренний ClientHello, ключ в DNS, что видят провайдер и CDN, и как проверить своё соединение.
Годами единственным элементом HTTPS-соединения, который всё ещё называл сайт открытым текстом, было поле Server Name Indication (SNI) в TLS-рукопожатии. Encrypted Client Hello (ECH) — стандартизированное исправление: браузер шифрует настоящий ClientHello и упаковывает его во внешний, безобидный на вид. Но значение ECH легко преувеличить. Он переносит секрет с «всех на пути» на «сервер, который расшифровывает», а на виду остаётся больше рукопожатия, чем принято считать. Здесь разобран механизм и для каждой стороны показано, что может и чего не может прочитать каждый наблюдатель.
Главное
- ECH стал стандартом. Спецификация опубликована как RFC 9849 (Proposed Standard, март 2026) после многих лет в статусе черновика
draft-ietf-tls-esni. - Два ClientHello в одном соединении. Браузер отправляет читаемый внешний ClientHello, адресованный
public_nameфронтального сервера, а настоящий внутренний ClientHello (с реальным SNI и списком ALPN) зашифрован внутри него. - Ключ берётся из DNS. Конфигурация ECH сервера публикуется в DNS-записи HTTPS/SVCB (RFC 9460), поэтому ECH защищает, только если сам этот запрос не читается. В RFC прямо сказано, что шифрование SNI малополезно без шифрования DNS.
- Сетевой отпечаток внешнего hello всё ещё возможен. Внешний hello — настоящий читаемый ClientHello, а спецификация разрешает клиенту копировать в него поля из внутреннего, так что привычки TLS-библиотеки не обязаны исчезнуть из трафика.
- Сервер, который расшифровывает, видит всё. ECH меняет то, что видит сеть, но не то, что видят CDN или исходный сервер.
Какую проблему решает ECH
TLS 1.3 шифрует сертификат сервера и большую часть рукопожатия, но ClientHello должен быть читаем до появления ключей. Поэтому SNI, сообщающий серверу, какое из его многих имён вам нужно, шёл открытым текстом. RFC называет его «возможно, самой чувствительной информацией, оставшейся незашифрованной в TLS 1.3». Более ранний документ с требованиями, RFC 8744, объясняет, почему прежние попытки зашифровать SNI были сложными, — отсюда и то, что готовый стандарт появился только в 2026 году. О том, что SNI выдаёт провайдеру или оператору Wi-Fi, читайте в статье что провайдер всё ещё видит при HTTPS; здесь речь о том, как работает исправление.
Внешний и внутренний ClientHello
С ECH браузер строит два сообщения:
- ClientHelloInner (внутреннее) — настоящее сообщение рукопожатия: реальный SNI, список ALPN (он объявляет протоколы вроде HTTP/2 или HTTP/3) и остальные расширения. Оно шифруется открытым ключом сервера с помощью HPKE (гибридное шифрование с открытым ключом) и дополняется заполнением, чтобы длина выдавала меньше.
- ClientHelloOuter (внешнее) — обычный на вид ClientHello. Его
server_nameравенpublic_nameиз конфигурации ECH — имени фронтального сервера (client-facing server — сервера, принимающего подключения клиентов), например общего имени хоста CDN. Зашифрованное внутреннее сообщение передаётся внутри в расширенииencrypted_client_hello.
Фронтальный сервер пытается расшифровать расширение. Если получилось, он продолжает рукопожатие по внутреннему hello, и соединение идёт к настоящему сайту. Если нет (неверный ключ или расширение было заглушкой), он считает внешний hello единственным содержимым и отвечает от имени public_name. Спецификация описывает две схемы: общий режим, где один провайдер — и фронтальный сервер, и исходный, и раздельный режим, где фронтальный сервер пересылает расшифрованный hello отдельному бэкенду.
RFC прямо формулирует одно следствие: ECH «показывает, что клиент подключается к конкретному поставщику услуг, но не показывает, какой именно сервер из анонимного множества завершает соединение». Если у сайта собственный IP, его выдаёт уже адрес назначения. ECH помогает тем сильнее, чем больше сайтов делят одну «входную дверь».
Откуда берётся ключ: DNS
Браузеру нужен открытый ключ сервера до подключения, и он получает его из DNS. Сервер публикует ECHConfigList (одну или несколько записей ECHConfig с ключом, идентификатором конфигурации и public_name) в DNS-записи HTTPS или SVCB, тип которой определён в RFC 9460.
Так возникает цепочка зависимостей. Если запрос записи HTTPS идёт открытым текстом, ваш резолвер и любой на пути узнают имя хоста раньше, чем ECH что-либо скроет. RFC отмечает также, что шифрованный DNS защищает от подмены конфигурации ECH атакующим в локальной сети, а шифрование SNI «менее полезно без шифрования DNS-запросов при передаче». На практике это DNS over HTTPS или DNS over TLS. Как настроить и проверить, описано в защите от DNS-утечек.
Кто что видит: таблица трёх наблюдателей
| Сеть на пути (провайдер, Wi-Fi) | Фронтальный сервер (например, CDN) | Исходный сервер за ним | |
|---|---|---|---|
| IP назначения | Да | Да | Да |
Внешний SNI (public_name) | Да | Да | Раздельный режим: нет |
| Реальный SNI и внутренний ALPN | Нет (зашифрованы) | Да, после расшифровки | Да |
| Прочие поля, скопированные во внешний hello | Да | Да | Неприменимо |
| Полный внутренний ClientHello | Нет | Да | Да |
| DNS-запрос открытым текстом, если он есть | Да | Неприменимо | Неприменимо |
Две строки заслуживают внимания. Во-первых, реальный SNI скрыт от сети, но не от стороны, которая завершает соединение. ECH — это не анонимность: CDN по-прежнему знает, к какому из его клиентов вы заходите. Во-вторых, строка «прочие поля» удивляет больше всего.
Что сетевой JA3/JA4 всё ещё читает
Распространённое упрощение, которое встречается и в нашей основной статье о TLS-отпечатках, звучит так: ECH оставляет наблюдателю лишь минимальный внешний ClientHello, что ограничивает снятие отпечатка. RFC подтверждает первую половину и осторожнее со второй. Строя внешний hello, клиент следует короткому списку правил (предложить TLS 1.3 или выше, скопировать идентификатор сессии, использовать новое случайное число, поместить public_name в server_name), а затем, по тексту, «он МОЖЕТ (MAY) скопировать любое другое поле из ClientHelloInner, кроме ClientHelloInner.random». В обсуждении анонимного множества спецификация добавляет, что особенности реализации, например порядок расширений в TLS-сообщениях, могут давать разное внешне видимое поведение даже при одинаковых настройках.
Так что внешний hello — настоящий ClientHello: в нём есть наборы шифров, расширения, поддерживаемые группы и порядок, и всё это читается в трафике. Пассивный наблюдатель может вычислить для него отпечаток вроде JA3 или JA4. Меняется то, какое hello описывает отпечаток и какие поля скрыты: реальный SNI и внутренний список ALPN больше не видны, а признак наличия SNI и значение ALPN, которые фиксирует JA4, берутся из внешнего hello. Будет ли внешний отпечаток таким же различимым, как сегодня, зависит от реализации каждого браузера, и RFC этого не гарантирует. Поэтому утверждение «ECH побеждает сетевые TLS-отпечатки» не доказано, а точнее сказать: «наблюдатель читает меньше». (То же верно для QUIC: см. отпечатки HTTP/3 и QUIC.)
На стороне сервера всё иначе. Фронтальный сервер расшифровывает внутренний hello и видит полный отпечаток клиента, поэтому вендоры антибот-защиты на уровне CDN ничего не теряют из-за ECH.
GREASE ECH: почему само расширение ни о чём не говорит
Браузер, у которого нет конфигурации ECH для сайта, всё равно отправляет расширение encrypted_client_hello, заполненное случайными байтами правдоподобной длины. RFC называет это GREASE ECH (идея та же, что у фиктивных значений в RFC 8701). Оно нужно, чтобы настоящий ECH не выделялся и промежуточные устройства не могли дёшево блокировать «расширение ECH», не ломая обычные соединения. Сервер, который не может его расшифровать, просто игнорирует его.
Практический вывод: если расширение видно в захваченном трафике, это ничего не говорит о том, было ли соединение защищено. Важно только успешное рукопожатие с принятым ECH. Спецификация честно признаёт, что GREASE и настоящий ECH неразличимы лишь для ограниченного пассивного наблюдателя; значения вроде внешнего SNI или идентификатора конфигурации по-прежнему могут их отличать.
Сбои: повторы, откат и блокировка
- Устаревший ключ и retry_configs. Кэш DNS и ротация ключей делают ключ в браузере устаревшим. Если сервер не может расшифровать, он завершает рукопожатие по внешнему hello и возвращает свежие
retry_configsв зашифрованном сообщении. Клиент проверяет сертификат на соответствиеpublic_name, затем повторяет попытку с новой конфигурацией. Спецификация велит клиентам не принимать повторныеretry_configsв ответ на повторную попытку: это признак неверно настроенного сервера. ech_required. Если клиент предложил настоящий ECH, а соединение в итоге обошлось без него, клиент прерывает его до отправки данных приложения, а не тихо откатывается к открытому SNI.- Конфигурации нет вовсе. Если в DNS-записи нет параметра ECH (или запись HTTPS вырезана), у браузера нет ключа для шифрования, и он подключается по-старому, с GREASE, если его поддерживает. Покажет ли браузер при этом ошибку или продолжит — решение продукта, так что ECH стоит считать механизмом «по возможности» (best-effort).
- Сети, которым ECH не по душе. RFC признаёт, что некоторые операторы могут блокировать настоящий ECH, пропуская GREASE, а управляемые среды, которые опираются на SNI для фильтрации или балансировки, могут отключать ECH политикой. Заявления о невозможности блокировки нет, сказано лишь, что ECH спроектирован так, чтобы пассивному наблюдателю было трудно отличить его от GREASE.
Проценты внедрения здесь не приводятся: любая цифра зависит от того, какие сайты и клиенты считать. О том, как крупный CDN внедрял ECH и что это значит для операторов, можно прочитать в материале Cloudflare.
Как проверить своё соединение
У любого сайта за Cloudflare есть диагностическая страница /cdn-cgi/trace. Откройте её и найдите строку sni=: sni=encrypted означает, что соединение использовало ECH, а sni=plaintext — что реальное имя сервера прошло по сети открытым текстом. Когда мы 2026-10-12 запросили browserinsight.net/cdn-cgi/trace клиентом без ECH, пришло sni=plaintext, и это ожидаемый результат для клиента без опубликованного ключа или с выключенным ECH. Проверка работает только для сайтов за Cloudflare, а собственные инструменты BrowserInsight ECH не определяют.
Выполните условия, и результат улучшится: используйте браузер с поддержкой ECH, включите шифрованный DNS и заходите на сайт, оператор которого опубликовал запись HTTPS с конфигурацией ECH. Что остаётся видимым и при этом, подскажет проверка IP, которая показывает адрес, видимый серверу: IP назначения остаётся виден сети независимо от ECH.
Часто задаваемые вопросы
Скрывает ли ECH от провайдера, какие сайты я посещаю?
Частично. Он скрывает реальное имя сервера в рукопожатии, но провайдер по-прежнему видит IP назначения и внешний public_name. Для сайтов, делящих IP со многими другими, например за крупным CDN, остаётся реальная неопределённость; у сайта с собственным IP его выдаёт один адрес.
Заменяет ли ECH VPN?
Нет. VPN меняет положение наблюдателя: провайдер видит только VPN, а VPN-сервис видит то, что видел бы провайдер. ECH скрывает от сети одно поле, а IP назначения, время и объём трафика остаются видимыми.
Работает ли ECH без шифрованного DNS?
Подключиться можно, но выигрыш в приватности ослабевает. Ключ берётся из DNS-записи, и запрос открытым текстом выдаёт имя хоста резолверу и устройствам на пути ещё до начала рукопожатия.
Может ли сайт узнать, использовал ли я ECH?
Да. Фронтальный сервер знает, расшифровал ли он расширение ECH, и CDN это показывает, как видно по строке sni= в выводе trace. Внутренний ClientHello этому серверу виден полностью.
Доказывает ли расширение в захваченном трафике, что ECH использовался?
Нет. Браузеры отправляют GREASE ECH, когда конфигурации нет, поэтому расширение может присутствовать и в незащищённых соединениях.


