mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2025-01-20 17:51:40 +03:00
58a458759a
* Update routing-lv1-part2.md * Update ch04-security.md
436 lines
26 KiB
Markdown
436 lines
26 KiB
Markdown
# Краткий обзор функции маршрутизации (routing) (часть 2)
|
||
|
||
Добро пожаловать на продолжение изучения **функции маршрутизации** в `Xray`!
|
||
|
||
В [части 1](./routing-lv1-part1.md) мы разобрались с логикой работы **функции маршрутизации** и настроили простое разделение трафика по домену на основе файла `geosite.dat`.
|
||
|
||
Как уже было сказано, разделение по домену — это лишь верхушка айсберга возможностей **функции маршрутизации**. Давайте посмотрим, что еще, кроме домена, можно использовать в качестве критерия для разделения трафика!
|
||
|
||
## 5. Покорение новых высот - Различные условия сопоставления маршрутов
|
||
|
||
> `[домен], [IP], [протокол], etc.`
|
||
|
||
Разделение по домену уже позволяет нам в общих чертах разделить сетевой трафик. Почему **в общих чертах**?
|
||
|
||
Потому что, хотя **"разделение мира на три части"** — это правильная стратегия, ее реализация только с помощью **доменов** имеет множество недостатков, например:
|
||
|
||
1. После прочтения нашего руководства я зарегистрировал новый домен `proxy.yourdomain.com` для своего VPS и хочу, чтобы трафик на него всегда проксировался. Есть ли он в `geosite.dat`?
|
||
2. У меня есть еще один домен `direct.yourdomain.com`, и я хочу, чтобы трафик на него всегда шел напрямую. Есть ли он в `geosite.dat`?
|
||
3. Правильно ли настроен прямой доступ для локального трафика на `127.0.0.1` (например, `docker`)?
|
||
4. Правильно ли настроен прямой доступ для трафика в моей локальной сети `192.168.*.*` (например, роутер, NAS)?
|
||
5. Правильно ли настроен прямой доступ для моих DNS-запросов к внутренним DNS-серверам (например, `223.5.5.5`)?
|
||
6. Правильно ли настроен прокси для моих DNS-запросов к внешним DNS-серверам (например, `1.1.1.1`)?
|
||
7. Правильно ли настроен прямой доступ для других внутренних сайтов, у которых нет доменного имени, а только IP-адрес, как у внутренних DNS-серверов?
|
||
8. Правильно ли настроен прокси для других внешних сайтов, у которых нет доменного имени, а только IP-адрес, как у внешних DNS-серверов?
|
||
9. Как настроить принудительное прямое подключение для торрент-трафика, который, хотя и поступает извне, может привести к блокировке VPS при проксировании?
|
||
10. ......
|
||
|
||
Я говорю, что разделение по домену имеет много недостатков, потому что файл `geosite.dat` содержит только ограниченный набор часто используемых доменов. Другими словами, полагаясь только на него, мы:
|
||
|
||
- не сможем сопоставить новые домены, которых нет в файле;
|
||
- не сможем сопоставить правила на основе IP-адресов;
|
||
- не сможем сопоставить правила на основе сетевых протоколов.
|
||
|
||
::: warning
|
||
Давайте вспомним, что происходит, когда эти условия не выполняются? Верно, срабатывает скрытое правило маршрутизации: **трафик перенаправляется на первый исходящий трафик**. Это означает, что:
|
||
|
||
- если вашим первым исходящим трафиком является `[direct-out]`: **все, что должно идти напрямую, будет работать правильно, а все, что должно проксироваться, будет работать неправильно**;
|
||
- если вашим первым исходящим трафиком является `[proxy-out-vless]`: **все, что должно проксироваться, будет работать правильно, а все, что должно идти напрямую, будет работать неправильно**.
|
||
:::
|
||
|
||
Поэтому нам нужен способ, который позволит нам получить и то, и другое. Существует ли такой способ? **Конечно, существует!** Нам просто нужны дополнительные **критерии сопоставления** помимо **домена**.
|
||
|
||
### 5.1 Разделение по определенному домену: `[domain], [full]` и т. д.
|
||
|
||
1. Для сопоставления поддомена, например `a-name.yourdomain.com`, мы используем `full: "a-name.yourdomain.com"`.
|
||
2. **Проблемы 1** и **2**, описанные выше, можно решить, указав исходящий трафик `[proxy-out-vless]` для `proxy.yourdomain.com` и исходящий трафик `[direct-out]` для `direct.yourdomain.com`.
|
||
3. Для сопоставления всех поддоменов `yourdomain.com` мы используем `domain: "yourdomain.com"`.
|
||
4. Эти два правила могут быть независимыми, чтобы настроить прямое подключение для одних поддоменов и проксирование для других.
|
||
5. Кроме того, `[domain]` поддерживает сопоставление с помощью регулярных выражений. Подробнее см. [документацию по модулю маршрутизации](../../../config/base/routing/).
|
||
|
||
Конфигурация выглядит следующим образом:
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
// Прямое подключение для определенного поддомена
|
||
{
|
||
"type": "field",
|
||
"domain": ["full:direct.yourdomain.com"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
// Проксирование для определенного поддомена
|
||
{
|
||
"type": "field",
|
||
"domain": ["full:proxy.yourdomain.com"],
|
||
"outboundTag": "proxy-out-vless"
|
||
},
|
||
// Проксирование для всех поддоменов
|
||
{
|
||
"type": "field",
|
||
"domain": ["yourdomain.com"],
|
||
"outboundTag": "proxy-out-vless"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.2 Разделение по IP-адресам из файла: `geoip.dat`
|
||
|
||
Подобно файлу правил `geosite.dat`, у нас есть файл правил `geoip.dat`, который предоставляет **готовый к использованию список категорий IP-адресов**, чтобы удовлетворить Ваши различные потребности.
|
||
|
||
|
||
1. Чтобы решить **проблемы 3** и **4**, описанные выше, мы используем категорию `geoip:private` и указываем исходящий трафик `[direct-out]`.
|
||
2. Чтобы решить **проблему 7**, мы используем категорию `geoip:cn` и указываем исходящий трафик `[direct-out]`.
|
||
3. Чтобы решить **проблему 8**, мы используем скрытое правило маршрутизации, поскольку в `geoip` нет категории "не китайские IP-адреса" (потому что это равносильно сбору всех IP-адресов в мире). Другими словами, мы размещаем `[proxy-out-vless]` на первом месте в списке исходящего трафика.
|
||
|
||
Конфигурация выглядит следующим образом:
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
// Прямое подключение для локальных и внутренних IP-адресов
|
||
{
|
||
"type": "field",
|
||
"ip": ["geoip:private"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
// Прямое подключение для китайских IP-адресов
|
||
{
|
||
"type": "field",
|
||
"ip": ["geoip:cn"],
|
||
"outboundTag": "direct-out"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.3 Разделение по определенному IP-адресу
|
||
|
||
1. Чтобы решить **проблему 5**, мы используем `ip: "223.5.5.5"` и указываем исходящий трафик `[direct-out]`.
|
||
2. Чтобы решить **проблему 6**, мы используем `ip: "1.1.1.1"` и указываем исходящий трафик `[proxy-out-vless]`.
|
||
|
||
Конфигурация выглядит следующим образом:
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
// Прямое подключение для определенного IP-адреса
|
||
{
|
||
"type": "field",
|
||
"ip": ["223.5.5.5"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
// Проксирование для определенного IP-адреса
|
||
{
|
||
"type": "field",
|
||
"ip": ["1.1.1.1"],
|
||
"outboundTag": "proxy-out-vless"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.4 Разделение по типу протокола: `[protocol]` и т. д.
|
||
|
||
1. Чтобы решить **проблему 9**, мы используем `"protocol": ["bittorrent"]` и указываем исходящий трафик `[direct-out]`.
|
||
|
||
::: tip
|
||
Вам нужно включить `sniffing` во входящем прокси, чтобы использовать этот метод разделения.
|
||
:::
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
// Прямое подключение для торрент-трафика
|
||
{
|
||
"type": "field",
|
||
"protocol": ["bittorrent"],
|
||
"outboundTag": "direct-out"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.5 Разделение по другим критериям
|
||
|
||
На данный момент мы рассмотрели лишь малую часть возможностей разделения трафика **функции маршрутизации**! Она поддерживает множество других критериев сопоставления! Я перечислю их здесь:
|
||
|
||
Критерии, которые мы уже рассмотрели:
|
||
|
||
- `inboundTag`
|
||
- `domain`
|
||
- `ip`
|
||
- `protocol`
|
||
|
||
Критерии, которые мы еще не рассмотрели:
|
||
|
||
- `port`
|
||
- `sourcePort`
|
||
- `network`
|
||
- `source`
|
||
- `user`
|
||
- `attrs`
|
||
|
||
Однако, это слишком много информации для уровня 1, поэтому, если вам нужны эти сложные критерии, пожалуйста, внимательно изучите [документацию по модулю маршрутизации](../../config/base/routing/) самостоятельно! Если у вас возникнут вопросы, задавайте их в Telegram-группе!
|
||
|
||
## 6. "Начало новой эры": обзор правил маршрутизации
|
||
|
||
К настоящему моменту у нас накопился внушительный набор правил маршрутизации. Чтобы избежать путаницы, давайте проведем полный обзор.
|
||
|
||
::: warning Внимание
|
||
Правила маршрутизации обрабатываются **последовательно сверху вниз**. Поэтому я рекомендую следующий порядок:
|
||
|
||
`[1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]`
|
||
:::
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
// [1-block Блокировка рекламы]
|
||
// 1.1 Блокировка рекламных доменов
|
||
{
|
||
"type": "field",
|
||
"domain": ["geosite:category-ads-all"],
|
||
"outboundTag": "block"
|
||
},
|
||
// [2-direct Прямое подключение к внутренним ресурсам]
|
||
// 2.1 Прямое подключение для китайских доменов и определенного поддомена
|
||
{
|
||
"type": "field",
|
||
"domain": ["geosite:cn", "full:direct.yourdomain.com"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
// 2.2 Прямое подключение для локальных, внутренних, китайских и определенных IP-адресов
|
||
{
|
||
"type": "field",
|
||
"ip": ["geoip:private", "geoip:cn", "223.5.5.5"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
// 2.3 Прямое подключение для торрент-трафика
|
||
{
|
||
"type": "field",
|
||
"protocol": ["bittorrent"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
// [3-proxy Проксирование для внешних ресурсов]
|
||
// 3.1 Проксирование для иностранных доменов, определенного поддомена и всех поддоменов
|
||
{
|
||
"type": "field",
|
||
"domain": [
|
||
"geosite:geolocation-!cn",
|
||
"full:proxy.yourdomain.com",
|
||
"yourdomain.com"
|
||
],
|
||
"outboundTag": "proxy-out-vless"
|
||
},
|
||
// 3.2 Проксирование для определенного IP-адреса
|
||
{
|
||
"type": "field",
|
||
"ip": ["1.1.1.1"],
|
||
"outboundTag": "proxy-out-vless"
|
||
}
|
||
// [4-default-routing Первый исходящий трафик]
|
||
// Трафик, не соответствующий ни одному правилу, обрабатывается первым исходящим трафиком
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Теперь правила маршрутизации выглядят так:
|
||
|
||
```mermaid
|
||
graph LR;
|
||
|
||
S(Данные приложения) .-> I[Входящий трафик]
|
||
|
||
subgraph Xray
|
||
I --> R[Маршрутизация] -- "geosite:category-ads-all" --> O1[block]
|
||
|
||
R[Маршрутизация] -- "geosite:cn" --> O2[direct]
|
||
R[Маршрутизация] -- "direct.yourdomain.com" --> O2[direct]
|
||
R[Маршрутизация] -- "geoip:private" --> O2[direct]
|
||
R[Маршрутизация] -- "geoip:cn" --> O2[direct]
|
||
R[Маршрутизация] -- "ip:223.5.5.5" --> O2[direct]
|
||
R[Маршрутизация] -- "protocol:bittorrent" --> O2[direct]
|
||
|
||
R[Маршрутизация] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||
R[Маршрутизация] -- "proxy.yourdomain.com" --> O3[proxy]
|
||
R[Маршрутизация] -- "*.yourdomain.com" --> O3[proxy]
|
||
R[Маршрутизация] -- "ip:1.1.1.1" --> O3[proxy]
|
||
|
||
R[Маршрутизация] -. "Трафик, не соответствующий ни одному правилу" .-> O4[Первый исходящий трафик]
|
||
|
||
end
|
||
|
||
O2 .-> D(Внутренний сервер)
|
||
O3 .-> V(VPS)
|
||
|
||
O1:::redclass
|
||
V:::greyclass
|
||
S:::greyclass
|
||
R:::routingclass
|
||
classDef redclass fill:#FF0000
|
||
classDef greyclass fill:#C0C0C0
|
||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||
|
||
```
|
||
|
||
Будет ли первым исходящим трафиком `[direct-out]` или `[proxy-out-vless]`, зависит от ваших потребностей.
|
||
|
||
## 7. Распространенные ошибки в конфигурации маршрутизации
|
||
|
||
Обратите внимание, что каждое правило маршрутизации, которое я привел выше, имеет **только один критерий сопоставления**. Это необходимо для того, чтобы правило работало корректно. Частая ошибка новичков при настройке маршрутизации заключается в том, что они **указывют несколько критериев сопоставления в одном правиле, что делает его недействительным**.
|
||
|
||
Например, предположим, что нужно настроить следующее:
|
||
|
||
1. Прямое подключение для собственного домена `direct.yourdomain.com`.
|
||
2. Прямое подключение для DNS-запросов к внутренним DNS-серверам (например, `223.5.5.5`).
|
||
|
||
### 7.1 Неправильный пример
|
||
|
||
Чтобы достичь этой цели, новичок может написать следующее правило маршрутизации:
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
{
|
||
"type": "field",
|
||
"ip": ["223.5.5.5"],
|
||
"domain": ["full:direct.yourdomain.com"],
|
||
"outboundTag": "direct-out"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Видите ли вы здесь ошибку? На первый взгляд, кажется, все правильно?
|
||
|
||
::: warning Внимание
|
||
**В одном правиле все критерии должны выполняться одновременно**, чтобы правило сработало. Логическое отношение — "**И**", а не "**ИЛИ**".
|
||
:::
|
||
|
||
Другими словами, это правило означает: **`Xray` направит трафик на исходящий трафик `[direct-out]` только в том случае, если целевой адрес равен `direct.yourdomain.com` **и** `223.5.5.5` одновременно**.
|
||
|
||
Очевидно, что один адрес не может быть равен двум разным значениям одновременно, поэтому это не только невыполнимое правило, но и не имеет ничего общего с нашей первоначальной целью.
|
||
|
||
### 7.2 Правильный пример
|
||
|
||
Правильное решение — разделить разные критерии сопоставления на разные правила:
|
||
|
||
```json
|
||
{
|
||
"routing": {
|
||
"domainStrategy": "AsIs",
|
||
"rules": [
|
||
{
|
||
"type": "field",
|
||
"ip": ["223.5.5.5"],
|
||
"outboundTag": "direct-out"
|
||
},
|
||
{
|
||
"type": "field",
|
||
"domain": ["full:direct.yourdomain.com"],
|
||
"outboundTag": "direct-out"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
На самом деле, в пункте 6 я уже привел упорядоченные правила, принцип которых заключается в том, что **одинаковые критерии сопоставления можно объединять, а разные критерии сопоставления должны быть разделены**.
|
||
|
||
## 8. Скрытые пути
|
||
|
||
> Секретный проход для преобразования `[domain]` в `[ip]`: `domainStrategy`
|
||
|
||
В пункте 5.4 мы рассмотрели различные **критерии** для сопоставления трафика, среди которых были **домен** `[domain]` и **IP-адрес** `[IP]`.
|
||
|
||
Если вы знакомы с принципами работы DNS, то знаете, что при обращении к домену `[domain]` сначала нужно отправить запрос на DNS-сервер, чтобы получить IP-адрес `[IP]`, соответствующий домену, а затем отправить фактический запрос на этот IP-адрес.
|
||
|
||
Поэтому у `Xray` есть два шанса определить тип входящего запроса к домену. Использовать ли эти два шанса, решает параметр `domainStrategy`. Он имеет три значения:
|
||
|
||
- `AsIs`
|
||
- `IPIfNonMatch`
|
||
- `IPOnDemand`
|
||
|
||
Давайте рассмотрим каждое из них:
|
||
|
||
### 8.1 Стратегия домена: `"AsIs"`
|
||
|
||
"As Domain Is" означает **"как есть, без лишних действий"**.
|
||
|
||
Проще говоря, **"сопоставлять только по домену"**.
|
||
|
||
::: tip
|
||
`AsIs` на самом деле означает **"как есть, без изменений"**. Описание 🍉-sensei не совсем точное.
|
||
:::
|
||
|
||
В этом режиме вся обработка выполняется внутри `Xray` без обмена данными с внешним миром, поэтому скорость максимальна. Стратегия обработки несопоставимых доменов также ясна: как уже говорилось ранее, они автоматически перенаправляются на первый исходящий трафик. Поэтому это **наиболее рекомендуемая стратегия** для обычного использования функции маршрутизации.
|
||
|
||
### 8.2 Стратегия домена: `"IPIfNonMatch"`
|
||
|
||
"lookup IP if (there's) no matching rule" означает **"искать IP-адрес, если не найдено совпадений по другим правилам"**.
|
||
|
||
Проще говоря, **"сначала сопоставить целевой адрес со всеми правилами, а если совпадений не найдено, то получить IP-адрес через DNS и снова сопоставить его со всеми правилами"**.
|
||
|
||
В этом режиме домены, не сопоставленные ни с одним правилом, будут проходить через DNS-запрос и второй этап сопоставления правил, что займет больше времени, чем в режиме `AsIs`. Поэтому это **не самая рекомендуемая стратегия**.
|
||
|
||
### 8.3 Стратегия домена: `"IPOnDemand"`
|
||
|
||
"Demand IP" означает **"запрашивать IP-адрес"**.
|
||
|
||
Проще говоря, **"если в правилах маршрутизации есть правила на основе IP-адреса, то все запросы на основе домена `[domain]` будут преобразованы в IP-адреса `[IP]` и сопоставлены с правилами на основе IP-адреса"**.
|
||
|
||
В этом режиме все запросы к доменам будут проходить через DNS-запрос, поэтому первый запрос будет медленным. Хотя благодаря механизму кэширования DNS в `Xray` последующие запросы к тому же домену будут быстрыми, в целом это **не самая рекомендуемая стратегия**.
|
||
|
||
::: warning
|
||
`domainStrategy` действует **только для доменов**, не путайте!
|
||
:::
|
||
|
||
## 9. Задание для размышления
|
||
|
||
До сих пор мы рассматривали логику конфигурации **маршрутизации** на основе **одного входящего** и **одного исходящего** трафика.
|
||
|
||
Но, как вы знаете, `Xray` поддерживает несколько портов и протоколов. Что, если я спрошу вас:
|
||
|
||
1. Я хочу, чтобы протокол `VLESS` перенаправлял мой обычный веб-трафик и трафик приложений на высокоскоростной сервер в США.
|
||
2. Я хочу, чтобы протокол `trojan` перенаправлял весь мой трафик Netflix на сервер в Японии, чтобы разблокировать все аниме.
|
||
3. Я хочу, чтобы протокол `shadowsocks` перенаправлял весь мой игровой трафик на сервер в Гонконге для минимальной задержки.
|
||
4. Я хочу, чтобы был отдельный порт, который перенаправлял бы весь трафик `telegram` на VPS.
|
||
5. Я хочу, чтобы был отдельный порт, который перенаправлял бы весь торрент-трафик на мощный сервер в Европе.
|
||
6. Я хочу......
|
||
|
||
Можно ли реализовать эти сценарии с помощью **функции маршрутизации**?
|
||
|
||
Ответ, конечно же, **да**! Однако, это выходит за рамки уровня 1, поэтому я оставлю это вам для самостоятельного изучения!
|
||
|
||
## 10. Заключение
|
||
|
||
На этом обзор **функции маршрутизации** в `Xray` завершен. Надеюсь, эта статья помогла вам лучше понять гибкость `Xray`.
|
||
|
||
## 11. Примечания
|
||
|
||
- Теперь вы можете перечитать раздел [Маршрутизация](../../config/routing.md) и посмотреть, стало ли вам что-то понятнее.
|
||
- 🍉🍉🍉🍉🍉 :D
|
||
|
||
|
||
|