368 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Markdown
		
	
	
			
		
		
	
	
			368 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Markdown
		
	
	
# Маршрутизация
 | 
						||
 | 
						||
Модуль маршрутизации может отправлять входящие данные через разные исходящие соединения в соответствии с разными правилами для достижения цели проксирования по требованию.
 | 
						||
 | 
						||
Например, распространенным сценарием использования является разделение внутреннего и внешнего трафика. Xray может использовать внутренние механизмы для определения трафика из разных регионов, а затем отправлять его на разные исходящие прокси.
 | 
						||
 | 
						||
Более подробный анализ функции маршрутизации: [Краткий анализ функции маршрутизации (routing)](../document/level-1/routing-lv1-part1.md).
 | 
						||
 | 
						||
## RoutingObject
 | 
						||
 | 
						||
`RoutingObject` соответствует элементу `routing` в файле конфигурации.
 | 
						||
 | 
						||
```json
 | 
						||
{
 | 
						||
  "routing": {
 | 
						||
    "domainStrategy": "AsIs",
 | 
						||
    "domainMatcher": "hybrid",
 | 
						||
    "rules": [],
 | 
						||
    "balancers": []
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
> `domainStrategy`: "AsIs" | "IPIfNonMatch" | "IPOnDemand"
 | 
						||
 | 
						||
Стратегия разрешения доменных имен. Используются разные стратегии в зависимости от настройки.
 | 
						||
 | 
						||
- `"AsIs"`: для выбора маршрута используются только доменные имена. Значение по умолчанию.
 | 
						||
- `"IPIfNonMatch"`: если доменное имя не соответствует ни одному правилу, доменное имя разрешается в IP-адрес (запись A или запись AAAA) для повторного сопоставления;
 | 
						||
  - Если у доменного имени несколько записей A, предпринимается попытка сопоставить все записи A, пока одна из них не будет соответствовать какому-либо правилу;
 | 
						||
  - Разрешенный IP-адрес используется только при выборе маршрута, в пересылаемых пакетах данных по-прежнему используется исходное доменное имя;
 | 
						||
- `"IPOnDemand"`: если при сопоставлении встречается любое правило на основе IP-адреса, доменное имя немедленно разрешается в IP-адрес для сопоставления;
 | 
						||
 | 
						||
> `domainMatcher`: "hybrid" | "linear"
 | 
						||
 | 
						||
Алгоритм сопоставления доменных имен. Используются разные алгоритмы в зависимости от настройки. Этот параметр влияет на все `RuleObject`, для которых не указан отдельный алгоритм сопоставления.
 | 
						||
 | 
						||
- `"hybrid"`: используется новый алгоритм сопоставления доменных имен, который работает быстрее и занимает меньше места. Значение по умолчанию.
 | 
						||
- `"linear"`: используется старый алгоритм сопоставления доменных имен.
 | 
						||
 | 
						||
> `rules`: \[[RuleObject](#ruleobject)\]
 | 
						||
 | 
						||
Соответствует массиву, каждый элемент которого является правилом.
 | 
						||
 | 
						||
Для каждого соединения маршрутизация будет выполняться в соответствии с этими правилами сверху вниз. Когда встречается первое действующее правило, это соединение перенаправляется на указанный им `outboundTag` или `balancerTag`.
 | 
						||
 | 
						||
::: tip
 | 
						||
Если ни одно правило не совпадает, трафик по умолчанию отправляется через первый исходящий канал.
 | 
						||
:::
 | 
						||
 | 
						||
> `balancers`: \[ [BalancerObject](#balancerobject) \]
 | 
						||
 | 
						||
Массив, каждый элемент которого является конфигурацией балансировщика нагрузки.
 | 
						||
 | 
						||
Когда правило указывает на балансировщик нагрузки, Xray выбирает исходящий канал через этот балансировщик нагрузки, а затем перенаправляет трафик через него.
 | 
						||
 | 
						||
### RuleObject
 | 
						||
 | 
						||
```json
 | 
						||
{
 | 
						||
  "domainMatcher": "hybrid",
 | 
						||
  "type": "field",
 | 
						||
  "domain": ["baidu.com", "qq.com", "geosite:cn"],
 | 
						||
  "ip": ["0.0.0.0/8", "10.0.0.0/8", "fc00::/7", "fe80::/10", "geoip:cn"],
 | 
						||
  "port": "53,443,1000-2000",
 | 
						||
  "sourcePort": "53,443,1000-2000",
 | 
						||
  "network": "tcp",
 | 
						||
  "source": ["10.0.0.1"],
 | 
						||
  "user": ["love@xray.com"],
 | 
						||
  "inboundTag": ["tag-vmess"],
 | 
						||
  "protocol": ["http", "tls", "quic", "bittorrent"],
 | 
						||
  "attrs": { ":method": "GET" },
 | 
						||
  "outboundTag": "direct",
 | 
						||
  "balancerTag": "balancer",
 | 
						||
  "ruleTag": "rule name"
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
::: danger
 | 
						||
Если указано несколько атрибутов, они должны выполняться **одновременно**, чтобы текущее правило вступило в силу.
 | 
						||
:::
 | 
						||
 | 
						||
> `domainMatcher`: "hybrid" | "linear"
 | 
						||
 | 
						||
Алгоритм сопоставления доменных имен. Используются разные алгоритмы в зависимости от настройки. Этот параметр имеет приоритет над `domainMatcher`, настроенным в `RoutingObject`.
 | 
						||
 | 
						||
- `"hybrid"`: используется новый алгоритм сопоставления доменных имен, который работает быстрее и занимает меньше места. Значение по умолчанию.
 | 
						||
- `"linear"`: используется старый алгоритм сопоставления доменных имен.
 | 
						||
 | 
						||
> `type`: "field"
 | 
						||
 | 
						||
В настоящее время поддерживается только опция `"field"`.
 | 
						||
 | 
						||
::: tip
 | 
						||
Можно опустить эту строку в Xray-core v1.8.7 или более поздней версии.
 | 
						||
:::
 | 
						||
 | 
						||
> `domain`: \[string\]
 | 
						||
 | 
						||
Массив, каждый элемент которого представляет собой сопоставление доменного имени. Возможны следующие форматы:
 | 
						||
 | 
						||
- Простая строка: правило вступает в силу, если эта строка соответствует любой части целевого доменного имени. Например, "sina.com" может соответствовать "sina.com", "sina.com.cn" и "www.sina.com", но не соответствует "sina.cn".
 | 
						||
- Регулярное выражение: начинается с `"regexp:"`, остальная часть является регулярным выражением. Правило вступает в силу, если это регулярное выражение соответствует целевому доменному имени. Например, `"regexp:\\\\.goo.\*\\\\.com\$"` соответствует "www.google.com" или "fonts.googleapis.com", но не соответствует "google.com". (Обратите внимание, что в json обратная косая черта, часто используемая в регулярных выражениях, используется как escape-символ, поэтому обратная косая черта `\` в регулярном выражении должна быть заменена на `\\`)
 | 
						||
- Поддомен (рекомендуется): начинается с `"domain:"`, остальная часть является доменным именем. Правило вступает в силу, если это доменное имя является целевым доменным именем или его поддоменом. Например, "domain:xray.com" соответствует "www.xray.com", "xray.com", но не соответствует "wxray.com".
 | 
						||
- Полное совпадение: начинается с `"full:"`, остальная часть является доменным именем. Правило вступает в силу, если это доменное имя полностью соответствует целевому доменному имени. Например, "full:xray.com" соответствует "xray.com", но не соответствует "www.xray.com".
 | 
						||
- Предопределенный список доменов: начинается с `"geosite:"`, остальная часть является именем, например, `geosite:google` или `geosite:cn`. Имена и списки доменов см. в разделе [Предопределенные списки доменов](#предопределенные-списки-доменов).
 | 
						||
- Загрузка доменных имен из файла: имеет вид `"ext:файл:тег"`, должно начинаться с `ext:` (в нижнем регистре), за которым следует имя файла и тег, файл хранится в [каталоге ресурсов](./features/env.md#путь-к-файлу-ресурсов), формат файла такой же, как у `geosite.dat`, тег должен существовать в файле.
 | 
						||
 | 
						||
::: tip
 | 
						||
`"ext:geoip.dat:cn"` эквивалентно `"geoip:cn"`
 | 
						||
:::
 | 
						||
 | 
						||
> `ip`: \[string\]
 | 
						||
 | 
						||
Массив, каждый элемент которого представляет собой диапазон IP-адресов. Правило вступает в силу, если какой-либо элемент соответствует целевому IP-адресу. Возможны следующие форматы:
 | 
						||
 | 
						||
- IP-адрес: например, `"127.0.0.1"`.
 | 
						||
- [CIDR](https://ru.wikipedia.org/wiki/Бесклассовая_междоменная_маршрутизация): например, `"10.0.0.0/8"`, также можно использовать `"0.0.0.0/0"` `"::/0"` для указания всех IPv4- или IPv6-адресов.
 | 
						||
- Предопределенный список IP-адресов: этот список встроен в каждый установочный пакет Xray, имя файла - `geoip.dat`. Формат использования: `"geoip:код_страны"`, должно начинаться с `geoip:` (в нижнем регистре), за которым следует двухбуквенный код страны, поддерживаются почти все страны с доступом в Интернет.
 | 
						||
  - Специальное значение: `"geoip:private"`, включает в себя все частные адреса, например, `127.0.0.1`.
 | 
						||
  - Функция инверсии (!), `"geoip:!cn"` означает результаты, не входящие в `geoip:cn`.
 | 
						||
- Загрузка IP-адресов из файла: имеет вид `"ext:файл:тег"`, должно начинаться с `ext:` (в нижнем регистре), за которым следует имя файла и тег, файл хранится в [каталоге ресурсов](./features/env.md#путь-к-файлу-ресурсов), формат файла такой же, как у `geoip.dat`, тег должен существовать в файле.
 | 
						||
 | 
						||
> `port`: number | string
 | 
						||
 | 
						||
Диапазон портов назначения, возможны три формата:
 | 
						||
 | 
						||
- `"a-b"`: a и b являются положительными целыми числами, меньшими 65536. Этот диапазон является замкнутым интервалом, правило вступает в силу, если порт назначения попадает в этот диапазон.
 | 
						||
- `a`: a является положительным целым числом, меньшим 65536. Правило вступает в силу, если порт назначения равен a.
 | 
						||
- Смесь двух вышеуказанных форматов, разделенных запятой ",". Например: `"53,443,1000-2000"`.
 | 
						||
 | 
						||
> `sourcePort`: number | string
 | 
						||
 | 
						||
Порт источника, возможны три формата:
 | 
						||
 | 
						||
- `"a-b"`: a и b являются положительными целыми числами, меньшими 65536. Этот диапазон является замкнутым интервалом, правило вступает в силу, если порт источника попадает в этот диапазон.
 | 
						||
- `a`: a является положительным целым числом, меньшим 65536. Правило вступает в силу, если порт источника равен a.
 | 
						||
- Смесь двух вышеуказанных форматов, разделенных запятой ",". Например: `"53,443,1000-2000"`.
 | 
						||
 | 
						||
> `network`: "tcp" | "udp" | "tcp,udp"
 | 
						||
 | 
						||
Допустимые значения: "tcp", "udp" или "tcp,udp". Правило вступает в силу, если тип соединения соответствует указанному.
 | 
						||
 | 
						||
Поскольку ядро явно поддерживает только два протокола четвёртого уровня — TCP и UDP, то маршрут с условием, включающим только `"network": "tcp,udp"`, может использоваться для **catch-all** маршрутизации всего трафика. Пример использования — поместить такой маршрут в самый конец всех правил маршрутизации для назначения выходного соединения по умолчанию, если не подходит ни одно из других правил (иначе ядро по умолчанию использует первое правило).
 | 
						||
 | 
						||
Конечно, другие варианты, явно подходящие для маршрутизации любого трафика, такие как указание диапазона портов **1-65535** или IP-адресов **0.0.0.0/0 + ::/0**, также имеют аналогичное действие.
 | 
						||
 | 
						||
> `source`: \[string\]
 | 
						||
 | 
						||
Массив, каждый элемент которого представляет собой диапазон IP-адресов. Возможные форматы: IP-адрес, CIDR, GeoIP и загрузка IP-адресов из файла. Правило вступает в силу, если какой-либо элемент соответствует IP-адресу источника.
 | 
						||
 | 
						||
> `user`: \[string\]
 | 
						||
 | 
						||
Массив, каждый элемент которого является адресом электронной почты. Правило вступает в силу, если какой-либо элемент соответствует пользователю-источнику.
 | 
						||
 | 
						||
Аналогично доменному имени, также поддерживается сопоставление с помощью регулярных выражений, начинающихся с `regexp:`. (Также необходимо заменить `\` на `\\`, см. объяснение в разделе `domain`)
 | 
						||
 | 
						||
> `inboundTag`: \[string\]
 | 
						||
 | 
						||
Массив, каждый элемент которого является тегом. Правило вступает в силу, если какой-либо элемент соответствует тегу входящего протокола.
 | 
						||
 | 
						||
> `protocol`: \[ "http" | "tls" | "quic" | "bittorrent" \]
 | 
						||
 | 
						||
Массив, каждый элемент которого представляет собой протокол. Правило вступает в силу, если какой-либо протокол соответствует типу протокола текущего соединения.
 | 
						||
`http` поддерживает только 1.0 и 1.1, h2 пока не поддерживается. (Трафик h2 в открытом виде также встречается очень редко)
 | 
						||
`tls` TLS 1.0 ~ 1.3
 | 
						||
`quic` из-за сложности этого протокола, перехват может иногда не срабатывать.
 | 
						||
`bittorrent` только самый базовый перехват, может не сработать для многих шифрований и обфускаций.
 | 
						||
 | 
						||
::: tip
 | 
						||
Необходимо включить опцию `sniffing` во входящем прокси, чтобы определить тип протокола, используемого соединением.
 | 
						||
:::
 | 
						||
 | 
						||
> `attrs`: object
 | 
						||
 | 
						||
JSON-объект, где ключи и значения являются строками. Используется для проверки значений атрибутов HTTP-трафика (по очевидным причинам, поддерживаются только 1.0 и 1.1). Правило срабатывает, если HTTP-заголовки содержат все указанные ключи, и значения содержат указанную подстроку. Ключи не чувствительны к регистру. Значения поддерживают использование регулярных выражений.
 | 
						||
 | 
						||
Также поддерживаются псевдозаголовки h2, такие как `:method` и `:path`, для сопоставления метода и пути (хотя в HTTP/1.1 эти заголовки отсутствуют)
 | 
						||
 | 
						||
Для метода, отличного от CONNECT, входящего HTTP-запроса, `attrs` можно получить напрямую, для других входящих запросов необходимо включить `sniffing`, чтобы получить эти значения для сопоставления.
 | 
						||
 | 
						||
Примеры:
 | 
						||
 | 
						||
- Проверка HTTP GET: `{":method": "GET"}`
 | 
						||
- Проверка HTTP Path: `{":path": "/test"}`
 | 
						||
- Проверка Content Type: `{"accept": "text/html"}`
 | 
						||
 | 
						||
> `outboundTag`: string
 | 
						||
 | 
						||
Соответствует тегу исходящего канала.
 | 
						||
 | 
						||
> `balancerTag`: string
 | 
						||
 | 
						||
Соответствует тегу балансировщика нагрузки.
 | 
						||
 | 
						||
::: tip
 | 
						||
Необходимо указать либо `balancerTag`, либо `outboundTag`. Если указаны оба, используется `outboundTag`.
 | 
						||
:::
 | 
						||
 | 
						||
> `ruleTag`: string
 | 
						||
 | 
						||
Необязательно, не имеет фактического эффекта, используется только для идентификации имени этого правила.
 | 
						||
 | 
						||
Если установлено, при совпадении с этим правилом в журнал с уровнем Info будет выводиться соответствующая информация, используемая для отладки того, какое правило маршрутизации сработало.
 | 
						||
 | 
						||
### BalancerObject
 | 
						||
 | 
						||
Конфигурация балансировщика нагрузки. Когда балансировщик нагрузки активен, он выбирает наиболее подходящий исходящий канал из указанных исходящих каналов в соответствии с конфигурацией и перенаправляет трафик через него.
 | 
						||
 | 
						||
```json
 | 
						||
{
 | 
						||
  "tag": "balancer",
 | 
						||
  "selector": [],
 | 
						||
  "fallbackTag": "outbound",
 | 
						||
  "strategy": {}
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
> `tag`: string
 | 
						||
 | 
						||
Тег этого балансировщика нагрузки, используется для сопоставления с `balancerTag` в `RuleObject`.
 | 
						||
 | 
						||
> `selector`: \[ string \]
 | 
						||
 | 
						||
Массив строк, каждая из которых будет использоваться для сопоставления с префиксом тега исходящего канала. Например, для следующих тегов исходящих каналов: `[ "a", "ab", "c", "ba" ]`, `"selector": ["a"]` будет соответствовать `[ "a", "ab" ]`.
 | 
						||
 | 
						||
Обычно, когда находится несколько исходящих подключений (outbound), они используются для равномерного распределения нагрузки.
 | 
						||
 | 
						||
> `fallbackTag`: string
 | 
						||
 | 
						||
Если на основе результатов наблюдения за подключениями все исходящие (outbound) оказываются недоступными, то используется исходящее подключение, указанное в этой настройке.
 | 
						||
Примечание: необходимо добавить конфигурацию [observatory](./observatory.md#observatoryobject) или [burstObservatory](./observatory.md#burstobservatoryobject).
 | 
						||
 | 
						||
> `strategy`: [StrategyObject](#strategyobject)
 | 
						||
 | 
						||
#### StrategyObject
 | 
						||
 | 
						||
```json
 | 
						||
{
 | 
						||
  "type": "roundRobin",
 | 
						||
  "settings": {}
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
> `type` : "random" | "roundRobin" | "leastPing" | "leastLoad"
 | 
						||
 | 
						||
- `random`: значение по умолчанию. Случайным образом выбирает соответствующий исходящий прокси.
 | 
						||
- `roundRobin`: выбирает соответствующие исходящие прокси по очереди.
 | 
						||
- `leastPing` Выбирает исходящий прокси с наименьшей задержкой на основе результатов наблюдения за подключениями. Необходимо добавить конфигурацию [observatory](./observatory.md#observatoryobject) или [burstObservatory](./observatory.md#burstobservatoryobject).
 | 
						||
- `leastLoad` Выбирает наиболее стабильный исходящий прокси на основе результатов наблюдения за подключениями. Необходимо добавить конфигурацию [observatory](./observatory.md#observatoryobject) или [burstObservatory](./observatory.md#burstobservatoryobject).
 | 
						||
 | 
						||
> `settings`: [StrategySettingsObject](#strategysettingsobject)
 | 
						||
 | 
						||
##### StrategySettingsObject
 | 
						||
 | 
						||
Это необязательный параметр конфигурации, формат которого различается для разных стратегий балансировки нагрузки. В настоящее время этот параметр конфигурации можно добавить только для стратегии балансировки нагрузки `leastLoad`.
 | 
						||
 | 
						||
```json
 | 
						||
{
 | 
						||
  "expected": 2,
 | 
						||
  "maxRTT": "1s",
 | 
						||
  "tolerance": 0.01,
 | 
						||
  "baselines": ["1s"],
 | 
						||
  "costs": [
 | 
						||
    {
 | 
						||
      "regexp": false,
 | 
						||
      "match": "tag",
 | 
						||
      "value": 0.5
 | 
						||
    }
 | 
						||
  ]
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
> `expected`: number
 | 
						||
 | 
						||
Количество оптимальных узлов, выбираемых балансировщиком нагрузки. Трафик будет случайным образом распределен между этими узлами.
 | 
						||
 | 
						||
> `maxRTT`: string
 | 
						||
 | 
						||
Максимально допустимое время RTT (задержки) при измерении скорости.
 | 
						||
 | 
						||
> `tolerance`: float number
 | 
						||
 | 
						||
Максимально допустимая доля неудачных измерений скорости, например, 0.01 означает, что допустим 1% неудачных измерений (похоже, не реализовано).
 | 
						||
 | 
						||
> `baselines`: \[ string \]
 | 
						||
 | 
						||
Максимально допустимое стандартное отклонение времени RTT при измерении скорости.
 | 
						||
 | 
						||
> `costs`: \[ CostObject \]
 | 
						||
 | 
						||
Необязательный параметр конфигурации, массив, позволяющий задать веса для всех исходящих соединений.
 | 
						||
 | 
						||
> `regexp`: true | false
 | 
						||
 | 
						||
Использовать ли регулярные выражения для выбора `Tag` исходящего соединения.
 | 
						||
 | 
						||
> `match`: string
 | 
						||
 | 
						||
Сопоставление `Tag` исходящего соединения.
 | 
						||
 | 
						||
> `value`: float number
 | 
						||
 | 
						||
Значение веса. Чем больше значение, тем менее вероятно, что соответствующий узел будет выбран.
 | 
						||
 | 
						||
### Примеры конфигурации балансировки нагрузки
 | 
						||
 | 
						||
```json
 | 
						||
    "routing": {
 | 
						||
        "rules": [
 | 
						||
            {
 | 
						||
                "inboundTag": [
 | 
						||
                    "in"
 | 
						||
                ],
 | 
						||
                "balancerTag": "round"
 | 
						||
            }
 | 
						||
        ],
 | 
						||
        "balancers" : [
 | 
						||
            {
 | 
						||
                "selector": [
 | 
						||
                    "out"
 | 
						||
                ],
 | 
						||
                "strategy": {
 | 
						||
                    "type":"roundRobin"
 | 
						||
                },
 | 
						||
                "tag": "round"
 | 
						||
            }
 | 
						||
        ]
 | 
						||
    }
 | 
						||
 | 
						||
    "inbounds": [
 | 
						||
        {
 | 
						||
            "tag": "in"
 | 
						||
        }
 | 
						||
    ]
 | 
						||
 | 
						||
    "outbounds": [
 | 
						||
        {
 | 
						||
            "tag": "out1"
 | 
						||
        },
 | 
						||
        {
 | 
						||
            "tag": "out2"
 | 
						||
        }
 | 
						||
    ]
 | 
						||
```
 | 
						||
 | 
						||
### Предопределенные списки доменов
 | 
						||
 | 
						||
Этот список встроен в каждый установочный пакет Xray, имя файла - `geosite.dat`. Этот файл содержит некоторые распространенные доменные имена. Формат использования: `geosite:имя_файла`, например, `geosite:google` означает фильтрацию маршрутизации или DNS для доменных имен, соответствующих `google` в файле.
 | 
						||
 | 
						||
Распространенные доменные имена:
 | 
						||
 | 
						||
- `category-ads`: содержит распространенные доменные имена рекламы.
 | 
						||
- `category-ads-all`: содержит распространенные доменные имена рекламы, а также доменные имена поставщиков рекламы.
 | 
						||
- `cn`: эквивалентно объединению `geolocation-cn` и `tld-cn`.
 | 
						||
- `apple`: содержит большинство доменных имен Apple.
 | 
						||
- `google`: содержит большинство доменных имен Google.
 | 
						||
- `microsoft`: содержит большинство доменных имен Microsoft.
 | 
						||
- `facebook`: содержит большинство доменных имен Facebook.
 | 
						||
- `twitter`: содержит большинство доменных имен Twitter.
 | 
						||
- `telegram`: содержит большинство доменных имен Telegram.
 | 
						||
- `geolocation-cn`: содержит распространенные доменные имена сайтов материкового Китая.
 | 
						||
- `geolocation-!cn`: содержит распространенные доменные имена сайтов, не относящихся к материковому Китаю.
 | 
						||
- `tld-cn`: содержит домены верхнего уровня, управляемые CNNIC для использования в материковом Китае, например, доменные имена, оканчивающиеся на `.cn`, `.中国`.
 | 
						||
- `tld-!cn`: содержит домены верхнего уровня, не используемые в материковом Китае, например, доменные имена, оканчивающиеся на `.tw` (Тайвань), `.jp` (Япония), `.sg` (Сингапур), `.us` (США), `.ca` (Канада) и т.д.
 | 
						||
 | 
						||
Вы также можете просмотреть полный список доменов здесь: [Domain list community](https://github.com/v2fly/domain-list-community).
 |