ECH
ECH (Encrypted Client Hello) шифрует TLS ClientHello, включая SNI (Server Name Indication), так что промежуточным устройствам виден только подставное «публичное имя» (public name).
Без ECH SNI передаётся в открытом виде в каждом рукопожатии, что позволяет промежуточным устройствам анализировать и блокировать его. С ECH настоящее имя сервера находится внутри зашифрованных данных.
Обратите внимание, что ECH защищает только SNI в QUIC/TLS-рукопожатии. Если вы уже используете обфускацию, всё соединение и так не распознаётся как QUIC, поэтому ECH не даёт дополнительной выгоды. ECH наиболее полезен в «голом» режиме, где QUIC-рукопожатие стандартное, а SNI — основной открытый отпечаток.
Как это работает
Развёртывание ECH включает два артефакта, генерируемых вместе как пара ключей:
- Приватный ключ, который остаётся на сервере и используется для расшифровки настоящего ClientHello.
- Config list (публичный), который клиенты используют для шифрования своего ClientHello. Он также содержит public name — подставной SNI, который отображается в открытом виде.
Когда клиент подключается с ECH, он отправляет ClientHello, видимый SNI которого — это public name (например, decoy.example.com), тогда как настоящий SNI и остальная часть рукопожатия зашифрованы внутри расширения ECH.
Генерация ключей
Hysteria не генерирует ключи ECH самостоятельно. Мы рекомендуем использовать sing-box для создания пары ключей:
Аргумент — это public name. Он НЕ обязан быть доменом, которым вы владеете, но для лучшей маскировки это должно быть безобидное имя, которое правдоподобно обслуживает обычный трафик. Команда выводит два PEM-блока:
-----BEGIN ECH CONFIGS-----
...
-----END ECH CONFIGS-----
-----BEGIN ECH KEYS-----
...
-----END ECH KEYS-----
Сохраните весь вывод в файл (например, ech.pem). Сервер считывает из него блок ECH KEYS; вам не нужно вручную разделять блоки.
Настройка сервера
Добавьте блок ech, указывающий на файл ключа.
При запуске сервер выводит в лог config list, который нужен клиентам:
INFO ECH enabled, set the following config list on clients (tls.ech) {"configList": "AEz+DQBIAAAg..."}
Скопируйте эту строку в base64 — именно её вы передаёте клиентам. (Это то же значение, что и блок ECH CONFIGS, только закодированное в base64 в одну строку.)
Настройка клиента
Установите tls.ech равным config list из лога сервера. Значением может быть непосредственно строка base64 или путь к файлу, содержащему её (либо сырой base64, либо PEM-блок ECH CONFIGS):
- Ваше настоящее имя сервера, используемое для проверки сертификата.
- Config list из лога сервера или путь к файлу, содержащему его.
Config list также можно передать в URI для обмена через параметр запроса ech.
Важные особенности поведения
-
Включение ECH обратно совместимо. Сервер с включённым ECH по-прежнему принимает клиентов, которые не используют ECH; такие клиенты просто отправляют свой SNI в открытом виде, как раньше. Это означает, что вы можете включить ECH на сервере, не ломая существующих клиентов.
-
Fail-closed. Если клиент настроен на ECH, но сервер его отклоняет (например, потому что config list устарел после повторной генерации ключей или на сервере ECH вообще не настроен), соединение завершается неудачей.
-
insecureне применяется к отклонению ECH. Когда ECH отклоняется, TLS-стек выполняет обязательную проверку сертификата по public name и игнорируетtls.insecure. Если вы тестируете с самоподписанным сертификатом, а сервер на самом деле не принимает ECH, вы увидите ошибку проверки сертификата.