FinalMask
FinalMask добавляет последний слой маскировки после того, как ядро уже обработало шифрование транспортного уровня, включая TLS и REALITY.
Его можно использовать для разных видов маскировки TCP- и UDP-трафика, а также для настройки параметров QUIC.
FinalMaskObject
FinalMaskObject соответствует полю finalmask в StreamSettingsObject.
{
// пример для outbound, аналогично применимо к inbound
"outbounds": [
{
// ...
"streamSettings": {
"finalmask": {
"tcp": [
{
"type": "",
"settings": {}
}
],
"udp": [
{
"type": "",
"settings": {}
}
],
"quicParams": {
"congestion": "force-brutal",
"bbrProfile": "standard",
"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
}
}
}
}
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
TCPMask
Массив для маскировки TCP-трафика, исходящего из ядра. Первый элемент массива является самым внешним слоем маскировки.
{
"finalmask": {
"tcp": [
{
"type": "",
"settings": {}
}
]
}
}2
3
4
5
6
7
8
9
10
11
type: header-custom | fragment | sudoku
Тип этого слоя маскировки.
settings: header-custom | fragment | sudoku
Конкретные настройки для этого типа маскировки. Поля каждого типа приведены ниже.
header-custom
{
"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": []
}
]
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
{
"packets": "tlshello",
"length": "100-200",
"delay": "10-20",
"maxSplit": "3-6"
}2
3
4
5
6
Управляет исходящей TCP-фрагментацией. В некоторых случаях это может обмануть системы цензуры, например помочь обойти SNI-блоклисты.
"length", "delay" и "maxSplit" имеют тип Int32Range.
"packets": поддерживаются два режима фрагментации. "1-3" разрезает TCP-поток и применяется к 1-й, 2-й и 3-й операциям записи клиента. "tlshello" фрагментирует пакет TLS-рукопожатия.
"length": длина фрагмента в байтах. Не может быть 0.
"delay": интервал между фрагментами в миллисекундах.
Если значение равно 0 и задано "packets": "tlshello", фрагментированный Client Hello будет отправлен в одном TCP-пакете, если его исходный размер не превышает MSS или MTU и система не фрагментирует его автоматически.
"maxSplit": максимальное количество фрагментов. Ограничивает, на сколько частей можно разделить один пакет. 0 означает без ограничений.
sudoku
{
"password": "",
"ascii": "",
"customTable": "", // в upstream-документации поле называется custom_table
"customTables": [""], // в upstream-документации поле называется custom_tables
"paddingMin": 0, // в upstream-документации поле называется padding_min
"paddingMax": 0 // в upstream-документации поле называется padding_max
}2
3
4
5
6
7
8
9
10
Значение этих полей см. в upstream-документации.
UDPMask
Массив для маскировки UDP-трафика, исходящего из ядра. Первый элемент массива является самым внешним слоем маскировки.
{
"finalmask": {
"udp": [
{
"type": "",
"settings": {}
}
]
}
}2
3
4
5
6
7
8
9
10
11
type: header-custom | header-dns | header-dtls | header-srtp | header-utp | header-wechat | header-wireguard | mkcp-original | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp
Тип этого слоя маскировки.
settings: header-custom | header-dns | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp
Конкретные настройки для этого типа маскировки. Поля каждого типа приведены ниже.
header-custom
Всегда объединяется с заголовком пакета.
{
"client": [
{
"rand": 0,
"randRange": "0-255",
"type": "",
"packet": []
}
],
"server": [
{
"rand": 0,
"randRange": "0-255",
"type": "",
"packet": []
}
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
client[n].rand: добавляет указанное количество случайных байтов. Несовместимо с packet.
client[n].randRange: диапазон значений случайных байтов. По умолчанию 0-255.
client[n].type: тип packet. Поддерживаются array, str, hex и base64. Значение по умолчанию - array.
client[n].packet: добавляет фиксированные данные. Несовместимо с rand.
header-dns
Старая DNS-маскировка из mKCP. В некоторых кампусных сетях DNS-запросы разрешены до авторизации, поэтому этот режим добавляет DNS-заголовок к KCP.
{
"domain": "www.example.com"
}2
3
header-dtls
Старая DTLS-маскировка из mKCP. Маскирует пакеты под DTLS 1.2. Дополнительных настроек нет.
header-srtp
Старая SRTP-маскировка из mKCP. Маскирует пакеты под SRTP и может определяться как трафик видеозвонков, например FaceTime. Дополнительных настроек нет.
header-utp
Старая uTP-маскировка из mKCP. Маскирует пакеты под uTP и может определяться как трафик загрузки BitTorrent. Дополнительных настроек нет.
header-wechat
Старая маскировка WeChat Video из mKCP. Маскирует пакеты под трафик видеозвонков WeChat. Дополнительных настроек нет.
header-wireguard
Старая маскировка WireGuard из mKCP. Маскирует пакеты под трафик WireGuard, хотя это не настоящий протокол WireGuard. Дополнительных настроек нет.
mkcp-original
Простая обфускация, которая раньше применялась в mKCP по умолчанию. Она может понадобиться для подключения к старым серверам mKCP. Дополнительных настроек нет.
mkcp-aes128gcm
Соответствует старой функции seed в mKCP. Использует AES-128-GCM для обфускации.
{
"password": "your-password"
}2
3
noise
Шум, отправляемый перед реальными данными.
{
"reset": "30-60",
"noise": [
{
"rand": "1-8192",
"randRange": "0-255",
"type": "",
"packet": [],
"delay": "10-20"
}
]
}2
3
4
5
6
7
8
9
10
11
12
reset: значение типа Int32Range в секундах. После отправки шума состояние сбрасывается через указанное время, и шум можно снова отправить на тот же адрес. 0 означает не сбрасывать, то есть отправить только один раз.
rand: добавляет случайные байты или случайные байты заданной длины. Несовместимо с packet.
randRange: диапазон значений случайных байтов. По умолчанию 0-255.
type: тип packet. Поддерживаются array, str, hex и base64. Значение по умолчанию - array.
packet: добавляет фиксированные данные. Несовместимо с rand.
delay: задержка в миллисекундах. После отправки одного элемента шума Xray ждёт указанное время перед отправкой следующего.
salamander
Обфускация Salamander. Используется в Hysteria2.
{
"password": "your-password"
}2
3
sudoku
{
"password": "",
"ascii": "",
"customTable": "",
"customTables": [""],
"paddingMin": 0,
"paddingMax": 0
}2
3
4
5
6
7
8
9
10
Значения те же, что и в TCP-версии.
xdns
Использует DNS-запросы для передачи данных, подобно DNSTT. Для переноса полезной нагрузки выполняются стандартные DNS-запросы; поддерживаются типы TXT, A и AAAA.
Из-за технических ограничений эффективный MTU очень мал, QUIC использовать нельзя, поэтому рекомендуется сочетать этот режим с mKCP. Рекомендуемые значения MTU: на клиенте 130; на сервере 900 для TXT, который почти передаёт исходные байты, для AAAA разумно уменьшить значение примерно до половины или ниже, а для A - примерно до одной восьмой или ниже. Теоретическая эффективность кодирования различается, а реальные значения зависят от того, сколько AAAA- или A-записей промежуточные форвардеры готовы терпеть в ответах.
Поскольку выполняются стандартные запросы, они могут пересылаться через любой UDP DNS-сервер, хотя эффективность может быть очень низкой.
Чтобы использовать эту функцию, сервер должен слушать порт 53, затем прокси-протокол должен указывать на DNS-сервер, например 8.8.8.8:53, и у вас должен быть домен из domains, после чего его NS-запись нужно направить на сервер.
Например, если у вас есть example.com, задайте A-запись a.example.com, указывающую на IP сервера, затем задайте NS-запись t.example.com, указывающую на t.example.com, и используйте t.example.com. Хост, используемый в A-записи, не должен быть поддоменом хоста, используемого в NS-записи.
{
"domains": ["t.example.com"],
"resolvers": ["t.example.com+udp://8.8.8.8:53"]
}2
3
4
domains: используется на стороне сервера. Список доменов. Поддерживает указание типа запроса в формате domain:method, где method может быть txt, a или aaaa. Если method не указан, тип запроса не ограничивается.
resolvers: используется на стороне клиента. Список DNS-резолверов. Формат: domain[:method]+udp://server:port, где method может быть txt по умолчанию, a или aaaa.
Хотя бы одно из domains и resolvers должно быть заполнено.
xicmp
Требует как минимум права CAP_NET_RAW и должен быть самым внешним слоем, то есть первым элементом массива. Его нельзя использовать вместе с udpHop и dialerProxy.
{
"listenIp": "0.0.0.0",
"id": 0
}2
3
4
listenIp: IP-адрес для прослушивания. По умолчанию "0.0.0.0".
Обратите внимание, что это отличается от обычных адресов прослушивания TCP/UDP "0.0.0.0" и "::". Поскольку ICMP по IPv4 и ICMPv6 по IPv6 несовместимы, указание "0.0.0.0" здесь означает прослушивание только IPv4 ICMP, и наоборот.
id: если один IP используется несколькими клиентами, серверу рекомендуется оставлять это значение равным 0.
quicParams
{
"finalmask": {
"quicParams": {
"congestion": "force-brutal",
"bbrProfile": "standard",
"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
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Используется для настройки параметров QUIC в XHTTP H3 и Hysteria.
congestion: reno | bbr | brutal | force-brutal
Алгоритм управления перегрузкой. В Hysteria по умолчанию используется brutal, а в XHTTP H3 - bbr.
reno и bbr - известные алгоритмы.
brutal: согласует с другой стороной фиксированную скорость отправки пакетов или откатывается к BBR.
force-brutal: то же, что и brutal, но принудительно использует для исходящего трафика фиксированную скорость отправки из brutalUp, игнорируя согласование с другой стороной.
Обратите внимание: XHTTP H3 не может использовать режим brutal, потому что у него нет механизма согласования, но поддерживает force-brutal, которому согласование не требуется.
bbrProfile: conservative | standard | aggressive
Когда для QUIC выбран алгоритм BBR, этот параметр управляет BBR-профилем. Значение по умолчанию - standard. conservative немного осторожнее, aggressive немного агрессивнее.
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 и он всё равно ограничивается значением на стороне сервера.
Помните, что направления относительны: исходящая скорость сервера соответствует входящей скорости клиента, а входящая скорость сервера - исходящей скорости клиента.
udpHop: {"ports": string, "interval": number}
Настройка прыжков по UDP-портам.
ports задаёт диапазон портов. Это может быть строка с одним числом, например "1234", или диапазон, например "1145-1919" для портов с 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 не делает этого автоматически. Если ваша ОС не входит в linux, windows или darwin, возможно, вам придётся отключить его вручную.
maxIncomingStreams: number
Параметр стороны сервера. Если задан, он не должен быть меньше 8.