TLS — Xray-core
Настройки TLS в Xray живут в streamSettings.tlsSettings, когда streamSettings.security равно "tls". Эта же структура покрывает ECH и семейство отпечатков uTLS. О REALITY см. REALITY — это параллельное значение streamSettings.security со своим собственным блоком.
Параметры TLS
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
allowInsecure | bool | false | true | false | Пропустить проверку сертификата сервера. Только для тестирования — в боевых конфигурациях это поле никогда не должно быть установлено. |
certificates | []*TLSCertConfig | [] | [TLSCertConfig] | Сертификаты сервера (входящее подключение) или закрепление доверенных ЦС (исходящее). Несколько записей включают выбор по SNI на входящем подключении. |
serverName | string | (inferred) | <hostname> | Ожидаемое имя сервера. На исходящем подключении — отправляемый SNI и значение, сверяемое с конечным сертификатом сервера. На входящем — SNI, используемый при выпуске сертификата через ACME. |
alpn | *StringList | ["h2", "http/1.1"] | <ALPN string> | Список согласования протоколов прикладного уровня (ALPN), предлагаемый пиру. |
enableSessionResumption | bool | false | true | false | Включить возобновление TLS-сессий по session ticket (на стороне клиента). |
disableSystemRoot | bool | false | true | false | Игнорировать системный набор корневых ЦС. При true принимаются только записи `certificates` (в режиме `verify`). |
minVersion | string | 1.2 | 1.0 | 1.1 | 1.2 | 1.3 | Минимально допустимая версия TLS. |
maxVersion | string | 1.3 | 1.0 | 1.1 | 1.2 | 1.3 | Максимально допустимая версия TLS. |
cipherSuites | string | (library default) | <comma-separated cipher list> | Переопределить список наборов шифров. Использует имена в стиле OpenSSL (например, `TLS_AES_128_GCM_SHA256:...`). Внимание: для TLS 1.3 игнорируется — настраивается только выбор шифров для 1.2. |
fingerprint | string | (unset) | chrome | firefox | safari | edge | 360 | qq | ios | android | random | randomized | Отпечаток ClientHello uTLS. Определяет всю форму ClientHello (наборы шифров, расширения, алгоритмы подписи) — перекрывает явное поле `cipherSuites`. |
rejectUnknownSni | bool | false | true | false | Входящее подключение — отклонять TLS-соединения, чей SNI не совпадает ни с одним из настроенных сертификатов. |
curvePreferences | *StringList | (library default) | X25519 | P-256 | P-384 | P-521 | X25519MLKEM768 | Переопределить список предпочтений кривых для обмена ключами. Порядок имеет значение. |
masterKeyLog | string | (unset) | <file path> | Путь в стиле SSLKEYLOGFILE для записи TLS-ключей (расшифровка в Wireshark). Не включайте в боевой среде. |
pinnedPeerCertSha256 | string | (unset) | <base64 SHA-256> | Закрепить сертификат пира. Только для исходящего подключения — соединение отклоняется, если SHA-256 конечного сертификата не совпадает. |
verifyPeerCertByName | string | (unset) | <hostname> | Если задано, проверять, что Subject CN/SAN сертификата пира совпадает с этим именем, а не с `serverName`. Полезно, когда SNI отличается от канонического имени сертификата (схемы в духе REALITY). |
echServerKeys | string | (unset) | <base64 ECHConfigList> | Входящее подключение — набор серверных ключей ECH. |
echConfigList | string | (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[]
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
certificateFile | string | (unset) | <PEM file path> | Путь к PEM-файлу сертификата. Взаимоисключимо с `certificate`. |
certificate | []string | (unset) | [<PEM line>] | PEM сертификата прямо в конфигурации, массивом строк (по элементу на строку либо весь PEM одним элементом). |
keyFile | string | (unset) | <PEM file path> | Путь к PEM-файлу закрытого ключа. |
key | []string | (unset) | [<PEM line>] | PEM закрытого ключа прямо в конфигурации. |
usage | string | encipherment | encipherment | verify | issue | Роль этого сертификата: `encipherment` (сертификат сервера), `verify` (доверенный ЦС для проверки пира), `issue` (ЦС для выпуска сертификатов на каждое соединение в некоторых режимах пересылки). |
ocspStapling | uint64 | 3600 | <seconds> | Как часто обновлять OCSP-степлинг. 0 — отключено. |
oneTimeLoading | bool | false | true | false | Читать сертификат и ключ один раз при запуске, а не при каждой перезагрузке. Автоматически становится true при встроенных `certificate`/`key` (нет пути, откуда перечитывать). |
buildChain | bool | false | true | false | Автоматически загружать промежуточные ЦС для построения полной цепочки, если в переданном PEM только конечный сертификат. |
Исходный код: infra/conf/transport_security.go:248-257 · зафиксировано на v26.7.28 (5ca6f4b)
Примеры
Исходящее подключение — проверка по системному хранилищу корневых ЦС, принудительный TLS 1.3, отпечаток chrome:
{
"streamSettings": {
"security": "tls",
"tlsSettings": {
"serverName": "example.com",
"alpn": ["h2", "http/1.1"],
"minVersion": "1.3",
"maxVersion": "1.3",
"fingerprint": "chrome"
}
}
}Входящее подключение — обслуживание сертификата Let's Encrypt:
{
"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):
{
"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)
