Skip to content

TLS — sing-box ​

Каждый входящий и исходящий sing-box встраивает блок tls: { ... } через InboundTLSOptionsContainer / OutboundTLSOptionsContainer. Тот же блок содержит подблоки REALITY, ECH и uTLS как вложенные параметры — это не отдельные функции верхнего уровня.

Входящий tls ​

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseГлавный переключатель. При false остальная часть блока игнорируется.
server_namestring(inferred from SNI)<hostname>Ожидаемое имя сервера для выпуска сертификата через ACME. Обязательно, если задан acme.
insecureboolfalsetrue | falseПропустить проверку TLS. Только для тестов.
alpnbadoption.Listable[string][]<ALPN string>Список ALPN, предлагаемый клиентам.
min_versionstring1.21.0 | 1.1 | 1.2 | 1.3Минимально допустимая версия TLS.
max_versionstring1.31.0 | 1.1 | 1.2 | 1.3Максимально допустимая версия TLS.
cipher_suitesbadoption.Listable[string](library default)<cipher>Переопределить список наборов шифров (только TLS 1.2).
curve_preferencesbadoption.Listable[CurvePreference](library default)P256 | P384 | P521 | X25519 | X25519MLKEM768Список предпочитаемых кривых для обмена ключами.
certificatebadoption.Listable[string][]<PEM block>Встроенный PEM-сертификат сервера. Форма списка поддерживает полную цепочку.
certificate_pathstring(unset)<PEM file path>Путь к сертификату сервера.
client_authenticationClientAuthTypenono | request | require-any | verify-if-given | require-and-verifyПолитика клиентской аутентификации mTLS. Соответствует значениям ClientAuthType из crypto/tls.
client_certificatebadoption.Listable[string][]<PEM block>Доверенные корневые сертификаты клиентов (mTLS).
client_certificate_pathbadoption.Listable[string][]<PEM file path>Доверенные корневые сертификаты клиентов в виде путей.
client_certificate_public_key_sha256badoption.Listable[[]byte][]<SHA-256 bytes>Закрепить клиентский сертификат по SHA-256 открытого ключа. Полезно при выпуске одноразовых клиентских сертификатов.
keybadoption.Listable[string][]<PEM block>Встроенный приватный ключ сервера.
key_pathstring(unset)<file path>Путь к приватному ключу сервера.
kernel_txboolfalsetrue | falseKTLS в Linux — переложить TLS-шифрование исходящего трафика на ядро. Требует поддержки TLS в ядре и нужных криптомодулей.
kernel_rxboolfalsetrue | falseKTLS в Linux для входящего трафика.
handshake_timeoutbadoption.Duration15s<duration>Тайм-аут рукопожатия TLS (формат duration в Go).
certificate_provider*CertificateProviderOptions(unset)<provider tag> | CertificateProviderOptionsСертификат, управляемый поставщиком сертификатов: тег элемента верхнеуровневого certificate_providers или встроенный объект поставщика с type (acme, tailscale, cloudflare-origin-ca). Если задан, certificate / key не читаются. Взаимоисключим с acme; недоступен с reality.
acme*InboundACMEOptions(deprecated)InboundACMEOptionsУстарело: встроенный ACME. Используйте certificate_provider с type: acme — поля переносятся без изменений. Взаимоисключим с certificate_provider.
ech*InboundECHOptions(unset)InboundECHOptionsКонфигурация Encrypted Client Hello.
reality*InboundRealityOptions(unset)InboundRealityOptionsСерверная конфигурация REALITY. Взаимоисключима с обычным TLS — REALITY заменяет TLS-рукопожатие.

Исходный код: option/tls.go:13-40 · зафиксировано на v1.14.2 (af6e64c)

Исходящий tls ​

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseГлавный переключатель.
enginestringgogo | apple | windowsРеализация TLS для рукопожатия. apple использует Network.framework (сборки для Apple с CGO); windows — Schannel через SSPI (Windows build 17763+, TLS 1.3 только в Windows 11 / Server 2022+). Движки, отличные от go, принимают только server_name, insecure, alpn, min_version, max_version, certificate(_path), certificate_public_key_sha256 и handshake_timeout; любой другой параметр TLS отклоняется при запуске.
disable_sniboolfalsetrue | falseПолностью убрать расширение SNI из ClientHello.
server_namestring(server address)<hostname>SNI, отправляемый серверу, и имя, сверяемое с конечным (leaf) сертификатом.
insecureboolfalsetrue | falseПропустить проверку сертификата сервера.
alpnbadoption.Listable[string][]<ALPN string>Список ALPN, предлагаемый серверу.
min_versionstring1.21.0 | 1.1 | 1.2 | 1.3Минимально допустимая версия TLS.
max_versionstring1.31.0 | 1.1 | 1.2 | 1.3Максимально допустимая версия TLS.
cipher_suitesbadoption.Listable[string](library default)<cipher>Переопределить список наборов шифров.
curve_preferencesbadoption.Listable[CurvePreference](library default)<see inbound>Предпочтения кривых для обмена ключами.
certificatebadoption.Listable[string][]<PEM block>Доверенные сертификаты ЦС, добавляемые к системному корневому хранилищу. Используйте с insecure: false для серверов с самоподписанными сертификатами.
certificate_pathstring(unset)<file path>Доверенные ЦС в виде пути.
certificate_public_key_sha256badoption.Listable[[]byte][]<SHA-256 bytes>Закрепить сертификат сервера по SHA-256 открытого ключа.
client_certificatebadoption.Listable[string][]<PEM block>Клиентский сертификат (mTLS).
client_certificate_pathstring(unset)<file path>Клиентский сертификат в виде пути.
client_keybadoption.Listable[string][]<PEM block>Приватный ключ клиента.
client_key_pathstring(unset)<file path>Приватный ключ клиента в виде пути.
fragmentboolfalsetrue | falseФрагментация рукопожатия на уровне TCP. Разбивает ClientHello по пакетам, чтобы обойти DPI, работающий по SNI.
fragment_fallback_delaybadoption.Duration500ms<duration>Если фрагментированное рукопожатие не завершилось за это время, повторить попытку без фрагментации.
record_fragmentboolfalsetrue | falseФрагментация на уровне TLS-записей (агрессивнее fragment — разбивает сам поток TLS-записей, а не только TCP-пакеты).
spoofstring(unset)<hostname>Перед настоящим ClientHello отправлять его поддельную копию с этим SNI, чтобы обмануть middlebox-фильтры SNI, пропускающие определённые имена хостов. Должно отличаться от server_name. Только Linux, macOS и Windows; нужны права на raw-сокеты (CAP_NET_RAW + CAP_NET_ADMIN в Linux, root в macOS, администратор в Windows; Windows ARM64 не поддерживается).
spoof_methodstringwrong-sequencewrong-sequence | wrong-checksum | wrong-ack | wrong-md5 | wrong-timestampКак заставить настоящий сервер отбросить поддельный сегмент: номер последовательности вне окна (по умолчанию), неверная контрольная сумма, ACK вне окна, опция TCP-MD5 или отодвинутая в прошлое метка времени (wrong-timestamp не поддерживается в macOS).
kernel_txboolfalsetrue | falseKTLS в Linux для исходящего трафика.
kernel_rxboolfalsetrue | falseKTLS в Linux для входящего трафика.
handshake_timeoutbadoption.Duration15s<duration>Тайм-аут рукопожатия TLS (формат duration в Go).
ech*OutboundECHOptions(unset)OutboundECHOptionsКонфигурация ECH. Если не задана, ECH не используется (кроме автообнаружения через HTTPS-записи).
utls*OutboundUTLSOptions(unset)OutboundUTLSOptionsИмитация ClientHello через uTLS.
reality*OutboundRealityOptions(unset)OutboundRealityOptionsКлиентская конфигурация REALITY. Взаимоисключима с обычным TLS.

Исходный код: option/tls.go:107-136 · зафиксировано на v1.14.2 (af6e64c)

utls ​

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseВключить uTLS.
fingerprintstringchromechrome | firefox | safari | ios | android | edge | 360 | qq | random | randomizedИмитируемый отпечаток браузера. Определяет весь ClientHello (наборы шифров, расширения, подписи).

Исходный код: option/tls.go:247-250 · зафиксировано на v1.14.2 (af6e64c)

Поставщики сертификатов ​

Сертификат сервера может поступать от поставщика сертификатов, а не из файлов или встроенного блока acme. Поставщики объявляются в верхнеуровневом массиве certificate_providers (у каждого type и tag), а в tls.certificate_provider на них ссылаются по тегу — или прямо там задают встроенный объект поставщика. Типы: acme (нужен тег сборки with_acme), tailscale (переиспользует конечную точку Tailscale; в tailnet должны быть включены MagicDNS и HTTPS) и cloudflare-origin-ca. Полный справочник параметров: Поставщики сертификатов. Поставщик acme:

ПолеТипПо умолчаниюДопустимые значенияОписание
domainbadoption.Listable[string](required)<domain> | …Домены, для которых запрашиваются сертификаты. Обязательно.
data_directorystring(certmagic default)<dir path>Где хранятся состояние ACME и сертификаты. По умолчанию: $XDG_DATA_HOME/certmagic или $HOME/.local/share/certmagic.
emailstring(unset)<e-mail>E-mail учётной записи для создания или выбора аккаунта ACME.
providerstringletsencryptletsencrypt | zerossl | <https:// directory URL>ACME-CA. При zerossl учётные данные EAB запрашиваются автоматически, если задан email, а external_account пуст.
account_keystring(unset)<PEM key>PEM-ключ существующего аккаунта ACME.
dns01_challenge*ACMEProviderDNS01ChallengeOptions(unset)ACMEProviderDNS01ChallengeOptionsНастройки проверки DNS-01 (provider: alidns, cloudflare, acmedns, а также ttl, propagation_delay, propagation_timeout, resolvers, override_domain). Если заданы, остальные типы проверок отключаются.
key_typeACMEKeyType(certmagic default)ed25519 | p256 | p384 | rsa2048 | rsa4096Тип ключа для новых сертификатов.
profilestring(unset)<ACME profile>Профиль ACME для выпуска. С Let's Encrypt shortlived выбирается автоматически, если среди доменов есть IP-адрес.
http_client*HTTPClientOptions(default client)<http_clients tag> | HTTPClientOptionsHTTP-клиент для всех запросов ACME: встроенный объект или тег элемента http_clients.

Исходный код: option/acme.go:15-31 · зафиксировано на v1.14.2 (af6e64c)

Примеры ​

Входящий со встроенным поставщиком сертификатов ACME:

json
{
  "inbounds": [{
    "type": "vless",
    "listen_port": 443,
    "users": [{ "uuid": "..." }],
    "tls": {
      "enabled": true,
      "server_name": "example.com",
      "alpn": ["h2", "http/1.1"],
      "certificate_provider": {
        "type": "acme",
        "domain": ["example.com"],
        "email": "admin@example.com"
      }
    }
  }]
}

Исходящий с отпечатком chrome через uTLS и скрытием SNI фрагментацией TCP:

json
{
  "outbounds": [{
    "type": "vless",
    "server": "example.com",
    "server_port": 443,
    "uuid": "...",
    "tls": {
      "enabled": true,
      "server_name": "example.com",
      "utls": { "enabled": true, "fingerprint": "chrome" },
      "fragment": true,
      "fragment_fallback_delay": "500ms"
    }
  }]
}

Взаимный TLS — сервер требует клиентские сертификаты:

json
{
  "inbounds": [{
    "type": "http",
    "listen_port": 8443,
    "tls": {
      "enabled": true,
      "certificate_path": "/etc/ssl/cert.pem",
      "key_path": "/etc/ssl/key.pem",
      "client_authentication": "require-and-verify",
      "client_certificate_path": ["/etc/ssl/clients-ca.pem"]
    }
  }]
}

Примечания ​

  • Пять значений client_authentication напрямую соответствуют crypto/tls.ClientAuthType в Go:
    • no — без клиентского сертификата (по умолчанию).
    • request — запросить сертификат, но принимать и без него.
    • require-any — требовать, но не проверять.
    • verify-if-given — проверять, если предоставлен.
    • require-and-verify — строгий mTLS.
  • fragment и record_fragment — два разных уровня:
    • fragment разбивает TCP-пакеты, несущие TLS-рукопожатие.
    • record_fragment разбивает сами TLS-записи (записи Handshake отправляются несколькими меньшими частями). Сначала используйте fragment; включайте record_fragment, только если DPI по SNI всё ещё классифицирует соединение.
  • kernel_tx / kernel_rx включают KTLS в Linux для AES-GCM и CHACHA20-POLY1305. В ядре должен быть загружен модуль tls и зарегистрированы нужные криптомодули.
  • Встроенный tls.acme устарел. Перенесите его поля без изменений в certificate_provider с type: acme (встроенно, как в примере, или общим через certificate_providers + тег). certificate_provider и acme нельзя совмещать, и REALITY не принимает ни то, ни другое.
  • engine: apple / windows передают рукопожатие TLS-стеку ОС. При запуске они отклоняют uTLS, REALITY, ECH, фрагментацию, KTLS, клиентские сертификаты, cipher_suites, curve_preferences, disable_sni и spoof.
  • spoof (вместе с spoof_method) доступен и для отдельных соединений — как параметры действия правила маршрутизации tls_spoof / tls_spoof_method.
  • REALITY (подблок reality) полностью заменяет TLS-рукопожатие — см. REALITY — sing-box.
  • ECH (подблок ech) встраивается в то же рукопожатие — см. ECH — sing-box.

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

  • Xray-core использует streamSettings.tlsSettings, а не встроенный блок tls. Имена полей в camelCase (serverName, cipherSuites). Отпечаток uTLS — поле верхнего уровня, а не подблок. См. TLS — Xray-core.
  • mihomo не имеет единого TLS-блока — каждый адаптер прокси несёт TLS-поля непосредственно в себе (tls, sni, alpn, skip-cert-verify и т. д.). См. TLS — mihomo.

Исходный код: option/tls.go:13-250 · v1.14.2 (af6e64c)

Core Tutorial от Argsment