mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-10-09 07:09:59 +03:00
add Russian lang (#529)
* add Russian lang support --------- Co-authored-by: 风扇滑翔翼 <Fangliding.fshxy@outlook.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# Советы для начинающих
|
||||
|
||||
**В этой главе вы найдете советы по использованию Xray для начинающих, в основном с описанием принципов работы часто используемых модулей Xray.**
|
||||
|
||||
[Обзор функции Fallback](./fallbacks-lv1.md)
|
||||
|
||||
[Обзор функции маршрутизации (routing) (часть 1)](./routing-lv1-part1.md)
|
||||
|
||||
[Обзор функции маршрутизации (routing) (часть 2)](./routing-lv1-part2.md)
|
||||
|
||||
[Обзор режимов работы Xray](./work.md)
|
||||
|
||||
[Маскировка и разделение трафика по доменам с помощью функции SNI Fallback](./fallbacks-with-sni.md)
|
||||
@@ -0,0 +1,395 @@
|
||||
# Обзор функции Fallback
|
||||
|
||||
При использовании Xray вы наверняка много раз слышали о функции **"fallback"**. В этой статье мы кратко рассмотрим логику этой функции и способы ее применения.
|
||||
|
||||
## 1. Что такое Fallback в простых словах
|
||||
|
||||
Если вы использовали [конфигурацию Xray](../level-0/ch07-xray-server.md#_7-4-配置xray) из нашего руководства и настроили [автоматическое перенаправление HTTP на HTTPS](../level-0/ch07-xray-server.md#_7-8-服务器优化之二-开启http自动跳转https), то у вас уже есть простой fallback на основе протокола `VLESS`:
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
// ... ...
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": 8080 // По умолчанию перенаправлять на прокси-сервер, защищенный от сканирования
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
// ... ...
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Как объяснить этот фрагмент конфигурации простыми словами?
|
||||
|
||||
1. **`Xray` прослушивает порт `[inbound port]` `443`**
|
||||
|
||||
Это означает, что `Xray` отвечает за прослушивание трафика `HTTPS` на порту `443`.
|
||||
|
||||
2. **`Xray` использует протокол `[inbound protocol]` `vless`**
|
||||
|
||||
Только трафик протокола `vless` будет обрабатываться `Xray` и перенаправляться на исходящие модули.
|
||||
|
||||
::: warning
|
||||
**Примечание:** Легковесный протокол `VLESS` был разработан с целью добавления функции fallback в `xray`, `v2fly` и другие ядра, а также для уменьшения избыточных проверок/шифрования. (Конечно, на данный момент протокол `trojan` в `xray` также полностью поддерживает функцию fallback.)
|
||||
:::
|
||||
|
||||
3. **Целевой порт fallback `[fallback dest]` - `8080`**
|
||||
|
||||
После того, как `Xray` получает входящий трафик на порт `443`, трафик протокола `vless` обрабатывается внутренне и перенаправляется на исходящий модуль. Другой трафик, не относящийся к протоколу `vless`, перенаправляется на порт `8080`.
|
||||
|
||||
::: warning
|
||||
**Вопрос:** Использовать единственное или множественное число?
|
||||
|
||||
Ответ: Внимательные читатели, должно быть, заметили, что в файле конфигурации используются множественные числа `inbounds`, `fallbacks`, но почему я использую единственное число: `inbound`, `fallback`?
|
||||
|
||||
Потому что множественное число в файле конфигурации означает, что `xray` поддерживает N элементов одного уровня (т.е. N входящих, M резервных и т.д.), а в приведенном выше примере анализа используется только один, поэтому я использовал единственное число.
|
||||
:::
|
||||
|
||||
4. **Трафик, перенаправляемый на порт `8080`, обрабатывается последующей программой**
|
||||
|
||||
В нашем примере порт `8080` обрабатывается `Nginx`, который находит и отображает страницу с маленькой пандой в соответствии с конфигурацией.
|
||||
|
||||
5. **В итоге, полный маршрут данных в нашем примере выглядит следующим образом:**
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
W(Внешний HTTP:80 запрос) --> N80(HTTP:80)
|
||||
|
||||
subgraph Nginx Внешнее прослушивание
|
||||
N80 -.- N301(301 перенаправление) -.- N443(HTTPS:443)
|
||||
end
|
||||
|
||||
N443 --> X(Xray прослушивает 443) .- X1{Проверка входящего трафика}
|
||||
X1 --> |Трафик VLESS| X2(Внутренние правила Xray)
|
||||
X2 --> O(Xray Outbounds Исходящий)
|
||||
X1 ==> |Fallback не VLESS трафика| N8080(Nginx:8080)
|
||||
N8080:::nginxclass ==> H(index.html)
|
||||
|
||||
H:::nginxclass
|
||||
classDef nginxclass fill:#FFFFDE
|
||||
|
||||
```
|
||||
|
||||
## 2. Что такое Fallback (ЧТО, КАК `v1`)
|
||||
|
||||
Основываясь на приведенном выше примере, вы должны понять, что такое fallback (Что) и как он работает (Как), проще говоря, вот эти несколько элементов:
|
||||
|
||||
1. Fallback происходит после того, как трафик поступает на **порт прослушивания `Xray`**.
|
||||
2. Fallback основывается на таких характеристиках трафика, как **тип протокола**.
|
||||
3. Целью fallback является определенный **порт**.
|
||||
4. Трафик, для которого выполнен fallback, обрабатывается программой, прослушивающей **порт fallback**.
|
||||
|
||||
## 3. Зачем нужен Fallback (ЗАЧЕМ `v1`)
|
||||
|
||||
Изначально он был предназначен для защиты от **активного зондирования** (Active Probing).
|
||||
|
||||
**Активное зондирование:** Проще говоря, это означает, что внешние злоумышленники отправляют определенные сетевые запросы и интерпретируют ответы сервера, чтобы определить, запущены ли на сервере такие прокси-инструменты, как `xray`, `v2fly`, `shadowsocks` и т.д. Если это удается точно определить, сервер может подвергнуться атаке или блокировке.
|
||||
|
||||
Интерпретировать ответы сервера можно потому, что полный запрос данных на самом деле состоит из множества этапов обмена данными, и на каждом этапе генерируются определенные характеристики программного обеспечения. Проще говоря:
|
||||
|
||||
- Ответ обычного сайта **обязательно будет** содержать характеристики таких инструментов веб-сервиса и базы данных, как `Nginx`, `Apache`, `MySQL` и т.д.
|
||||
- Ответ обычного сайта **не будет** содержать характеристики таких прокси-инструментов, как `xray`, `v2fly`, `shadowsocks` и т.д.
|
||||
|
||||
Таким образом, когда мы предоставляем `Xray` функцию **"fallback"** (как в приведенном выше примере, fallback на `Nginx`), любой запрос, используемый для зондирования, приводит к следующему:
|
||||
|
||||
- Зондирующий трафик не может получить доступ к вашим параметрам `VLESS` и поэтому будет перенаправлен на `Nginx`.
|
||||
- Весь зондирующий трафик перенаправляется на `Nginx`, поэтому ответ VPS-сервера **обязательно будет** содержать характеристики `Nginx`.
|
||||
- Поскольку сам `Xray` не отвечает на зондирующий трафик, ответ VPS **не будет** содержать характеристики `Xray`.
|
||||
|
||||
Таким образом, функция **"fallback"** решает проблему безопасности **активного зондирования** сервера с точки зрения логики взаимодействия данных.
|
||||
|
||||
## 4. Полное понимание Fallback (ЧТО, ЗАЧЕМ, КАК `v2`)
|
||||
|
||||
Почему нужно снова говорить о fallback? Потому что выше мы рассмотрели только первую версию fallback, основанную на "протоколе" и защите от **активного зондирования**.
|
||||
|
||||
В процессе постоянного развития и обновления протокола `VLESS` и функции `fallback` командой [RPRX](https://github.com/rprx) постепенно выяснилось, что fallback может быть более гибким и мощным. При условии обеспечения защиты от **активного зондирования** можно в полной мере использовать информацию, содержащуюся в первом пакете данных, для реализации многоэлементного и многоуровневого fallback (например, `path`, `alpn` и т.д.).
|
||||
|
||||
Основываясь на этой концепции разработки, функция **"fallback"** постепенно превратилась в то, чем она является сейчас, - в механизм, реализующий **полную маскировку --> ws-разделение --> многопротокольное и многопараметрическое разделение**. Финальная версия даже полностью заменила функцию разделения, которую раньше выполняли веб-серверы и другие инструменты. А поскольку описанная выше обработка **"fallback/разделения"** выполняется на этапе определения первого пакета за миллисекунды и не связана с какими-либо операциями с данными, она практически не приводит к потерям производительности.
|
||||
|
||||
**Таким образом, сейчас **полноценная функция "fallback" в `Xray`** обладает следующими свойствами:**
|
||||
|
||||
- **Безопасность:** полная защита от атак активного зондирования.
|
||||
- **Эффективность:** практически полное отсутствие потерь производительности.
|
||||
- **Гибкость:** гибкое разделение данных, повторное использование часто используемых портов (например, 443).
|
||||
|
||||
::: tip
|
||||
Хотя такой подробный подход может показаться несколько утомительным, только он позволяет в полной мере раскрыть уникальные преимущества **полноценного "fallback"**.
|
||||
:::
|
||||
|
||||
## 5. Пример и описание многоуровневого fallback
|
||||
|
||||
Теперь, когда мы понимаем, что такое **"полноценный fallback"**, мы можем приступить к настройке многоуровневого fallback.
|
||||
|
||||
### 5.1 Сначала скопируем фрагмент конфигурации прослушивания порта 443 на стороне сервера:
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // Укажите свой UUID
|
||||
"flow": "xtls-rprx-vision",
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": 1310, // По умолчанию перенаправлять на протокол Trojan Xray
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"path": "/websocket", // Обязательно укажите свой путь
|
||||
"dest": 1234,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"path": "/vmesstcp", // Обязательно укажите свой путь
|
||||
"dest": 2345,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"path": "/vmessws", // Обязательно укажите свой путь
|
||||
"dest": 3456,
|
||||
"xver": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"alpn": ["http/1.1"],
|
||||
"certificates": [
|
||||
{
|
||||
"certificateFile": "/path/to/fullchain.crt", // Укажите путь к вашему сертификату, абсолютный путь
|
||||
"keyFile": "/path/to/private.key" // Укажите путь к вашему закрытому ключу, абсолютный путь
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Как объяснить этот фрагмент конфигурации простыми словами?
|
||||
|
||||
1. **`Xray` прослушивает порт (`inbound port`) `443`**
|
||||
|
||||
Это означает, что `Xray` отвечает за прослушивание трафика `HTTPS` на порту `443` и использует сертификат `TLS`, указанный в `certificates`, для аутентификации.
|
||||
|
||||
2. **`Xray` использует протокол (`inbound protocol`) `vless`**
|
||||
|
||||
Трафик протокола `vless` напрямую передается в `Xray` для дальнейшей обработки.
|
||||
|
||||
3. **Трафик, не относящийся к протоколу `VLESS`, перенаправляется на 4 различных порта fallback:**
|
||||
|
||||
1. Трафик с `path`, равным `websocket`, перенаправляется на порт `1234` для дальнейшей обработки.
|
||||
2. Трафик с `path`, равным `vmesstcp`, перенаправляется на порт `2345` для дальнейшей обработки.
|
||||
3. Трафик с `path`, равным `vmessws`, перенаправляется на порт `3456` для дальнейшей обработки.
|
||||
4. Весь остальной трафик перенаправляется на порт `1310` для дальнейшей обработки.
|
||||
|
||||
4. **`xver`, равный `1`, означает, что функция `proxy protocol` включена, и реальный IP-адрес источника будет передан дальше.**
|
||||
|
||||
5. **Структура fallback показана на рисунке ниже:**
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
W443(Внешний HTTP:443 запрос) --> X443(Xray-inbound: 443) .- X1{Проверка входящего трафика}
|
||||
X1 --> |Протокол = VLESS| X2(Внутренние правила Xray)
|
||||
X2 --> O(Xray Outbounds Исходящий)
|
||||
|
||||
X1 --> |path = /websocket| X1234(Xray-inbound:1234)
|
||||
X1 --> |path = /vmesstcp| X2345(Xray-inbound:2345)
|
||||
X1 --> |path = /vmessws| X3456(Xray-inbound:3456)
|
||||
X1 --> |Весь остальной трафик| X1310(Xray-inbound:1310)
|
||||
|
||||
```
|
||||
|
||||
6. **Куда делся fallback на веб-страницу?**
|
||||
|
||||
Верно, внимательные читатели должны были заметить, что `fallback на nginx`, защищающий от **активного зондирования**, исчез!!! Почему? Не опасно ли это? Не волнуйтесь, давайте разбираться дальше:
|
||||
|
||||
### 5.2 Фрагмент конфигурации, отвечающий за обработку fallback:
|
||||
|
||||
1. Трафик, перенаправляемый на порт `1310`, обрабатывается в соответствии со следующей конфигурацией:
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 1310,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "trojan",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"password": "", // Укажите свой пароль
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
],
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": 80 // Или перенаправлять на другой прокси-сервер, защищенный от сканирования
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "none",
|
||||
"tcpSettings": {
|
||||
"acceptProxyProtocol": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Смотрите, произошло чудо, в протоколе `trojan` появился новый `fallbacks`. Как уже говорилось ранее, протокол `trojan` в `xray` также обладает полной функциональностью fallback, поэтому на этом этапе протокол `trojan` может снова выполнять проверку и fallback (это и есть легендарный "fallback в fallback"):
|
||||
|
||||
- Весь трафик протокола `trojan` передается в `Xray` для дальнейшей обработки.
|
||||
- Весь остальной трафик перенаправляется на порт `80`. **Защита от активного зондирования** реализована!
|
||||
|
||||
2. Трафик, перенаправляемый на порт `1234`, на самом деле является `vless+ws`:
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 1234,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // Укажите свой UUID
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "ws",
|
||||
"security": "none",
|
||||
"wsSettings": {
|
||||
"acceptProxyProtocol": true, // Напоминание: если вы используете Nginx/Caddy и т.д. для обратного проксирования WS, удалите эту строку
|
||||
"path": "/websocket" // Обязательно укажите свой путь, он должен совпадать с путем разделения
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Трафик, перенаправляемый на порт `2345`, на самом деле является прямым подключением `vmess`:
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 2345,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "vmess",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // Укажите свой UUID
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "none",
|
||||
"tcpSettings": {
|
||||
"acceptProxyProtocol": true,
|
||||
"header": {
|
||||
"type": "http",
|
||||
"request": {
|
||||
"path": [
|
||||
"/vmesstcp" // Обязательно укажите свой путь, он должен совпадать с путем разделения
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. Трафик, перенаправляемый на порт `3456`, на самом деле является `vmess+ws(+cdn)`.
|
||||
|
||||
::: warning
|
||||
Да, вы не ослышались, это одна из комбинаций, рекомендованных v2fly, и она полностью поддерживает `CDN`. Теперь она добавлена в наш идеальный набор fallback!
|
||||
:::
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 3456,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "vmess",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // Укажите свой UUID
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "ws",
|
||||
"security": "none",
|
||||
"wsSettings": {
|
||||
"acceptProxyProtocol": true, // Напоминание: если вы используете Nginx/Caddy и т.д. для обратного проксирования WS, удалите эту строку
|
||||
"path": "/vmessws" // Обязательно укажите свой путь, он должен совпадать с путем разделения
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
5. Теперь мы можем нарисовать полную схему fallback:
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
W443(Внешний HTTP:443 запрос) --> X443(Xray-inbound: 443) .- X1{Проверка входящего трафика}
|
||||
X1 --> |Протокол = VLESS| X2(Внутренние правила Xray)
|
||||
X2 --> XO(Xray Outbounds Исходящий)
|
||||
|
||||
X1 --> |path = /websocket| X1234(Xray-inbound:1234)
|
||||
X1 --> |path = /vmesstcp| X2345(Xray-inbound:2345)
|
||||
X1 --> |path = /vmessws| X3456(Xray-inbound:3456)
|
||||
X1 --> |Весь остальной трафик| X1310(Xray-inbound:1310)
|
||||
|
||||
X1234 --> X2
|
||||
X2345 --> X2
|
||||
X3456 --> X2
|
||||
|
||||
X1310 --> |Протокол = trojan| X2
|
||||
X1310 --> |Весь остальной трафик| N80(Nginx:80)
|
||||
|
||||
N80:::nginxclass --> H(index.html)
|
||||
|
||||
H:::nginxclass
|
||||
classDef nginxclass fill:#FFFFDE
|
||||
```
|
||||
|
||||
## 6. Заключение
|
||||
|
||||
На этом обзор функции **"fallback"** в `Xray` завершен. Надеемся, что эта статья поможет вам лучше понять возможности `Xray`.
|
||||
|
||||
## 7. Дополнительное задание
|
||||
|
||||
Позвольте мне нагло оставить вам дополнительное задание: есть ли что-то, что можно оптимизировать в шаблоне [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/), описанном в этой статье?
|
||||
|
||||
Подсказка: автоматическое перенаправление HTTP на HTTPS.
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,333 @@
|
||||
---
|
||||
title: SNI Fallback
|
||||
---
|
||||
|
||||
# Маскировка и разделение трафика по доменам с помощью функции SNI Fallback
|
||||
|
||||
VLESS - это очень легкий протокол, который, как и Trojan, не использует сложного шифрования и обфускации трафика. Вместо этого он, подобно тому, как искусный мастер кунг-фу скрывает свою силу, шифрует трафик с помощью протокола TLS, маскируя его под обычный HTTPS-трафик и позволяя ему беспрепятственно проходить через Великий китайский файрвол. Для лучшей маскировки от активного зондирования вместе с VLESS была представлена функция Fallbacks (резервирование). В этой статье мы рассмотрим, как использовать функцию Fallbacks входящего протокола VLESS в Xray совместно с Nginx или Caddy для реализации разделения трафика по доменам при обеспечении полной маскировки.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
Из-за XTLS Xray необходимо прослушивать порт 443, что создает проблему, если на сервере уже запущен веб-сайт - сайт либо не сможет работать, либо его придется запускать на другом порту, что нежелательно. Есть три способа решить эту проблему:
|
||||
|
||||
- Xray прослушивает другие часто используемые порты (например, 22, 3389, 8443).
|
||||
|
||||
Это самое простое решение, но оно не идеально.
|
||||
|
||||
- Nginx или HAProxy прослушивает порт 443 и выполняет обратное проксирование на уровне L4 с разделением трафика по SNI, что позволяет использовать один порт для нескольких сервисов.
|
||||
|
||||
Этот вариант более сложный и требует определенных знаний Nginx или HAProxy, поэтому мы не будем его здесь подробно рассматривать.
|
||||
|
||||
- Xray прослушивает порт 443 и использует функцию Fallbacks для перенаправления трафика веб-сайта на Nginx или Caddy на основе SNI.
|
||||
|
||||
Этот вариант имеет среднюю сложность и является тем, который мы рассмотрим в этом руководстве.
|
||||
|
||||
## Что такое SNI
|
||||
|
||||
**SNI** (Server Name Indication) - это расширение протокола TLS. Те, кто знаком с обратным проксированием, знают, что для правильной маршрутизации трафика по доменному имени необходимо следующее правило:
|
||||
|
||||
```nginx
|
||||
proxy_set_header Host имя_хоста;
|
||||
```
|
||||
|
||||
Эта строка устанавливает HTTP-заголовок "Host" на определенное имя хоста. Зачем это нужно? Обычно у одного сервера один IP-адрес, но на нем может быть запущено несколько сайтов. Пользователи получают IP-адрес по доменному имени и обращаются к серверу, но как сервер определяет, какой именно сайт запрашивает пользователь? Для этого используются виртуальные хосты, основанные на имени.
|
||||
|
||||
Когда веб-сервер получает запрос, он проверяет заголовок "Host" и направляет пользователя на нужный сайт. Однако, когда HTTP-трафик шифруется с помощью TLS, этот простой метод перестает работать. TLS-рукопожатие происходит до того, как сервер увидит какие-либо HTTP-заголовки, поэтому сервер не может использовать информацию из заголовка "Host", чтобы решить, какой сертификат предоставить, и тем более не может определить, к какому сайту обращается пользователь.
|
||||
|
||||
SNI решает эту проблему, позволяя клиенту отправлять имя хоста как часть TLS-рукопожатия. Поэтому при использовании Nginx для обратного проксирования HTTPS-трафика необходимо добавить в конфигурацию `proxy_ssl_server_name on;`. В этом случае Nginx будет отправлять информацию SNI на проксируемый сервер, решая проблему неработающих виртуальных хостов по HTTPS. Кроме того, при использовании SNI можно получить доступ к нужному сайту, даже не указывая заголовок "Host".
|
||||
|
||||
## Идея
|
||||
|
||||

|
||||
|
||||
После получения трафика на порт 443 Xray расшифровывает TLS и перенаправляет трафик с длиной первого пакета менее 18 байт, неверной версией протокола или ошибкой аутентификации на адрес, указанный в `dest`, на основе совпадения `name`, `path` или `alpn`.
|
||||
|
||||
## Добавление DNS-записей
|
||||
|
||||

|
||||
|
||||
Измените домен и IP-адрес в соответствии с вашей ситуацией.
|
||||
|
||||
## Запрос TLS-сертификата
|
||||
|
||||
Поскольку нам нужно разделять трафик по доменам с разными поддоменами, а wildcard-сертификат покрывает только домены между двумя точками (например, сертификат для `*.example.com` не будет действовать для `example.com` и `*.*.example.com`), нам нужно запросить wildcard-сертификат с [SAN](https://ru.wikipedia.org/wiki/Subject_Alternative_Name). Согласно информации на сайте Let's Encrypt[^1], для запроса wildcard-сертификата требуется проверка DNS-01. В этом руководстве мы рассмотрим, как запросить бесплатный TLS-сертификат Let's Encrypt с помощью [acme.sh](https://acme.sh) для домена, управляемого Cloudflare. Инструкции для других провайдеров DNS можно найти в [dnsapi · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki/dnsapi).
|
||||
|
||||
Сначала нужно создать API-токен на [панели управления Cloudflare](https://dash.cloudflare.com/profile/api-tokens). Параметры следующие:
|
||||
|
||||

|
||||
|
||||
Настройка прав доступа очень важна, остальные параметры можно оставить по умолчанию.
|
||||
|
||||
После создания вы получите строку символов - это и есть ваш API-токен (`CF_Token`). Сохраните его в надежном месте, так как он больше не будет отображаться.
|
||||
|
||||
::: tip Внимание
|
||||
Следующие действия необходимо выполнять от имени пользователя root. Использование sudo может привести к ошибкам.
|
||||
:::
|
||||
|
||||
```bash
|
||||
curl https://get.acme.sh | sh # Установка acme.sh
|
||||
export CF_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" # Установка переменной окружения с API-токеном
|
||||
acme.sh --issue -d example.com -d *.example.com --dns dns_cf # Запрос сертификата с проверкой DNS-01
|
||||
mkdir /etc/ssl/xray # Создание каталога для хранения сертификата
|
||||
acme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --key-file /etc/ssl/xray/privkey.key --reloadcmd "chown nobody:nogroup -R /etc/ssl/xray && systemctl restart xray" # Установка сертификата в указанный каталог и настройка команды для автоматического перезапуска Xray после обновления сертификата
|
||||
```
|
||||
|
||||
## Конфигурация Xray
|
||||
|
||||
```json
|
||||
{
|
||||
"log": {
|
||||
"loglevel": "warning"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "UUID",
|
||||
"flow": "xtls-rprx-vision"
|
||||
}
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"path": "/vmessws",
|
||||
"dest": 5000,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"dest": 5001,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"alpn": "h2",
|
||||
"dest": 5002,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"name": "blog.example.com",
|
||||
"dest": 5003,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"name": "blog.example.com",
|
||||
"alpn": "h2",
|
||||
"dest": 5004,
|
||||
"xver": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"alpn": ["h2", "http/1.1"],
|
||||
"certificates": [
|
||||
{
|
||||
"certificateFile": "/etc/ssl/xray/cert.pem",
|
||||
"keyFile": "/etc/ssl/xray/privkey.key"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "127.0.0.1",
|
||||
"port": 5000,
|
||||
"protocol": "vmess",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "UUID"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "ws",
|
||||
"wsSettings": {
|
||||
"acceptProxyProtocol": true,
|
||||
"path": "/vmessws"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Эта конфигурация предназначена для Nginx. Обратите внимание на следующие детали:
|
||||
|
||||
- О Proxy Protocol
|
||||
|
||||
Proxy Protocol - это протокол, разработанный HaProxy для решения проблемы потери информации о клиенте при проксировании, часто используемый в цепочках прокси-серверов и обратных прокси. Традиционные методы решения этой проблемы, как правило, сложны и имеют много ограничений, в то время как Proxy Protocol очень прост - он просто добавляет пакет данных с информацией об исходном соединении (четверка "источник-назначение:порт") при передаче данных.
|
||||
|
||||
У всего есть свои плюсы и минусы, и Proxy Protocol не исключение.
|
||||
|
||||
- Если есть отправка, должен быть и прием, и наоборот.
|
||||
- Один и тот же порт не может одновременно поддерживать соединения с данными Proxy Protocol и без них (например, разные виртуальные хосты (server) Nginx на одном порту, что по сути является следствием предыдущего пункта)[^2][^3].
|
||||
|
||||
Если вы столкнулись с ошибками, убедитесь, что ваша конфигурация соответствует этим условиям.
|
||||
|
||||
Здесь мы используем Proxy Protocol, чтобы целевой сервер, на который перенаправляется трафик, получал реальный IP-адрес клиента.
|
||||
|
||||
Кроме того, если в конфигурации входящего трафика Xray есть `"acceptProxyProtocol": true`, ReadV будет отключен.
|
||||
|
||||
- О HTTP/2
|
||||
|
||||
Во-первых, порядок элементов в `inbounds.streamSettings.tlsSettings.alpn` важен: `h2` должен быть перед `http/1.1`, чтобы обеспечить совместимость при использовании HTTP/2. Обратный порядок приведет к тому, что HTTP/2 будет понижен до HTTP/1.1 во время согласования, делая конфигурацию недействительной.
|
||||
|
||||
В приведенной выше конфигурации каждая запись fallback для Nginx разделена на две. Это связано с тем, что h2 - это обязательное зашифрованное соединение HTTP/2, что хорошо для безопасности передачи данных в Интернете, но не нужно внутри сервера. h2c же - это незашифрованное соединение HTTP/2, подходящее для этой среды. Однако Nginx не может одновременно прослушивать HTTP/1.1 и h2c на одном порту. Чтобы решить эту проблему, необходимо указать `alpn` (в разделе `fallbacks`, а не `tlsSettings`), чтобы сопоставить результаты согласования TLS ALPN.
|
||||
|
||||
Рекомендуется указывать `alpn` только в двух случаях[^4]:
|
||||
|
||||
- опустить
|
||||
- `"h2"`
|
||||
|
||||
Если вы используете Caddy, то вам не нужно так усложнять, поскольку он **может** одновременно прослушивать HTTP/1.1 и h2c на одном порту. Изменения в конфигурации следующие:
|
||||
|
||||
```json
|
||||
{
|
||||
"fallbacks": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"path": "/vmessws",
|
||||
"dest": 5000,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"dest": 5001,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"name": "blog.example.com",
|
||||
"dest": 5002,
|
||||
"xver": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Конфигурация Nginx
|
||||
|
||||
Nginx будет установлен из официального репозитория.
|
||||
|
||||
```bash
|
||||
sudo apt install curl gnupg2 ca-certificates lsb-release
|
||||
echo "deb [arch=amd64] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
|
||||
| sudo tee /etc/apt/sources.list.d/nginx.list
|
||||
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
|
||||
sudo apt update
|
||||
sudo apt install nginx
|
||||
```
|
||||
|
||||
Удалите `/etc/nginx/conf.d/default.conf` и создайте `/etc/nginx/conf.d/fallbacks.conf` со следующим содержимым:
|
||||
|
||||
```nginx
|
||||
set_real_ip_from 127.0.0.1;
|
||||
real_ip_header proxy_protocol;
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:5001 proxy_protocol default_server;
|
||||
listen 127.0.0.1:5002 proxy_protocol default_server http2;
|
||||
|
||||
location / {
|
||||
root /srv/http/default;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:5003 proxy_protocol;
|
||||
listen 127.0.0.1:5004 proxy_protocol http2;
|
||||
|
||||
server_name blog.example.com;
|
||||
|
||||
location / {
|
||||
root /srv/http/blog.example.com;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
## Конфигурация Caddy
|
||||
|
||||
Инструкции по установке Caddy можно найти в [Install — Caddy Documentation](https://caddyserver.com/docs/install).
|
||||
|
||||
Чтобы Caddy мог получать реальный IP-адрес посетителя, необходимо скомпилировать Caddy с модулем Proxy Protocol. Рекомендуется скомпилировать его прямо на сайте Caddy.
|
||||
|
||||
```bash
|
||||
sudo curl -o /usr/bin/caddy "https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458"
|
||||
sudo chmod +x /usr/bin/caddy
|
||||
```
|
||||
|
||||
Просто замените существующий бинарный файл.
|
||||
|
||||
::: tip
|
||||
Рекомендуется сначала установить Caddy, следуя инструкциям на официальном сайте, а затем заменить бинарный файл. Это избавит от необходимости настраивать запуск сервиса вручную.
|
||||
:::
|
||||
|
||||
Отредактируйте `/etc/caddy/Caddyfile`:
|
||||
|
||||
```Caddyfile
|
||||
{
|
||||
servers 127.0.0.1:5001 {
|
||||
listener_wrappers {
|
||||
proxy_protocol
|
||||
}
|
||||
protocol {
|
||||
allow_h2c
|
||||
}
|
||||
}
|
||||
servers 127.0.0.1:5002 {
|
||||
listener_wrappers {
|
||||
proxy_protocol
|
||||
}
|
||||
protocol {
|
||||
allow_h2c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:5001 {
|
||||
root * /srv/http/default
|
||||
file_server
|
||||
log
|
||||
bind 127.0.0.1
|
||||
}
|
||||
|
||||
http://blog.example.com:5002 {
|
||||
root * /srv/http/blog.example.com
|
||||
file_server
|
||||
log
|
||||
bind 127.0.0.1
|
||||
}
|
||||
|
||||
:80 {
|
||||
redir https://{host}{uri} permanent
|
||||
}
|
||||
```
|
||||
|
||||
## Ссылки
|
||||
|
||||
1. [Указание имени сервера - Википедия](https://ru.wikipedia.org/wiki/Указание_имени_сервера)
|
||||
2. [Home · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki)
|
||||
3. [HTTP/2 - Википедия](https://ru.wikipedia.org/wiki/HTTP/2)
|
||||
|
||||
## Примечания
|
||||
|
||||
[^1]: [Часто задаваемые вопросы - Let's Encrypt - бесплатные SSL/TLS сертификаты](https://letsencrypt.org/ru/docs/faq/)
|
||||
[^2]: [Proxy Protocol - HAProxy Technologies](https://www.haproxy.com/blog/haproxy/proxy-protocol/)
|
||||
[^3]: [proxy protocol 介绍及 nginx 配置 - 简书](https://www.jianshu.com/p/cc8d592582c9)
|
||||
[^4]: [v2fly-github-io/vless.md at master · rprx/v2fly-github-io](https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md)
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,422 @@
|
||||
# Краткий обзор функции маршрутизации (routing) (часть 1)
|
||||
|
||||
Если "мощность" Xray в основном заключается в его высокой скорости и широкой совместимости, то его "гибкость" в первую очередь связана с продуманной функцией **"routing" (маршрутизация)**. В этой статье мы кратко рассмотрим логику этой функции и способы ее применения.
|
||||
|
||||
## 1. Знакомство с тремя братьями-маршрутизаторами
|
||||
|
||||
Чтобы понять маршрутизацию, нужно понимать, что для ее полноценной работы нужны три компонента: 1. **входящий трафик** (inbound); 2. **маршрутизация** (routing); 3. **исходящий трафик** (outbound).
|
||||
|
||||

|
||||
|
||||
Три брата, поклявшиеся в верности, не обязательно родились в один день, но должны быть готовы умереть в один день.
|
||||
|
||||
Поэтому запомните: если один из элементов работает неправильно, функция маршрутизации может не работать.
|
||||
|
||||
Поскольку маршрутизация очень гибкая, чтение только технической документации может вас запутать, поэтому в этой статье мы будем использовать конкретные примеры, чтобы объяснить все пошагово.
|
||||
|
||||
::: warning
|
||||
Функция маршрутизации настолько гибкая, что примеры в этой статье приведены только для объяснения соответствующих концепций. На практике, пожалуйста, корректируйте их в соответствии с вашими потребностями.
|
||||
:::
|
||||
|
||||
## 2. Основы: "Братья едины"
|
||||
|
||||
На рисунке ниже показан пример, когда входящий трафик от приложения поступает на `Xray` на клиенте, маршрутизируется на исходящий трафик и отправляется на VPS.
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
S(Данные приложения) .-> I[Входящий трафик]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[Маршрутизация] --> O[Исходящий трафик]
|
||||
end
|
||||
|
||||
O .-> V(VPS)
|
||||
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE
|
||||
|
||||
```
|
||||
|
||||
Давайте проанализируем каждый шаг:
|
||||
|
||||
### 2.1 Входящий трафик
|
||||
|
||||
::: tip
|
||||
**Входящий трафик (inbound):** это то, как трафик попадает в `Xray`.
|
||||
:::
|
||||
|
||||
Пример конфигурации входящего трафика ниже означает, что данные поступают в `Xray` по протоколу `socks` через порт `10808` с локального адреса `127.0.0.1`. `Xray` присваивает этому входящему трафику имя `inbound-10808` с помощью `[tag]`.
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "inbound-10808",
|
||||
"protocol": "socks",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 10808,
|
||||
"settings": {
|
||||
"udp": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 Исходящий трафик
|
||||
|
||||
::: tip
|
||||
**Исходящий трафик (outbound):** это то, как трафик выходит из `Xray`.
|
||||
:::
|
||||
|
||||
Пример конфигурации исходящего трафика ниже означает, что данные отправляются на соответствующий VPS по протоколу `VLESS` с использованием `tcp + xtls` и других параметров. `Xray` присваивает этому исходящему трафику имя `proxy-out-vless` с помощью `[tag]`.
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "proxy-out-vless",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "a-name.yourdomain.com",
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid",
|
||||
"flow": "xtls-rprx-vision",
|
||||
"encryption": "none",
|
||||
"level": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"serverName": "a-name.yourdomain.com",
|
||||
"allowInsecure": false,
|
||||
"fingerprint": "chrome"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 Маршрутизация
|
||||
|
||||
::: tip
|
||||
**Маршрутизация (routing):** это соединение канала между **входящим** и **исходящим** трафиком с помощью определенного **условия**.
|
||||
:::
|
||||
|
||||
Пример конфигурации маршрутизации ниже означает, что весь трафик, поступающий в `Xray` через входящий трафик с `[tag]="inbound-10808"`, **на 100%** перенаправляется на исходящий трафик с `[tag]="proxy-out-vless"` без разделения или каких-либо других действий.
|
||||
|
||||
```json
|
||||
{
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"inboundTag": ["inbound-10808"],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Таким образом, мы реализовали очень простое правило, описанное в начале: **входящий трафик от приложения поступает на `Xray` на клиенте, маршрутизируется на исходящий трафик и отправляется на VPS**.
|
||||
|
||||
### 2.4 Анализ параметров конфигурации маршрутизации: критерии фильтрации трафика
|
||||
|
||||
Обратите внимание на конфигурацию маршрутизации. Мы видим несколько новых терминов:
|
||||
|
||||
1. `"domainStrategy": "AsIs"`
|
||||
2. `“rules”`
|
||||
3. `"type": "field"`
|
||||
4. `"inboundTag": ["inbound-10808"]`
|
||||
5. `"outboundTag": "proxy-out-vless"`
|
||||
|
||||
Пока оставим `domainStrategy` в стороне и кратко объясним остальные:
|
||||
|
||||
| Название параметра | Значение параметра | Описание параметра |
|
||||
| :---------------- | :----------------- | :------------------ |
|
||||
| `“rules”` | | Внутри этого параметра находятся подробные настройки **правил маршрутизации**. |
|
||||
| `"type"` | `"field"` | На данный момент этот параметр не имеет особого значения, но его нельзя опускать, поэтому просто укажите его. |
|
||||
| `"inboundTag"` | `["inbound-10808"]` | **Критерий** фильтрации трафика - это **тег входящего трафика**, а **условие** сейчас только одно: **источник входящего трафика - `inbound-10808`**. |
|
||||
| `"outboundTag"` | `"proxy-out-vless"` | Если указанное выше условие фильтрации выполняется (т.е. входящий трафик имеет `[tag]="inbound-10808"`), `Xray` направит трафик на исходящий трафик с `[tag]="proxy-out-vless"`. |
|
||||
|
||||
В этом примере у нас есть только один входящий трафик с `"inboundTag" = "inbound-10808"` и один исходящий трафик с `[tag]="proxy-out-vless"`. Поэтому, согласно приведенному выше правилу маршрутизации, весь трафик, поступающий в `Xray` через порт `10808`, **на 100%** соответствует условиям фильтрации, выбирается модулем маршрутизации и перенаправляется на единственный исходящий трафик.
|
||||
|
||||
Таким образом, **входящий трафик**, **маршрутизация** и **исходящий трафик** уже могут работать вместе. Конечно, в данном случае 100% перенаправление не имеет особого смысла. Давайте посмотрим, какие преимущества может дать такой механизм разделения труда.
|
||||
|
||||
## 3. Первые шаги: "Разделение мира на три части" - "Разделение по домену"
|
||||
|
||||
> `[geosite.dat]`
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
S(Данные приложения) .-> I[Входящий трафик]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[Маршрутизация] -- "geosite:category-ads-all" --> O1[block]
|
||||
R[Маршрутизация] -- "geosite:cn" --> O2[direct]
|
||||
R[Маршрутизация] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
|
||||
Эта конфигурация реализует самый простой и распространенный (используемый в нашем руководстве) набор правил маршрутизации:
|
||||
|
||||
1. Блокировка рекламы (`[block]`)
|
||||
2. Прямое подключение к внутренним ресурсам (`[direct]`)
|
||||
3. Перенаправление трафика на VPS (`[proxy]`)
|
||||
|
||||
::: warning Внимание
|
||||
В нашем руководстве прямое подключение настроено для **внутренних доменов**, **внутренних IP-адресов** и **локальных IP-адресов**. Здесь мы рассмотрим только **внутренние домены**.
|
||||
:::
|
||||
|
||||
### 3.1 Входящий трафик
|
||||
|
||||
Оставляем `inbound-10808` из предыдущего примера без изменений.
|
||||
|
||||
### 3.2 Исходящий трафик
|
||||
|
||||
В предыдущем примере у нас уже есть исходящий трафик `[proxy]` - `"proxy-out-vless"`, поэтому он остается без изменений. Очевидно, что нам нужно добавить два новых типа исходящего трафика: `[block]` и `[direct]`, как показано ниже:
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "proxy-out-vless"
|
||||
// ... ...
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"protocol": "blackhole"
|
||||
},
|
||||
{
|
||||
"tag": "direct-out",
|
||||
"protocol": "freedom"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Приведенная выше конфигурация означает:
|
||||
|
||||
1. Конфигурация исходящего трафика `[proxy-out-vless]` из предыдущего примера остается без изменений.
|
||||
2. Добавлен протокол **`blackhole` (черная дыра)**. Трафик, отправляемый через этот протокол, попадает в "черную дыру" внутри `Xray` и не может выйти наружу, что фактически блокирует его (`[block]`).
|
||||
3. Добавлен протокол **`freedom` (свобода)**. Трафик, отправляемый через этот протокол, свободно покидает `Xray` и следует к своему первоначальному адресу, как будто его и не было, что фактически означает прямое подключение (`[direct]`). (Здесь я назвал его `[direct-out]`, чтобы подчеркнуть, что это исходящий трафик).
|
||||
|
||||
### 3.3 Маршрутизация
|
||||
|
||||
Настало время для чуда! Мы можем связать все это вместе с помощью конфигурации **маршрутизации**!
|
||||
|
||||
```json
|
||||
{
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"domain": ["geosite:category-ads-all"],
|
||||
"outboundTag": "block"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"domain": ["geosite:cn"],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"domain": ["geosite:geolocation-!cn"],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Чтобы понять этот файл конфигурации, нам нужно кратко объяснить несколько новых параметров:
|
||||
|
||||
- `"domain": ["geosite:category-ads-all"]`
|
||||
- `"domain": ["geosite:cn"]`
|
||||
- `"domain": ["geosite:geolocation-!cn"]`
|
||||
|
||||
### 3.4 Краткий обзор файла доменов: `geosite.dat`
|
||||
|
||||
На самом деле, вы, вероятно, уже догадались по названиям этих параметров:
|
||||
|
||||
- `"domain"`: **критерий** фильтрации трафика в этот раз - это **доменное имя** (а не тег входящего трафика).
|
||||
- `"geosite"`: `Xray` будет искать **соответствующие доменные имена** в файле `geosite.dat`.
|
||||
- `"category-ads-all"`: **все рекламные домены**, указанные в этом файле.
|
||||
- `"cn"`: **китайские домены**, указанные в этом файле.
|
||||
- `"geolocation-!cn"`: **не китайские домены**, указанные в этом файле.
|
||||
|
||||
С учетом этих пояснений конфигурацию из пункта 3.3 можно перевести так:
|
||||
|
||||
1. Трафик от приложений, пытающихся получить доступ к иностранным доменам (`"domain": "geolocation-!cn"`), перенаправляется на VPS через исходящий трафик `[proxy-out-vless]`.
|
||||
2. Трафик от приложений, пытающихся получить доступ к иностранным рекламным доменам (`"domain": "geosite:category-ads-all"`), блокируется (`[block]`) путем перенаправления в "черную дыру".
|
||||
3. Трафик от приложений, пытающихся получить доступ к китайским доменам (`"domain": "geosite:cn"`), отправляется напрямую (`[direct-out]`).
|
||||
|
||||
Вот так проявляются преимущества **функции маршрутизации**.
|
||||
|
||||
### 3.5 Так что же такое `geosite.dat`? Разве у нас нет `GFWList`?
|
||||
|
||||
Представьте, что в мире миллионы доменов. Если бы нам приходилось вручную собирать и вводить каждый домен для каждого правила маршрутизации, основанного на доменном имени, это было бы крайне неэффективно!
|
||||
|
||||
А если бы все домены относились только к одному типу и могли быть обработаны только одним из трех способов: `[direct], [proxy], [block]`, это было бы очень неудобно!
|
||||
|
||||
Как Гуань Юю нужен его Цинлун Яньюэдао, так и **функции маршрутизации** нужен свой волшебный меч - файл `geosite.dat`, который представляет собой готовый к использованию **список категорий доменов**. Он позволяет пользователям легко вызывать любую подкатегорию с помощью формата `geosite:xxx` и настраивать правила маршрутизации в соответствии со своими потребностями.
|
||||
|
||||
Такая модульная структура обеспечивает гораздо большую гибкость, чем традиционный список заблокированных доменов [`GFWList`](https://github.com/gfwlist/gfwlist). Например, вы можете указать, что домены Apple (`geosite:apple`) и домены, связанные с iCloud (`geosite:icloud`), должны проксироваться (`[proxy]`), а домены обновлений Apple (`geosite:apple-update`) должны подключаться напрямую (`[direct]`) для максимальной скорости загрузки.
|
||||
|
||||
::: warning
|
||||
**Внимание:** на данный момент существует несколько вариантов файла `geosite.dat`:
|
||||
|
||||
- Изначально, когда `Victoria Raymond` активно занималась проектом `Project V`, она предоставляла соответствующий проект [`domain-list-community`](https://github.com/v2ray/domain-list-community), который использовался для сбора, хранения и классификации часто используемых типов доменов.
|
||||
- После того, как Виктория внезапно исчезла, и разработка `Project V` приостановилась, сообщество `v2fly` продолжило поддерживать и обновлять свою версию [`domain-list-community`](https://github.com/v2fly/domain-list-community).
|
||||
- В то же время [@Loyalsoldier](Loyalsoldier) ведет свой собственный, модифицированный и расширенный файл правил маршрутизации [v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat), который предлагает множество различных вариантов и логики классификации.
|
||||
- Кроме того, команда `Project X` планирует в будущем создать и поддерживать файл правил маршрутизации [Xray-rules-dat](https://github.com/XTLS/Xray-rules-dat), который будет лучше подходить для использования с `Xray`. ~~(Как видите, папка уже создана, так что это дело времени)~~
|
||||
|
||||
Вы даже можете создать свой собственный файл `geosite` и подключить его к `Xray`, но это выходит за рамки данной статьи, поэтому мы не будем на этом останавливаться.
|
||||
|
||||
Если вы обнаружите, что некоторые домены не классифицированы должным образом, пожалуйста, создайте issue или отправьте pull request в один из перечисленных выше проектов! Поддерживайте сообщество - каждый за всех, и все за одного!
|
||||
|
||||
:::
|
||||
|
||||
### 3.6 Секретное оружие: скрытое правило маршрутизации
|
||||
|
||||
На самом деле, если вы внимательно посмотрите на приведенные выше правила, то заметите одну проблему: все наши правила определяют только то, **куда** следует перенаправлять входящий трафик, **если он соответствует определенному условию**. Но что произойдет, если файл `geosite.dat` неполный, и наш входящий трафик **не соответствует ни одному условию**? Как поступит `Xray`?
|
||||
|
||||
::: warning Внимание
|
||||
Если вы думаете, что **если условие не выполняется, то соединение не будет установлено**, то вам нужно подумать еще раз. Соединение будет разорвано только в том случае, если указано правило `[block]`, которое перенаправляет трафик в "черную дыру" (`blackhole`).
|
||||
:::
|
||||
|
||||
На самом деле, чтобы избежать путаницы из-за неполных правил маршрутизации, `Xray` предоставляет скрытое правило: **если входящий трафик не соответствует ни одному условию, он перенаправляется на первый исходящий трафик**.
|
||||
|
||||
Таким образом, ни один трафик не будет потерян. Поэтому важно поместить ваш самый надежный исходящий трафик на **первое место**, чтобы он служил вам верным стражем.
|
||||
|
||||
### 3.7 Снова смотрим на карту "трех царств"
|
||||
|
||||
Поскольку в предыдущем примере мы поместили `[proxy-out-vless]` на первое место в списке исходящего трафика, при срабатывании скрытого правила трафик будет перенаправляться на удаленный VPS по протоколу `VLESS`. Таким образом, полная логика работы `Xray` выглядит следующим образом:
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
S(Данные приложения) .-> I[Входящий трафик]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[Маршрутизация] -- "geosite:category-ads-all" --> O1[block]
|
||||
R[Маршрутизация] -- "geosite:cn" --> O2[direct]
|
||||
R[Маршрутизация] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
R[Маршрутизация] -. "Трафик, не соответствующий ни одному правилу" .-> O4[Первый исходящий трафик]
|
||||
|
||||
end
|
||||
|
||||
O2 .-> D(Внутренний сервер)
|
||||
O3 .-> V(VPS)
|
||||
O4 .-> V(VPS)
|
||||
|
||||
O1:::redclass
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
|
||||
classDef redclass fill:#FF0000
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||||
|
||||
```
|
||||
|
||||
Фактически, это и есть то, что традиционно называется **"проксирование по умолчанию, прямой доступ к внутренним сайтам по белому списку"**.
|
||||
|
||||
## 4. "Разделение мира на три части" - "Битва Вэй и Шу"
|
||||
|
||||
Теперь, когда вы знаете о скрытом правиле маршрутизации по умолчанию (**"если входящий трафик не соответствует ни одному условию, он перенаправляется на первый исходящий трафик"**), вы должны понимать, что то, будет ли **проксирование** или **прямое подключение** основным режимом работы, зависит от того, какой исходящий трафик стоит на первом месте!
|
||||
|
||||
На предыдущем шаге мы настроили правило **"проксирование по умолчанию, прямой доступ к внутренним сайтам по белому списку"**. Теперь, чтобы получить правило **"прямое подключение по умолчанию, проксирование иностранных сайтов по белому списку"**, нам просто нужно **поместить правило прямого подключения на первое место**.
|
||||
|
||||
Это очень просто, не правда ли?
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "direct-out",
|
||||
"protocol": "freedom"
|
||||
},
|
||||
{
|
||||
"tag": "proxy-out-vless"
|
||||
// ... ...
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"protocol": "blackhole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Теперь правила маршрутизации выглядят так:
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
|
||||
S(Данные приложения) .-> I[Входящий трафик]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[Маршрутизация] -- "geosite:category-ads-all" --> O1[block]
|
||||
R[Маршрутизация] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
R[Маршрутизация] -- "geosite:cn" --> O2[direct]
|
||||
R[Маршрутизация] -. "Трафик, не соответствующий ни одному правилу" .-> O4[Первый исходящий трафик]
|
||||
|
||||
end
|
||||
|
||||
O2 .-> D(Внутренний сервер)
|
||||
O3 .-> V(VPS)
|
||||
O4 .-> D
|
||||
|
||||
O1:::redclass
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
classDef redclass fill:#FF0000
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||||
|
||||
```
|
||||
|
||||
В этом и заключается гибкость функции маршрутизации - вы можете свободно менять порядок правил для достижения различных результатов.
|
||||
|
||||
На этом мы закончили объяснение того, **как использовать файл `geosite.dat` для разделения сетевого трафика по доменному имени с помощью правил маршрутизации**.
|
||||
|
||||
## 5. Покорение новых высот - Различные условия сопоставления маршрутов
|
||||
|
||||
Пожалуйста, убедитесь, что вы хорошо усвоили материал, изложенный выше, поскольку это основа для понимания принципов работы **функции маршрутизации**. Имея эту базу, мы можем двигаться дальше и рассмотреть более подробные параметры конфигурации и условия сопоставления.
|
||||
|
||||
После того, как вы прочитаете следующий раздел, вы сможете свободно настраивать свои собственные правила маршрутизации! Так чего же мы ждем? Давайте перейдем к [части 2](./routing-lv1-part2.md)!
|
||||
@@ -0,0 +1,434 @@
|
||||
# Краткий обзор функции маршрутизации (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-адресов**. Он позволяет пользователям легко вызывать любую подкатегорию с помощью формата `geoip:xxx` и настраивать правила маршрутизации в соответствии со своими потребностями.
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# Режимы работы Xray
|
||||
|
||||
## Режим одного сервера
|
||||
|
||||
Как и в случае с другими прокси-инструментами, вам понадобится сервер с настроенным Xray, а затем установить и настроить клиент Xray на вашем устройстве, после чего вы сможете свободно пользоваться Интернетом.
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
A(ПК) -.- B(Брандмауэр);
|
||||
B -.-> C(Внешний сайт);
|
||||
A --> D(Xray/VPS);
|
||||
D --> C;
|
||||
A --> E(Внутренний сайт);
|
||||
```
|
||||
|
||||
Один сервер Xray может одновременно обслуживать несколько устройств, использующих разные протоколы проксирования. При правильной настройке Xray может распознавать и различать трафик, который нужно проксировать, и трафик, который можно отправлять напрямую, без проксирования.
|
||||
|
||||
## Режим моста
|
||||
|
||||
Если вы не хотите настраивать маршрутизацию на каждом устройстве, вы можете настроить промежуточный сервер, который будет принимать весь трафик от клиентов и перенаправлять его в зависимости от настроек.
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
A(ПК) -.-> B(Брандмауэр);
|
||||
B -.-> C(Внешний сайт);
|
||||
A --> D(Внутренний VPS);
|
||||
D --> E(Внешний VPS);
|
||||
E --> C;
|
||||
D --> F(Внутренний сайт);
|
||||
```
|
||||
|
||||
## Принцип работы
|
||||
|
||||
Перед настройкой Xray давайте рассмотрим, как он работает. Ниже представлена схема внутреннего устройства одного процесса Xray. Несколько процессов Xray работают независимо друг от друга.
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
A1(inbound) --> D(Dispatcher / Router / DNS);
|
||||
A2(inbound) --> D;
|
||||
A3(inbound) --> D;
|
||||
A4(inbound) --> D;
|
||||
D --> B1(outbound);
|
||||
D --> B2(outbound);
|
||||
D --> B3(outbound);
|
||||
D --> B4(outbound);
|
||||
```
|
||||
|
||||
- Для нормальной работы необходимо настроить как минимум одно входящее соединение (Inbound) и одно исходящее соединение (Outbound).
|
||||
- Входящее соединение отвечает за связь с клиентом (например, браузером):
|
||||
- Входящее соединение обычно можно настроить с аутентификацией пользователя, например, с использованием ID и пароля;
|
||||
- После получения данных входящее соединение передает их диспетчеру (Dispatcher) для распределения.
|
||||
- Исходящее соединение отвечает за отправку данных на сервер, например, на другой Xray, работающий на другом хосте.
|
||||
- При наличии нескольких исходящих соединений можно настроить маршрутизацию (Routing) для указания, какое исходящее соединение должно использоваться для определенного типа трафика.
|
||||
- При необходимости маршрутизатор обращается к DNS для получения дополнительной информации для принятия решения.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user