Skip to content

TLS — Xray-core

Настройки TLS в Xray живут в streamSettings.tlsSettings, когда streamSettings.security равно "tls". Эта же структура покрывает ECH и семейство отпечатков uTLS. О REALITY см. REALITY — это параллельное значение streamSettings.security со своим собственным блоком.

Параметры TLS

ПолеТипПо умолчаниюДопустимые значенияОписание
allowInsecureboolfalsetrue | falseПропустить проверку сертификата сервера. Только для тестирования — в боевых конфигурациях это поле никогда не должно быть установлено.
certificates[]*TLSCertConfig[][TLSCertConfig]Сертификаты сервера (входящее подключение) или закрепление доверенных ЦС (исходящее). Несколько записей включают выбор по SNI на входящем подключении.
serverNamestring(inferred)<hostname>Ожидаемое имя сервера. На исходящем подключении — отправляемый SNI и значение, сверяемое с конечным сертификатом сервера. На входящем — SNI, используемый при выпуске сертификата через ACME.
alpn*StringList["h2", "http/1.1"]<ALPN string>Список согласования протоколов прикладного уровня (ALPN), предлагаемый пиру.
enableSessionResumptionboolfalsetrue | falseВключить возобновление TLS-сессий по session ticket (на стороне клиента).
disableSystemRootboolfalsetrue | falseИгнорировать системный набор корневых ЦС. При true принимаются только записи `certificates` (в режиме `verify`).
minVersionstring1.21.0 | 1.1 | 1.2 | 1.3Минимально допустимая версия TLS.
maxVersionstring1.31.0 | 1.1 | 1.2 | 1.3Максимально допустимая версия TLS.
cipherSuitesstring(library default)<comma-separated cipher list>Переопределить список наборов шифров. Использует имена в стиле OpenSSL (например, `TLS_AES_128_GCM_SHA256:...`). Внимание: для TLS 1.3 игнорируется — настраивается только выбор шифров для 1.2.
fingerprintstring(unset)chrome | firefox | safari | edge | 360 | qq | ios | android | random | randomizedОтпечаток ClientHello uTLS. Определяет всю форму ClientHello (наборы шифров, расширения, алгоритмы подписи) — перекрывает явное поле `cipherSuites`.
rejectUnknownSniboolfalsetrue | falseВходящее подключение — отклонять TLS-соединения, чей SNI не совпадает ни с одним из настроенных сертификатов.
curvePreferences*StringList(library default)X25519 | P-256 | P-384 | P-521 | X25519MLKEM768Переопределить список предпочтений кривых для обмена ключами. Порядок имеет значение.
masterKeyLogstring(unset)<file path>Путь в стиле SSLKEYLOGFILE для записи TLS-ключей (расшифровка в Wireshark). Не включайте в боевой среде.
pinnedPeerCertSha256string(unset)<base64 SHA-256>Закрепить сертификат пира. Только для исходящего подключения — соединение отклоняется, если SHA-256 конечного сертификата не совпадает.
verifyPeerCertByNamestring(unset)<hostname>Если задано, проверять, что Subject CN/SAN сертификата пира совпадает с этим именем, а не с `serverName`. Полезно, когда SNI отличается от канонического имени сертификата (схемы в духе REALITY).
echServerKeysstring(unset)<base64 ECHConfigList>Входящее подключение — набор серверных ключей ECH.
echConfigListstring(unset)<base64 ECHConfigList>Исходящее подключение — закреплённый список конфигураций ECH. Если не задан, ECH обнаруживается автоматически через DNS-запросы HTTPS-записей.
echSockopt*SocketConfig(unset)SocketConfigПараметры сокета, применяемые к DNS-запросу обнаружения ECH.

Исходный код: infra/conf/transport_security.go:300-319 · зафиксировано на v26.7.28 (5ca6f4b)

certificates[]

ПолеТипПо умолчаниюДопустимые значенияОписание
certificateFilestring(unset)<PEM file path>Путь к PEM-файлу сертификата. Взаимоисключимо с `certificate`.
certificate[]string(unset)[<PEM line>]PEM сертификата прямо в конфигурации, массивом строк (по элементу на строку либо весь PEM одним элементом).
keyFilestring(unset)<PEM file path>Путь к PEM-файлу закрытого ключа.
key[]string(unset)[<PEM line>]PEM закрытого ключа прямо в конфигурации.
usagestringenciphermentencipherment | verify | issueРоль этого сертификата: `encipherment` (сертификат сервера), `verify` (доверенный ЦС для проверки пира), `issue` (ЦС для выпуска сертификатов на каждое соединение в некоторых режимах пересылки).
ocspStaplinguint643600<seconds>Как часто обновлять OCSP-степлинг. 0 — отключено.
oneTimeLoadingboolfalsetrue | falseЧитать сертификат и ключ один раз при запуске, а не при каждой перезагрузке. Автоматически становится true при встроенных `certificate`/`key` (нет пути, откуда перечитывать).
buildChainboolfalsetrue | falseАвтоматически загружать промежуточные ЦС для построения полной цепочки, если в переданном PEM только конечный сертификат.

Исходный код: infra/conf/transport_security.go:248-257 · зафиксировано на v26.7.28 (5ca6f4b)

Примеры

Исходящее подключение — проверка по системному хранилищу корневых ЦС, принудительный TLS 1.3, отпечаток chrome:

json
{
  "streamSettings": {
    "security": "tls",
    "tlsSettings": {
      "serverName": "example.com",
      "alpn": ["h2", "http/1.1"],
      "minVersion": "1.3",
      "maxVersion": "1.3",
      "fingerprint": "chrome"
    }
  }
}

Входящее подключение — обслуживание сертификата Let's Encrypt:

json
{
  "streamSettings": {
    "security": "tls",
    "tlsSettings": {
      "serverName": "example.com",
      "certificates": [
        {
          "certificateFile": "/etc/ssl/cert.pem",
          "keyFile": "/etc/ssl/key.pem",
          "usage": "encipherment",
          "ocspStapling": 3600
        }
      ],
      "rejectUnknownSni": true
    }
  }
}

Исходящее подключение с закреплённым сертификатом (фиксация на конкретном SHA-256):

json
{
  "streamSettings": {
    "security": "tls",
    "tlsSettings": {
      "serverName": "example.com",
      "pinnedPeerCertSha256": "<base64-SHA256-of-leaf-cert>"
    }
  }
}

Примечания

  • fingerprint — это uTLS: он переписывает весь ClientHello, имитируя выбранный браузер. Когда он задан, cipherSuites, curvePreferences и minVersion/maxVersion по большей части игнорируются, потому что uTLS управляет ими сам.
  • TLS 1.3 игнорирует cipherSuites — так устроена стандартная библиотека Go; настраивается только выбор шифров TLS 1.2. Чтобы повлиять на выбор обмена ключами в TLS 1.3, используйте curvePreferences.
  • Поле certificates[].usage критично:
    • encipherment — обычный сертификат сервера.
    • verify — используется как доверенный корневой ЦС на исходящей стороне. Сочетайте с disableSystemRoot: true, чтобы игнорировать системный набор.
    • issue — используется для выпуска сертификатов на каждое соединение в некоторых режимах пересылки (MITM-пропуск HTTPS).
  • verifyPeerCertByName отвязывает SNI от проверяемого имени — полезно в схемах в духе REALITY, где SNI указывает на публичный сайт, а фактический сертификат выдан для сервера Xray.
  • masterKeyLog — отладочное средство; формат файла соответствует спецификации SSLKEYLOGFILE, которую понимает Wireshark. Никогда не включайте в боевой среде.

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

  • sing-box использует единый блок tls: { ... }, встроенный в каждое входящее и исходящее подключение. Имена полей в snake_case (server_name, cipher_suites), а REALITY / ECH / uTLS живут во вложенных под-блоках. См. TLS — sing-box.
  • mihomo рассыпает поля TLS прямо по каждому адаптеру прокси — tls, sni, alpn, skip-cert-verify и т. д. Единого блока TLS нет. См. TLS — mihomo.

Исходный код: infra/conf/transport_security.go:248-319 · v26.7.28 (5ca6f4b)

Core Tutorial от Argsment