Skip to content

ECH — sing-box

sing-box реализует ECH с обеих сторон как вложенный подблок блока tls:. Обе структуры разделяют устаревшие переключатели постквантовых подписей, оставшиеся с экспериментальной фазы черновиков TLS 1.3, — в текущих сборках оба ничего не делают.

Входящий tls.ech

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseВключить ECH для этого входящего.
keybadoption.Listable[string][]<base64 ECH key>Встроенный набор ключей ECH. Принимает одну строку или список строк (по одному блоку в стиле PEM на запись).
key_pathstring(unset)<file path>Путь к файлу с набором ключей ECH. Взаимоисключим с `key`.
pq_signature_schemes_enabledboolfalsetrue | falseУстарело. Постквантовые схемы подписи не поддерживаются стандартной библиотекой Go.
dynamic_record_sizing_disabledboolfalsetrue | falseУстарело. Установка этого поля не давала эффекта даже тогда, когда оно поддерживалось.

Исходный код: option/tls.go:206-215 · зафиксировано на v1.13.15 (3708fa1)

Исходящий tls.ech

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseВключить ECH для этого исходящего.
configbadoption.Listable[string][]<base64 ECHConfigList>Закреплённый список конфигураций ECH. Если не задан, sing-box обнаруживает его автоматически через DNS-записи HTTPS.
config_pathstring(unset)<file path>Закреплённая конфигурация в виде пути.
query_server_namestring(server_name)<hostname>Имя хоста для DNS-запроса HTTPS-записи при автообнаружении ECH. По умолчанию — `tls.server_name` исходящего.
pq_signature_schemes_enabledboolfalsetrue | falseУстарело.
dynamic_record_sizing_disabledboolfalsetrue | falseУстарело.

Исходный код: option/tls.go:217-227 · зафиксировано на v1.13.15 (3708fa1)

Примеры

Входящий — обслуживание ECH с файлом ключа:

json
{
  "inbounds": [{
    "type": "vless",
    "listen_port": 443,
    "users": [{ "uuid": "..." }],
    "tls": {
      "enabled": true,
      "server_name": "example.com",
      "certificate_path": "/etc/ssl/cert.pem",
      "key_path": "/etc/ssl/key.pem",
      "ech": {
        "enabled": true,
        "key_path": "/etc/sing-box/ech.key"
      }
    }
  }]
}

Исходящий — оппортунистический ECH (автообнаружение):

json
{
  "outbounds": [{
    "type": "vless",
    "server": "example.com",
    "server_port": 443,
    "uuid": "...",
    "tls": {
      "enabled": true,
      "server_name": "example.com",
      "ech": { "enabled": true }
    }
  }]
}

Исходящий — закреплённая конфигурация ECH:

json
{
  "outbounds": [{
    "type": "vless",
    "server": "example.com",
    "server_port": 443,
    "uuid": "...",
    "tls": {
      "enabled": true,
      "server_name": "example.com",
      "ech": {
        "enabled": true,
        "config": ["<base64 ECHConfigList>"],
        "query_server_name": "cover.example.com"
      }
    }
  }]
}

Примечания

  • ECH требует TLS 1.3. Задайте tls.min_version: "1.3", если хотите требовать его принудительно; на 1.2 расширение ECH молча отбрасывается.
  • Поле key входящего принимает список, потому что операторы часто ротируют ключи ECH — перечисление нового ключа рядом со старым позволяет клиентам с кэшированным состоянием HKDF завершить последние запросы перед переключением.
  • Автообнаружение (исходящий с enabled: true и пустым config) запрашивает DNS-запись HTTPS для query_server_name (или tls.server_name, если переопределение пусто). Цепочка резолверов следует стандартной DNS-конфигурации sing-box.
  • Два устаревших поля (pq_signature_schemes_enabled, dynamic_record_sizing_disabled) сохранены для совместимости парсера, но не влияют на работу — их можно смело удалять из существующих конфигураций.

Сравнение с другими ядрами

  • Xray-core предоставляет ECH как три поля прямо в tlsSettings (echServerKeys, echConfigList, echSockopt), а не как подблок. См. ECH — Xray-core.
  • mihomo использует блок ech-opts на каждом прокси с теми же тремя пользовательскими полями (enable, config, query-server-name). См. ECH — mihomo.

Исходный код: option/tls.go:206-227 · v1.13.15 (3708fa1)

Core Tutorial от Argsment