Skip to content

Маршрутизация — Xray-core

Блок routing — это движок, решающий, какое исходящее подключение использует соединение. Он содержит список правил (сопоставляются по порядку, побеждает первое), глобальную domainStrategy и именованные балансировщики balancers, которые можно указывать как цель правила.

Параметры верхнего уровня

ПолеТипПо умолчаниюДопустимые значенияОписание
rules[]json.RawMessage[]<rule object array>Правила маршрутизации, вычисляемые в порядке объявления. Побеждает первое совпавшее правило.
domainStrategy*stringAsIsAsIs | IpIfNonMatch | IpOnDemandКак домены назначения разрешаются для сопоставления правил. `AsIs` оставляет домены строками (совпадают только доменные правила); `IpIfNonMatch` разрешает в IP, когда не совпало ни одно доменное правило; `IpOnDemand` разрешает заранее, как только есть IP-правила.
balancers[]*BalancingRule[][BalancingRule]Именованные балансировщики нагрузки, используемые как `balancerTag` в целях правил.

Исходный код: infra/conf/router.go:71-75 · зафиксировано на v26.7.28 (5ca6f4b)

rules[] — объект правила

Каждое правило — JSON-объект, у которого ключи сопоставления выбирают множество соединений, а ключи цели решают, куда они пойдут. Форма полиморфна: парсер смотрит, какие ключи сопоставления присутствуют.

Ключи сопоставления (все необязательны, объединяются по И):

ПолеТипОписание
typestringДолжно быть "field" (устаревший "chain" и другие типы существовали в V2Ray; сейчас поддерживается только field).
domain / domains[]stringСопоставление по домену назначения. Принимает шаблоны: full:example.com, domain:example.com, regexp:.+\\.com$, keyword:google, geosite:cn.
ip[]stringСопоставление по IP назначения. Принимает обычный IP, CIDR, geoip:cn.
source[]stringСопоставление по IP источника (тот же синтаксис, что и ip).
portstringСопоставление по порту назначения. 80, 80-90, 80,443,8080-8090.
sourcePortstringСопоставление по порту источника (тот же синтаксис).
networkstringСопоставление по транспорту. tcp, udp, tcp,udp.
user[]stringСопоставление по email-метке пользователя входящего подключения.
inboundTag[]stringСопоставление по тегу входящего подключения.
protocol[]stringСопоставление по определённому сниффингом прикладному протоколу. http, tls, bittorrent, quic. Сниффинг должен быть включён на входящем подключении.
attrsmap[string]stringСопоставление по атрибутам сниффинга (например, Host).
domainMatcherstringРеализация сопоставителя доменов. hybrid (по умолчанию, быстрый) или linear.

Ключи цели (нужен ровно один):

ПолеОписание
outboundTagОтправить совпавший трафик в это исходящее подключение.
balancerTagОтправить совпавший трафик в балансировщик (который выберет исходящее подключение из своего пула).

Плюс поле метаданных:

ПолеОписание
ruleTagЧеловекочитаемое имя правила. Отображается в API и журналах.

balancers[]

ПолеТипПо умолчаниюДопустимые значенияОписание
tagstring(required)<string>Имя балансировщика. Используется полем `balancerTag` правил маршрутизации.
selectorStringList(required)[<outbound-tag prefix>]Префиксы тегов исходящих подключений. Любое исходящее подключение, чей тег начинается с одного из них, включается в пул балансировщика.
strategyStrategyConfig{type: "random"}{type: "random|leastLoad|leastPing|roundRobin", settings?: {...}}Стратегия выбора. `random` берёт любого участника пула; `roundRobin` перебирает по кругу; `leastPing` выбирает участника с наименьшей наблюдаемой задержкой (требует [`observatory`](/ru/xray/observatory)); `leastLoad` выбирает наименее нагруженного.
fallbackTagstring(unset)<outbound tag>Исходящее подключение, используемое когда пул балансировщика пуст или все его участники недоступны.

Исходный код: infra/conf/router.go:21-26 · зафиксировано на v26.7.28 (5ca6f4b)

Варианты стратегий

  • random — равномерный случайный выбор.
  • roundRobin — перебор пула по кругу.
  • leastPing — выбор участника с наименьшей задержкой. Требует включённого observatory или burstObservatory, чтобы у каждого исходящего подключения была известная задержка.
  • leastLoad — выбор наименее нагруженного участника. Несёт strategyLeastLoadConfig (см. infra/conf/router_strategy.go) с полями настройки проверок доступности.

Примеры

Прямое направление внутрикитайского трафика (канонический паттерн для Китая):

json
{
  "routing": {
    "domainStrategy": "IpIfNonMatch",
    "rules": [
      { "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" },
      { "type": "field", "domain": ["geosite:cn"], "outboundTag": "direct" },
      { "type": "field", "ip": ["geoip:cn"], "outboundTag": "direct" },
      { "type": "field", "outboundTag": "proxy" }
    ]
  }
}

Маршрутизация через балансировщик с выбором по задержке:

json
{
  "routing": {
    "rules": [
      { "type": "field", "outboundTag": "direct", "domain": ["geosite:cn"] },
      { "type": "field", "balancerTag": "proxy-balance" }
    ],
    "balancers": [
      {
        "tag": "proxy-balance",
        "selector": ["proxy-"],
        "strategy": { "type": "leastPing" },
        "fallbackTag": "direct"
      }
    ]
  },
  "observatory": {
    "subjectSelector": ["proxy-"],
    "probeURL": "http://cp.cloudflare.com/generate_204",
    "probeInterval": "30s"
  }
}

Сопоставление по прикладному протоколу (требует сниффинга на входящем подключении):

json
{
  "inbounds": [{
    "port": 1080,
    "protocol": "socks",
    "sniffing": { "enabled": true, "destOverride": ["http", "tls"] }
  }],
  "routing": {
    "rules": [
      { "type": "field", "protocol": ["bittorrent"], "outboundTag": "block" }
    ]
  }
}

Примечания

  • Правила вычисляются в порядке объявления. Побеждает первое совпавшее; последующие правила видят только несовпавший трафик.
  • domainStrategy решает, что происходит, когда есть только IP-правила:
    • AsIs — доменные адресаты минуют IP-правила. Самый дешёвый вариант.
    • IpIfNonMatch — разрешать домен в IP, только если ни одно правило не совпало по домену. Сбалансированный вариант.
    • IpOnDemand — разрешать каждый домен в IP заранее, как только есть IP-правила. Самый точный и самый дорогой.
  • Доменные префиксы (full:, domain:, regexp:, keyword:, geosite:) разбираются внутри сопоставителя. Без префикса поведение по умолчанию — domain: (совпадение по суффиксу).
  • Правила geoip: и geosite: читают внешние файлы данных (geoip.dat / geosite.dat), обычно лежащие рядом с бинарным файлом Xray. Имена категорий (cn, private, apple, google, …) определены в этих файлах.
  • Эти файлы данных теперь можно автообновлять: блок верхнего уровня geodata скачивает свежие geoip.dat / geosite.dat по cron-расписанию через выбранное исходящее подключение. См. Geo-данные.
  • Входящий сниффинг питает ключи сопоставления protocol и attrs. Блок sniffing входящего подключения принимает destOverride плюс списки исключений domainsExcluded и — новинка недавних версий Xray — ipsExcluded, которые пропускают переопределение адресата для совпавших доменов / IP (наряду с metadataOnly и routeOnly).
  • Балансировщики со strategy: leastPing работают только при настроенном observatory или burst-observatory.
  • ruleTag позволяет управлять правилами во время работы через gRPC RoutingService (см. API).

Сравнение с другими ядрами

  • sing-box использует структурированные правила в snake_case с явными полями по каждому критерию (domain_suffix, ip_cidr, process_name). Правила могут нести action (route, direct, reject, hijack-dns, sniff, resolve, route-options), а не только тег исходящего подключения. См. Маршрутизация — sing-box.
  • mihomo использует компактные строковые правила (DOMAIN-SUFFIX,example.com,proxy), вычисляемые по порядку, плюс отдельный механизм rule-providers: для удалённых списков правил. См. Маршрутизация — mihomo.

Исходный код: infra/conf/router.go:21-75 · v26.7.28 (5ca6f4b)

Core Tutorial от Argsment