mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-10-03 04:18:21 +03:00
RU Refactor Transports
This commit is contained in:
@@ -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/" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ Winter cannot cover the NEXT FUTURE...
|
||||
|
||||
## 2022.8.28 <Badge>[v1.5.10](https://github.com/XTLS/Xray-core/releases/tag/v1.5.10)</Badge>
|
||||
|
||||
Нижний транспорт поддерживает более разумную конфигурацию TCP Keepalive.
|
||||
`sockopt` теперь поддерживает более разумную конфигурацию TCP Keepalive.
|
||||
|
||||
## 2022.6.20 <Badge>[v1.5.8](https://github.com/XTLS/Xray-core/releases/tag/v1.5.8)</Badge>
|
||||
|
||||
|
||||
@@ -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 во время рукопожатия. Это разные вещи.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
Если значение равно `true`, dokodemo-door будет распознавать данные, перенаправленные iptables, и пересылать их на соответствующий целевой адрес.
|
||||
|
||||
См. настройку `tproxy` в разделе [Конфигурация транспорта](../transport.md#sockoptobject).
|
||||
См. настройку `tproxy` в разделе [Sockopt](../transports/sockopt.md#sockoptobject).
|
||||
|
||||
> `userLevel`: number
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ VLESS - это легкий транспортный протокол без с
|
||||
|
||||
XTLS доступен только в следующих комбинациях
|
||||
|
||||
- TCP+TLS/Reality В этом случае зашифрованные данные копируются напрямую на низком уровне (если передается TLS 1.3).
|
||||
- TCP+TLS/REALITY В этом случае зашифрованные данные копируются напрямую на низком уровне (если передается TLS 1.3).
|
||||
- VLESS Encryption Нет ограничений на транспорт нижнего уровня; если транспорт не поддерживает прямое копирование (см. выше), то выполняется только проброс Encryption.
|
||||
|
||||
> `reverse`: struct
|
||||
|
||||
@@ -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 не будут иметь эффекта.<br>
|
||||
Если вам требуется перенаправление с поддержкой транспортного уровня, используйте `SockOpt.dialerProxy` или установите `transportLayer` в `true`.
|
||||
По умолчанию этот способ пересылки **игнорирует** собственную конфигурацию транспорта этого outbound (например XHTTP, REALITY или Sockopt), поэтому `streamSettings` у данного outbound не будут работать.<br>
|
||||
Если вам нужна пересылка с поддержкой `streamSettings`, используйте `Sockopt.dialerProxy` или установите здесь `transportLayer` в `true`.
|
||||
:::
|
||||
|
||||
> `transportLayer`: true | false
|
||||
|
||||
`true` преобразует эту настройку в `SockOpt.dialerProxy` для поддержки перенаправления на транспортном уровне. По умолчанию `false` (преобразование не выполняется).
|
||||
`true` преобразует эту настройку в `Sockopt.dialerProxy`, чтобы пересылка использовала `streamSettings` этого outbound. По умолчанию `false`.
|
||||
|
||||
### MuxObject
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ Freedom — это исходящий протокол, который можн
|
||||
|
||||
Значение по умолчанию — `"AsIs"`.
|
||||
|
||||
Все параметры по смыслу аналогичны `domainStrategy` в [sockopt](../transport.md#sockoptobject).
|
||||
Все параметры по смыслу аналогичны `domainStrategy` в [Sockopt](../transports/sockopt.md#sockoptobject).
|
||||
|
||||
Только использование `AsIs` в этом разделе позволяет передать доменное имя в последующий модуль `sockopt`. Если установить значение, отличное от `AsIs`, домен будет разрешен в конкретный IP, что сделает последующие настройки `sockopt.domainStrategy` и связанный с ними механизм `happyEyeballs` недействительными. (Если вы не изменяли эти настройки, негативного влияния не будет).
|
||||
|
||||
|
||||
@@ -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`, и его использование с другими транспортными уровнями не рекомендуется.
|
||||
|
||||
@@ -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
|
||||
|
||||
+53
-1253
File diff suppressed because it is too large
Load Diff
@@ -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`.
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -37,7 +37,7 @@ mKCP жертвует пропускной способностью ради у
|
||||
```
|
||||
|
||||
::: tip
|
||||
Поля `header` и `seed` были удалены, пожалуйста, используйте [FinalMask](../transport.md#finalmaskobject) для настройки.
|
||||
Поля `header` и `seed` были удалены, пожалуйста, используйте [FinalMask](./finalmask.md#finalmaskobject) для настройки.
|
||||
|
||||
Также была удалена стандартная обфускация mKCP; для подключения к старым версиям серверов необходимо настроить `mkcp-original` в FinalMask.
|
||||
:::
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
# REALITY
|
||||
|
||||
REALITY — это модификация TLS, которая использует внешний вид и характеристики рукопожатия целевого сайта как маскировку.
|
||||
|
||||
:::: tip
|
||||
REALITY сейчас является одной из самых сильных схем защиты транспорта, а снаружи такой трафик выглядит как обычный веб-трафик.<br>
|
||||
Включение 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
|
||||
|
||||
Начальный путь и параметры краулера. Рекомендуется использовать разные значения для разных клиентов.
|
||||
@@ -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"<br>
|
||||
> "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"<br>
|
||||
> "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.
|
||||
@@ -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 <cert.pem>` или через `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`.
|
||||
Reference in New Issue
Block a user