From 6ad465c38984c3f7a9fc94c1a7288f668f195717 Mon Sep 17 00:00:00 2001
From: Meow <197331664+Meo597@users.noreply.github.com>
Date: Sat, 9 May 2026 06:47:48 +0800
Subject: [PATCH] RU Refactor Transports
---
.vitepress/menus/nav.ru.mts | 2 +-
.vitepress/menus/sidebar.ru.mts | 49 +-
docs/ru/about/news.md | 2 +-
docs/ru/config/features/fallback.md | 4 +-
docs/ru/config/inbound.md | 6 +-
docs/ru/config/inbounds/tunnel.md | 2 +-
docs/ru/config/inbounds/vless.md | 2 +-
docs/ru/config/outbound.md | 16 +-
docs/ru/config/outbounds/freedom.md | 2 +-
docs/ru/config/outbounds/hysteria.md | 2 +-
docs/ru/config/outbounds/vless.md | 2 +-
docs/ru/config/transport.md | 1306 +---------------------
docs/ru/config/transports/finalmask.md | 404 +++++++
docs/ru/config/transports/httpupgrade.md | 4 +-
docs/ru/config/transports/index.md | 16 +-
docs/ru/config/transports/mkcp.md | 2 +-
docs/ru/config/transports/reality.md | 203 ++++
docs/ru/config/transports/sockopt.md | 296 +++++
docs/ru/config/transports/tls.md | 338 ++++++
19 files changed, 1365 insertions(+), 1293 deletions(-)
create mode 100644 docs/ru/config/transports/finalmask.md
create mode 100644 docs/ru/config/transports/reality.md
create mode 100644 docs/ru/config/transports/sockopt.md
create mode 100644 docs/ru/config/transports/tls.md
diff --git a/.vitepress/menus/nav.ru.mts b/.vitepress/menus/nav.ru.mts
index 8e5042cb..44e613c2 100644
--- a/.vitepress/menus/nav.ru.mts
+++ b/.vitepress/menus/nav.ru.mts
@@ -9,7 +9,7 @@ export const nav: DefaultTheme.Config["nav"] = [
{ text: "Базовая конфигурация", link: "/ru/config/" },
{ text: "Входящие подключения", link: "/ru/config/inbounds/" },
{ text: "Исходящие подключения", link: "/ru/config/outbounds/" },
- { text: "Транспортный уровень", link: "/ru/config/transports/" }
+ { text: "Конфигурация транспорта", link: "/ru/config/transports/" }
]
},
{
diff --git a/.vitepress/menus/sidebar.ru.mts b/.vitepress/menus/sidebar.ru.mts
index 6e17889e..b9cc1dfd 100644
--- a/.vitepress/menus/sidebar.ru.mts
+++ b/.vitepress/menus/sidebar.ru.mts
@@ -47,7 +47,7 @@ export const sidebar: DefaultTheme.Config["sidebar"] = {
{ text: "Маршрутизация", link: "/ru/config/routing.md" },
{ text: "Статистика", link: "/ru/config/stats.md" },
{
- text: "Способы передачи",
+ text: "Конфигурация транспорта",
link: "/ru/config/transport.md"
},
{ text: "Метрики", link: "/ru/config/metrics.md" },
@@ -125,28 +125,47 @@ export const sidebar: DefaultTheme.Config["sidebar"] = {
]
},
{
- text: "Способы передачи",
+ text: "Конфигурация транспорта",
link: "/ru/config/transports/",
collapsed: true,
items: [
- { text: "RAW", link: "/ru/config/transports/raw.md" },
{
- text: "XHTTP: За пределами REALITY",
- link: "/ru/config/transports/xhttp.md"
- },
- { text: "mKCP", link: "/ru/config/transports/mkcp.md" },
- { text: "gRPC", link: "/ru/config/transports/grpc.md" },
- {
- text: "WebSocket",
- link: "/ru/config/transports/websocket.md"
+ text: "Способы передачи",
+ items: [
+ { text: "RAW", link: "/ru/config/transports/raw.md" },
+ {
+ text: "XHTTP: За пределами REALITY",
+ link: "/ru/config/transports/xhttp.md"
+ },
+ { text: "mKCP", link: "/ru/config/transports/mkcp.md" },
+ { text: "gRPC", link: "/ru/config/transports/grpc.md" },
+ {
+ text: "WebSocket",
+ link: "/ru/config/transports/websocket.md"
+ },
+ {
+ text: "HTTPUpgrade",
+ link: "/ru/config/transports/httpupgrade.md"
+ },
+ {
+ text: "Hysteria",
+ link: "/ru/config/transports/hysteria.md"
+ }
+ ]
},
{
- text: "HTTPUpgrade",
- link: "/ru/config/transports/httpupgrade.md"
+ text: "Безопасность транспорта",
+ items: [
+ { text: "REALITY", link: "/ru/config/transports/reality.md" },
+ { text: "TLS", link: "/ru/config/transports/tls.md" }
+ ]
},
{
- text: "Hysteria",
- link: "/ru/config/transports/hysteria.md"
+ text: "Дополнительные настройки",
+ items: [
+ { text: "FinalMask", link: "/ru/config/transports/finalmask.md" },
+ { text: "Sockopt", link: "/ru/config/transports/sockopt.md" }
+ ]
}
]
}
diff --git a/docs/ru/about/news.md b/docs/ru/about/news.md
index e6198ed5..c483397f 100644
--- a/docs/ru/about/news.md
+++ b/docs/ru/about/news.md
@@ -348,7 +348,7 @@ Winter cannot cover the NEXT FUTURE...
## 2022.8.28 [v1.5.10](https://github.com/XTLS/Xray-core/releases/tag/v1.5.10)
-Нижний транспорт поддерживает более разумную конфигурацию TCP Keepalive.
+`sockopt` теперь поддерживает более разумную конфигурацию TCP Keepalive.
## 2022.6.20 [v1.5.8](https://github.com/XTLS/Xray-core/releases/tag/v1.5.8)
diff --git a/docs/ru/config/features/fallback.md b/docs/ru/config/features/fallback.md
index d61c25cf..78f55325 100644
--- a/docs/ru/config/features/fallback.md
+++ b/docs/ru/config/features/fallback.md
@@ -38,7 +38,7 @@ Fallback также может разделять трафик различны
Элемент `fallbacks` является необязательным и может использоваться только для комбинации транспорта TCP+TLS.
-- Если этот элемент имеет дочерние элементы, в [Inbound TLS](../transport.md#tlsobject) необходимо установить `"alpn":["http/1.1"]`.
+- Если этот элемент имеет дочерние элементы, в [Inbound TLS](../transports/tls.md#tlsobject) необходимо установить `"alpn":["http/1.1"]`.
Обычно сначала нужно настроить набор резервных путей по умолчанию с опущенными или пустыми `alpn` и `path`, а затем настроить другие разделения по мере необходимости.
@@ -56,7 +56,7 @@ VLESS будет перенаправлять трафик с длиной пе
При необходимости VLESS попытается прочитать результат согласования TLS ALPN, и в случае успеха выведет в лог `realAlpn =`.
Назначение: решает проблему несовместимости службы h2c Nginx с http/1.1, для которой в Nginx требуется написать две строки listen, по одной для 1.1 и h2c.
-Примечание: если в `fallbacks alpn` присутствует `"h2"`, в [Inbound TLS](../transport.md#tlsobject) необходимо установить `"alpn":["h2","http/1.1"]` для поддержки доступа h2.
+Примечание: если в `fallbacks alpn` присутствует `"h2"`, в [Inbound TLS](../transports/tls.md#tlsobject) необходимо установить `"alpn":["h2","http/1.1"]` для поддержки доступа h2.
::: tip
`alpn`, установленный в Fallback, соответствует фактически согласованному ALPN, а `alpn`, установленный в Inbound TLS, - это список дополнительных ALPN во время рукопожатия. Это разные вещи.
diff --git a/docs/ru/config/inbound.md b/docs/ru/config/inbound.md
index ce98d4d3..cdb59567 100644
--- a/docs/ru/config/inbound.md
+++ b/docs/ru/config/inbound.md
@@ -38,7 +38,7 @@
Можно добавить `@` в начало пути, чтобы использовать [абстрактный сокет](https://www.man7.org/linux/man-pages/man7/unix.7.html), или `@@`, чтобы использовать абстрактный сокет с заполнением.
При указании Unix domain socket параметры `port` и `allocate` игнорируются.
-В настоящее время поддерживаются протоколы VLESS, VMess, Trojan и типы транспорта TCP, WebSocket, HTTP/2, gRPC.
+В настоящее время поддерживаются протоколы VLESS, VMess и Trojan, а также только транспортные способы на базе TCP, например `tcp`, `websocket`, `grpc`. Транспорт на базе UDP, такой как `mkcp`, не поддерживается.
При указании Unix domain socket можно указать права доступа к сокету, добавив запятую и индикатор прав доступа, например `"/dev/shm/domain.socket,0666"`.
Это может помочь решить проблемы с правами доступа к сокету, которые возникают по умолчанию.
@@ -68,9 +68,9 @@
Конкретные настройки зависят от протокола.
См. описание `InboundConfigurationObject` для каждого протокола.
-> `streamSettings`: [StreamSettingsObject](./transport.md#streamsettingsobject)
+> `streamSettings`: [StreamSettingsObject](./transport.md)
-Тип транспорта (transport) - это способ взаимодействия текущего узла Xray с другими узлами.
+Конфигурация транспорта для этого входящего подключения.
> `tag`: string
diff --git a/docs/ru/config/inbounds/tunnel.md b/docs/ru/config/inbounds/tunnel.md
index e55a887e..c03f4b53 100644
--- a/docs/ru/config/inbounds/tunnel.md
+++ b/docs/ru/config/inbounds/tunnel.md
@@ -52,7 +52,7 @@
Если значение равно `true`, dokodemo-door будет распознавать данные, перенаправленные iptables, и пересылать их на соответствующий целевой адрес.
-См. настройку `tproxy` в разделе [Конфигурация транспорта](../transport.md#sockoptobject).
+См. настройку `tproxy` в разделе [Sockopt](../transports/sockopt.md#sockoptobject).
> `userLevel`: number
diff --git a/docs/ru/config/inbounds/vless.md b/docs/ru/config/inbounds/vless.md
index 4d672c0f..dd87c3d6 100644
--- a/docs/ru/config/inbounds/vless.md
+++ b/docs/ru/config/inbounds/vless.md
@@ -131,7 +131,7 @@ VLESS - это легкий транспортный протокол без с
XTLS доступен только в следующих комбинациях
-- TCP+TLS/Reality В этом случае зашифрованные данные копируются напрямую на низком уровне (если передается TLS 1.3).
+- TCP+TLS/REALITY В этом случае зашифрованные данные копируются напрямую на низком уровне (если передается TLS 1.3).
- VLESS Encryption Нет ограничений на транспорт нижнего уровня; если транспорт не поддерживает прямое копирование (см. выше), то выполняется только проброс Encryption.
> `reverse`: struct
diff --git a/docs/ru/config/outbound.md b/docs/ru/config/outbound.md
index ed9cb8f3..ccd4218b 100644
--- a/docs/ru/config/outbound.md
+++ b/docs/ru/config/outbound.md
@@ -66,9 +66,9 @@ Xray будет использовать случайный IP-адрес из
Если это поле не пустое, его значение должно быть **уникальным** среди всех тегов.
:::
-> `streamSettings`: [StreamSettingsObject](./transport.md#streamsettingsobject)
+> `streamSettings`: [StreamSettingsObject](./transport.md)
-Тип транспорта (transport) - это способ взаимодействия текущего узла Xray с другими узлами.
+Конфигурация транспорта для этого исходящего подключения.
> `proxySettings`: [ProxySettingsObject](#proxysettingsobject)
@@ -82,10 +82,10 @@ Xray будет использовать случайный IP-адрес из
Если при исходящем подключении отправляется запрос к доменному имени, эта опция управляет тем, будет ли оно разрешено (и каким образом) в IP-адрес для отправки.
-Значение по умолчанию — `AsIs`, то есть отправка на удаленный сервер «как есть». Значения всех параметров примерно соответствуют `domainStrategy` в [sockopt](./transport.md#sockoptobject).
+Значение по умолчанию — `AsIs`, то есть отправка на удаленный сервер «как есть». Значения всех параметров примерно соответствуют `domainStrategy` в [Sockopt](./transports/sockopt.md#sockoptobject).
::: tip
-Здесь контролируются **проксируемые запросы**. Если адресом исходящего прокси-сервера является доменное имя, и для этого домена необходимо выбрать стратегию разрешения, следует настроить `domainStrategy` в [sockopt](./transport.md#sockoptobject).
+Здесь контролируются **проксируемые запросы**. Если адресом исходящего прокси-сервера является доменное имя, и для этого домена необходимо выбрать стратегию разрешения, следует настроить `domainStrategy` в [Sockopt](./transports/sockopt.md#sockoptobject).
:::
### ProxySettingsObject
@@ -102,15 +102,15 @@ Xray будет использовать случайный IP-адрес из
Если указан тег другого Outbound, данные, исходящие из этого Outbound, будут перенаправлены через указанный Outbound.
::: danger
-Эта опция конфликтует с [SockOpt.dialerProxy](./transport.md#sockoptobject), используйте только один из этих вариантов по необходимости.
+Эта опция конфликтует с [Sockopt.dialerProxy](./transports/sockopt.md#sockoptobject), используйте только один из этих вариантов по необходимости.
-По умолчанию этот метод перенаправления **не проходит** через транспортный уровень (REALITY/XHTTP/gRPC...), то есть `streamSettings` данного Outbound не будут иметь эффекта.
-Если вам требуется перенаправление с поддержкой транспортного уровня, используйте `SockOpt.dialerProxy` или установите `transportLayer` в `true`.
+По умолчанию этот способ пересылки **игнорирует** собственную конфигурацию транспорта этого outbound (например XHTTP, REALITY или Sockopt), поэтому `streamSettings` у данного outbound не будут работать.
+Если вам нужна пересылка с поддержкой `streamSettings`, используйте `Sockopt.dialerProxy` или установите здесь `transportLayer` в `true`.
:::
> `transportLayer`: true | false
-`true` преобразует эту настройку в `SockOpt.dialerProxy` для поддержки перенаправления на транспортном уровне. По умолчанию `false` (преобразование не выполняется).
+`true` преобразует эту настройку в `Sockopt.dialerProxy`, чтобы пересылка использовала `streamSettings` этого outbound. По умолчанию `false`.
### MuxObject
diff --git a/docs/ru/config/outbounds/freedom.md b/docs/ru/config/outbounds/freedom.md
index f2e34330..ad26343b 100644
--- a/docs/ru/config/outbounds/freedom.md
+++ b/docs/ru/config/outbounds/freedom.md
@@ -57,7 +57,7 @@ Freedom — это исходящий протокол, который можн
Значение по умолчанию — `"AsIs"`.
-Все параметры по смыслу аналогичны `domainStrategy` в [sockopt](../transport.md#sockoptobject).
+Все параметры по смыслу аналогичны `domainStrategy` в [Sockopt](../transports/sockopt.md#sockoptobject).
Только использование `AsIs` в этом разделе позволяет передать доменное имя в последующий модуль `sockopt`. Если установить значение, отличное от `AsIs`, домен будет разрешен в конкретный IP, что сделает последующие настройки `sockopt.domainStrategy` и связанный с ними механизм `happyEyeballs` недействительными. (Если вы не изменяли эти настройки, негативного влияния не будет).
diff --git a/docs/ru/config/outbounds/hysteria.md b/docs/ru/config/outbounds/hysteria.md
index e29d41aa..0bd7ef89 100644
--- a/docs/ru/config/outbounds/hysteria.md
+++ b/docs/ru/config/outbounds/hysteria.md
@@ -2,7 +2,7 @@
Реализация клиента протокола Hysteria.
-Эта страница очень проста, так как протокол hysteria фактически разделен на простой протокол управления прокси и оптимизированный низкоуровневый транспорт QUIC. В Xray протокол прокси и низкоуровневый транспорт разделены, подробности см. в разделе [hysteriaSettings](../transports/hysteria.md) [finalmask.quicParams](../transport.md#quicParams) низкоуровневого транспорта.
+Эта страница очень проста, так как протокол hysteria фактически состоит из простого протокола управления прокси и оптимизированной QUIC-реализации транспорта. В Xray прокси-протокол и конфигурация транспорта разделены. Подробности, включая `brutal`, см. в параметрах транспорта [hysteriaSettings](../transports/hysteria.md) и [FinalMask.quicParams](../transports/finalmask.md#quicparams).
::: tip
Сам протокол `hysteria` не имеет аутентификации. При использовании с транспортным уровнем, отличным от `hysteria`, он не сможет выступать в качестве прокси для `udp`, и его использование с другими транспортными уровнями не рекомендуется.
diff --git a/docs/ru/config/outbounds/vless.md b/docs/ru/config/outbounds/vless.md
index 4d1bc877..b2d2a23b 100644
--- a/docs/ru/config/outbounds/vless.md
+++ b/docs/ru/config/outbounds/vless.md
@@ -84,7 +84,7 @@ VLESS - это легкий транспортный протокол без с
XTLS доступен только в следующих комбинациях
-- TCP+TLS/Reality: если в данный момент передаётся TLS 1.3, ядро попытается выполнить Splice на зашифрованных данных нижнего уровня; в случае успеха это позволит сэкономить все IO-затраты ядра.
+- TCP+TLS/REALITY: если в данный момент передаётся TLS 1.3, ядро попытается выполнить Splice на зашифрованных данных нижнего уровня; в случае успеха это позволит сэкономить все IO-затраты ядра.
- VLESS Encryption: не имеет ограничений по нижнему уровню транспорта. Если нижний уровень не TCP, будет предпринята только попытка «прозрачного» прохождения Encryption, что сэкономит накладные расходы Encryption; если же используется TCP, всё равно будет предпринята попытка выполнения Splice.
::: tip О Splice
diff --git a/docs/ru/config/transport.md b/docs/ru/config/transport.md
index dbaf84d7..52be5644 100644
--- a/docs/ru/config/transport.md
+++ b/docs/ru/config/transport.md
@@ -1,26 +1,33 @@
-# Способы передачи (uTLS, REALITY)
+# Конфигурация транспорта
-Способ передачи (transport) — это способ взаимодействия текущего узла Xray с другими узлами.
+Конфигурация транспорта определяет, как текущий экземпляр Xray взаимодействует с другой стороной. Этой стороной может быть как другой узел Xray, так и обычный публичный сетевой адрес.
-Транспорт определяет способ передачи данных. Обычно оба конца сетевого подключения должны использовать одинаковый транспорт.
-Например, если один конец использует WebSocket, то другой конец также должен использовать WebSocket, иначе соединение не будет установлено.
+Она описывает часть ниже самого прокси-протокола: способ переноса потока, защиту транспорта и дополнительные низкоуровневые настройки.
+
+Эти три группы относятся к разным уровням и в определенных пределах могут комбинироваться:
+
+- Способы передачи определяют, как именно переносится поток данных, например через RAW, WebSocket, gRPC или Hysteria.
+- Безопасность транспорта определяет механизм защиты, например TLS или REALITY.
+- Дополнительные настройки управляют низкоуровневым сетевым поведением и финальной маскировкой трафика.
+
+Часть параметров транспорта напрямую влияет на способ установления соединения с удаленной стороной. Для параметров, которые требуют согласования, обе стороны обычно должны использовать совместимые настройки. Например, если одна сторона использует WebSocket, другая тоже должна использовать WebSocket, иначе соединение не будет установлено.
+
+Для прямых исходящих соединений, таких как [Freedom](./outbounds/freedom.md), другой стороной может быть не другой узел Xray, а просто публичный адрес назначения. В этом случае конфигурация транспорта не используется для согласования с другим Xray, а управляет локальным исходящим соединением. В таком сценарии доступен только `sockopt`.
## StreamSettingsObject
-`StreamSettingsObject` соответствует элементу `streamSettings` в [`InboundObject`](./inbound.md) или [`OutboundObject`](./outbound.md).
+`StreamSettingsObject` соответствует полю `streamSettings` в [`InboundObject`](./inbound.md) или [`OutboundObject`](./outbound.md). Каждый inbound или outbound может иметь собственную конфигурацию транспорта.
```json
{
- // outbound example; also applies to inbound
+ // пример для outbound, аналогично применимо к inbound
"outbounds": [
{
// ...
"streamSettings": {
- // [!code focus:34]
+ // [!code focus:16]
+ // Способы передачи
"network": "raw",
- "security": "none",
- "tlsSettings": {},
- "realitySettings": {},
"rawSettings": {},
"xhttpSettings": {},
"kcpSettings": {},
@@ -28,1290 +35,83 @@
"wsSettings": {},
"httpupgradeSettings": {},
"hysteriaSettings": {},
- "finalmask": {
- "tcp": [],
- "udp": [],
- "quicParams": {}
- },
- "sockopt": {
- "mark": 0,
- "tcpMaxSeg": 1440,
- "tcpFastOpen": false,
- "tproxy": "off",
- "domainStrategy": "AsIs",
- "happyEyeballs": {},
- "dialerProxy": "",
- "acceptProxyProtocol": false,
- "tcpKeepAliveInterval": 0,
- "tcpKeepAliveIdle": 300,
- "tcpUserTimeout": 10000,
- "tcpCongestion": "bbr",
- "interface": "wg0",
- "v6only": false,
- "tcpWindowClamp": 600,
- "tcpMptcp": false
- }
+ // Безопасность транспорта
+ "security": "none",
+ "realitySettings": {},
+ "tlsSettings": {},
+ // Дополнительные настройки
+ "finalmask": {},
+ "sockopt": {}
}
}
]
}
```
-> `network`: "raw" | "xhttp" | "kcp" | "grpc" | "ws" | "httpupgrade" | "hysteria"
+> `network`: "raw" | "xhttp" | "mkcp" | "grpc" | "websocket" | "httpupgrade" | "hysteria"
-Тип способа передачи, используемого потоком данных соединения, по умолчанию `"raw"`.
-
-::: tip
-**Начиная с версии v24.9.30**, для более точного отражения фактического поведения, тип передачи `tcp` был переименован в `raw`. Для обеспечения совместимости `"network": "raw"` и `"network": "tcp"`, `rawSettings` и `tcpSettings` являются синонимами.
-:::
-
-> `security`: "none" | "tls" | "reality"
-
-Включено ли шифрование транспортного уровня, поддерживаемые опции:
-
-- `"none"` означает отсутствие шифрования (значение по умолчанию)
-- `"tls"` означает использование [TLS](https://ru.wikipedia.org/wiki/Протокол_защиты_транспортного_уровня).
-- `"reality"` означает использование REALITY.
-
-> `tlsSettings`: [TLSObject](#tlsobject)
-
-Конфигурация TLS. TLS предоставляется Golang, обычно результатом согласования TLS является использование TLS 1.3, DTLS не поддерживается.
-
-> `realitySettings`: [RealityObject](#realityobject)
-
-Конфигурация Reality. Reality — это оригинальная технология Xray. Reality обеспечивает более высокий уровень безопасности, чем TLS, и настраивается так же, как TLS.
-
-::: tip
-Reality — это самое безопасное на данный момент решение для шифрования передачи данных, и внешний вид трафика такой же, как и при обычном просмотре веб-страниц. Включение Reality и настройка подходящего режима управления потоком XTLS Vision может повысить производительность в несколько раз или даже в десятки раз.
-:::
+Способ передачи, используемый потоком данных. Значение по умолчанию — `raw`.
> `rawSettings`: [RawObject](./transports/raw.md)
-Конфигурация RAW для текущего соединения, действительна только если это соединение использует RAW.
+Настройки RAW для потока данных. Действуют только когда `network` равно `raw`.
-> `xhttpSettings`: [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113#discussioncomment-11468947)
+> `xhttpSettings`: [XHTTPObject](./transports/xhttp.md)
-Конфигурация XHTTP для текущего соединения, действительна только если это соединение использует XHTTP.
+Настройки XHTTP для потока данных. Действуют только когда `network` равно `xhttp`.
> `kcpSettings`: [KcpObject](./transports/mkcp.md)
-Конфигурация mKCP для текущего соединения, действительна только если это соединение использует mKCP.
+Настройки mKCP для потока данных. Действуют только когда `network` равно `mkcp`.
> `grpcSettings`: [GRPCObject](./transports/grpc.md)
-Конфигурация gRPC для текущего соединения, действительна только если это соединение использует gRPC.
+Настройки gRPC для потока данных. Действуют только когда `network` равно `grpc`.
> `wsSettings`: [WebSocketObject](./transports/websocket.md)
-Конфигурация WebSocket для текущего соединения, действительна только если это соединение использует WebSocket.
+Настройки WebSocket для потока данных. Действуют только когда `network` равно `websocket`.
-> `httpupgradeSettings`: [HttpUpgradeObject](./transports/httpupgrade.md)
+> `httpupgradeSettings`: [HTTPUpgradeObject](./transports/httpupgrade.md)
-Конфигурация HTTPUpgrade для текущего соединения, действительна только если это соединение использует HTTPUpgrade.
+Настройки HTTPUpgrade для потока данных. Действуют только когда `network` равно `httpupgrade`.
> `hysteriaSettings`: [HysteriaObject](./transports/hysteria.md)
-Конфигурация Hysteria для текущего соединения, действительна только если это соединение использует Hysteria.
+Настройки Hysteria для потока данных. Действуют только когда `network` равно `hysteria`.
-> `sockopt`: [SockoptObject](#sockoptobject)
+---
-Конкретные настройки, связанные с прозрачным проксированием.
+> `security`: "none" | "reality" | "tls"
-> `finalmask`: [FinalMaskObject](#finalmaskobject)
+Включать ли защиту транспорта. Поддерживаются следующие значения:
-Конфигурация FinalMask, используемая для универсальной маскировки трафика.
+- `"none"` означает, что защита отключена (значение по умолчанию)
+- `"reality"` означает использование REALITY
+- `"tls"` означает использование [TLS](https://ru.wikipedia.org/wiki/Протокол_защиты_транспортного_уровня)
-### TLSObject
+> `realitySettings`: [RealityObject](./transports/reality.md)
-```json
-{
- "serverName": "xray.com",
- "verifyPeerCertByName": "",
- "rejectUnknownSni": false,
- "allowInsecure": false,
- "alpn": ["h2", "http/1.1"],
- "minVersion": "1.2",
- "maxVersion": "1.3",
- "cipherSuites": "Здесь укажите названия необходимых вам наборов шифров, разделяя их двоеточиями",
- "certificates": [],
- "disableSystemRoot": false,
- "enableSessionResumption": false,
- "fingerprint": "chrome",
- "pinnedPeerCertSha256": "",
- "curvePreferences": [""],
- "masterKeyLog": "",
- "echConfigList": "",
- "echServerKeys": "",
- "echSockopt": {}
-}
-```
+Настройки REALITY. REALITY — это модификация TLS, которая использует внешний вид и характеристики рукопожатия целевого сайта как маскировку.
-> `serverName`: string
-
-Указывает доменное имя сертификата сервера, полезно, когда соединение устанавливается по IP-адресу.
-
-Если оставить пустым, автоматически используется значение из адреса (если это доменное имя), это значение также используется для проверки действительности сертификата сервера.
-
-Специальное значение `"FromMitM"`. Это заставит использовать SNI, содержащийся в TLS, который был расшифрован входящим соединением dokodemo-door.
-
-> `verifyPeerCertByName`: string
-
-Только для клиента. Используется для SNI при проверке сертификата. Можно указать несколько доменов, разделяя их `,` (достаточно, чтобы хотя бы один SAN сертификата присутствовал в этом списке). Это переопределит `serverName`, используемый для проверки; применяется для маскировки домена (Domain Fronting) и других специальных целей.
-
-Специальное значение `"FromMitM"`: при его использовании в список будет дополнительно добавлен SNI из TLS-трафика, расшифрованного входящим соединением `dokodomo-door`.
-
-> `rejectUnknownSni`: bool
-
-Если значение равно `true`, то сервер отклонит рукопожатие TLS, если полученный SNI не соответствует доменному имени сертификата. По умолчанию равно `false`.
-
-> `alpn`: \[ string \]
-
-Массив строк, указывающий значения ALPN, указанные во время рукопожатия TLS. Значение по умолчанию: `["h2", "http/1.1"]`.
-
-Специальное значение: `["FromMitM"]` (когда это единственный элемент) заставит исходящий TLS использовать ALPN из TLS-соединения, расшифрованного входящим `dokodemo-door`.
-
-> `minVersion`: string
-
-`minVersion` — это минимально допустимая версия TLS.
-
-> `maxVersion`: string
-
-`maxVersion` — это максимально допустимая версия TLS.
-
-> `cipherSuites`: string
-
-`CipherSuites` используется для настройки списка поддерживаемых наборов шифров, разделенных двоеточиями.
-
-Вы можете найти список наборов шифров Golang и их описания [здесь](https://golang.org/src/crypto/tls/cipher_suites.go#L500) или [здесь](https://golang.org/src/crypto/tls/cipher_suites.go#L44).
-
-::: danger
-Эти два параметра конфигурации не являются обязательными и обычно не влияют на безопасность. Если они не настроены, Golang автоматически выберет их в зависимости от устройства. Если вы не знакомы с ними, пожалуйста, не настраивайте эти параметры, вы несете ответственность за проблемы, вызванные неправильным заполнением.
-:::
-
-> `allowInsecure`: true | false
-
-Разрешить ли небезопасные соединения (только для клиента). Значение по умолчанию: `false`.
-
-Если значение равно `true`, то Xray не будет проверять действительность сертификата TLS, предоставленного удаленным хостом.
-
-::: danger
-~~Из соображений безопасности этот параметр не следует устанавливать в значение `true` в реальных сценариях, иначе вы можете подвергнуться атаке типа «человек посередине».~~
-
-Эта опция устарела. Используйте `pinnedPeerCertSha256` для ручного указания необходимого сертификата.
-:::
-
-> `disableSystemRoot`: true | false
-
-Отключить ли корневые сертификаты операционной системы. Значение по умолчанию: `false`.
-
-Если значение равно `true`, то Xray будет использовать только сертификаты, указанные в `certificates`, для рукопожатия TLS. Если значение равно `false`, то Xray будет использовать только корневые сертификаты операционной системы для рукопожатия TLS.
-
-> `enableSessionResumption`: true | false
-
-Включить ли восстановление сессии. По умолчанию отключено, и оно будет работать только в том случае, если как сервер, так и клиент поддерживают эту функцию и активировали её.
-
-Если восстановление сессии будет успешно согласовано, передача сертификатов во время рукопожатия станет необязательной. Это может немного сократить время на рукопожатие (разница практически незаметна).
-
-Обратите внимание, что это не TLS 0RTT. Функция TLS 0RTT пока не поддерживается в gotls, и это не уменьшит количество RTT в процессе TLS-рукопожатия.
-
-> `fingerprint` : string
-
-Этот параметр используется для настройки указанного отпечатка `TLS Client Hello`.
-
-Значение по умолчанию `chrome` .
-
-При включении Xray будет **эмулировать** отпечаток `TLS` через библиотеку uTLS или генерировать его случайным образом.
-Поддерживаются четыре режима настройки:
-
-1. Отпечатки TLS последних версий популярных браузеров, включая:
-
-- `"chrome"`
-- `"firefox"`
-- `"safari"`
-- `"ios"`
-- `"android"`
-- `"edge"`
-- `"360"`
-- `"qq"`
-
-2. Автоматическая генерация отпечатка при запуске Xray:
-
-- `"random"`: случайный выбор из новых версий браузеров.
-- `"randomized"`: полная случайная генерация уникального отпечатка (100% поддержка TLS 1.3 с использованием X25519)
-
-3. Использование имени переменной отпечатка uTLS, например, `"HelloRandomizedNoALPN"` `"HelloChrome_106_Shuffle"`. Полный список см. в [библиотеке uTLS](https://github.com/refraction-networking/utls/blob/master/u_common.go#L434).
-
-4. Отключение **эмуляции** отпечатка `TLS Client Hello`
-
-::: danger
-Из соображений безопасности этот параметр не следует устанавливать в значение `unsafe`.
-:::
-
-- `"unsafe"`: отпечаток go/tls
+Действуют только когда `security` равно `reality`.
::: tip
-Эта функция только **эмулирует** отпечаток `TLS Client Hello`, поведение и другие отпечатки такие же, как у Golang. Если вам нужна более полная эмуляция отпечатка и поведения браузера `TLS`, используйте [Browser Dialer](./transports/websocket.md#browser-dialer).
+REALITY сейчас является одной из самых сильных схем защиты транспорта, а снаружи такой трафик выглядит максимально похоже на обычный веб-трафик. В сочетании с подходящим режимом XTLS Vision можно также получить прирост производительности в несколько раз или даже больше чем в десять раз.
:::
-::: tip
-При использовании этой функции некоторые параметры TLS, влияющие на отпечаток TLS, будут переопределены библиотекой utls и не будут действовать, например, ALPN.
-Передаваемые параметры:
-`"serverName" "disableSystemRoot" "pinnedPeerCertSha256" "masterKeyLog"`
-:::
+> `tlsSettings`: [TLSObject](./transports/tls.md)
-> `pinnedPeerCertSha256`: string
+Настройки TLS. Реализация TLS предоставляется Go. В обычных условиях переговоры обычно приходят к TLS 1.3. DTLS не поддерживается.
-Используется для указания SHA256-хеша сертификата удаленного сервера. Используется шестнадцатеричный формат (hex), регистр не важен. Например: `e8e2d387fdbffeb38e9c9065cf30a97ee23c0e3d32ee6f78ffae40966befccc9`. Можно перечислить несколько хешей через запятую `,`; проверка считается пройденной при совпадении любого из них.
+Действуют только когда `security` равно `tls`.
-Эта кодировка совпадает с отпечатком SHA-256 в просмотрщике сертификатов Chrome, а также с форматом Certificate Fingerprints SHA-256 на сайте crt.sh. Значение можно вычислить с помощью команды `xray tls hash --cert ` или `openssl x509 -noout -fingerprint -sha256 -in cert.pem` (формат с двоеточиями, который она генерирует, также поддерживается). Команда `xray tls ping` также выводит SHA256-хеш удаленного сертификата.
+---
-Эта проверка переопределяет стандартную валидацию сертификатов. Возможны два сценария:
+> `finalmask`: [FinalMaskObject](./transports/finalmask.md)
-- 1. Если ядро находит совпадающий хеш для конечного (leaf) сертификата, проверка сразу же проходит успешно.
-- 2. Если ядро находит совпадающий хеш для сертификата CA (это может быть корневой или промежуточный сертификат), оно проверит, подписан ли конечный сертификат этим CA, используя для валидации значение из `serverName`.
+Настройки FinalMask для финальной маскировки трафика.
-> `certificates`: \[ [CertificateObject](#certificateobject) \]
+> `sockopt`: [SockoptObject](./transports/sockopt.md)
-Список сертификатов, каждый элемент которого представляет собой сертификат (рекомендуется fullchain).
-
-::: tip
-Если вам нужно получить оценку A/A+ в ssllibs или myssl,
-пожалуйста, обратитесь к [этому](https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600).
-:::
-
-> `curvePreferences`: \[ string \]
-
-Массив строк, задающий предпочтительные кривые для выполнения ECDHE во время TLS-рукопожатия. Список поддерживаемых кривых приведён ниже (регистр не имеет значения):
-CurveP256
-CurveP384
-CurveP521
-X25519
-X25519MLKEM768
-SecP256r1MLKEM768*
-SecP384r1MLKEM1024*
-
-\*: Не поддерживается utls
-
-Значение по умолчанию начиная с go1.26 включает все вышеперечисленные кривые. Изменение порядка не заставляет клиента или сервер отдавать предпочтение конкретной кривой; фактическая кривая будет согласована самим механизмом обмена ключами.
-
-> `masterKeyLog` : string
-
-Файл журнала (Pre)-Master-Secret, путь к которому задаётся здесь, может быть использован в Wireshark и других программах для расшифровки TLS-соединений, устанавливаемых Xray.
-
-> `echConfigList` : string
-
-Только для клиента. Задаёт ECHConfig; если значение задано — клиент включает Encrypted Client Hello. Поддерживаются два формата.
-
-Фиксированный ECHConfig, например `"AF7+DQBaAAAgACA51i3Ssu4wUMV4FNCc8iRX5J+YC4Bhigz9sacl2lCfSQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAAtleGFtcGxlLmNvbQAA"`
-
-Получение через DNS. Удобно при использовании CDN: по HTTPS-записи можно динамически получить ECHConfig; Xray будет соблюдать TTL, возвращённый сервером. Запрашивается SNI из конфигурации или доменное имя сервера (если SNI пуст и целью является домен).
-
-Базовый вид строки: `"udp://1.1.1.1"` — запрос по UDP DNS к 1.1.1.1. `"https://1.1.1.1/dns-query"` — запрос по DoH (пример; замените на доступный сервер). В обоих случаях можно указать порт, например `udp://1.1.1.1:53`; если порт не указан, берутся значения по умолчанию 53/443.
-
-Особый случай: можно задать домен, из чьей записи будет браться ECHConfig, например `"example.com+https://1.1.1.1/dns-query"`. Тогда Xray принудительно использует ECHConfig из DNS-записи example.com, что полезно, если нужно получить ECHConfig через DNS, но не хочется светить целевой домен в HTTPS-запросе или публиковать у него HTTPS-запись.
-
-> `echServerKeys` : string
-
-Только для сервера. Включает Encrypted Client Hello на стороне сервера.
-
-Создайте ключи командой `xray tls ech --serverName example.com` где `example.com` — SNI, который будет открыт наружу (можно указать любой). Server Key содержит и ECHConfig; если клиентский Config потерян, его можно восстановить командой `xray tls ech -i "ваш server key"`.
-Полученный Config можно опубликовать в HTTPS-записи DNS (см. пример в [Google DNS](https://dns.google/query?name=encryptedsni.com&rr_type=HTTPS) или RFC 9460).
-
-Учтите: сервер, настроенный на использование ECH, всё ещё принимает обычные не-ECH-соединения. Но клиент, настроенный на ECH, при неудачной ECH-рукопожатии сразу завершит соединение, не откатываясь к открытому SNI.
-
-> `echSockopt` : [SockoptObject](#sockoptobject)
-
-Настраивает параметры базового `socket` для соединения, используемого при выполнении DNS-запросов для записей `ECH`.
-
-### RealityObject
-
-```json
-{
- "show": false,
- "target": "example.com:443",
- "xver": 0,
- "serverNames": ["example.com", "www.example.com"],
- "privateKey": "",
- "minClientVer": "",
- "maxClientVer": "",
- "maxTimeDiff": 0,
- "shortIds": ["", "0123456789abcdef"],
- "mldsa65Seed": "",
- "limitFallbackUpload": {
- "afterBytes": 0,
- "bytesPerSec": 0,
- "burstBytesPerSec": 0
- },
- "limitFallbackDownload": {
- "afterBytes": 0,
- "bytesPerSec": 0,
- "burstBytesPerSec": 0
- },
- "fingerprint": "chrome",
- "serverName": "",
- "password": "",
- "shortId": "",
- "mldsa65Verify": "",
- "spiderX": ""
-}
-```
-
-::: tip
-Дополнительную информацию см. в проекте [REALITY](https://github.com/XTLS/REALITY).
-:::
-
-::: tip
-Reality лишь модифицирует TLS, и для реализации на стороне клиента достаточно незначительных изменений — полностью случайного session id и кастомной проверки сертификатов. Теоретически это полностью совместимо с большинством TLS-реализаций.
-:::
-
-> `show` : true | false
-
-Если значение равно `true`, выводить отладочную информацию.
-
-::: tip
-Ниже приведена конфигурация для **входящего** подключения (**сервера**).
-:::
-
-> `target` : string
-
-Обязательный параметр, формат такой же, как у [dest](./features/fallback.md#fallbackobject) в VLESS `fallbacks`.
-
-Прежнее название — `dest`. В текущей версии оба поля являются взаимными псевдонимами.
-
-Если целевой сервер поддерживает пост-квантовый алгоритм обмена ключами X25519MLKEM768, то клиент reality автоматически применит этот алгоритм для согласования ключей. Чтобы проверить поддержку, выполните команду `xray tls ping cloudflare.com` (замените адрес на `dest`, при необходимости добавьте номер порта).
-
-Ядро по наличию этого поля определяет, является ли текущая конфигурация клиентской или серверной. Не указывайте его на стороне клиента, иначе возникнут ошибки распознавания.
-
-::: warning
-Из соображений маскировки Xray будет **непосредственно перенаправлять** трафик с неудачной аутентификацией (недопустимый запрос REALITY) на `dest`.
-Если IP-адрес сайта `dest` особый (например, сайт использует CloudFlare CDN), это равносильно тому, что ваш сервер действует как port forward для CloudFlare, что может привести к злоупотреблению.
-
-Чтобы этого избежать, можно рассмотреть возможность использования Nginx и других методов для фильтрации нежелательных SNI.
-Или вы также можете рассмотреть настройку соответствующих параметров `limitFallbackUpload` и `limitFallbackDownload`, чтобы ограничить скорость.
-:::
-
-> `xver` : number
-
-Необязательный параметр, формат такой же, как у [xver](./features/fallback.md#fallbackobject) в VLESS `fallbacks`.
-
-> `serverNames` : \[string\]
-
-Обязательный параметр, список доступных `serverName` для клиента, подстановочные знаки \* пока не поддерживаются.
-
-Обычно он совпадает с `dest`, фактическое допустимое значение — это любой SNI, принимаемый сервером (в зависимости от конфигурации `dest`), в качестве справки можно использовать [SAN](https://ru.wikipedia.org/wiki/Subject_Alternative_Name) возвращаемого сертификата.
-
-Может содержать пустое значение `""`, что означает принятие соединений без SNI.
-
-> `privateKey` : string
-
-Обязательный параметр, генерируется с помощью команды `./xray x25519`.
-
-> `minClientVer` : string
-
-Необязательный параметр, минимальная версия Xray клиента, формат: `x.y.z`.
-
-> `maxClientVer` : string
-
-Необязательный параметр, максимальная версия Xray клиента, формат: `x.y.z`.
-
-> `maxTimeDiff` : number
-
-Необязательный параметр, максимально допустимая разница во времени в миллисекундах.
-
-> `shortIds` : \[string\]
-
-Обязательный параметр, список доступных `shortId` для клиента, можно использовать для различения разных клиентов.
-
-Требования к формату см. в `shortId`.
-
-Если содержит пустое значение, `shortId` клиента может быть пустым.
-
-> `mldsa65Seed` : string
-
-Только для сервера. Приватный ключ, применяемый для добавления к сертификату, выдаваемому клиенту Reality, дополнительной пост-квантовой подписи по схеме ML-DSA-65. Назначение — защитить соединение на случай появления квантового компьютера, способного взломать X25519: даже если пароль будет скомпрометирован, MITM-атака останется невозможной.
-
-Сгенерировать пару ключей можно командой `xray mldsa65`. После того как приватный ключ внесён в конфигурацию сервера, подпись добавляется в расширение сертификата; на старые клиенты или клиенты без поддержки этой функции это не влияет.
-
-После включения этой функции длина сертификата, возвращаемого целевым сервером (target), **обязательно** должна превышать 3500 байт. Пост-квантовая подпись увеличивает размер временного сертификата Reality; чтобы не создавать отличительную особенность, сертификат target тоже должен быть крупным. Проверить размер можно командой `xray tls ping example.com`.
-Для полной пост-квантовой защиты сам target также должен поддерживать ключевой обмен X25519MLKEM768. Поддержку можно проверить той же командой, указанной выше.
-
-> `limitFallbackUpload`/`limitFallbackDownload`
-
-::: warning
-Предупреждение: Лучшей практикой для REALITY всегда является использование сертификата из той же ASN, поэтому, скорее всего, вам эта функция не понадобится; только если вы вынуждены использовать сертификат CDN, можно рассмотреть включение этой функции, чтобы избежать превращения вашего сервера в узел для других.
-
-Включение ограничения скорости может ввести новые характеристики, обнаруживаемые GFW! Если вы разработчик GUI/панели/скрипта установки в один клик, обязательно рандомизируйте эти параметры!
-:::
-
-::: tip
-`limitFallbackUpload` и `limitFallbackDownload` являются необязательными параметрами. Они позволяют ограничить скорость передачи данных для резервных (fallback) соединений, не прошедших проверку. Параметр `bytesPerSec` по умолчанию равен 0, что означает, что ограничение скорости не включено.
-
-Принцип работы: Для каждого соединения алгоритм ограничения скорости включается после передачи `afterBytes` байтов.
-
-Ограничение скорости реализовано с помощью алгоритма "маркерная корзина" (token bucket). Вместимость корзины равна `burstBytesPerSec`. Каждый переданный байт потребляет один маркер, и изначально корзина заполнена до `burstBytesPerSec`.
-
-Каждую секунду корзина пополняется на `bytesPerSec` маркеров, пока не достигнет своей максимальной вместимости.
-
-Пример: `afterBytes=10485760`, `burstBytesPerSec=5242880`, `bytesPerSec=1048576` означают, что после передачи 10 МB скорость будет ограничена до 1 МB/с. Если передача приостановится, через 5 секунд скорость может временно вырасти до 5 МB/с (burst), а затем снова вернется к 1 МB/с.
-
-Рекомендации: Слишком большие значения `afterBytes` и `burstBytesPerSec` не приведут к желаемому эффекту ограничения скорости. Слишком маленькие значения `bytesPerSec` и `burstBytesPerSec` могут быть легко обнаружены.
-
-Следует разумно подбирать параметры в зависимости от размера ресурсов веб-сайта-источника. Если внезапные скачки скорости нежелательны, установите для `burstBytesPerSec` значение 0.
-:::
-
-> `afterBytes` : number
-
-Необязательный параметр. Ограничение скорости для резервных соединений REALITY. Ограничение вступает в силу после передачи указанного количества байт. По умолчанию 0.
-
-> `bytesPerSec` : number
-
-Необязательный параметр. Ограничение скорости для резервных соединений REALITY. Задаёт базовую скорость (байт/секунду). По умолчанию 0, что означает отключение функции ограничения скорости.
-
-> `burstBytesPerSec` : number
-
-Необязательный параметр. Ограничение скорости для резервных соединений REALITY. Задаёт пиковую (burst) скорость (байт/секунду). Действует, когда значение больше `bytesPerSec`.
-
-::: tip
-Ниже приведена конфигурация для **исходящего** подключения (**клиента**).
-:::
-
-> `serverName` : string
-
-Один из `serverNames` сервера.
-
-Если `serverNames` сервера содержит пустое значение, то, как и в случае с TLS, клиент может использовать `"serverName": "0.0.0.0"` для установления соединения без SNI. В отличие от TLS, REALITY не требует и не имеет опции разрешения небезопасных соединений для этой функции. При использовании этой функции убедитесь, что `dest` возвращает сертификат по умолчанию при принятии соединений без SNI.
-
-> `fingerprint` : string
-
-Обязательный параметр, такой же, как в [TLSObject](#tlsobject).
-
-> `shortId` : string
-
-Один из `shortIds` сервера.
-
-Длина — 8 байт, то есть 16 шестнадцатеричных цифр (0-f), может быть меньше 16, ядро автоматически добавит 0 в конец, но количество цифр должно быть **четным** (потому что один байт состоит из 2 шестнадцатеричных цифр).
-
-Например, `aa1234` будет автоматически дополнено до `aa12340000000000`, а `aaa1234` приведет к ошибке.
-
-0 также является четным числом, поэтому, если `shordIDs` сервера содержит пустое значение `""`, клиент также может быть пустым.
-
-> `password` : string
-
-Обязательный параметр: публичный ключ, соответствующий приватному ключу сервера. Генерируется командой
-`./xray x25519 -i "серверный приватный ключ"`.
-
-Ранее назывался `publicKey`, однако во избежание недоразумений переименован (формально это X25519-публичный ключ, но в концепции Reality он хранится у клиента и не должен публиковаться).
-
-> `mldsa65Verify` : string
-
-Необязательный параметр. Публичный ключ для проверки подписи ML-DSA-65.
-Если поле не пустое, клиент будет использовать указанный ключ для валидации сертификата, возвращённого сервером. Подробности см. в описании параметра `"mldsa65Seed"`.
-
-> `spiderX` : string
-
-Начальный путь и параметры для краулера, рекомендуется использовать разные для каждого клиента.
-
-#### CertificateObject
-
-```json
-{
- "ocspStapling": 0,
- "oneTimeLoading": false,
- "usage": "encipherment",
- "buildChain": false,
- "certificateFile": "/path/to/certificate.crt",
- "keyFile": "/path/to/key.key",
- "certificate": [
- "--BEGIN CERTIFICATE--",
- "MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",
- "ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",
- "DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",
- "3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",
- "OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",
- "pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",
- "OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",
- "noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",
- "A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",
- "MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",
- "7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",
- "9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",
- "6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",
- "r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",
- "d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",
- "--END CERTIFICATE--"
- ],
- "key": [
- "--BEGIN RSA PRIVATE KEY--",
- "MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",
- "bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",
- "GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",
- "jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",
- "itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",
- "IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",
- "qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",
- "C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",
- "/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",
- "aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",
- "/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",
- "bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",
- "8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",
- "pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",
- "L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",
- "3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",
- "az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",
- "gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",
- "TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",
- "eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",
- "64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",
- "8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",
- "GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",
- "ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",
- "cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",
- "--END RSA PRIVATE KEY--"
- ]
-}
-```
-
-Сертификат сервера будет автоматически перезагружаться каждые 3600 секунд (то есть каждый час).
-
-> `ocspStapling`: number
-
-Интервал обновления OCSP Stapling в секундах, по умолчанию 0. Любое ненулевое значение включит OCSP Stapling и переопределит время горячей перезагрузки сертификата по умолчанию в 3600 секунд (OCSP Stapling выполняется во время перезагрузки).
-
-> `oneTimeLoading`: true | false
-
-Загружать только один раз, по умолчанию `false`. Если значение `true`, функции горячей перезагрузки сертификата и OCSP Stapling будут отключены.
-
-::: warning
-Если значение равно `true`, то OCSP-Stapling будет отключено.
-:::
-
-> `usage`: "encipherment" | "verify" | "issue"
-
-Использование сертификата, значение по умолчанию: `"encipherment"`.
-
-- `"encipherment"`: сертификат используется для аутентификации и шифрования TLS.
-- `"verify"`: сертификат используется для проверки сертификата удаленного TLS. При использовании этого значения текущий сертификат должен быть сертификатом ЦС.
-- `"issue"`: сертификат используется для выпуска других сертификатов. При использовании этого значения текущий сертификат должен быть сертификатом ЦС.
-
-::: tip СОВЕТ 1
-В Windows вы можете установить самоподписанный сертификат ЦС в систему, чтобы проверить сертификат удаленного TLS.
-:::
-
-::: tip СОВЕТ 2
-Когда поступает новый запрос от клиента, предполагая, что указанный `serverName` равен `"xray.com"`, Xray сначала ищет в списке сертификатов сертификат, который можно использовать для `"xray.com"`, и, если он не найден, использует любой сертификат с `usage`, равным `"issue"`, для выпуска сертификата, подходящего для `"xray.com"`, со сроком действия один час. Новый сертификат будет добавлен в список сертификатов для последующего использования.
-:::
-
-::: tip СОВЕТ 3
-Если одновременно указаны `certificateFile` и `certificate`, Xray отдает приоритет `certificateFile`. То же самое касается `keyFile` и `key`.
-:::
-
-::: tip СОВЕТ 4
-Когда `usage` равно `"verify"`, то `keyFile` и `key` могут быть пустыми.
-:::
-
-::: tip СОВЕТ 5
-Используйте `xray tls cert` для генерации самоподписанного сертификата ЦС.
-:::
-
-::: tip СОВЕТ 6
-Если у вас уже есть доменное имя, вы можете использовать инструменты для удобного получения бесплатных сторонних сертификатов, например, [acme.sh](https://github.com/acmesh-official/acme.sh).
-:::
-
-> `buildChain`: true | false
-
-Вступает в силу только при использовании сертификата `"issue"`, если значение равно `true`, то сертификат ЦС будет встроен в цепочку сертификатов при выпуске сертификата.
-
-::: tip СОВЕТ 1
-Не следует встраивать корневой сертификат в цепочку сертификатов. Этот параметр следует включать только при подписании сертификата ЦС в качестве промежуточного сертификата.
-:::
-
-> `certificateFile`: string
-
-Путь к файлу сертификата, например, сгенерированному с помощью OpenSSL, с расширением .crt.
-
-> `certificate`: \[ string \]
-
-Массив строк, представляющий содержимое сертификата, формат см. в примере. Используйте либо `certificate`, либо `certificateFile`.
-
-> `keyFile`: string
-
-Путь к файлу ключа, например, сгенерированному с помощью OpenSSL, с расширением .key. В настоящее время не поддерживаются файлы ключей, защищенные паролем.
-
-> `key`: \[ string \]
-
-Массив строк, представляющий содержимое ключа, формат см. в примере. Используйте либо `key`, либо `keyFile`.
-
-### SockoptObject
-
-```json
-{
- "mark": 0,
- "tcpMaxSeg": 1440,
- "tcpFastOpen": false,
- "tproxy": "off",
- "domainStrategy": "AsIs",
- "dialerProxy": "",
- "happyEyeballs": {},
- "acceptProxyProtocol": false,
- "tcpKeepAliveInterval": 0,
- "tcpKeepAliveIdle": 300,
- "tcpUserTimeout": 10000,
- "tcpcongestion": "bbr",
- "interface": "wg0",
- "V6Only": false,
- "tcpWindowClamp": 600,
- "tcpMptcp": false,
- "addressPortStrategy": "",
- "customSockopt": []
-}
-```
-
-> `mark`: number
-
-Целое число. Если значение не равно нулю, то исходящее соединение помечается этим значением с помощью SO_MARK.
-
-- Работает только в Linux.
-- Требуются права CAP_NET_ADMIN.
-
-> `tcpMaxSeg`: number
-
-Используется для установки максимального сегмента TCP-пакета (Maximum Segment Size).
-
-> `tcpFastOpen`: true | false | number
-
-Включить [TCP Fast Open](https://ru.wikipedia.org/wiki/TCP_Fast_Open).
-
-Если значение равно `true` или **положительному целому числу**, то TFO включается; если значение равно `false` или **отрицательному числу**, то TFO принудительно отключается; если параметр отсутствует или равен `0`, то используются настройки системы по умолчанию. Можно использовать как для входящих, так и для исходящих подключений.
-
-- Доступно только в следующих (или более новых) версиях операционных систем:
- - Linux 3.16: требуется настройка параметра ядра `net.ipv4.tcp_fastopen`, который представляет собой битовую маску, где `0x1` означает, что клиент может включать TFO, а `0x2` означает, что сервер может включать TFO; значение по умолчанию — `0x1`, если серверу необходимо включить TFO, установите значение этого параметра ядра в `0x3`.
- - ~~Windows 10 (1607)~~ (реализовано неправильно)
- - Mac OS 10.11 / iOS 9 (требуется тестирование)
- - FreeBSD 10.3 (Server) / 12.0 (Client): необходимо установить параметры ядра `net.inet.tcp.fastopen.server_enabled` и `net.inet.tcp.fastopen.client_enabled` в значение `1`. (Требуется тестирование)
-
-- Для входящих подключений установленное здесь **положительное целое число** представляет собой [максимальное количество ожидающих запросов на подключение TFO](https://tools.ietf.org/html/rfc7413#section-5.1), **обратите внимание, что не все операционные системы поддерживают эту настройку**:
- - Linux / FreeBSD: установленное здесь **положительное целое число** представляет собой максимальное значение, максимально допустимое значение — 2147483647, если установлено значение `true`, то используется значение `256`; обратите внимание, что в Linux `net.core.somaxconn` ограничивает максимальное значение, если оно превышает `somaxconn`, то необходимо также увеличить `somaxconn`.
- - Mac OS: если здесь установлено значение `true` или **положительное целое число**, это означает только включение TFO, максимальное значение необходимо установить отдельно с помощью параметра ядра `net.inet.tcp.fastopen_backlog`.
- - Windows: если здесь установлено значение `true` или **положительное целое число**, это означает только включение TFO.
-
-- Для исходящих подключений установка значения `true` или **положительного целого числа** в любой операционной системе означает только включение TFO.
-
-> `tproxy`: "redirect" | "tproxy" | "off"
-
-Включить ли прозрачное проксирование (только для Linux).
-
-- `"redirect"`: использовать прозрачное проксирование в режиме перенаправления. Поддерживаются все TCP-соединения на основе IPv4/6.
-- `"tproxy"`: использовать прозрачное проксирование в режиме TProxy. Поддерживаются все TCP- и UDP-соединения на основе IPv4/6.
-- `"off"`: отключить прозрачное проксирование.
-
-Для прозрачного проксирования требуются права root или `CAP_NET_ADMIN`.
-
-::: danger
-Если в [Dokodemo-door](./inbounds/tunnel.md) указано `followRedirect: true` и `tproxy` в настройках Sockopt пуст, то значение `tproxy` в настройках Sockopt будет установлено в `"redirect"`.
-:::
-
-> `domainStrategy`: "AsIs"
-> "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"
-> "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"
-
-Значение по умолчанию: `"AsIs"`.
-
-Если целевой адрес представлен доменным именем, можно настроить соответствующее значение. Поведение Freedom в зависимости от настройки следующее:
-
-- При использовании `"AsIs"` Xray не выполняет специальную обработку домена. В конечном итоге Xray инициирует соединение, используя встроенный `Dial` из Go. Приоритет выбора адреса фиксирован значениями по умолчанию из RFC6724 (настройки, такие как `gai.conf`, игнорируются). Как правило, приоритет отдается IPv6.
-- При использовании другого значения будет применен [встроенный DNS-сервер](dns.md) Xray-core для разрешения доменного имени.
- Если объект `DNSObject` отсутствует, будет использоваться системный DNS. Если существует несколько подходящих IP-адресов, ядро выберет один из них случайным образом.
-- `"IPv4"` означает попытку подключения только через IPv4, `"IPv4v6"` означает попытку подключения через IPv4 или IPv6, но для доменов dual-stack предпочтение отдается IPv4. (При перестановке v4 и v6 местами логика аналогична, поэтому не описывается повторно).
-- Если во встроенном DNS установлен параметр `"queryStrategy"`, то фактическое поведение будет комбинацией с этим параметром, и будут разрешаться только типы IP-адресов, присутствующие в обоих параметрах. Например:
- `"queryStrategy": "UseIPv4"` и `"domainStrategy": "UseIP"` фактически эквивалентны `"domainStrategy": "UseIPv4"`.
-
-::: tip TIP
-При использовании режимов `"UseIP"` и `"ForceIP"` и если в [конфигурации исходящего подключения](outbound.md#outboundobject) указан `sendThrough`, ядро автоматически определит необходимый тип IP (IPv4 или IPv6) на основе значения `sendThrough`. Если вручную указан один тип IP (например, UseIPv4), но он не соответствует локальному адресу, указанному в `sendThrough`, подключение завершится неудачно.
-:::
-
-::: danger
-Неправильная конфигурация после включения этой функции может привести к бесконечному циклу.
-
-Кратко: для подключения к серверу необходимо дождаться результата DNS-запроса; для завершения DNS-запроса необходимо подключиться к серверу.
-
-> Tony: Что было раньше, курица или яйцо?
-
-Подробное объяснение:
-
-1. Условие возникновения: прокси-сервер (proxy.com). Встроенный DNS-сервер, режим не Local.
-2. Xray пытается установить TCP-соединение с proxy.com **до** того, как запросит proxy.com через встроенный DNS-сервер.
-3. Встроенный DNS-сервер устанавливает соединение с dns.com и отправляет запрос для получения IP-адреса proxy.com.
-4. **Неправильные** правила маршрутизации приводят к тому, что proxy.com проксирует запрос, отправленный на шаге 3.
-5. Xray пытается установить другое TCP-соединение с proxy.com.
-6. Перед установкой соединения запрашивает proxy.com через встроенный DNS-сервер.
-7. Встроенный DNS-сервер повторно использует соединение с шага 3 и отправляет запрос.
-8. Возникает проблема. Установка соединения на шаге 3 требует ожидания результата запроса на шаге 7; завершение запроса на шаге 7 требует полного установления соединения на шаге 3.
-9. Игра окончена!
-
-Решение:
-
-- Изменить правила маршрутизации для встроенного DNS-сервера.
-- Использовать Hosts.
-- ~~Если вы все еще не знаете решения, не используйте эту функцию.~~
-
-Поэтому **не рекомендуется** неопытным пользователям самостоятельно использовать эту функцию.
-:::
-
-> `dialerProxy`: ""
-
-Идентификатор исходящего прокси. Если значение не пустое, для установления соединения будет использоваться указанный outbound. Эта опция может быть использована для поддержки цепочной переадресации на уровне транспорта.
-
-::: danger
-Эта опция несовместима с ProxySettingsObject.Tag
-:::
-
-> `acceptProxyProtocol`: true | false
-
-Только для inbound, указывает, следует ли принимать PROXY protocol.
-
-[PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) предназначен для передачи реального исходного IP-адреса и порта запроса. **Если вы не знакомы с ним, проигнорируйте этот параметр**.
-
-Распространенное программное обеспечение обратного прокси (например, HAProxy, Nginx) может быть настроено на его отправку, VLESS fallbacks xver также может его отправлять.
-
-Если установлено значение `true`, после установления TCP-соединения на самом нижнем уровне, запрашивающая сторона должна сначала отправить PROXY protocol v1 или v2, иначе соединение будет закрыто.
-
-> `tcpKeepAliveIdle`: number
-
-Порог времени простоя TCP в секундах. Когда время простоя TCP-соединения достигает этого порога, начинают отправляться Keep-Alive пакеты.
-
-Для исходящего трафика Xray использует значения по умолчанию из Chrome: как `idle`, так и `interval` равны 45 с. Если этот параметр или `tcpKeepAliveInterval` установить в отрицательное значение, стандартный keep-alive будет отключён; положительное же значение перезапишет настройку по умолчанию.
-
-Для входящего трафика Keep-Alive по умолчанию отключён; он будет активирован, если любой из этих параметров или `tcpKeepAliveInterval` имеет ненулевое значение. Если указан только один из них, второй примет значение, заданное операционной системой.
-
-> `tcpKeepAliveInterval`: number
-
-Интервал (в секундах) между отправками keep-alive-пакетов после того, как TCP-соединение перешло в состояние Keep-Alive. Остальное поведение описано выше.
-
-> `tcpUserTimeout`: number
-
-В миллисекундах. Подробнее: https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md
-
-> `tcpcongestion`: ""
-
-Алгоритм управления перегрузкой TCP. Поддерживается только в Linux.
-Если этот параметр не настроен, используется значение по умолчанию системы.
-
-::: tip Распространенные алгоритмы
-
-- bbr (рекомендуется)
-- cubic
-- reno
-
-:::
-
-::: tip
-Выполните команду `sysctl net.ipv4.tcp_congestion_control`, чтобы получить значение по умолчанию системы.
-:::
-
-> `interface`: ""
-
-Указывает имя сетевого интерфейса для исходящего трафика. Поддерживается в Linux, iOS, macOS и Windows.
-
-> `V6Only`: true | false
-
-Если установлено значение `true`, адрес `::` принимает только IPv6-соединения. Поддерживается только в Linux.
-
-> `tcpWindowClamp`: number
-
-Объявленный размер окна ограничен этим значением. Ядро выберет максимальное значение между этим значением и SOCK_MIN_RCVBUF/2.
-
-> `tcpMptcp`: true | false
-
-По умолчанию этот параметр имеет значение `false`. Установите его в `true`, чтобы включить [Multipath TCP](https://en.wikipedia.org/wiki/Multipath_TCP).
-
-Обратите внимание, что этот параметр действует только на стороне клиента. В Golang версии 1.24 и выше MPTCP уже включен по умолчанию на стороне сервера (при прослушивании соединений).
-
-Для работы MPTCP требуется Linux с ядром версии 5.6 или новее.
-
-> `tcpNoDelay`: true | false
-
-Этот параметр удален, так как golang по умолчанию включает TCP no delay. Если вы хотите отключить его, используйте customSockopt.
-
-> `addressPortStrategy`: "none" | "SrvPortOnly" | "SrvAddressOnly" | "SrvPortAndAddress" | "TxtPortOnly" | "TxtAddressOnly" | "TxtPortAndAddress"
-
-Использование SRV или TXT записей для определения целевого адреса/порта исходящего трафика. По умолчанию `none` (отключено).
-
-Запросы DNS выполняются через системный DNS (не через встроенный DNS Xray). Домен для DNS запроса определяется настройками исходящего подключения. Если DNS запрос не удался, трафик отправляется по исходному адресу и порту.
-
-Префикс `Srv` указывает на запрос SRV-записей (стандартный формат), префикс `Txt` - на запрос TXT-записей (формат вида `127.0.0.1:80`).
-
-`PortOnly`: Сброс только порта.
-`AddressOnly`: Сброс только адреса.
-`PortAndAddress`: Сброс адреса и порта.
-
-Важно! Данная настройка применяется _до_ этапа выбора стратегии разрешения доменов (`domainStrategy`) в `sockopt`. После сброса адреса продолжает действовать `domainStrategy` (если она активна), но _после_ того, как `domainStrategy` в `Freedom` уже отработала. Если в `Freedom` настроено явное разрешение в IP-адрес, данная опция не оказывает никакого эффекта.
-
-PS: Если трафик домена, например, обычный веб-трафик, маршрутизируется через `Freedom` с установленной стратегией `AsIs`, то при активации этой опции будет предпринята попытка разрешить домен и сбросить адрес/порт в соответствии с полученными данными. Например, ядро Xray попытается запросить SRV-запись для `google.com` и перенаправить трафик, опираясь на информацию из этой записи.
-
-> `customSockopt`: []
-
-Массив, позволяющий опытным пользователям указывать любые необходимые sockopt. Теоретически все вышеперечисленные настройки, связанные с соединением, могут быть эквивалентно настроены здесь. В настоящее время поддерживаются операционные системы Linux, Windows, Darwin. Приведенный ниже пример эквивалентен `"tcpcongestion": "bbr"` в ядре.
-
-Перед использованием убедитесь, что вы понимаете программирование сокетов Linux.
-
-```json
-"customSockopt": [
- {
- "system": "linux",
- "type": "str",
- "level":"6",
- "opt": "13",
- "value": "bbr"
- }
-]
-```
-
-> `system`: ""
-
-Необязательное поле. Указывает операционную систему, для которой будет применяться данная опция. Если текущая операционная система не совпадает с указанной, эта опция (`sockopt`) будет пропущена. В настоящее время доступны значения: `linux`, `windows`, `darwin` (все в нижнем регистре). Если оставить пустым, опция будет применена независимо от операционной системы.
-
-> `type`: ""
-
-Обязательный параметр. Тип настройки. Допустимые значения: int или str.
-
-> `level`: ""
-
-Необязательный параметр. Уровень протокола, определяющий область действия. По умолчанию: 6 (TCP).
-
-> `opt`: ""
-
-Название опции, которую нужно установить. Используется десятичное представление (в примере, значение TCP_CONGESTION, определенное как 0xd, преобразуется в десятичное 13).
-
-> `value`: ""
-
-Значение, которое нужно установить для опции. В примере устанавливается значение bbr.
-
-Если `type` указан как int, значение должно быть десятичным числом.
-
-> `happyEyeballs`: [HappyEyeballsObject](#happyeyeballsobject)
-
-Реализация Happy Eyeballs (RFC-8305), применима только для TCP. Когда целью является домен, выполняется «гонка» подключений к полученным IP-адресам, и выбирается первый успешный результат. Работает только в том случае, если `Sockopt.domainStrategy` установлен в значение, отличное от `AsIs`.
-
-Внимание: `UseIPv4v6` / `ForceIPv4v6` сокращают список доступных IP только до IPv4; запрос IPv6 выполняется только в случае сбоя (fallback). Такое использование не рекомендуется. Рекомендуется использовать `UseIP` / `ForceIP` в сочетании с `HappyEyeballs.interleave`.
-
-::: warning
-При использовании этой функции не используйте `domainStrategy` для исходящего соединения `Freedom`, так как это приведет к тому, что `Sockopt` будет видеть только конечный, уже выбранный IP-адрес.
-:::
-
-#### HappyEyeballsObject
-
-```json
-"happyEyeballs": {
- "tryDelayMs": 250,
- "prioritizeIPv6": false,
- "interleave": 1,
- "maxConcurrentTry": 4
-}
-```
-
-> `tryDelayMs`: number
-
-Интервал времени между каждым запросом "гонки", в миллисекундах. По умолчанию 0 (что означает, что функция отключена), рекомендуемое значение — 250.
-
-> `prioritizeIPv6`: bool
-
-Тип первого IP-адреса при сортировке IP-адресов. По умолчанию `false` (то есть IPv4 будет первым).
-
-> `interleave`: number
-
-"First Address Family count" из RFC-8305, значение по умолчанию — 1. Этот параметр определяет чередование при сортировке IP-адресов разных версий.
-
-Например, очередь IP-адресов для набора номера будет отсортирована как 46464646 (при значении 1) или 44664466 (при значении 2) (где 6 — это IPv6-адрес, а 4 — IPv4-адрес).
-
-> `maxConcurrentTry`: number
-
-Максимальное количество одновременных попыток. Используется для предотвращения ситуации, когда ядро создает большое количество соединений, если разрешено много IP-адресов и ни одно из соединений не увенчалось успехом. По умолчанию 4, установка значения 0 отключает happyEyeballs.
-
-### FinalMaskObject
-
-FinalMask применяет последний слой маскировки к трафику после того, как ядро завершит обработку шифрования транспортного уровня, включая TLS/REALITY.
-
-```json
-{
- "tcp": [
- {
- "type": "",
- "settings": {}
- }
- ],
- "udp": [
- {
- "type": "",
- "settings": {}
- }
- ],
- "quicParams": {
- "congestion": "force-brutal",
- "debug": false,
- "brutalUp": "60 mbps",
- "brutalDown": 0,
- "udpHop": {
- "ports": "20000-50000",
- "interval": "5-10"
- },
- "initStreamReceiveWindow": 8388608,
- "maxStreamReceiveWindow": 8388608,
- "initConnectionReceiveWindow": 20971520,
- "maxConnectionReceiveWindow": 20971520,
- "maxIdleTimeout": 30,
- "keepAlivePeriod": 0,
- "disablePathMTUDiscovery": false,
- "maxIncomingStreams": 1024
- }
-}
-```
-
-> `tcp[n].type`: header-custom | fragment | sudoku
-
-Первый элемент в массиве — это самый внешний камуфляж.
-
-Используется совместно с транспортными уровнями raw | httpupgarde | websocket | gRPC | xhttp.
-
-`header-custom`:
-
-`fragment`:
-
-`sudoku`:
-
-> `tcp[n].settings`: header-custom | fragment | sudoku
-
-#### header-custom
-
-```json
-{
- "clients": [
- [
- {
- "delay": 0,
- "rand": 0,
- "randRange": "0-255",
- "type": "",
- "packet": []
- }
- ]
- ],
- "servers": [
- [
- {
- "delay": 0,
- "rand": 0,
- "randRange": "0-255",
- "type": "",
- "packet": []
- }
- ]
- ],
- "errors": [
- [
- {
- "delay": 0,
- "rand": 0,
- "randRange": "0-255",
- "type": "",
- "packet": []
- }
- ]
- ]
-}
-```
-
-`clients[n][m].delay`: Единица измерения — миллисекунды; значение 0 указывает на то, что пакет ранее был отправлен фрагментарно.
-
-`clients[n][m].rand`: Добавляет заданную длину случайных байтов, что конфликтует с функцией `packet`.
-
-`clients[n][m].randRange`: Диапазон случайных байтов, по умолчанию 0-255.
-
-`clients[n][m].type`: Тип `packet` может быть `array | str | hex | base64`, по умолчанию используется `array`.
-
-`clients[n][m].packet`: Добавление фиксированных данных конфликтует с `rand`.
-
-#### fragment
-
-```json
-{
- "packets": "tlshello",
- "length": "100-200",
- "delay": "10-20",
- "maxSplit": "3-6"
-}
-```
-
-#### sudoku
-
-```json
-{
- "password": "",
- "ascii": "",
-
- "customTable": "", // custom_table в официальной документации
- "customTables": [""], // custom_tables в официальной документации
-
- "paddingMin": 0, // padding_min в официальной документации
- "paddingMax": 0 // padding_max в официальной документации
-}
-```
-
-См. [официальную документацию](https://github.com/SUDOKU-ASCII/sudoku/blob/main/configs/README.md) для описания полей.
-
-> `udp[n].type`: header-custom | header-dns | header-dtls | header-srtp | header-utp | header-wechat | header-wireguard | mkcp-original | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp
-
-Первый элемент в массиве — это самый внешний камуфляж.
-
-Используется совместно с транспортными слоями raw udp | kcp | hysteria | xhttp h3.
-
-`header-custom`: Всегда объединяйте пакеты данных в заголовок пакета.
-
-`header-dns`: DNS-маскировка оригинального mKCP. Некоторые кампусные сети разрешают DNS-запросы без входа; добавляет DNS-заголовок к KCP.
-
-`header-dtls`: DTLS-маскировка оригинального mKCP. Маскирует как пакеты DTLS 1.2. Без дополнительных настроек.
-
-`header-srtp`: SRTP-маскировка оригинального mKCP. Маскирует как пакеты SRTP, будет распознаваться как данные видеозвонков (например, FaceTime). Без дополнительных настроек.
-
-`header-utp`: Маскировка uTP оригинального mKCP. Маскирует как uTP-пакеты, будет распознаваться как данные загрузок BT. Без дополнительных настроек.
-
-`header-wechat`: Маскировка под WeChat Video оригинального mKCP. Маскирует как данные видеозвонков WeChat. Без дополнительных настроек.
-
-`header-wireguard`: WireGuard-маскировка оригинального mKCP. Маскирует как пакеты WireGuard. (Не настоящий протокол WireGuard) Без дополнительных настроек.
-
-`mkcp-original`: Простая обфускация, которая раньше применялась в mKCP по умолчанию; возможно, вам понадобится настроить её для подключения к старым серверам mKCP. Без дополнительных настроек.
-
-`mkcp-aes128gcm`: Соответствует функции `seed` оригинального mKCP. Использует AES-128-GCM для обфускации.
-
-`noise`: Перед передачей данных отправляется шум.
-
-`salamander`: Обфускация Salamander (из Hysteria2).
-
-`sudoku`:
-
-`xdns`: использующая DNS-запросы для передачи данных (похоже на DNSTT). Она выполняет стандартные запросы DNS TXT для передачи полезной нагрузки.
-
-Из-за технических ограничений предоставляемый MTU очень мал, использование QUIC невозможно, рекомендуется использовать в паре с mKCP. Рекомендуемые значения MTU: клиент — 130, сервер — 900.
-
-`domain` — домен, используемый для запросов.
-
-Поскольку выполняемые запросы являются стандартными, они могут пересылаться через любой UDP DNS-сервер, хотя эффективность может быть крайне низкой.
-
-Чтобы использовать эту функцию, сервер должен слушать порт 53, затем протокол прокси должен указывать цель на DNS-сервер (например, 8.8.8.8:53), и вы должны владеть доменом `domain` и направить его NS-запись на сервер.
-
-Например, если вы являетесь владельцем example.com, вы можете установить запись A для a.example.com, указывающую на IP-адрес, установить запись NS для t.example.com, указывающую на t.example.com, и в конечном итоге использовать t.example.com. Запись A не может быть поддоменом записи NS.
-
-`xicmp`: Для этого требуются как минимум права доступа `CAP_NET_RAW`, и он должен находиться на самом внешнем уровне, то есть первым элементом массива. Его нельзя использовать с `udpHop` или `dialerProxy`.
-
-> `udp[n].settings`: header-custom | header-dns | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp
-
-#### header-custom
-
-```json
-{
- "client": [
- {
- "rand": 0,
- "randRange": "0-255",
- "type": "",
- "packet": []
- }
- ],
- "server": [
- {
- "rand": 0,
- "randRange": "0-255",
- "type": "",
- "packet": []
- }
- ]
-}
-```
-
-`client[n].rand`: Добавляет заданную длину случайных байтов, что конфликтует с функцией `packet`.
-
-`client[n].randRange`: Диапазон случайных байтов, по умолчанию 0-255.
-
-`client[n].type`: Тип `packet` может быть `array | str | hex | base64`, по умолчанию используется `array`.
-
-`client[n].packet`: Добавление фиксированных данных конфликтует с `rand`.
-
-#### header-dns
-
-```json
-{
- "domain": "www.example.com"
-}
-```
-
-#### mkcp-aes128gcm
-
-```json
-{
- "password": "your-password"
-}
-```
-
-#### noise
-
-```json
-{
- "reset": 0,
- "noise": [
- {
- "rand": "1-8192",
- "randRange": "0-255",
- "type": "",
- "packet": [],
- "delay": "10-20"
- }
- ]
-}
-```
-
-`noise[n].rand`: Добавляет случайные или заданные по длине случайные байты, что конфликтует с `packet`.
-
-`noise[n].randRange`: Диапазон случайных байтов, по умолчанию 0-255.
-
-`noise[n].type`: Тип `packet` может быть `array | str | hex | base64`, по умолчанию используется `array`.
-
-`noise[n].packet`: Добавление фиксированных данных конфликтует с `rand`.
-
-`noise[n].delay`: Единица измерения — миллисекунды. После отправки одного шумового сигнала перед отправкой следующего проходит заданное время задержки.
-
-#### salamander
-
-```json
-{
- "password": "your-password"
-}
-```
-
-#### sudoku
-
-```json
-{
- "password": "",
- "ascii": "",
-
- "customTable": "",
- "customTables": [""],
-
- "paddingMin": 0,
- "paddingMax": 0
-}
-```
-
-Аналогично версии TCP.
-
-#### xdns
-
-```json
-{
- "domain": "www.example.com"
-}
-```
-
-#### xicmp
-
-```json
-{
- "listenIp": "0.0.0.0",
- "id": 0
-}
-```
-
-`listenIp`: IP-адрес, на котором будет осуществляться прослушивание.
-
-`id`: Если под одним и тем же IP-адресом находится несколько клиентов, рекомендуется установить значение 0 на сервере.
-
-> `quicParams`: [quicParamsObject](#quicParams)
-
-#### quicParams
-
-```json
-{
- "congestion": "force-brutal",
- "debug": false,
- "brutalUp": "60 mbps",
- "brutalDown": 0,
- "udpHop": {
- "ports": "20000-50000",
- "interval": "5-10"
- },
- "initStreamReceiveWindow": 8388608,
- "maxStreamReceiveWindow": 8388608,
- "initConnectionReceiveWindow": 20971520,
- "maxConnectionReceiveWindow": 20971520,
- "maxIdleTimeout": 30,
- "keepAlivePeriod": 0,
- "disablePathMTUDiscovery": false,
- "maxIncomingStreams": 1024
-}
-```
-
-Используется для настройки параметров QUIC для XHTTP H3 и Hysteria.
-
-> `congestion`: reno | bbr | brutal | force-brutal
-
-Алгоритм управления перегрузкой. Hysteria по умолчанию использует `brutal`, XHTTP H3 по умолчанию использует `bbr`.
-
-`reno`/`bbr`: Известные алгоритмы.
-
-`brutal`: Согласовывает фиксированную скорость отправки пакетов с другой стороной или переключается на BBR. Поддерживается только в транспорте Hysteria (поскольку XHTTP не имеет механизма согласования).
-
-`force-brutal`: Аналогично `brutal`, но принудительно использует фиксированную скорость отправки `brutalUp` для исходящего трафика, игнорируя согласование с другой стороной.
-
-> `debug`: false | true
-
-Включить логирование в режиме bbr/brutal congestal control.
-
-> `brutalUp`: string
-
-> `brutalDown`: string
-
-Ограничение скорости загрузки/скачивания (upload/download). Значение по умолчанию 0.
-
-Формат удобен для пользователя, поддерживает различные распространенные записи бит в секунду, включая `1000000`, `100kb`, `20 mb`, `100 mbps`, `1g`, `1 tbps` и т.д. Регистр не важен, пробелы между единицами необязательны. Без единиц измерения по умолчанию используется bps (бит в секунду), значение не может быть ниже 65535 bps.
-
-Поведение согласования соответствует Hysteria brutal:
-
-Значение на сервере ограничивает максимальную скорость режима Brutal, которую может выбрать клиент; 0 означает отсутствие ограничений для клиента.
-
-Если на клиенте 0, используется режим BBR; если не 0, используется режим Brutal, который будет ограничен сервером.
-
-Обратите внимание на относительность: загрузка (upload) сервера — это скачивание (download) клиента, а скачивание (download) сервера — это загрузка (upload) клиента.
-
-> `udpHop`: {"ports": string, "interval": number}
-
-`ports` — это диапазон портов для скачков. Может быть строкой с числом, например `"1234"`; или числовым диапазоном, например `"1145-1919"`, что означает 775 портов от 1145 до 1919. Можно использовать запятые для разделения, например `11,13,15-17` означает 5 портов: 11, 13, и с 15 по 17.
-
-`interval` — это интервал переключения портов в секундах. Минимальное значение — 5, значение по умолчанию — 30 секунд.
-
-> `initStreamReceiveWindow`: number
-
-> `maxStreamReceiveWindow`: number
-
-> `initConnectionReceiveWindow`: number
-
-> `maxConnectionReceiveWindow`: number
-
-Эти четыре параметра являются конкретными параметрами окна QUIC. **Не рекомендуется изменять эти значения, если вы не понимаете полностью, что делаете**. Если вы все же меняете их, рекомендуется сохранять соотношение окна приема потока к окну приема соединения как 2:5.
-
-> `maxIdleTimeout`: number
-
-Максимальное время ожидания простоя (в секундах). Через какое время сервер закроет соединение, если не получит никаких данных от клиента. Диапазон 4~120 секунд, по умолчанию 30 секунд.
-
-> `keepAlivePeriod`: number
-
-Интервал QUIC KeepAlive (в секундах). Диапазон 2~60 секунд. По умолчанию отключено.
-
-> `disablePathMTUDiscovery`: bool
-
-Отключить ли обнаружение Path MTU Discovery.
-
-В других реализациях команды !linux && !windows && !darwin OS принудительно отключены, тогда как в xray это не является обязательным. Если ваша ОС не (linux || windows || darwin), вам может потребоваться отключить их вручную.
-
-> `maxIncomingStreams`: number
-
-Если заданы параметры на стороне сервера, их количество не должно быть меньше 8.
+Настройки низкоуровневого сетевого поведения.
diff --git a/docs/ru/config/transports/finalmask.md b/docs/ru/config/transports/finalmask.md
new file mode 100644
index 00000000..ee3b31a4
--- /dev/null
+++ b/docs/ru/config/transports/finalmask.md
@@ -0,0 +1,404 @@
+# FinalMask
+
+FinalMask добавляет последний слой маскировки после того, как ядро уже обработало защиту транспорта, включая TLS и REALITY.
+
+Он используется для разных вариантов TCP- и UDP-маскировки, а также для настройки параметров QUIC.
+
+## FinalMaskObject
+
+`FinalMaskObject` соответствует полю `finalmask` в [`StreamSettingsObject`](../transport.md#streamsettingsobject).
+
+```json
+{
+ // пример для outbound, аналогично применимо к inbound
+ "outbounds": [
+ {
+ // ...
+ "streamSettings": {
+ "finalmask": {
+ // [!code focus:30]
+ "tcp": [
+ {
+ "type": "",
+ "settings": {}
+ }
+ ],
+ "udp": [
+ {
+ "type": "",
+ "settings": {}
+ }
+ ],
+ "quicParams": {
+ "congestion": "force-brutal",
+ "debug": false,
+ "brutalUp": "60 mbps",
+ "brutalDown": 0,
+ "udpHop": {
+ "ports": "20000-50000",
+ "interval": "5-10"
+ },
+ "initStreamReceiveWindow": 8388608,
+ "maxStreamReceiveWindow": 8388608,
+ "initConnectionReceiveWindow": 20971520,
+ "maxConnectionReceiveWindow": 20971520,
+ "maxIdleTimeout": 30,
+ "keepAlivePeriod": 0,
+ "disablePathMTUDiscovery": false,
+ "maxIncomingStreams": 1024
+ }
+ }
+ }
+ }
+ ]
+}
+```
+
+> `tcp[n].type`: header-custom | fragment | sudoku
+
+Первый элемент массива является самым внешним слоем маскировки.
+
+Используется вместе с `raw`, `httpupgrade`, `websocket`, `grpc` и `xhttp`.
+
+`header-custom`:
+
+`fragment`:
+
+`sudoku`:
+
+> `tcp[n].settings`: header-custom | fragment | sudoku
+
+### header-custom
+
+```json
+{
+ "clients": [
+ [
+ {
+ "delay": 0,
+ "rand": 0,
+ "randRange": "0-255",
+ "type": "",
+ "packet": []
+ }
+ ]
+ ],
+ "servers": [
+ [
+ {
+ "delay": 0,
+ "rand": 0,
+ "randRange": "0-255",
+ "type": "",
+ "packet": []
+ }
+ ]
+ ],
+ "errors": [
+ [
+ {
+ "delay": 0,
+ "rand": 0,
+ "randRange": "0-255",
+ "type": "",
+ "packet": []
+ }
+ ]
+ ]
+}
+```
+
+`clients[n][m].delay`: задержка в миллисекундах. Если значение равно `0`, данные отправляются слитно с предыдущим пакетом.
+
+`clients[n][m].rand`: добавить заданное число случайных байт. Несовместимо с `packet`.
+
+`clients[n][m].randRange`: диапазон значений случайных байт. По умолчанию `0-255`.
+
+`clients[n][m].type`: тип `packet`. Поддерживаются `array`, `str`, `hex` и `base64`. Значение по умолчанию — `array`.
+
+`clients[n][m].packet`: добавить фиксированные данные. Несовместимо с `rand`.
+
+### fragment
+
+```json
+{
+ "packets": "tlshello",
+ "length": "100-200",
+ "delay": "10-20",
+ "maxSplit": "3-6"
+}
+```
+
+### sudoku
+
+```json
+{
+ "password": "",
+ "ascii": "",
+
+ "customTable": "", // в upstream документации поле называется custom_table
+ "customTables": [""], // в upstream документации поле называется custom_tables
+
+ "paddingMin": 0, // в upstream документации поле называется padding_min
+ "paddingMax": 0 // в upstream документации поле называется padding_max
+}
+```
+
+Смысл этих полей описан в [upstream-документации](https://github.com/SUDOKU-ASCII/sudoku/blob/main/configs/README.md).
+
+> `udp[n].type`: header-custom | header-dns | header-dtls | header-srtp | header-utp | header-wechat | header-wireguard | mkcp-original | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp
+
+Первый элемент массива является самым внешним слоем маскировки.
+
+Используется вместе с `raw` UDP, `kcp`, `hysteria` и `xhttp` H3.
+
+`header-custom`: всегда добавляется как объединенный заголовок пакета.
+
+`header-dns`: старая DNS-маскировка mKCP. В некоторых кампусных сетях DNS-запросы разрешены до авторизации, поэтому этот режим добавляет DNS-заголовок к KCP.
+
+`header-dtls`: старая DTLS-маскировка mKCP. Имитирует пакеты DTLS 1.2. Дополнительных настроек нет.
+
+`header-srtp`: старая SRTP-маскировка mKCP. Похожа на трафик видеозвонков вроде FaceTime. Дополнительных настроек нет.
+
+`header-utp`: старая uTP-маскировка mKCP. Похожа на BitTorrent-трафик. Дополнительных настроек нет.
+
+`header-wechat`: старая маскировка под WeChat Video из mKCP. Дополнительных настроек нет.
+
+`header-wireguard`: старая WireGuard-маскировка mKCP. Выглядит как пакеты WireGuard, хотя реальным протоколом WireGuard не является. Дополнительных настроек нет.
+
+`mkcp-original`: простая обфускация, которая раньше была значением по умолчанию в mKCP. Может понадобиться для подключения к старым mKCP-серверам. Дополнительных настроек нет.
+
+`mkcp-aes128gcm`: старый режим `seed` в mKCP. Использует AES-128-GCM для обфускации.
+
+`noise`: шум, отправляемый перед реальной полезной нагрузкой.
+
+`salamander`: обфускация Salamander из Hysteria2.
+
+`sudoku`:
+
+`xdns`: передает данные через DNS-запросы по схеме, похожей на DNSTT. Для переноса полезной нагрузки выполняются обычные DNS TXT-запросы.
+
+Из-за технических ограничений эффективный MTU очень маленький, поэтому QUIC здесь непрактичен. Рекомендуется сочетать режим с mKCP. Рекомендуемые MTU — 130 на клиенте и 900 на сервере.
+
+Так как запросы являются стандартными DNS-запросами, их может пересылать любой UDP DNS-сервер, хотя эффективность будет низкой.
+
+Для использования этого режима сервер должен слушать порт 53, прокси-протокол должен указывать целью DNS-сервер вроде `8.8.8.8:53`, а вы должны владеть доменом `domain` и направить его NS-запись на сервер.
+
+Например, если у вас есть `example.com`, можно создать A-запись вроде `a.example.com`, указывающую на IP сервера, затем NS-запись вроде `t.example.com`, указывающую на `t.example.com`, и использовать `t.example.com` как рабочий домен. A-запись не должна быть поддоменом NS-записи.
+
+`xicmp`: требует как минимум `CAP_NET_RAW`, должен быть самым внешним слоем, то есть первым элементом массива, и несовместим с `udpHop` и `dialerProxy`.
+
+> `udp[n].settings`: header-custom | header-dns | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp
+
+### header-custom
+
+```json
+{
+ "client": [
+ {
+ "rand": 0,
+ "randRange": "0-255",
+ "type": "",
+ "packet": []
+ }
+ ],
+ "server": [
+ {
+ "rand": 0,
+ "randRange": "0-255",
+ "type": "",
+ "packet": []
+ }
+ ]
+}
+```
+
+`client[n].rand`: добавить заданное число случайных байт. Несовместимо с `packet`.
+
+`client[n].randRange`: диапазон значений случайных байт. По умолчанию `0-255`.
+
+`client[n].type`: тип `packet`. Поддерживаются `array`, `str`, `hex` и `base64`. Значение по умолчанию — `array`.
+
+`client[n].packet`: добавить фиксированные данные. Несовместимо с `rand`.
+
+### header-dns
+
+```json
+{
+ "domain": "www.example.com"
+}
+```
+
+### mkcp-aes128gcm
+
+```json
+{
+ "password": "your-password"
+}
+```
+
+### noise
+
+```json
+{
+ "reset": 0,
+ "noise": [
+ {
+ "rand": "1-8192",
+ "randRange": "0-255",
+ "type": "",
+ "packet": [],
+ "delay": "10-20"
+ }
+ ]
+}
+```
+
+`noise[n].rand`: добавить случайные байты или случайное число байт. Несовместимо с `packet`.
+
+`noise[n].randRange`: диапазон значений случайных байт. По умолчанию `0-255`.
+
+`noise[n].type`: тип `packet`. Поддерживаются `array`, `str`, `hex` и `base64`. Значение по умолчанию — `array`.
+
+`noise[n].packet`: добавить фиксированные данные. Несовместимо с `rand`.
+
+`noise[n].delay`: задержка в миллисекундах. После отправки одного элемента шума Xray ждет указанное время перед следующим.
+
+### salamander
+
+```json
+{
+ "password": "your-password"
+}
+```
+
+### sudoku
+
+```json
+{
+ "password": "",
+ "ascii": "",
+
+ "customTable": "",
+ "customTables": [""],
+
+ "paddingMin": 0,
+ "paddingMax": 0
+}
+```
+
+Здесь действуют те же значения, что и в TCP-версии.
+
+### xdns
+
+```json
+{
+ "domain": "www.example.com"
+}
+```
+
+### xicmp
+
+```json
+{
+ "listenIp": "0.0.0.0",
+ "id": 0
+}
+```
+
+`listenIp`: IP-адрес, на котором выполняется прослушивание.
+
+`id`: если несколько клиентов используют один IP, серверу рекомендуется оставлять здесь `0`.
+
+> `quicParams`: [quicParamsObject](#quicParams)
+
+### quicParams
+
+```json
+{
+ "congestion": "force-brutal",
+ "debug": false,
+ "brutalUp": "60 mbps",
+ "brutalDown": 0,
+ "udpHop": {
+ "ports": "20000-50000",
+ "interval": "5-10"
+ },
+ "initStreamReceiveWindow": 8388608,
+ "maxStreamReceiveWindow": 8388608,
+ "initConnectionReceiveWindow": 20971520,
+ "maxConnectionReceiveWindow": 20971520,
+ "maxIdleTimeout": 30,
+ "keepAlivePeriod": 0,
+ "disablePathMTUDiscovery": false,
+ "maxIncomingStreams": 1024
+}
+```
+
+Используется для настройки параметров QUIC в XHTTP H3 и Hysteria.
+
+> `congestion`: reno | bbr | brutal | force-brutal
+
+Алгоритм управления перегрузкой. В Hysteria по умолчанию используется `brutal`, в XHTTP H3 — `bbr`.
+
+`reno` и `bbr` — обычные известные алгоритмы.
+
+`brutal` согласует фиксированную скорость отправки пакетов с другой стороной или откатывается к BBR. Поддерживается только в Hysteria, потому что у XHTTP нет механизма согласования.
+
+`force-brutal` работает так же, как `brutal`, но принудительно использует фиксированную исходящую скорость из `brutalUp`, игнорируя переговоры с другой стороной.
+
+> `debug`: false | true
+
+Включает логирование для реализаций `bbr` и `brutal`.
+
+> `brutalUp`: string
+
+> `brutalDown`: string
+
+Ограничения исходящей и входящей скорости. Значение по умолчанию — `0`.
+
+Формат дружелюбный: поддерживаются записи вроде `1000000`, `100kb`, `20 mb`, `100 mbps`, `1g`, `1 tbps`. Регистр неважен, пробелы необязательны. Если единицы измерения не указаны, используется `bps`. Значение не может быть ниже 65535 bps.
+
+Переговоры работают так же, как у Hysteria Brutal:
+
+Серверное значение ограничивает максимальную скорость режима Brutal, которую клиент может выбрать. `0` означает отсутствие ограничения со стороны сервера.
+
+Если на клиенте указано `0`, используется режим BBR. Если значение не нулевое, используется Brutal-режим, но он все равно ограничивается серверной стороной.
+
+Не забывайте про относительность направлений: серверный upload — это клиентский download, а серверный download — это клиентский upload.
+
+> `udpHop`: {"ports": string, "interval": number}
+
+Настройка прыжков по UDP-портам.
+
+`ports` задает диапазон портов. Это может быть одиночная строка вроде `"1234"`, диапазон вроде `"1145-1919"` или несколько сегментов через запятую, например `11,13,15-17`.
+
+`interval` — интервал переключения портов в секундах. Минимум — 5, значение по умолчанию — 30 секунд.
+
+> `initStreamReceiveWindow`: number
+
+> `maxStreamReceiveWindow`: number
+
+> `initConnectionReceiveWindow`: number
+
+> `maxConnectionReceiveWindow`: number
+
+Это низкоуровневые параметры QUIC-окон. **Не меняйте их, если не понимаете точно, что делаете.** Если менять их все же нужно, рекомендуется сохранять соотношение окна потока и окна соединения на уровне 2:5.
+
+> `maxIdleTimeout`: number
+
+Максимальный таймаут простоя в секундах. Это время, после которого сервер закроет соединение, если не получает данные от клиента. Допустимый диапазон — от 4 до 120 секунд. Значение по умолчанию — 30 секунд.
+
+> `keepAlivePeriod`: number
+
+Интервал QUIC KeepAlive в секундах. Допустимый диапазон — от 2 до 60 секунд. По умолчанию выключено.
+
+> `disablePathMTUDiscovery`: bool
+
+Отключать ли Path MTU Discovery.
+
+Во многих других реализациях на системах вне Linux, Windows и Darwin этот режим отключается принудительно, тогда как Xray не делает этого автоматически. Если ваша ОС не входит в эти три, возможно, придется отключить его вручную.
+
+> `maxIncomingStreams`: number
+
+Только для сервера. Если параметр задан, он не должен быть меньше `8`.
diff --git a/docs/ru/config/transports/httpupgrade.md b/docs/ru/config/transports/httpupgrade.md
index a1509b27..d4e03638 100644
--- a/docs/ru/config/transports/httpupgrade.md
+++ b/docs/ru/config/transports/httpupgrade.md
@@ -8,9 +8,9 @@
**Рекомендуется переключиться на [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113#discussioncomment-11468947), чтобы избежать значительных характеристик трафика, таких как HTTPUpgrade «ALPN is http/1.1».**
:::
-## HttpUpgradeObject
+## HTTPUpgradeObject
-`HttpUpgradeObject` соответствует элементу `httpupgradeSettings` в [`StreamSettingsObject`](../transport.md#streamsettingsobject).
+`HTTPUpgradeObject` соответствует элементу `httpupgradeSettings` в [`StreamSettingsObject`](../transport.md#streamsettingsobject).
```json
{
diff --git a/docs/ru/config/transports/index.md b/docs/ru/config/transports/index.md
index 09dd2a83..117c67fc 100644
--- a/docs/ru/config/transports/index.md
+++ b/docs/ru/config/transports/index.md
@@ -1,6 +1,8 @@
-# Список транспортных слоев Xray
+# Список конфигурации транспорта Xray
-Xray поддерживает следующие транспортные слои:
+Xray поддерживает следующие категории конфигурации транспорта:
+
+## Способы передачи
- [RAW](raw.md)
- [XHTTP: Beyond REALITY](xhttp.md)
@@ -9,3 +11,13 @@ Xray поддерживает следующие транспортные сло
- [WebSocket](websocket.md)
- [HTTPUpgrade](httpupgrade.md)
- [Hysteria](hysteria.md)
+
+## Безопасность транспорта
+
+- [REALITY](reality.md)
+- [TLS](tls.md)
+
+## Дополнительные настройки
+
+- [FinalMask](finalmask.md)
+- [Sockopt](sockopt.md)
diff --git a/docs/ru/config/transports/mkcp.md b/docs/ru/config/transports/mkcp.md
index bc7f3dd2..2fbaebb2 100644
--- a/docs/ru/config/transports/mkcp.md
+++ b/docs/ru/config/transports/mkcp.md
@@ -37,7 +37,7 @@ mKCP жертвует пропускной способностью ради у
```
::: tip
-Поля `header` и `seed` были удалены, пожалуйста, используйте [FinalMask](../transport.md#finalmaskobject) для настройки.
+Поля `header` и `seed` были удалены, пожалуйста, используйте [FinalMask](./finalmask.md#finalmaskobject) для настройки.
Также была удалена стандартная обфускация mKCP; для подключения к старым версиям серверов необходимо настроить `mkcp-original` в FinalMask.
:::
diff --git a/docs/ru/config/transports/reality.md b/docs/ru/config/transports/reality.md
new file mode 100644
index 00000000..982947e7
--- /dev/null
+++ b/docs/ru/config/transports/reality.md
@@ -0,0 +1,203 @@
+# REALITY
+
+REALITY — это модификация TLS, которая использует внешний вид и характеристики рукопожатия целевого сайта как маскировку.
+
+:::: tip
+REALITY сейчас является одной из самых сильных схем защиты транспорта, а снаружи такой трафик выглядит как обычный веб-трафик.
+Включение REALITY вместе с подходящим режимом управления потоком XTLS Vision может дать прирост производительности в несколько раз или даже больше чем в десять раз.
+
+::: details Для разработчиков
+REALITY модифицирует только TLS. На стороне клиента в основном требуется легкая обработка полностью случайного session ID и пользовательской проверки сертификата, поэтому теоретически оно совместимо с большинством TLS-комбинаций.
+Подробнее см. в [проекте REALITY](https://github.com/XTLS/REALITY).
+:::
+::::
+
+## RealityObject
+
+`RealityObject` соответствует полю `realitySettings` в [`StreamSettingsObject`](../transport.md#streamsettingsobject).
+
+```json
+{
+ // пример для outbound, аналогично применимо к inbound
+ "outbounds": [
+ {
+ // ...
+ "streamSettings": {
+ "security": "reality",
+ "realitySettings": {
+ // [!code focus:28]
+ // Входящие настройки (сервер)
+ "show": false,
+ "target": "example.com:443",
+ "xver": 0,
+ "serverNames": ["example.com", "www.example.com"],
+ "privateKey": "",
+ "minClientVer": "",
+ "maxClientVer": "",
+ "maxTimeDiff": 0,
+ "shortIds": ["", "0123456789abcdef"],
+ "mldsa65Seed": "",
+ "limitFallbackUpload": {
+ "afterBytes": 0,
+ "bytesPerSec": 0,
+ "burstBytesPerSec": 0
+ },
+ "limitFallbackDownload": {
+ "afterBytes": 0,
+ "bytesPerSec": 0,
+ "burstBytesPerSec": 0
+ },
+ // Исходящие настройки (клиент)
+ "serverName": "",
+ "fingerprint": "chrome",
+ "password": "",
+ "shortId": "",
+ "mldsa65Verify": "",
+ "spiderX": ""
+ }
+ }
+ }
+ ]
+}
+```
+
+> `show`: true | false
+
+Если значение равно `true`, выводится отладочная информация.
+
+::: tip
+Ниже идут параметры **inbound** (**серверной стороны**).
+:::
+
+> `target`: string
+
+Обязательный параметр. Формат такой же, как у [dest](../features/fallback.md#fallbackobject) в fallback VLESS.
+
+Старое имя поля — `dest`. В текущих версиях оба поля являются алиасами.
+
+Если `target` поддерживает постквантовый алгоритм обмена ключами X25519MLKEM768, клиент REALITY также автоматически будет использовать его при согласовании ключей. Проверить поддержку можно командой `xray tls ping cloudflare.com`, подставив вместо домена ваш `target` и при необходимости порт.
+
+Ядро отличает серверную и клиентскую конфигурацию по наличию этого поля. Не заполняйте его на клиенте, иначе определение роли будет неправильным.
+
+::: warning
+Для маскировки Xray **напрямую пересылает** трафик, который не прошел проверку, то есть не является корректным REALITY-запросом, на `target`.
+Если IP-адрес `target` особый, например это сайт за Cloudflare CDN, ваш сервер фактически превращается в порт-форвардер для Cloudflare и после сканирования может использоваться посторонними.
+
+Чтобы этого избежать, можно поставить перед Xray Nginx или другой фильтр по SNI.
+Также можно рассмотреть `limitFallbackUpload` и `limitFallbackDownload`.
+:::
+
+> `xver`: number
+
+Необязательный параметр. Формат такой же, как у [xver](../features/fallback.md#fallbackobject) в fallback VLESS.
+
+> `serverNames`: [string]
+
+Обязательный параметр. Список допустимых для клиента значений `serverName`. Подстановочный символ `*` не поддерживается.
+
+Обычно достаточно держать этот список согласованным с `target`. На практике допустимы любые SNI, которые принимает сервер в соответствии с поведением `target`, обычно ориентируясь на [SAN](https://ru.wikipedia.org/wiki/Subject_Alternative_Name) сертификата, который возвращает целевой сайт.
+
+В списке может присутствовать пустая строка `""`, что означает разрешение соединений без SNI. Для этого не требуется IP-сертификат у `target`; достаточно, чтобы он не отклонял Client Hello без SNI. При использовании этого режима клиентский `serverName` не должен быть пустым, вместо этого нужно указать любой корректный IP-адрес как заглушку.
+
+Поведение сервера на запросы без SNI можно посмотреть через `xray tls ping`.
+
+> `privateKey`: string
+
+Обязательный параметр. Генерируется командой `./xray x25519`.
+
+> `minClientVer`: string
+
+Необязательный параметр. Минимальная версия клиента Xray в формате `x.y.z`.
+
+> `maxClientVer`: string
+
+Необязательный параметр. Максимальная версия клиента Xray в формате `x.y.z`.
+
+> `maxTimeDiff`: number
+
+Необязательный параметр. Максимально допустимая разница времени в миллисекундах.
+
+> `shortIds`: [string]
+
+Обязательный параметр. Список допустимых `shortId`, которыми можно различать клиентов.
+
+Требования к формату описаны у поля `shortId`.
+
+Если список содержит пустую строку, клиентский `shortId` тоже может быть пустым.
+
+> `mldsa65Seed`: string
+
+Только для сервера. Приватный ключ, который используется для добавления дополнительной постквантовой подписи к сертификату, отправляемому клиенту REALITY, по алгоритму ML-DSA-65. Если когда-нибудь появится квантовый компьютер, способный ломать x25519, утечка `password` может позволить MITM-атаку; эта функция предназначена для защиты от такого будущего риска.
+
+Сгенерировать пару ключей можно командой `xray mldsa65`. После настройки приватного ключа на сервере подпись добавляется только как расширение сертификата и не влияет на старых клиентов или клиентов, которые не включали эту возможность.
+
+После включения этой функции сертификат, который возвращает `target`, **должен** быть длиннее 3500 байт, потому что постквантовая подпись делает временный сертификат REALITY больше. Чтобы это само не превратилось в отпечаток, сертификат `target` тоже должен быть большим. Проверить это можно через `xray tls ping example.com`. Для полной постквантовой устойчивости `target` также должен поддерживать X25519MLKEM768.
+
+> `limitFallbackUpload` / `limitFallbackDownload`
+
+::: warning
+Лучшая практика для REALITY по-прежнему состоит в том, чтобы брать сертификаты у ресурса в том же ASN, поэтому в большинстве случаев эта функция вам не понадобится. Имеет смысл рассматривать ее только если вы вынуждены использовать сертификат чего-то вроде бесплатного CDN Cloudflare и хотите не допустить превращения сервера в ускоритель для посторонних.
+
+Само ограничение fallback-трафика тоже является отпечатком, поэтому не рекомендуется. Если вы делаете панель или one-click скрипт, такие параметры стоит рандомизировать.
+:::
+
+::: tip
+`limitFallbackUpload` и `limitFallbackDownload` необязательны и позволяют ограничивать скорость fallback-соединений, не прошедших проверку. Значение `bytesPerSec` по умолчанию равно `0`, то есть ограничение выключено.
+
+Механизм такой: для каждого непрошедшего проверку fallback-соединения ограничение включается после передачи `afterBytes` байт.
+Используется алгоритм token bucket. Размер корзины равен `burstBytesPerSec`. Каждый переданный байт тратит один токен. Изначально корзина заполнена полностью.
+Каждую секунду в нее добавляется `bytesPerSec` токенов, пока она снова не заполнится.
+
+Пример: `afterBytes=10485760`, `burstBytesPerSec=5242880`, `bytesPerSec=1048576` означает ограничение до 1 МБ/с после передачи 15 МБ. Если передача приостановится, через 5 секунд можно снова кратковременно выйти на 5 МБ/с.
+
+Если `afterBytes` и `burstBytesPerSec` слишком большие, практического эффекта почти не будет. Если `bytesPerSec` и `burstBytesPerSec` слишком маленькие, поведение становится слишком легко отличимым.
+Подбирать эти параметры нужно с учетом размера ресурсов у сайта, чей сертификат используется. Если всплески не нужны, установите `burstBytesPerSec` в `0`.
+:::
+
+> `afterBytes`: number
+
+Необязательный параметр. Ограничение скорости для fallback-соединения REALITY начинает действовать только после передачи указанного числа байт. По умолчанию `0`.
+
+> `bytesPerSec`: number
+
+Необязательный параметр. Базовая скорость ограничения для fallback-соединения REALITY, в байтах в секунду. По умолчанию `0`, то есть отключено.
+
+> `burstBytesPerSec`: number
+
+Необязательный параметр. Пиковая скорость ограничения для fallback-соединения REALITY, в байтах в секунду. Работает, когда значение больше `bytesPerSec`.
+
+::: tip
+Ниже идут параметры **outbound** (**клиентской стороны**).
+:::
+
+> `serverName`: string
+
+Одно из серверных значений `serverNames`.
+
+Клиент также может указать здесь любой IP-адрес. Тогда Xray отправит Client Hello без SNI. Для этого в серверном `serverNames` должна присутствовать пустая строка `""`.
+
+> `fingerprint`: string
+
+Обязательный параметр. Работает так же, как [TLSObject](./tls.md#tlsobject). Значение `unsafe`, отключающее uTLS для обычного TLS, здесь не поддерживается, потому что REALITY опирается на эту библиотеку для управления низкоуровневыми параметрами TLS.
+
+> `shortId`: string
+
+Одно из серверных значений `shortIds`.
+
+Длина составляет 8 байт, то есть до 16 шестнадцатеричных символов в диапазоне `0`-`f`. Поле может быть короче 16 символов, тогда ядро автоматически дополнит его нулями справа, но количество символов обязательно должно быть **четным**, потому что один байт задается двумя hex-символами.
+
+Например, `aa1234` автоматически превратится в `aa12340000000000`, а `aaa1234` вызовет ошибку.
+
+Ноль тоже четный, поэтому если в серверном `shortIds` есть пустая строка `""`, клиентское значение тоже может быть пустым.
+
+> `password`: string
+
+Обязательный параметр. Публичный ключ, соответствующий приватному ключу сервера. Генерируется командой `./xray x25519 -i "приватный ключ сервера"`. Раньше поле называлось `publicKey`, но было переименовано, чтобы не вводить в заблуждение: формально это действительно x25519 public key, но в модели REALITY он хранится у клиента и не должен восприниматься как что-то публично публикуемое.
+
+> `mldsa65Verify`
+
+Необязательный параметр. Публичный ключ для проверки подписи `mldsa65`. Если значение не пустое, Xray использует его для проверки сертификата, полученного от сервера. Подробности см. у `mldsa65Seed`.
+
+> `spiderX`: string
+
+Начальный путь и параметры краулера. Рекомендуется использовать разные значения для разных клиентов.
diff --git a/docs/ru/config/transports/sockopt.md b/docs/ru/config/transports/sockopt.md
new file mode 100644
index 00000000..040c4cd8
--- /dev/null
+++ b/docs/ru/config/transports/sockopt.md
@@ -0,0 +1,296 @@
+# Sockopt
+
+Sockopt используется для настройки низкоуровневого сетевого поведения.
+
+С его помощью можно управлять прозрачным проксированием, стратегией DNS-разрешения и различными параметрами socket.
+
+## SockoptObject
+
+`SockoptObject` соответствует полю `sockopt` в [`StreamSettingsObject`](../transport.md#streamsettingsobject).
+
+```json
+{
+ // пример для outbound, аналогично применимо к inbound
+ "outbounds": [
+ {
+ // ...
+ "streamSettings": {
+ "sockopt": {
+ // [!code focus:18]
+ "mark": 0,
+ "tcpMaxSeg": 1440,
+ "tcpFastOpen": false,
+ "tproxy": "off",
+ "domainStrategy": "AsIs",
+ "happyEyeballs": {},
+ "dialerProxy": "",
+ "acceptProxyProtocol": false,
+ "tcpKeepAliveInterval": 0,
+ "tcpKeepAliveIdle": 300,
+ "tcpUserTimeout": 10000,
+ "tcpcongestion": "bbr",
+ "interface": "wg0",
+ "V6Only": false,
+ "tcpWindowClamp": 600,
+ "tcpMptcp": false,
+ "addressPortStrategy": "",
+ "customSockopt": []
+ }
+ }
+ }
+ ]
+}
+```
+
+> `mark`: number
+
+Целое число. Если значение не равно нулю, исходящие соединения помечаются через `SO_MARK`.
+
+- Только Linux.
+- Требуются права `CAP_NET_ADMIN`.
+
+> `tcpMaxSeg`: number
+
+Используется для задания максимального размера сегмента TCP.
+
+> `tcpFastOpen`: true | false | number
+
+Включает или отключает [TCP Fast Open](https://ru.wikipedia.org/wiki/TCP_Fast_Open).
+
+Если указано `true` или положительное число, TFO включается. Если указано `false` или отрицательное число, TFO принудительно отключается. Если поле отсутствует или равно `0`, используется поведение системы по умолчанию. Параметр доступен и для inbound, и для outbound.
+
+- Работает только на следующих версиях ОС и новее:
+ - Linux 3.16: требует настройки `net.ipv4.tcp_fastopen`. Это bitmap, где `0x1` разрешает клиентскую сторону, а `0x2` — серверную. По умолчанию используется `0x1`. Если TFO нужно на сервере, задайте `0x3`.
+ - ~~Windows 10 (1607)~~, но реализация некорректна
+ - Mac OS 10.11 / iOS 9, требуется проверка
+ - FreeBSD 10.3 на сервере / 12.0 на клиенте: нужны `net.inet.tcp.fastopen.server_enabled=1` и `net.inet.tcp.fastopen.client_enabled=1`, тоже требуется проверка
+
+- Для inbound положительное число означает [максимальное число ожидающих TFO-соединений](https://tools.ietf.org/html/rfc7413#section-5.1). **Не все ОС позволяют задавать это здесь**:
+ - Linux / FreeBSD: положительное число используется как лимит. Максимум — 2147483647. Если задано `true`, используется `256`. В Linux сверху это также ограничивает `net.core.somaxconn`.
+ - Mac OS: `true` или положительное число лишь включает TFO. Размер очереди задается отдельно через `net.inet.tcp.fastopen_backlog`.
+ - Windows: `true` или положительное число только включает TFO.
+
+- Для outbound `true` или положительное число просто означает включение TFO на поддерживаемой ОС.
+
+> `tproxy`: "redirect" | "tproxy" | "off"
+
+Включать ли прозрачное проксирование. Только Linux.
+
+- `"redirect"`: режим Redirect, поддерживает все IPv4/IPv6 TCP-соединения
+- `"tproxy"`: режим TProxy, поддерживает все IPv4/IPv6 TCP- и UDP-соединения
+- `"off"`: прозрачное проксирование отключено
+
+Для прозрачного проксирования нужны root или `CAP_NET_ADMIN`.
+
+::: danger
+Если в [Dokodemo-door](../inbounds/tunnel.md) параметр `followRedirect` равен `true`, а `tproxy` в Sockopt пустой, то значение `tproxy` будет автоматически установлено в `"redirect"`.
+:::
+
+> `domainStrategy`: "AsIs"
+> "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"
+> "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"
+
+Значение по умолчанию — `"AsIs"`.
+
+Когда целевой адрес является доменным именем, это поле управляет тем, как outbound будет его разрешать и использовать:
+
+- При `"AsIs"` Xray никак специально не обрабатывает доменное имя и в конце использует обычный dialer Go. Приоритет фиксирован правилами RFC 6724 и обычно приводит к предпочтению IPv6.
+- При любом другом значении Xray использует [встроенный DNS](../dns.md). Если `DNSObject` отсутствует, используется системный DNS. Если есть несколько подходящих IP-адресов, ядро случайным образом выбирает один.
+- `"IPv4"` означает попытку использовать только IPv4. `"IPv4v6"` означает использование IPv4 или IPv6, но для dual-stack домена предпочитается IPv4. Аналогично работают и IPv6-first варианты.
+- Если во встроенном DNS также задан `"queryStrategy"`, фактическое поведение определяется пересечением двух настроек. Например, `"queryStrategy": "UseIPv4"` вместе с `"domainStrategy": "UseIP"` фактически эквивалентно `"domainStrategy": "UseIPv4"`.
+- Варианты `"Use*"` делают fallback к `"AsIs"`, если результат разрешения не соответствует нужному семейству адресов.
+- Варианты `"Force*"` завершают соединение ошибкой, если получить нужный тип адреса не удалось.
+
+::: tip TIP
+Если используется `"UseIP"` или `"ForceIP"` и в [OutboundObject](../outbound.md#outboundobject) задан `sendThrough`, ядро автоматически определяет нужное семейство адресов по локальному адресу. Если вручную зафиксировать, например, `UseIPv4`, а `sendThrough` указывает на IPv6-адрес, соединение завершится ошибкой.
+:::
+
+::: danger
+Неправильная настройка этой функции может привести к бесконечному циклу.
+
+Коротко: чтобы подключиться к серверу, нужно дождаться DNS-результата, а чтобы завершить DNS-запрос, нужно подключиться к серверу.
+
+Подробно:
+
+1. Есть прокси-сервер `proxy.com` и встроенный DNS в не-Local режиме.
+2. Перед подключением к `proxy.com` Xray сначала пытается разрешить `proxy.com` через встроенный DNS.
+3. Встроенный DNS устанавливает соединение с `dns.com`, чтобы узнать IP-адрес `proxy.com`.
+4. Неудачные правила маршрутизации отправляют запрос из шага 3 через `proxy.com`.
+5. Xray снова пытается подключиться к `proxy.com`.
+6. Перед этим он опять пытается разрешить `proxy.com` через встроенный DNS.
+7. Встроенный DNS переиспользует соединение из шага 3 и отправляет новый запрос.
+8. Возникает тупик: соединение из шага 3 ждет результат запроса из шага 7, а запрос из шага 7 не завершится, пока соединение из шага 3 не установится полностью.
+9. Game over.
+
+Возможные решения:
+
+- Исправить маршрутизацию для встроенного DNS.
+- Использовать hosts.
+- ~~Если вы до сих пор не понимаете решение, не включайте эту функцию.~~
+
+Поэтому неопытным пользователям использовать эту возможность без понимания маршрутизации не рекомендуется.
+:::
+
+> `dialerProxy`: ""
+
+Идентификатор outbound. Если поле не пустое, для установления соединения используется указанный outbound. Это позволяет делать цепочку с учетом транспортных настроек.
+
+::: danger
+Эта настройка несовместима с `ProxySettingsObject.Tag`.
+:::
+
+> `acceptProxyProtocol`: true | false
+
+Только для inbound. Определяет, принимать ли PROXY protocol.
+
+[PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) используется для передачи реального IP-адреса и порта источника. Если вы не знаете, что это такое, просто игнорируйте параметр.
+
+Его умеют отправлять обычные reverse proxy, например HAProxy и Nginx, а также VLESS fallback с `xver`.
+
+Если значение равно `true`, после установления TCP-соединения удаленная сторона обязана сразу отправить PROXY protocol v1 или v2, иначе соединение будет закрыто.
+
+> `tcpKeepAliveIdle`: number
+
+Порог простоя TCP в секундах. После такого времени бездействия начинают отправляться Keep-Alive пакеты.
+
+Для outbound Xray использует такие же значения по умолчанию, как Chrome: и idle, и interval равны 45 секундам. Если установить этот параметр или `tcpKeepAliveInterval` в отрицательное значение, keepalive по умолчанию отключается; положительное значение его переопределяет.
+
+Для inbound Keep-Alive по умолчанию выключен. Он включается, если этот параметр или `tcpKeepAliveInterval` не равны нулю. Если задан только один из них, второй берется из настроек ОС.
+
+> `tcpKeepAliveInterval`: number
+
+Интервал в секундах между Keep-Alive пакетами после перехода TCP в keepalive-состояние. Остальное поведение описано выше.
+
+> `tcpUserTimeout`: number
+
+В миллисекундах. См.: https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md
+
+> `tcpcongestion`: ""
+
+Алгоритм управления перегрузкой TCP. Только Linux.
+Если значение не задано, используется системное значение по умолчанию.
+
+::: tip Часто используемые алгоритмы
+
+- `bbr` (рекомендуется)
+- `cubic`
+- `reno`
+
+:::
+
+::: tip
+Текущее системное значение можно посмотреть командой `sysctl net.ipv4.tcp_congestion_control`.
+:::
+
+> `interface`: ""
+
+Привязывает исходящее соединение к конкретному имени сетевого интерфейса. Поддерживается в Linux, iOS, Mac OS и Windows.
+
+> `V6Only`: true | false
+
+Если значение равно `true`, прослушивание на `::` принимает только IPv6-соединения. Только Linux.
+
+> `tcpWindowClamp`: number
+
+Ограничивает объявляемый размер TCP-окна этим значением. Ядро выбирает максимум между ним и `SOCK_MIN_RCVBUF / 2`.
+
+> `tcpMptcp`: true | false
+
+Значение по умолчанию — `false`. Если установить `true`, включается [Multipath TCP](https://en.wikipedia.org/wiki/Multipath_TCP). Параметр относится только к клиентской стороне, поскольку начиная с Go 1.24 прослушивание уже включает MPTCP по умолчанию. Требуется Linux kernel 5.6 или новее.
+
+> `tcpNoDelay`: true | false
+
+Этот параметр удален, потому что Go и так включает TCP no delay по умолчанию. Если вам нужно отключить его, используйте `customSockopt`.
+
+> `addressPortStrategy`: "none" | "SrvPortOnly" | "SrvAddressOnly" | "SrvPortAndAddress" | "TxtPortOnly" | "TxtAddressOnly" | "TxtPortAndAddress"
+
+Позволяет использовать SRV- или TXT-записи для задания адреса и или порта цели для outbound. По умолчанию используется `none`, то есть функция выключена.
+
+Эти запросы идут через системный DNS, а не через встроенный DNS Xray. В качестве имени для запроса берется домен outbound. Если запрос не удался, используется исходный адрес и порт.
+
+Префикс `Srv` означает стандартный запрос SRV-записи. Префикс `Txt` означает TXT-запись в формате вроде `127.0.0.1:80`.
+
+`PortOnly` заменяет только порт. `AddressOnly` — только адрес. `PortAndAddress` — и адрес, и порт.
+
+Эта настройка применяется раньше `domainStrategy` внутри `sockopt`. После подмены адрес по-прежнему проходит через `domainStrategy`, если он задан. Но применяется она уже после `Freedom.domainStrategy`, поэтому если `Freedom` заранее разрешил домен в IP, этот механизм уже не сработает.
+
+На практике это означает, что если обычный доменный трафик попадает в `Freedom` с `AsIs`, после включения этого параметра ядро начнет пытаться переписать адрес и порт, например через SRV-запись `google.com`.
+
+> `customSockopt`: []
+
+Массив для продвинутых пользователей, которым нужно вручную задать произвольные socket options. Теоретически через него можно воспроизвести все связанные с соединением настройки выше, а также выставить параметры, которые существуют на уровне socket, но не вынесены напрямую в ядре. Сейчас поддерживаются Linux, Windows и Darwin. Пример ниже эквивалентен `"tcpcongestion": "bbr"`.
+
+Используйте этот механизм только если понимаете socket programming.
+
+```json
+"customSockopt": [
+ {
+ "system": "linux",
+ "type": "str",
+ "level": "6",
+ "opt": "13",
+ "value": "bbr"
+ }
+]
+```
+
+> `system`: ""
+
+Необязательный параметр. Ограничивает применение конкретной ОС. Если текущая система не совпадает, эта настройка пропускается. Поддерживаются `linux`, `windows` и `darwin`, все в нижнем регистре. Если поле пустое, настройка применяется напрямую.
+
+> `type`: ""
+
+Обязательный параметр. Тип значения. Сейчас поддерживаются `int` и `str`.
+
+> `level`: ""
+
+Необязательный параметр. Уровень протокола. По умолчанию используется `6`, то есть TCP.
+
+> `opt`: ""
+
+Номер socket option в десятичной форме. В примере выше `13` — это десятичная форма значения `TCP_CONGESTION`, которое в hex записывается как `0xd`.
+
+> `value`: ""
+
+Значение, которое нужно установить. В примере выше это `bbr`.
+
+Если `type` равно `int`, значение должно быть задано десятичным числом.
+
+> `happyEyeballs`: [HappyEyeballsObject](#happyeyeballsobject)
+
+Реализация Happy Eyeballs по RFC 8305, только для TCP. Когда целью является доменное имя, Xray запускает гонку между разрешенными адресами и выбирает первый успешный. Работает только если `Sockopt.domainStrategy` не равен `AsIs`.
+
+Значения `UseIPv4v6` и `ForceIPv4v6` фактически сводят список к IPv4 и только при неудаче обращаются к IPv6. Это не рекомендуется. Лучше использовать `UseIP` или `ForceIP` вместе с `HappyEyeballs.interleave`.
+
+::: warning
+Не используйте это вместе с `domainStrategy` у `Freedom`, потому что тогда `Sockopt` видит уже конечный IP после подмены.
+:::
+
+### HappyEyeballsObject
+
+```json
+"happyEyeballs": {
+ "tryDelayMs": 250,
+ "prioritizeIPv6": false,
+ "interleave": 1,
+ "maxConcurrentTry": 4
+}
+```
+
+> `tryDelayMs`: number
+
+Задержка между попытками гонки в миллисекундах. Значение по умолчанию — `0`, то есть функция выключена. Рекомендуемое значение — `250`.
+
+> `prioritizeIPv6`: bool
+
+Определяет, какой тип адреса будет первым после сортировки. По умолчанию `false`, то есть IPv4 идет первым.
+
+> `interleave`: number
+
+Параметр RFC 8305 `First Address Family Count`. Значение по умолчанию — `1`. Он определяет, как IPv4 и IPv6 адреса чередуются в очереди.
+
+Например, очередь может выглядеть как `46464646`, если значение равно `1`, или как `44664466`, если значение равно `2`, где `6` означает IPv6, а `4` — IPv4.
+
+> `maxConcurrentTry`: number
+
+Максимальное количество параллельных попыток. Это не дает ядру открыть слишком много соединений, если домен разрешился в большой список адресов и все они неудачны. Значение по умолчанию — `4`. Значение `0` отключает Happy Eyeballs.
diff --git a/docs/ru/config/transports/tls.md b/docs/ru/config/transports/tls.md
new file mode 100644
index 00000000..f4c0a8cc
--- /dev/null
+++ b/docs/ru/config/transports/tls.md
@@ -0,0 +1,338 @@
+# TLS
+
+TLS — это обычный механизм защиты транспорта.
+
+Он используется для настройки шифрования транспортного уровня, проверки сертификатов, отпечатков клиента и связанных параметров сертификата.
+
+## TLSObject
+
+`TLSObject` соответствует полю `tlsSettings` в [`StreamSettingsObject`](../transport.md#streamsettingsobject).
+
+```json
+{
+ // пример для outbound, аналогично применимо к inbound
+ "outbounds": [
+ {
+ // ...
+ "streamSettings": {
+ "security": "tls",
+ "tlsSettings": {
+ // [!code focus:18]
+ "serverName": "xray.com",
+ "verifyPeerCertByName": "",
+ "rejectUnknownSni": false,
+ "allowInsecure": false,
+ "alpn": ["h2", "http/1.1"],
+ "minVersion": "1.2",
+ "maxVersion": "1.3",
+ "cipherSuites": "Укажите нужные наборы шифров, разделяя их двоеточием",
+ "certificates": [],
+ "disableSystemRoot": false,
+ "enableSessionResumption": false,
+ "fingerprint": "",
+ "pinnedPeerCertSha256": "",
+ "curvePreferences": [""],
+ "masterKeyLog": "",
+ "echServerKeys": "",
+ "echConfigList": "",
+ "echSockopt": {}
+ }
+ }
+ }
+ ]
+}
+```
+
+> `serverName`: string
+
+Имя сервера. Значение должно присутствовать в SAN серверного сертификата. Это может быть доменное имя или IP-адрес. Если указано доменное имя, оно отправляется в расширении SNI внутри Client Hello. Для IP-адреса SNI не отправляется, потому что SNI не поддерживает IP. Для IPv6 используйте запись в `[]`.
+
+Если поле пустое, Xray автоматически использует значение `address`, если это доменное имя.
+
+Специальное значение `"FromMitM"` заставляет использовать SNI, извлеченный из TLS, расшифрованного входящим `dokodemo-door`.
+
+> `verifyPeerCertByName`: string
+
+Только для клиента. SNI, используемый при проверке сертификата. Можно указать несколько доменов через `,`; достаточно, чтобы хотя бы один SAN сертификата совпал с одним из них. Это поле переопределяет `serverName`, используемый для проверки, и нужно для специальных сценариев вроде domain fronting.
+
+Специальное значение `"FromMitM"` дополнительно добавляет SNI, извлеченный из TLS, расшифрованного входящим `dokodemo-door`.
+
+> `rejectUnknownSni`: bool
+
+Если значение равно `true`, сервер отклоняет TLS-рукопожатие, если полученный SNI не соответствует домену сертификата. Значение по умолчанию — `false`.
+
+> `alpn`: [string]
+
+Массив строк, задающий значения ALPN при TLS-рукопожатии. Значение по умолчанию — `["h2", "http/1.1"]`.
+
+Специальное значение `["FromMitM"]`, когда это единственный элемент массива, заставляет исходящий TLS использовать ALPN из TLS-соединения, расшифрованного входящим `dokodemo-door`.
+
+> `minVersion`: string
+
+`minVersion` — минимально допустимая версия TLS.
+
+> `maxVersion`: string
+
+`maxVersion` — максимально допустимая версия TLS.
+
+> `cipherSuites`: string
+
+`cipherSuites` задает список поддерживаемых наборов шифров, разделенных `:`.
+
+Названия наборов шифров Go и их описание можно посмотреть [здесь](https://golang.org/src/crypto/tls/cipher_suites.go#L500) или [здесь](https://golang.org/src/crypto/tls/cipher_suites.go#L44).
+
+::: danger
+В большинстве случаев эти параметры не нужны и обычно не влияют на безопасность. Если их не задавать, Go выбирает их автоматически в зависимости от платформы. Если вы плохо понимаете, что делаете, лучше не настраивать их вручную.
+:::
+
+> `allowInsecure`: true | false
+
+Разрешать ли небезопасные соединения. Только для клиента. Значение по умолчанию — `false`.
+
+Если значение равно `true`, Xray не проверяет корректность TLS-сертификата удаленной стороны.
+
+::: danger
+~~По соображениям безопасности этот параметр не стоит использовать в реальных сценариях, иначе вы можете стать уязвимы для MITM-атак.~~
+
+Этот параметр устарел. Вместо него используйте `pinnedPeerCertSha256`.
+:::
+
+> `disableSystemRoot`: true | false
+
+Отключать ли встроенные корневые сертификаты операционной системы. Значение по умолчанию — `false`.
+
+Если значение равно `true`, Xray использует при TLS-рукопожатии только сертификаты из `certificates`. Если `false`, используются только системные корневые сертификаты.
+
+> `enableSessionResumption`: true | false
+
+Включать ли возобновление сессии. По умолчанию эта функция выключена и используется только если и сервер, и клиент ее включили.
+
+При успешном согласовании сертификаты не нужно повторно передавать во время рукопожатия. Это дает очень небольшой выигрыш по времени.
+
+Это не TLS 0-RTT. `gotls` пока не поддерживает такую возможность, поэтому RTT TLS-рукопожатия не уменьшается.
+
+> `fingerprint`: string
+
+Этот параметр задает отпечаток `TLS Client Hello`. Значение по умолчанию — `chrome`. Чтобы вернуться к обычному Go TLS, укажите `unsafe`. При включении Xray через библиотеку uTLS **эмулирует** TLS-отпечаток или генерирует его случайно. Поддерживаются три способа настройки:
+
+1. Отпечатки последних версий популярных браузеров:
+
+- `"chrome"`
+- `"firefox"`
+- `"safari"`
+- `"ios"`
+- `"android"`
+- `"edge"`
+- `"360"`
+- `"qq"`
+
+2. Автоматическая генерация отпечатка при запуске Xray:
+
+- `"random"`: случайно выбирается отпечаток одного из новых браузеров
+- `"randomized"`: полностью случайный уникальный отпечаток с полной поддержкой TLS 1.3 и X25519
+
+3. Нативные имена hello-профилей uTLS, например `"HelloRandomizedNoALPN"` или `"HelloChrome_106_Shuffle"`. Полный список см. в [uTLS](https://github.com/refraction-networking/utls/blob/master/u_common.go#L434).
+
+::: tip
+Эта функция только **эмулирует** отпечаток `TLS Client Hello`. Остальное поведение и остальные отпечатки остаются такими же, как у Go. Если вам нужна более полная браузерная модель TLS, используйте [Browser Dialer](./websocket.md#browser-dialer).
+:::
+
+::: tip
+При использовании этой функции некоторые TLS-параметры, влияющие на отпечаток, будут перезаписаны библиотекой uTLS и перестанут действовать, например ALPN.
+Параметры, которые все равно передаются:
+`"serverName" "disableSystemRoot" "pinnedPeerCertSha256" "masterKeyLog"`
+:::
+
+> `pinnedPeerCertSha256`: string
+
+Используется для явного задания SHA-256 хеша сертификата удаленной стороны. Используется hex-формат, регистр неважен, например `e8e2d387fdbffeb38e9c9065cf30a97ee23c0e3d32ee6f78ffae40966befccc9`. Можно перечислить несколько значений через `,`; проверка пройдет, если совпадет любое из них.
+
+Этот формат совпадает с SHA-256 fingerprint в просмотрщике сертификатов Chrome и с форматом сертификатных отпечатков на crt.sh. Вычислить его можно командой `xray tls hash --cert ` или через `openssl x509 -noout -fingerprint -sha256 -in cert.pem`; формат OpenSSL с двоеточиями тоже поддерживается. Команда `xray tls ping` также выводит SHA-256 отпечаток удаленного сертификата.
+
+Эта проверка заменяет обычную валидацию сертификата. Возможны два случая:
+
+- Если ядро находит совпавший хеш у leaf-сертификата, проверка сразу считается успешной.
+- Если совпавший хеш относится к CA-сертификату, корневому или промежуточному, ядро использует значение `serverName`, чтобы убедиться, что leaf-сертификат подписан именно этим CA.
+
+> `certificates`: \[ [CertificateObject](#certificateobject) \]
+
+Список сертификатов. Каждый элемент представляет один сертификат. Рекомендуется использовать полную цепочку.
+
+::: tip
+Если вы хотите получить оценку A или A+ в инструментах вроде ssllibs или myssl, см. [это обсуждение](https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600).
+:::
+
+> `curvePreferences`: [string]
+
+Массив строк, задающий поддерживаемые кривые для ECDHE во время TLS-рукопожатия:
+
+```text
+CurveP256
+CurveP384
+CurveP521
+X25519
+X25519MLKEM768
+SecP256r1MLKEM768*
+SecP384r1MLKEM1024*
+```
+
+\*: uTLS не поддерживает эти кривые
+
+Начиная с Go 1.26 значение по умолчанию включает все перечисленные кривые. Изменение порядка не заставляет клиента или сервер предпочитать конкретную кривую: фактический выбор происходит обычным механизмом согласования ключей.
+
+> `masterKeyLog`: string
+
+Путь к файлу `(Pre)-Master-Secret`, который можно использовать, например, в Wireshark для расшифровки TLS-соединений Xray.
+
+> `echServerKeys`: string
+
+Параметр только для сервера. Используется для включения Encrypted Client Hello на сервере.
+
+Сгенерировать ECH Server Key и соответствующий Config можно командой `xray tls ech --serverName example.com`. `example.com` — это внешний SNI, который будет виден снаружи после шифрования настоящего SNI, и здесь можно использовать любое значение. В Server Key уже содержится ECHConfig. Если клиентский Config потерян, его можно заново получить через `xray tls ech -i "your server key"`. Публиковать его можно в HTTPS-записи DNS; формат см. [здесь](https://dns.google/query?name=encryptedsni.com&rr_type=HTTPS) или в RFC 9460.
+
+Даже после настройки ECH сервер все равно принимает обычные не-ECH соединения.
+
+> `echConfigList`: string
+
+Параметр только для клиента. Задает ECHConfig. Непустое значение означает, что клиент включает Encrypted Client Hello. Поддерживаются два формата.
+
+Первый — фиксированная строка ECHConfig, например:
+
+`"AF7+DQBaAAAgACA51i3Ssu4wUMV4FNCc8iRX5J+YC4Bhigz9sacl2lCfSQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAAtleGFtcGxlLmNvbQAA"`
+
+Второй — запрос через DNS-сервер. Например, при использовании CDN можно получать ECHConfig динамически из HTTPS-записей. Если найден корректный ECH Config, Xray будет уважать TTL, который вернул сервер. Целью запроса становится заданный SNI или домен сервера, если SNI пустой и цель — доменное имя.
+
+Базовый формат — `"udp://1.1.1.1"`, то есть получение ECHConfig через UDP DNS 1.1.1.1. Можно также использовать `"https://1.1.1.1/dns-query"` или `h2c://` для DoH или h2c. Во всех случаях можно явно указать порт, например `udp://1.1.1.1:53`. Если порт не указан, используется стандартный для протокола.
+
+Также можно отдельно указать домен для поиска ECHConfig в форме `"example.com+https://1.1.1.1/dns-query"`. Тогда Xray принудительно использует ECHConfig из DNS-записей `example.com`. Это удобно, если вы хотите получать ECHConfig через DNS, но не хотите явно светить HTTPS-запросы к целевому домену.
+
+> `echSockopt`: [SockoptObject](./sockopt.md#sockoptobject)
+
+Настраивает низкоуровневые параметры сокета для соединения, которое используется при DNS-запросе ECH-записей.
+
+### CertificateObject
+
+```json
+{
+ "ocspStapling": 0,
+ "oneTimeLoading": false,
+ "usage": "encipherment",
+ "buildChain": false,
+ "certificateFile": "/path/to/certificate.crt",
+ "keyFile": "/path/to/key.key",
+ "certificate": [
+ "--BEGIN CERTIFICATE--",
+ "MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",
+ "ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",
+ "DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",
+ "3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",
+ "OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",
+ "pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",
+ "OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",
+ "noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",
+ "A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",
+ "MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",
+ "7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",
+ "9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",
+ "6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",
+ "r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",
+ "d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",
+ "--END CERTIFICATE--"
+ ],
+ "key": [
+ "--BEGIN RSA PRIVATE KEY--",
+ "MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",
+ "bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",
+ "GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",
+ "jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",
+ "itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",
+ "IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",
+ "qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",
+ "C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",
+ "/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",
+ "aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",
+ "/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",
+ "bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",
+ "8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",
+ "pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",
+ "L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",
+ "3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",
+ "az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",
+ "gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",
+ "TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",
+ "eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",
+ "64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",
+ "8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",
+ "GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",
+ "ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",
+ "cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",
+ "--END RSA PRIVATE KEY--"
+ ]
+}
+```
+
+По умолчанию серверные сертификаты перезагружаются каждые 3600 секунд, то есть раз в час.
+
+> `ocspStapling`: number
+
+Интервал обновления OCSP stapling в секундах. Значение по умолчанию — `0`. Любое ненулевое значение включает OCSP stapling и одновременно заменяет стандартный 3600-секундный интервал горячей перезагрузки сертификата.
+
+> `oneTimeLoading`: true | false
+
+Загрузка только один раз. Значение по умолчанию — `false`. Если установить `true`, отключаются и горячая перезагрузка сертификата, и OCSP stapling.
+
+> `usage`: "encipherment" | "verify" | "issue"
+
+Назначение сертификата. Значение по умолчанию — `"encipherment"`.
+
+- `"encipherment"`: сертификат используется для TLS-аутентификации и шифрования
+- `"verify"`: сертификат используется для проверки удаленных TLS-сертификатов; в этом случае он должен быть CA-сертификатом
+- `"issue"`: сертификат используется для выпуска других сертификатов; в этом случае он тоже должен быть CA-сертификатом
+
+::: tip TIP 1
+В Windows самоподписанный CA-сертификат можно установить в системное хранилище и использовать для проверки удаленных TLS-сертификатов.
+:::
+
+::: tip TIP 2
+Когда приходит новый запрос клиента и, например, указан `serverName` равный `"xray.com"`, Xray сначала ищет в списке сертификат, подходящий для `"xray.com"`. Если такого нет, используется любой сертификат с `usage: "issue"` для выпуска нового сертификата на `"xray.com"` сроком на один час, после чего этот сертификат добавляется в список для дальнейшего использования.
+:::
+
+::: tip TIP 3
+Если одновременно заданы `certificateFile` и `certificate`, Xray предпочитает `certificateFile`. То же самое относится к `keyFile` и `key`.
+:::
+
+::: tip TIP 4
+Если `usage` равно `"verify"`, поля `keyFile` и `key` могут быть пустыми.
+:::
+
+::: tip TIP 5
+Самоподписанный CA-сертификат можно сгенерировать командой `xray tls cert`.
+:::
+
+::: tip TIP 6
+Если у вас уже есть домен, бесплатный сторонний сертификат удобно получать через инструменты вроде [acme.sh](https://github.com/acmesh-official/acme.sh).
+:::
+
+> `buildChain`: true | false
+
+Действует только если назначение сертификата — `issue`. Если установить `true`, CA-сертификат будет встроен в выпускаемую цепочку сертификатов.
+
+::: tip TIP 1
+Корневой сертификат не стоит встраивать в цепочку. Этот параметр уместен только если подписывающий CA является промежуточным сертификатом.
+:::
+
+> `certificateFile`: string
+
+Путь к файлу сертификата, например к `.crt`, сгенерированному через OpenSSL.
+
+> `certificate`: [string]
+
+Массив строк с содержимым сертификата в формате, показанном выше. Используйте либо `certificate`, либо `certificateFile`.
+
+> `keyFile`: string
+
+Путь к файлу приватного ключа, например к `.key`, сгенерированному через OpenSSL. Ключи, защищенные паролем, сейчас не поддерживаются.
+
+> `key`: [string]
+
+Массив строк с содержимым приватного ключа в том же формате, что и в примере выше. Используйте либо `key`, либо `keyFile`.