Зачем вообще нужен ECH и что он прячет
Если вы уже настраивали HTTPS, то знаете: содержимое HTTP-трафика шифруется, но часть «метаданных соединения» исторически оставалась видимой. Самая болезненная утечка приватности в TLS — это SNI (Server Name Indication): имя хоста, которое клиент отправляет в начале рукопожатия, чтобы сервер (или CDN/прокси) выбрал правильный сертификат и виртуальный хост.
Проблема простая: даже при идеальном HTTPS наблюдатель в сети видел домен назначения, потому что SNI передавался в открытом виде. DNS тоже может многое раскрывать, но даже при DoH/DoT и кэше резолвера SNI долго оставался «железным» источником правды.
ECH (Encrypted ClientHello) шифрует чувствительную часть ClientHello, включая SNI (и часть расширений), так что пассивный наблюдатель видит лишь «внешний» ClientHello без целевого домена. Это важный кусок общей истории про приватность TLS.
ECH не делает вас «невидимыми». Он закрывает конкретную утечку (SNI и часть ClientHello), но не заменяет нормальный DNS, здравую модель проксирования и грамотную TLS-конфигурацию.
Как ECH устроен концептуально: outer и inner ClientHello
В ECH рукопожатие условно делится на два слоя:
- Outer ClientHello — то, что видит сеть. В нём минимум информации, достаточный, чтобы дойти до ECH-совместимой точки входа (например, edge CDN), но без раскрытия целевого хоста.
- Inner ClientHello — зашифрованная часть, где лежит «настоящий» SNI и нужные расширения TLS.
Чтобы клиент смог зашифровать inner-часть, ему нужно заранее получить ECH-конфигурацию (публичный ключ и параметры). В современном мире это обычно доставляется через DNS в виде записей SVCB/HTTPS (часто говорят «HTTPS record»), где публикуется ECHConfig.
Практический вывод для админов: ECH тесно завязан на DNS-цепочку и чаще внедряется не на «голом origin», а на уровне фронта (CDN/edge), который управляет сертификатами и маршрутизацией.

Где здесь Nginx: что можно и чего нельзя ожидать
Самый частый вопрос от владельца origin-сервера: «А как включить ECH в Nginx?» На текущем этапе индустрии ответ обычно такой: ECH проще и реалистичнее включать на edge (CDN/прокси), а не на вашем Nginx.
- ECH требует, чтобы точка, принимающая первичное TLS-соединение, умела расшифровать inner ClientHello и дальше выбрать правильный маршрут/сертификат.
- Если у вас десятки доменов на одном IP, именно фронт должен понять, какой хост запрошен — а это как раз то, что ECH скрывает от сети, но не от доверенной точки входа.
- Даже если origin теоретически будет уметь ECH, остаётся вопрос распространения ECHConfig через DNS, совместимости клиентов и корректного фолбэка.
Поэтому в реальных прод-схемах Nginx чаще оказывается за CDN, а ECH «живет» на стороне фронта. На origin при этом по-прежнему важны обычные TLS-вещи: современные протоколы, корректные цепочки сертификатов, ALPN, HTTP/2, аккуратные таймауты и предсказуемая обработка заголовков.
Важная мысль: ECH защищает приватность на участке «клиент → точка терминации TLS». Если TLS терминируется на CDN, то ECH защищает именно этот участок, но не «CDN → origin» (там обычно отдельный TLS, часто с обычным SNI, и это нормально).
Если вы размещаете много сайтов на одном сервере и вам важно аккуратно управлять сертификатами и виртуальными хостами, проще держать это на предсказуемой площадке: для небольшой пачки сайтов часто достаточно виртуального хостинга, а для сложных схем с прокси, собственными правилами фаервола и кастомными демонами — VDS.
Cloudflare и ECH: типичная модель (на уровне CDN)
В типовом сценарии CDN выступает TLS-терминатором на краю сети. В этом режиме фронт может:
- опубликовать DNS-записи SVCB/HTTPS с ECHConfig;
- принять соединение от клиента по TLS и расшифровать ECH (inner ClientHello);
- маршрутизировать запрос на нужный hostname и отдать корректный сертификат, не раскрывая SNI пассивному наблюдателю.
Дальше CDN устанавливает отдельное соединение до origin. У origin в логах вы обычно увидите IP CDN (если не настроили прокидывание реального IP) и «внутренний» SNI/Host уже на канале CDN → origin. Это ожидаемо: задача ECH — не скрыть домен от вашего доверенного фронта, а скрыть его от посторонних на пути.
Отдельный практический момент: в мультидоменной схеме за CDN проще поймать ошибки, когда до origin доходит не тот виртуальный хост (дефолтный server), и вы видите странные 4xx/5xx. Для разбора таких кейсов полезно держать под рукой материал про ошибку 421 и SNI при работе через CDN и Nginx.
ECH и приватность: что реально улучшается (и что нет)
С точки зрения приватности TLS ECH закрывает классический кейс «видно домен по SNI». Это особенно заметно, когда много сайтов разделяют один IP (виртуальный хостинг, крупные CDN, SaaS-платформы).
Но важно понимать, какие сигналы остаются даже при ECH:
- IP-адрес точки входа всё равно виден. Если у домена выделенный IP и он ни с кем не делится, по одному IP часто можно догадаться о цели.
- DNS может раскрывать домен, если запросы видны наблюдателю или резолвер не защищён.
- Тайминги и поведение (размеры, частота, характер запросов) остаются косвенными признаками.
Поэтому ECH — не «серебряная пуля», а логичное продолжение эволюции HTTPS: убрать самые очевидные утечки там, где это технически возможно.
Совместимость клиентов и типовые причины «почему у меня не работает»
ECH — история не только про сервер/edge, но и про клиентов (браузеры, TLS-библиотеки, корпоративные прокси). На практике встречаются сценарии:
- клиент не поддерживает ECH и ходит обычным TLS с открытым SNI;
- клиент поддерживает ECH, но не получил ECHConfig (например, DNS-цепочка не отдала HTTPS record);
- в корпоративной среде включена TLS-инспекция (подмена сертификатов), из-за чего возникают ошибки или принудительный фолбэк;
- часть сетей/оборудования ломает или фильтрует неизвестные расширения TLS.
Если вы тестируете ECH «в лоб» на origin без CDN, обычно упираетесь в то, что клиенту буквально неоткуда взять корректный ECHConfig, либо ожидания по DNS/сертификатам не совпадают.
Как проверить ECH на практике: DNS, curl и базовая диагностика
Прикладная задача админа — понять две вещи: клиент пытается использовать ECH и соединение фактически проходит в ECH-режиме (если поддерживается). Экосистема всё ещё в движении, поэтому ключевое правило: ориентируйтесь на конкретные версии инструментов.
1) Проверяем версию curl и TLS-бэкенд
curl -V
В выводе смотрите, какой TLS-бэкенд используется (OpenSSL, LibreSSL, BoringSSL и т.п.). Поддержка ECH зависит именно от TLS-стека и сборки.
2) Базовая проверка HTTPS и согласование ALPN
curl -I -v https://example.com/
Это не про ECH напрямую, но помогает убедиться, что точка живая: какой протокол согласован (HTTP/2 или HTTP/1.1), что с цепочкой сертификатов, нет ли неожиданных редиректов.
3) Проверка DNS HTTPS-record (SVCB/HTTPS)
ECHConfig обычно публикуется через запись типа HTTPS. Быстро проверить наличие можно так (если ваши утилиты поддерживают тип HTTPS):
dig HTTPS example.com
Если ответ пустой, часто это означает, что клиенту неоткуда взять ECH-конфиг. Но учитывайте, что поддержка типа HTTPS есть не везде (и на стороне резолверов, и в локальных утилитах).
4) Ищем ECH-опции в curl (если они есть в вашей сборке)
curl --help all | grep -i ech
Если опции присутствуют, используйте именно те флаги, которые показывает ваш curl. Универсального и стабильного «curl --ech ...» для всех сборок тут нет: детали зависят от версии и TLS-бэкенда.
Если ECH в помощи не видно, но вам нужно протестировать — проще использовать отдельную тестовую VM/контейнер с актуальной сборкой curl и TLS-стеком. На прод-серверах это обычно не требуется.
5) Параллельная диагностика обычного TLS через openssl
openssl s_client -connect example.com:443 -servername example.com -tls1_3
Это покажет, что без ECH сервер корректно обслуживает ваш hostname по SNI. Если уже здесь проблемы с сертификатом/виртуальным хостом, ECH ничего не «исправит».
Что менять на origin Nginx, если ECH включён на edge
Самое важное: ECH на стороне CDN почти не требует изменений в конфиге Nginx. Но есть вещи, которые стоит привести в порядок, чтобы схема «клиент → CDN → Nginx» оставалась надёжной и предсказуемой.
1) Реальный IP клиента в логах и приложении
Иначе вы будете видеть только адреса CDN, а это ломает rate limit, аудит, антифрод и расследования. В Nginx обычно используют realip-модуль: real_ip_header и set_real_ip_from.
Критично: список доверенных диапазонов должен быть корректным и обновляться. Если не готовы сопровождать — лучше логировать IP прокси как есть, чем включать «доверие ко всем».
2) TLS от CDN до origin
Не выключайте TLS на участке CDN → origin «ради простоты». Если вы строите приватность на фронте, логично шифровать и внутренний участок. На практике это стандартный HTTPS-листенер Nginx и нормальный сертификат (в том числе origin-only).
Если вам нужен управляемый выпуск и продление сертификатов для origin, особенно в мультидоменной схеме, посмотрите на SSL-сертификаты: это снижает шанс «проспать» истечение цепочки и получить ночной инцидент.
3) SNI/Host и мультисайты на origin
Если на origin много server_name, убедитесь, что CDN ходит к вам с корректным SNI и заголовком Host. Иначе получите неправильный сертификат/дефолтный vhost и неожиданные 4xx/5xx.
4) Логи и приватность
ECH скрывает SNI «в сети», но вы сами можете раскрывать лишнее в логах. Проверьте, что вы не логируете чувствительные параметры запросов, токены, e-mail и прочие данные, которые не должны попадать в журналы.

Ограничения и подводные камни
- Нужны DNS HTTPS-record и корректная выдача этих записей клиентам (резолверы, кеширование, поддержка типов).
- Нужна поддержка клиента: часть устройств/ПО будет ходить без ECH.
- Диагностика усложняется: раньше по дампу трафика можно было увидеть SNI, теперь чаще придётся опираться на логи edge/origin и корреляцию запросов (request id).
- Не путайте ECH и ESNI: ESNI был ранним подходом и эволюционировал в ECH. В обсуждениях термины иногда смешивают.
Практический чек-лист: «хочу ECH на edge, у меня Nginx на бэкенде»
Убедитесь, что сайт стабильно работает по HTTPS без ECH: корректные сертификаты, цепочки, адекватные TLS-настройки, предсказуемые редиректы.
Проверьте, что у домена реально отдаются записи SVCB/HTTPS и клиенты могут получить ECHConfig через свои резолверы.
Проведите тесты клиентом, который умеет ECH (браузер/сборка curl с поддержкой), и зафиксируйте ожидаемое поведение.
На origin настройте real IP аккуратно и безопасно, чтобы не потерять видимость для rate limit, WAF-логики приложения и расследований.
Проверьте, что CDN доходит до нужного vhost на origin (SNI/Host), и что у вас нет «случайного» дефолтного сервера.
Заранее продумайте диагностику инцидентов: request id, единый формат логов, хранение логов edge/origin, минимизация PII.
Итоги
ECH (Encrypted ClientHello) — заметный шаг в сторону приватности HTTPS: он скрывает SNI и часть TLS ClientHello от пассивного наблюдателя. В реальной эксплуатации ECH чаще включается на уровне CDN/edge, а Nginx остаётся origin-сервером за прокси. Для админа это означает, что фокус должен быть не на «включить ECH в Nginx», а на корректной TLS-терминации на фронте, DNS HTTPS-record, совместимости клиентов и дисциплине на бэкенде (real IP, SNI/Host, логи).
Для проверки начинайте с базовой диагностики TLS и DNS, а затем используйте клиентские инструменты (curl/браузер), ориентируясь на конкретные возможности вашей сборки.


