26 KiB
Краткий обзор функции маршрутизации (routing) (часть 2)
Добро пожаловать на продолжение изучения функции маршрутизации в Xray
!
В части 1 мы разобрались с логикой работы функции маршрутизации и настроили простое разделение трафика по домену на основе файла geosite.dat
.
Как уже было сказано, разделение по домену — это лишь верхушка айсберга возможностей функции маршрутизации. Давайте посмотрим, что еще, кроме домена, можно использовать в качестве критерия для разделения трафика!
5. Покорение новых высот - Различные условия сопоставления маршрутов
[домен], [IP], [протокол], etc.
Разделение по домену уже позволяет нам в общих чертах разделить сетевой трафик. Почему в общих чертах?
Потому что, хотя "разделение мира на три части" — это правильная стратегия, ее реализация только с помощью доменов имеет множество недостатков, например:
- После прочтения нашего руководства я зарегистрировал новый домен
proxy.yourdomain.com
для своего VPS и хочу, чтобы трафик на него всегда проксировался. Есть ли он вgeosite.dat
? - У меня есть еще один домен
direct.yourdomain.com
, и я хочу, чтобы трафик на него всегда шел напрямую. Есть ли он вgeosite.dat
? - Правильно ли настроен прямой доступ для локального трафика на
127.0.0.1
(например,docker
)? - Правильно ли настроен прямой доступ для трафика в моей локальной сети
192.168.*.*
(например, роутер, NAS)? - Правильно ли настроен прямой доступ для моих DNS-запросов к внутренним DNS-серверам (например,
223.5.5.5
)? - Правильно ли настроен прокси для моих DNS-запросов к внешним DNS-серверам (например,
1.1.1.1
)? - Правильно ли настроен прямой доступ для других внутренних сайтов, у которых нет доменного имени, а только IP-адрес, как у внутренних DNS-серверов?
- Правильно ли настроен прокси для других внешних сайтов, у которых нет доменного имени, а только IP-адрес, как у внешних DNS-серверов?
- Как настроить принудительное прямое подключение для торрент-трафика, который, хотя и поступает извне, может привести к блокировке VPS при проксировании?
- ......
Я говорю, что разделение по домену имеет много недостатков, потому что файл geosite.dat
содержит только ограниченный набор часто используемых доменов. Другими словами, полагаясь только на него, мы:
- не сможем сопоставить новые домены, которых нет в файле;
- не сможем сопоставить правила на основе IP-адресов;
- не сможем сопоставить правила на основе сетевых протоколов.
::: warning Давайте вспомним, что происходит, когда эти условия не выполняются? Верно, срабатывает скрытое правило маршрутизации: трафик перенаправляется на первый исходящий трафик. Это означает, что:
- если вашим первым исходящим трафиком является
[direct-out]
: все, что должно идти напрямую, будет работать правильно, а все, что должно проксироваться, будет работать неправильно; - если вашим первым исходящим трафиком является
[proxy-out-vless]
: все, что должно проксироваться, будет работать правильно, а все, что должно идти напрямую, будет работать неправильно. :::
Поэтому нам нужен способ, который позволит нам получить и то, и другое. Существует ли такой способ? Конечно, существует! Нам просто нужны дополнительные критерии сопоставления помимо домена.
5.1 Разделение по определенному домену: [domain], [full]
и т. д.
- Для сопоставления поддомена, например
a-name.yourdomain.com
, мы используемfull: "a-name.yourdomain.com"
. - Проблемы 1 и 2, описанные выше, можно решить, указав исходящий трафик
[proxy-out-vless]
дляproxy.yourdomain.com
и исходящий трафик[direct-out]
дляdirect.yourdomain.com
. - Для сопоставления всех поддоменов
yourdomain.com
мы используемdomain: "yourdomain.com"
. - Эти два правила могут быть независимыми, чтобы настроить прямое подключение для одних поддоменов и проксирование для других.
- Кроме того,
[domain]
поддерживает сопоставление с помощью регулярных выражений. Подробнее см. документацию по модулю маршрутизации.
Конфигурация выглядит следующим образом:
{
"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-адресов, чтобы удовлетворить Ваши различные потребности.
- Чтобы решить проблемы 3 и 4, описанные выше, мы используем категорию
geoip:private
и указываем исходящий трафик[direct-out]
. - Чтобы решить проблему 7, мы используем категорию
geoip:cn
и указываем исходящий трафик[direct-out]
. - Чтобы решить проблему 8, мы используем скрытое правило маршрутизации, поскольку в
geoip
нет категории "не китайские IP-адреса" (потому что это равносильно сбору всех IP-адресов в мире). Другими словами, мы размещаем[proxy-out-vless]
на первом месте в списке исходящего трафика.
Конфигурация выглядит следующим образом:
{
"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-адресу
- Чтобы решить проблему 5, мы используем
ip: "223.5.5.5"
и указываем исходящий трафик[direct-out]
. - Чтобы решить проблему 6, мы используем
ip: "1.1.1.1"
и указываем исходящий трафик[proxy-out-vless]
.
Конфигурация выглядит следующим образом:
{
"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]
и т. д.
- Чтобы решить проблему 9, мы используем
"protocol": ["bittorrent"]
и указываем исходящий трафик[direct-out]
.
::: tip
Вам нужно включить sniffing
во входящем прокси, чтобы использовать этот метод разделения.
:::
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// Прямое подключение для торрент-трафика
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "direct-out"
}
]
}
}
5.5 Разделение по другим критериям
На данный момент мы рассмотрели лишь малую часть возможностей разделения трафика функции маршрутизации! Она поддерживает множество других критериев сопоставления! Я перечислю их здесь:
Критерии, которые мы уже рассмотрели:
inboundTag
domain
ip
protocol
Критерии, которые мы еще не рассмотрели:
port
sourcePort
network
source
user
attrs
Однако, это слишком много информации для уровня 1, поэтому, если вам нужны эти сложные критерии, пожалуйста, внимательно изучите документацию по модулю маршрутизации самостоятельно! Если у вас возникнут вопросы, задавайте их в Telegram-группе!
6. "Начало новой эры": обзор правил маршрутизации
К настоящему моменту у нас накопился внушительный набор правил маршрутизации. Чтобы избежать путаницы, давайте проведем полный обзор.
::: warning Внимание Правила маршрутизации обрабатываются последовательно сверху вниз. Поэтому я рекомендую следующий порядок:
[1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]
:::
{
"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 Первый исходящий трафик]
// Трафик, не соответствующий ни одному правилу, обрабатывается первым исходящим трафиком
]
}
}
Теперь правила маршрутизации выглядят так:
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. Распространенные ошибки в конфигурации маршрутизации
Обратите внимание, что каждое правило маршрутизации, которое я привел выше, имеет только один критерий сопоставления. Это необходимо для того, чтобы правило работало корректно. Частая ошибка новичков при настройке маршрутизации заключается в том, что они указывют несколько критериев сопоставления в одном правиле, что делает его недействительным.
Например, предположим, что нужно настроить следующее:
- Прямое подключение для собственного домена
direct.yourdomain.com
. - Прямое подключение для DNS-запросов к внутренним DNS-серверам (например,
223.5.5.5
).
7.1 Неправильный пример
Чтобы достичь этой цели, новичок может написать следующее правило маршрутизации:
{
"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 Правильный пример
Правильное решение — разделить разные критерии сопоставления на разные правила:
{
"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
поддерживает несколько портов и протоколов. Что, если я спрошу вас:
- Я хочу, чтобы протокол
VLESS
перенаправлял мой обычный веб-трафик и трафик приложений на высокоскоростной сервер в США. - Я хочу, чтобы протокол
trojan
перенаправлял весь мой трафик Netflix на сервер в Японии, чтобы разблокировать все аниме. - Я хочу, чтобы протокол
shadowsocks
перенаправлял весь мой игровой трафик на сервер в Гонконге для минимальной задержки. - Я хочу, чтобы был отдельный порт, который перенаправлял бы весь трафик
telegram
на VPS. - Я хочу, чтобы был отдельный порт, который перенаправлял бы весь торрент-трафик на мощный сервер в Европе.
- Я хочу......
Можно ли реализовать эти сценарии с помощью функции маршрутизации?
Ответ, конечно же, да! Однако, это выходит за рамки уровня 1, поэтому я оставлю это вам для самостоятельного изучения!
10. Заключение
На этом обзор функции маршрутизации в Xray
завершен. Надеюсь, эта статья помогла вам лучше понять гибкость Xray
.
11. Примечания
- Теперь вы можете перечитать раздел Маршрутизация и посмотреть, стало ли вам что-то понятнее.
- 🍉🍉🍉🍉🍉 :D