FinalMask
FinalMask добавляет последний слой маскировки после того, как ядро уже обработало шифрование транспортного уровня, включая TLS и REALITY.
Его можно использовать для разных видов маскировки TCP- и UDP-трафика, а также для настройки параметров QUIC.
FinalMaskObject
FinalMaskObject соответствует полю finalmask в StreamSettingsObject.
{
// пример для outbound, аналогично применимо к inbound
"outbounds": [
{
// ...
"streamSettings": {
"finalmask": {
"tcp": [
{
"type": "",
"settings": {}
}
],
"udp": [
{
"type": "",
"settings": {}
}
],
"quicParams": {}
}
}
}
]
}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
TCPMask
Массив для маскировки TCP-трафика, исходящего из ядра. Первый элемент массива является самым внутренним слоем маскировки.
{
"finalmask": {
"tcp": [
{
"type": "",
"settings": {}
}
]
}
}2
3
4
5
6
7
8
9
10
11
type: string
Тип этого слоя маскировки.
settings: object
Конкретные настройки для этого типа маскировки.
Поля каждого типа приведены ниже.
header-custom
{
"type": "header-custom",
"settings": {
"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
36
37
38
39
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
{
"type": "fragment",
"settings": {
"packets": "tlshello",
"lengths": ["3-5", "6-8", "10-20"],
"delays": ["10-20"],
"maxSplit": "3-6"
}
}2
3
4
5
6
7
8
9
10
Управляет исходящей TCP-фрагментацией. В некоторых случаях это может обмануть системы цензуры, например помочь обойти SNI-блоклисты.
"length", "delay" и "maxSplit" имеют тип Int32Range.
"packets": поддерживаются два режима фрагментации. "1-3" разрезает TCP-поток и применяется к 1-й, 2-й и 3-й операциям записи клиента. "tlshello" фрагментирует пакет TLS-рукопожатия.
"lengths": длина фрагмента в байтах.
n-й элемент массива задаёт ожидаемую длину n-го фрагмента, отрезаемого от текущего обрабатываемого пакета; последний элемент продолжает применяться ко всем последующим фрагментам, отрезаемым от этого пакета. Все элементы, кроме последнего, могут быть 0 (иначе это приведёт к бесконечному холостому циклу); для нарезки TCP-потока это выражается в том, что данные не отправляются, а для tlshello — в отправке нарушающей RFC пустой TLS-записи (допускается некоторыми реализациями, но не Golang).
"delays": интервал между фрагментами в миллисекундах.
n-й элемент массива задаёт, сколько ждать после отправки n-го фрагмента, отрезаемого от текущего обрабатываемого пакета; последний элемент продолжает применяться ко всем последующим фрагментам, отрезаемым от этого пакета.
Если значение равно 0 и задано "packets": "tlshello", фрагментированный Client Hello будет отправлен в одном TCP-пакете, если его исходный размер не превышает MSS или MTU и система не фрагментирует его автоматически.
"maxSplit": максимальное количество фрагментов. Ограничивает, на сколько частей можно разделить один пакет. 0 означает без ограничений.
sudoku
{
"type": "sudoku",
"settings": {
"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
11
12
13
14
Значение этих полей см. в upstream-документации.
filter
{
"type": "filter",
"settings": {
"allowedSourceIPs": ["geoip:cn", "10.0.0.0/8", "fd00::/8"],
"blockedSourceIPs": ["10.20.0.0/16", "fd00:20::/48"]
}
}2
3
4
5
6
7
8
Фильтр трафика для контроля доступа. Пока поддерживается только фильтрация по IP-адресу источника во входящих подключениях (inbound) (не действует для outbound). Фильтрация выполняется после успешного завершения трёхстороннего рукопожатия TCP.
Если нет особых причин для другого порядка, размещайте filter во внешнем слое, то есть последним элементом массива.
allowedSourceIPs: белый список IP-адресов источника. Если он непустой, IP-адрес источника должен быть доступен и соответствовать хотя бы одной записи для пропуска трафика.
blockedSourceIPs: чёрный список IP-адресов источника. Трафик с IP-адресов, соответствующих любой из его записей, отклоняется.
Оба поля поддерживают записи GeoIP (например, geoip:cn) и диапазоны CIDR для IPv4 и IPv6; использование аналогично сопоставлению IP-адресов в правилах маршрутизации.
Если настроены оба списка, IP-адрес источника допускается только при совпадении с белым списком и отсутствии совпадения с чёрным.
UDPMask
Массив для маскировки UDP-трафика, исходящего из ядра. Первый элемент массива является самым внутренним слоем маскировки.
{
"finalmask": {
"udp": [
{
"type": "",
"settings": {}
}
]
}
}2
3
4
5
6
7
8
9
10
11
type: string
Тип этого слоя маскировки.
settings: object
Конкретные настройки для этого типа маскировки.
Поля каждого типа приведены ниже.
header-custom
Всегда объединяется с заголовком пакета.
{
"type": "header-custom",
"settings": {
"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
19
20
21
22
client[n].rand: добавляет указанное количество случайных байтов. Несовместимо с packet.
client[n].randRange: диапазон значений случайных байтов. По умолчанию 0-255.
client[n].type: тип packet. Поддерживаются array, str, hex и base64. Значение по умолчанию - array.
client[n].packet: добавляет фиксированные данные. Несовместимо с rand.
mkcp-legacy
{
"type": "mkcp-legacy",
"settings": {
"header": "", // dns dtls srtp utp wechat wireguard
"value": "" // password domain
}
}2
3
4
5
6
7
8
Маскировка/обфускация заголовка пакетов в стиле старого mKCP. Значение value зависит от header. Обратите внимание: подделка - это лишь простая подделка заголовка пакета и не означает реализацию полного протокола.
Когда пусто: применяется шифрование AES-128-GCM, где
value- пароль. Еслиvalueпусто, вместо этого используется простая XOR-обфускация по умолчанию.
dns: подделка под DNS-запрос.value- указанный домен; при пустом значении по умолчаниюwww.baidu.com.
dtls: подделка под данные приложения DTLS 1.2.valueне используется.
srtp: подделка под SRTP.valueне используется.
utp: подделка под uTP (BitTorrent).valueне используется.
valueне используется.
wireguard: подделка под WireGuard.valueне используется.
noise
Шум, отправляемый перед реальными данными.
{
"type": "noise",
"settings": {
"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
13
14
15
16
reset: значение типа Int32Range в секундах. После отправки шума состояние сбрасывается через указанное время, и шум можно снова отправить на тот же адрес. 0 означает не сбрасывать, то есть отправить только один раз.
rand: добавляет случайные байты или случайные байты заданной длины. Несовместимо с packet.
randRange: диапазон значений случайных байтов. По умолчанию 0-255.
type: тип packet. Поддерживаются array, str, hex, base64 и exp. Значение по умолчанию - array.
packet: добавляет фиксированные данные. Несовместимо с rand.
При "type": "exp" packet - это строка-выражение, из которой собирается один пакет шума. Он генерируется заново при каждой отправке, поэтому может содержать меняющиеся данные, например метку времени. Части выражения склеиваются по порядку в один пакет:
<b hex>: фиксированные байты в шестнадцатеричном виде, необязательный префикс0xигнорируется<r N>или<r A-B>:Nслучайных байтов или случайное количество отAдоB<rc N>или<rc A-B>: то же, случайные буквы (a-zA-Z)<rd N>или<rd A-B>: то же, случайные цифры (0-9)<t>: текущее Unix-время в секундах, 4 байта big-endian<c>: счётчик, 4 байта big-endian, каждый раз увеличивается на единицу<n>: 8 случайных байтов
Например, {"type": "exp", "packet": "<b 0d0a0d0a><t><r 24>"} отправляет \r\n\r\n, метку времени и 24 случайных байта одним пакетом.
delay: задержка в миллисекундах. После отправки одного элемента шума Xray ждёт указанное время перед отправкой следующего.
salamander
Обфускация Salamander. Используется в Hysteria2.
{
"type": "salamander",
"settings": {
"password": "your-password",
"packetSize": "512-1200"
}
}2
3
4
5
6
7
8
password: пароль обфускации.
gecko
packetSize: Int32Range
Если не пусто, включает обфускацию Gecko: к QUIC-пакетам с длинным заголовком применяется дополнительная обфускация с фрагментацией и заполнением (пакеты с коротким заголовком используют Salamander напрямую). packetSize задаёт размер фрагмента, а его верхняя граница не должна превышать 2048.
sudoku
{
"type": "sudoku",
"settings": {
"password": "",
"ascii": "",
"customTable": "",
"customTables": [""],
"paddingMin": 0,
"paddingMax": 0
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
Значения те же, что и в 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, указывающую на a.example.com, и используйте t.example.com. Хост, используемый в A-записи, не должен быть поддоменом хоста, используемого в NS-записи.
{
"type": "xdns",
"settings": {
"domains": [
{
"names": ["t.example.com"],
"lenLimit": 255, // 0-255; default: 255
"labelLimit": 63, // 0-63; default: 63
"types": [1, 5, 16, 28], // 1:A 5:CNAME 16:TXT 28:AAAA; client default: 16, server default: all
"edns0": 1232 // 0,512-4096; default: 0
}
],
"resolvers": [
{
"addrs": ["udp://127.0.0.1:53"] // [protocol://]host[:port], no defaults
}
]
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Совместимо только с kcp; рекомендуется значение TTI, равное 200. Настройка MTU требуется только на стороне сервера (см. раздел настроек MTU). Расчет CNAME относительно сложен; как правило, полученные значения находятся в диапазоне между значениями для записей AAAA и TXT:
- При edns0 = 512: A 39, TXT 215, AAAA 117
- При edns0 = 1232: A 174, TXT 932, AAAA 492
xicmp
{
"type": "xicmp",
"settings": {
"dgram": false, // optional
"ips": [] // optional
}
}2
3
4
5
6
7
8
dgram: Более низкие права доступа, только на стороне клиента (Linux, Mac, iOS)
ips: В настоящее время CIDR не поддерживается
realm
Самодельный https://github.com/apernet/hysteria-realm-server
{
"type": "realm",
"settings": {
"url": "realm://public@xxx/your-realm-name",
"stunServers": [
"stun.nextcloud.com:3478",
"global.stun.twilio.com:3478"
],
"tlsConfig": {}, // optional
"ipMode": "dual",
"portMapping": {
"enabled": false,
"timeout": 10,
"lifetime": 600
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
url: realm[+http]://token@host[:port]/id
stunServers: Для предсказания портов NAT используется несколько адресов IPv4/IPv6
tlsConfig: То же, что tlsSettings
ipMode: Управляйте разрешением доменных имен STUN и фильтрацией одноранговых узлов (peer) в пределах области (realm)
portMapping.enabled: Включите фиксированное сопоставление портов для улучшения доступности входящих соединений
portMapping.timeout: секунды
portMapping.lifetime: секунды
Для регистрации сбоев соединения требуется уровень отладки. К возможным факторам, способствующим возникновению проблем, относятся поставщик STUN, поставщик Realm
udphop
{
"type": "udphop",
"settings": {
"mode": "intervallocal,intervalremote", // intervallocal intervalremote perconnremote
"interval": "5-10",
"remoteIPs": [""],
"remotePorts": "20000-50000,443"
}
}2
3
4
5
6
7
8
9
10
intervallocal: Поддерживает только WireGuard, Hysteria и xhttp-h3
intervalremote: Требует использования в связке с iptables или nftables
perconnremote: Требует использования в связке с iptables или nftables
mode: Список, разделенный запятыми; обычно intervallocal,intervalremote, либо только intervallocal, либо только perconnremote
interval: секунды
remoteIPs: Обязателен только в том случае, если mode включает intervalremote или perconnremote; если поле не заполнено, адрес наследуется с вышестоящего уровня. Поддерживается нотация CIDR.
remotePorts: Обязателен только в том случае, если mode включает intervalremote или perconnremote; если поле не заполнено, адрес наследуется с вышестоящего уровня
filter
Фильтр трафика для контроля доступа. Пока поддерживается только фильтрация по IP-адресу источника во входящих подключениях (inbound) (не действует для outbound). UDP-пакеты фильтруются по отдельности. Остальные настройки и поведение такие же, как у TCP-версии.
Если нет особых причин для другого порядка, размещайте filter во внешнем слое, то есть последним элементом массива.
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 и MASQUE H3.
congestion: reno | bbr | brutal | force-brutal
Алгоритм управления перегрузкой. В Hysteria по умолчанию используется brutal, а в XHTTP H3 и MASQUE - bbr; в MASQUE brutal тоже работает как 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.