EN: Retranslate all documents via Gemini Pro 3, Human proofreading

This commit is contained in:
Meow
2026-01-24 06:07:31 +08:00
parent a07654a1d1
commit b7ee2196c6
91 changed files with 6053 additions and 5509 deletions
+232 -232
View File
@@ -1,10 +1,10 @@
# 回落 (fallbacks) 功能简析
# A Brief Analysis of Fallbacks
在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。
In the process of using Xray, you must have heard about the **[Fallback]** function countless times. This article will briefly explain the logic and usage of this function.
## 1. 回顾《小小白白话文》中的回落
## 1. Reviewing Fallbacks in the "Beginner's Guide"
如果你用了《小小白白话文》中的[Xray 配置](../level-0/ch07-xray-server.md#_7-4-配置xray),并完成了[HTTP 自动跳转 HTTPS 优化](../level-0/ch07-xray-server.md#_7-8-服务器优化之二-开启http自动跳转https),那么你已经有了基于 `VLESS` 协议的简易回落:
If you used the [Xray Configuration](../level-0/ch07-xray-server.md#_7-4-configuration-xray) from the *Beginner's Guide* and completed the [HTTP to HTTPS Redirection Optimization](../level-0/ch07-xray-server.md#_7-8-server-optimization-part-2-enable-http-automatic-jump-to-https), then you already have a simple fallback based on the `VLESS` protocol:
```json
{
@@ -19,7 +19,7 @@
"decryption": "none",
"fallbacks": [
{
"dest": 8080 // 默认回落到防探测的代理
"dest": 8080 // Default fallback to the probe-resistant proxy/service
}
]
},
@@ -31,109 +31,109 @@
}
```
这一段配置用人话要怎么解释呢?
How do we explain this configuration in plain language?
1. **`Xray` 的入站端口 `[inbound port]` 是 `443`**
1. **Xray's `[inbound port]` is `443`**
即由 `Xray` 负责监听 `443` 端口的 `HTTPS` 流量
This means `Xray` is responsible for listening to `HTTPS` traffic on port `443`.
2. **`Xray` 的入站协议 `[inbound protocol]` 是 `vless`**
2. **Xray's `[inbound protocol]` is `vless`**
只有 `vless` 协议的流量才会流入 `Xray` 中做后续处理。
Only traffic using the `vless` protocol will flow into `Xray` for further processing.
::: warning
**注:** `VLESS` 这个轻量协议开发的初衷就是给 `xray` 及 `v2fly` 等核心引入回落功能、并同时减少冗余校验/加密。(当然,到目前为止,`xray` 中的 `trojan` 协议也已完整支持回落功能。)
:::
::: warning
**Note:** The `VLESS` lightweight protocol was originally developed to introduce the fallback function to cores like `xray` and `v2fly`, while reducing redundant verification/encryption. (Of course, as of now, the `trojan` protocol in `xray` also fully supports the fallback function.)
:::
3. **回落目标端口 `[fallback dest]` 是 `8080`**
3. **The `[fallback dest]` is `8080`**
`Xray` 接受 `443` 端口的访问流量后,属于 `vless` 协议的流量、由 `Xray` 进行内部处理并转发至出站模块。而其他非 `vless` 协议的流量,则转发至 `8080` 端口。
After `Xray` accepts traffic on port `443`, traffic belonging to the `vless` protocol is processed internally by `Xray` and forwarded to the outbound module. Traffic that is *not* `vless` protocol is forwarded to port `8080`.
::: warning
**问:到底是单数还是复数?**
::: warning
**Q: Is it singular or plural?**
答:一定有聪明的同学发现,配置文件中,明明是复数 `inbounds`, `fallbacks`,为什么我解释的时候都是单数:`inbound`, `fallback` 呢?
A: Some sharp students may have noticed that in the configuration file, the keys are plural (`inbounds`, `fallbacks`), but when I explain them, I use the singular (`inbound`, `fallback`). Why?
因为,配置文件中用复数,说明 `xray` 支持 N 个同等级的元素(即 N 个入站,M 个回落等等),上面的示例解析中仅仅是其中一个,所以我用了单数。
:::
Because the plural form in the configuration file indicates that `xray` supports N elements of the same level (i.e., N inbounds, M fallbacks, etc.). In the example analysis above, we are referring to just one of them, so I used the singular.
:::
4. **回落给 `8080` 端口的流量,由后续程序处理**
4. **Traffic falling back to port `8080` is handled by a subsequent program**
小小白白话文中的示例,就是 `8080` 端口由 `Nginx` 处理,根据配置找到并展示小熊猫的网页。
In the example from the *Beginner's Guide*, port `8080` is handled by `Nginx`, which finds and displays the Red Panda webpage based on its configuration.
5. **总结,小小白白话文示例中的最简单回落,完整数据路线如下:**
5. **Summary: The complete data route for the simplest fallback in the Beginner's Guide is as follows:**
```mermaid
graph LR;
```mermaid
graph LR;
W(外部 HTTP:80 请求) --> N80(HTTP:80)
W(External HTTP:80 Request) --> N80(HTTP:80)
subgraph Nginx 外部监听
N80 -.- N301(301转写) -.- N443(HTTPS:443)
end
subgraph Nginx External Listener
N80 -.- N301(301 Redirect) -.- N443(HTTPS:443)
end
N443 --> X(Xray 监听 443) .- X1{入站判断}
X1 --> |接收 VLESS 流量| X2(Xray内部规则)
X2 --> O(Xray Outbounds 出站)
X1 ==> |回落 非VLESS 流量| N8080(Nginx:8080)
N8080:::nginxclass ==> H(index.html)
N443 --> X(Xray Listener 443) .- X1{Inbound Judgment}
X1 --> |Receive VLESS Traffic| X2(Xray Internal Rules)
X2 --> O(Xray Outbounds)
X1 ==> |Fallback Non-VLESS Traffic| N8080(Nginx:8080)
N8080:::nginxclass ==> H(index.html)
H:::nginxclass
classDef nginxclass fill:#FFFFDE
H:::nginxclass
classDef nginxclass fill:#FFFFDE
```
```
## 2. 重新认识回落 (WHAT, HOW `v1`)
## 2. Re-understanding Fallbacks (WHAT, HOW `v1`)
基于上面的示例,你应该就可以明白什么是回落(What)和怎么回落(How)了,简单地说就是下面这几个要素:
Based on the example above, you should understand what a fallback is (What) and how it works (How). Simply put, it involves these elements:
1. 回落的时间是流量进入 `Xray监听端口` 后
2. 回落的依据是 `协议类型` 等流量特征
3. 回落的目标是某个 `端口`
4. 被回落的流量由监听 `回落端口` 的后续程序接手
1. The **Time** of fallback is after traffic enters the `Xray Listening Port`.
2. The **Basis** for fallback is traffic characteristics like `Protocol Type`.
3. The **Target** of fallback is a specific `Port`.
4. The traffic being fallen back is taken over by a subsequent program listening on the `Fallback Port`.
## 3. 为什么要回落 (WHY `v1`)
## 3. Why Use Fallbacks (WHY `v1`)
最初,是为了防御 **【主动探测】** (Active Probing)
Initially, it was to defend against **[Active Probing]**.
**主动探测:** 简单粗暴的理解,就是指外部通过发送特定的网络请求,并解读服务器的回应内容,来推测服务器端是否运行了 `xray`, `v2fly`, `shadowsocks` 等代理工具。一旦可以准确认定,则服务器可能受到干扰或阻断。
**Active Probing:** To put it simply and crudely, this refers to external parties sending specific network requests and interpreting the server's response to guess whether the server is running proxy tools like `xray`, `v2fly`, or `shadowsocks`. Once accurately identified, the server may be interfered with or blocked.
之所以可以根据服务器回应内容进行解读,就是因为一次完整的数据请求,其实有很多数据交换的步骤,每一个步骤,都会产生一些软件特征。用大白话说就是:
The reason interpretation is possible based on server responses is that a complete data request involves many steps of data exchange, and each step produces certain software signatures. In plain English:
- 正常的网站的回应,一定【会有】类似 `Nginx`, `Apache`, `MySQL` 的 Web 服务、数据库等工具的特征
- 正常的网站的回应,一定【不会有】类似 `xray`, `v2fly`, `shadowsocks` 等代理工具的特征
- A normal website response will definitely **[HAVE]** signatures of Web services/databases like `Nginx`, `Apache`, `MySQL`, etc.
- A normal website response will definitely **[NOT HAVE]** signatures of proxy tools like `xray`, `v2fly`, `shadowsocks`, etc.
于是,当我们给 `Xray` 提供了【回落】功能后(如上例,回落给 `Nginx`),面对任何用来探测的请求,产生的结果是:
Therefore, when we provide the **[Fallback]** function to `Xray` (as in the example above, falling back to `Nginx`), the result when facing any probing request is:
- 探测流量无法掌握你的 `VLESS` 要素,故都会被回落至 `Nginx`
- 探测流量全都回落进入 `Nginx` ,故 VPS 服务器的回应一定【会有】 `Nginx` 的特征
- 因为 `Xray` 本身不对探测流量做任何回应 ,所以 VPS 的回应一定【不会有】 `Xray` 的特征
- Probing traffic cannot master your `VLESS` secrets/elements, so it will all fall back to `Nginx`.
- Since probing traffic falls back into `Nginx`, the VPS server's response will definitely **[HAVE]** `Nginx` signatures.
- Because `Xray` itself does not respond to probing traffic, the VPS response will definitely **[NOT HAVE]** `Xray` signatures.
至此,【回落】功能就从数据交互逻辑上解决了服务器被 **【主动探测】** 的安全隐患。
Thus, the **[Fallback]** function solves the security risk of the server being **[Actively Probed]** from the logic of data interaction.
## 4. 重新认识【回落の完全体】 (WHAT, WHY, HOW `v2`)
## 4. Re-understanding the [Perfect Form of Fallback] (WHAT, WHY, HOW `v2`)
为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。
Why do we need to understand fallbacks again? Because the above only explains the initial version of fallbacks based on "protocols" for resisting [Active Probing].
在 [RPRX](https://github.com/rprx) 不断开发迭代 `VLESS` 协议及 `fallback` 功能的过程中,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 `path`, `alpn` 等)
During the continuous development and iteration of the `VLESS` protocol and `fallback` function by [RPRX](https://github.com/rprx), it was discovered that fallbacks could be much more flexible and powerful. As long as the premise of resisting [Active Probing] is met, by fully utilizing the information in the first data packet, multi-element and multi-level fallbacks (such as `path`, `alpn`, etc.) can be achieved.
基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 `纯伪装 --> ws分流 --> 多协议多特征分流` 的进化。最终版甚至完全替代了以前要用 Web 服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。
Based on this development philosophy, the **[Fallback]** function has gradually grown into its current "Perfect Form," completing the evolution from `Pure Camouflage --> WS Shunting --> Multi-protocol Multi-feature Shunting`. The final version has even completely replaced the shunting functions that previously required Web servers or other tools. Moreover, since the aforementioned [Fallback/Shunting] processing is completed at the first packet judgment stage with millisecond-level speed and does not involve any data manipulation, there is almost no process loss.
**因此,现在 `Xray` 中【完整体的回落功能】,同时具备下述属性:**
**Therefore, the [Complete Fallback Function] in `Xray` now possesses the following attributes:**
- **安全:** 充分抵御主动探测攻击
- **高效:** 几乎毫无性能损失
- **灵活:** 数据灵活分流、常用端口复用(如 443)
- **Secure:** Fully resists active probing attacks.
- **Efficient:** Almost zero performance loss.
- **Flexible:** Flexible data shunting, reuse of common ports (like 443).
::: tip 啰嗦君
这样多轮介绍虽然略显繁琐,但只有这样层层深入展开,才能充分的说明【回落の完全体】独有的强大!
::: tip Mr. Wordy
Although explaining it in multiple rounds seems tedious, only by peeling it back layer by layer can we fully demonstrate the unique power of the [Perfect Form of Fallback]!
:::
## 5. 多层回落示例及解读
## 5. Multi-layer Fallback Example and Interpretation
理解了【回落の完全体】是什么,那就可以动手操作配置多层回落了。其实,项目已经提供了非常完整的示例,即官方模板中的 [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/)。
Now that you understand what the [Perfect Form of Fallback] is, you can get your hands dirty configuring multi-layer fallbacks.
### 5.1 首先,我将服务器端配置的 443 监听段摘抄如下:
### 5.1 First, I will extract the server-side configuration for port 443 as follows
```json
{
@@ -142,7 +142,7 @@
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"id": "", // Fill in your UUID
"flow": "xtls-rprx-vision",
"level": 0,
"email": "love@example.com"
@@ -151,21 +151,21 @@
"decryption": "none",
"fallbacks": [
{
"dest": 1310, // 默认回落到 Xray 的 Trojan 协议
"dest": 1310, // Default fallback to Xray's Trojan protocol
"xver": 1
},
{
"path": "/websocket", // 必须换成自定义的 PATH
"path": "/websocket", // Must be changed to your custom PATH
"dest": 1234,
"xver": 1
},
{
"path": "/vmesstcp", // 必须换成自定义的 PATH
"path": "/vmesstcp", // Must be changed to your custom PATH
"dest": 2345,
"xver": 1
},
{
"path": "/vmessws", // 必须换成自定义的 PATH
"path": "/vmessws", // Must be changed to your custom PATH
"dest": 3456,
"xver": 1
}
@@ -178,8 +178,8 @@
"alpn": ["http/1.1"],
"certificates": [
{
"certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径
"keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径
"certificateFile": "/path/to/fullchain.crt", // Absolute path to your certificate
"keyFile": "/path/to/private.key" // Absolute path to your private key
}
]
}
@@ -187,194 +187,194 @@
}
```
这一段配置用人话要怎么解释呢?
How do we explain this configuration in plain language?
1. **`Xray` 的入站端口 (`inbound port`) 是 `443`**
1. **Xray's `[inbound port]` is `443`**
即由 `Xray` 负责监听 `443` 端口的 `HTTPS` 流量,并使用 `certificates` 项下设定的 `TLS` 证书来进行验证
This means `Xray` is responsible for listening to `HTTPS` traffic on port `443` and uses the `TLS` certificate set under `certificates` for verification.
2. **`Xray` 的入站协议 (`inbound protocol`) 是 `vless`**
2. **Xray's `[inbound protocol]` is `vless`**
`vless` 协议流量直接流入 `Xray` 中做后续处理
`vless` protocol traffic flows directly into `Xray` for subsequent processing.
3. **非 `VLESS` 协议流量有 4 个不同的回落目标:**
1. `path` 为 `websocket` 的流量,回落给端口 `1234` 后续处理
2. `path` 为 `vmesstcp` 的流量,回落给端口 `2345` 后续处理
3. `path` 为 `vmessws` 的流量,回落给端口 `3456` 后续处理
4. 其它所有流量,回落给端口 `1310` 后续处理
3. **Non-`VLESS` protocol traffic has 4 different fallback targets:**
1. Traffic with `path` as `/websocket` falls back to port `1234` for processing.
2. Traffic with `path` as `/vmesstcp` falls back to port `2345` for processing.
3. Traffic with `path` as `/vmessws` falls back to port `3456` for processing.
4. All other traffic falls back to port `1310` for processing.
4. **`xver` 为 `1` 表示开启 `proxy protocol` 功能,向后传递来源真实 IP**
4. **`xver` set to `1` means enabling the `proxy protocol` function to pass the real source IP backwards.**
5. **上述回落结构如下图所示:**
5. **The fallback structure described above is shown in the diagram below:**
```mermaid
graph LR;
```mermaid
graph LR;
W443(外部 HTTP:443 请求) --> X443(Xray-inbound: 443) .- X1{入站判断}
X1 --> |协议 = VLESS 的流量| X2(Xray内部规则)
X2 --> O(Xray Outbounds 出站)
W443(External HTTP:443 Request) --> X443(Xray-inbound: 443) .- X1{Inbound Judgment}
X1 --> |Protocol = VLESS Traffic| X2(Xray Internal Rules)
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)
X1 --> |path = /websocket Traffic| X1234(Xray-inbound:1234)
X1 --> |path = /vmesstcp Traffic| X2345(Xray-inbound:2345)
X1 --> |path = /vmessws Traffic| X3456(Xray-inbound:3456)
X1 --> |All Other Traffic| X1310(Xray-inbound:1310)
```
```
6. **网页回落不见了!**
6. **The Web Page Fallback is missing!**
没错,聪明的同学应该发现了,防御【主动探测】的 `nginx回落` 不见了!!!这是为什么呢?会不会不安全?别急,我们继续分析:
That's right, clever students must have noticed that the `nginx fallback` for defending against [Active Probing] is gone!!! Why is that? Is it insecure? Don't worry, let's continue analyzing:
### 5.2 后续监听处理的配置段摘抄如下:
### 5.2 The configuration segments for subsequent listening processing are as follows
1. 后续处理回落至 `1310` 端口的流量,按照下面的配置验证、处理:
1. Traffic falling back to port `1310` is verified and processed according to the configuration below:
```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
}
}
}
```
```json
{
"port": 1310,
"listen": "127.0.0.1",
"protocol": "trojan",
"settings": {
"clients": [
{
"password": "", // Fill in your password
"level": 0,
"email": "love@example.com"
}
],
"fallbacks": [
{
"dest": 80 // Or fallback to another probe-resistant proxy
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true
}
}
}
```
看,神奇的事情发生了, `trojan` 协议这里又出现了一个新的 `fallbacks`。前面已经说过,`xray` 中的 `trojan` 协议也具有完整的回落能力,所以,此时 `trojan` 协议可以再次做判断和回落(这也就是传说中的套娃回落了):
- 所有 `trojan` 协议的流量,流入 `Xray` 中做后续处理
- 所有非 `trojan` 协议的流量,转发至 `80` 端口,【主动探测】的防御,完成!
Look, something magical happened. A new `fallbacks` section appeared here in the `trojan` protocol. As mentioned before, the `trojan` protocol in `xray` also has full fallback capabilities. So, at this point, the `trojan` protocol can perform judgment and fallback again (this is the legendary "Nested/Matryoshka" fallback):
- All `trojan` protocol traffic flows into `Xray` for subsequent processing.
- All non-`trojan` protocol traffic is forwarded to port `80`. The defense against [Active Probing] is complete!
2. 后续处理回落至 `1234` 端口的流量,仔细看!它其实是 `vless+ws`:
2. Traffic falling back to port `1234`. Look closely! It is actually `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" // 必须换成自定义的 PATH,需要和分流的一致
}
}
}
```
```json
{
"port": 1234,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // Fill in your UUID
"level": 0,
"email": "love@example.com"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // Reminder: Delete this line if using Nginx/Caddy to reverse proxy WS
"path": "/websocket" // Must be changed to custom PATH, matching the shunting path
}
}
}
```
3. 后续处理回落至 `2345` 端口的流量,仔细看!它其实是 `vmess直连`:
3. Traffic falling back to port `2345`. Look closely! It is actually `vmess direct connection`:
```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" // 必须换成自定义的 PATH,需要和分流的一致
]
}
}
}
}
}
```
```json
{
"port": 2345,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // Fill in your UUID
"level": 0,
"email": "love@example.com"
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true,
"header": {
"type": "http",
"request": {
"path": [
"/vmesstcp" // Must be changed to custom PATH, matching the shunting path
]
}
}
}
}
}
```
4. 后续处理回落至 `3456` 端口的流量,再仔细看!它其实是是 `vmess+ws(+cdn)`。
4. Traffic falling back to port `3456`. Look closely again! It is actually `vmess+ws(+cdn)`.
::: warning 说明
你没看错,这就是 v2fly 曾经推荐的组合之一,并可完整支持 `CDN`。现已加入完美回落套餐哦!
:::
::: warning Explanation
You read that right. This is one of the combinations previously recommended by v2fly, and it fully supports `CDN`. It is now included in the perfect fallback package!
:::
```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" // 必须换成自定义的 PATH,需要和分流的一致
}
}
}
```
```json
{
"port": 3456,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // Fill in your UUID
"level": 0,
"email": "love@example.com"
}
]
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // Reminder: Delete this line if using Nginx/Caddy to reverse proxy WS
"path": "/vmessws" // Must be changed to custom PATH, matching the shunting path
}
}
}
```
5. 至此,我们就能够完整的画出模板的回落路线了:
5. **With this, we can draw the complete fallback route for the template:**
```mermaid
graph LR;
W443(外部 HTTP:443 请求) --> X443(Xray-inbound: 443) .- X1{入站判断}
X1 --> |协议 = VLESS 的流量| X2(Xray内部规则)
X2 --> XO(Xray Outbounds 出站)
W443(External HTTP:443 Request) --> X443(Xray-inbound: 443) .- X1{Inbound Judgment}
X1 --> |Protocol = VLESS Traffic| X2(Xray Internal Rules)
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)
X1 --> |path = /websocket Traffic| X1234(Xray-inbound:1234)
X1 --> |path = /vmesstcp Traffic| X2345(Xray-inbound:2345)
X1 --> |path = /vmessws Traffic| X3456(Xray-inbound:3456)
X1 --> |All Other Traffic| X1310(Xray-inbound:1310)
X1234 --> X2
X2345 --> X2
X3456 --> X2
X1310 --> |协议 = trojan 的流量| X2
X1310 --> |其他所有流量| N80(Nginx:80)
X1310 --> |Protocol = trojan Traffic| X2
X1310 --> |All Other Traffic| N80(Nginx:80)
N80:::nginxclass --> H(index.html)
@@ -382,12 +382,12 @@
classDef nginxclass fill:#FFFFDE
```
## 6. 结语
## 6. Conclusion
至此,`Xray` 的【回落】功能就介绍完了。希望本文能够对你理解 `Xray` 的强大有所帮助。
This concludes the introduction to `Xray`'s **[Fallback]** function. I hope this article helps you understand the power of `Xray`.
## 7. 附加题
## 7. Bonus Question
我再无耻的留一个附加题:本文详解的 [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/) 模板?是否有可以优化的地方?
I will shamelessly leave a bonus question: Is there any room for optimization in the [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/) template detailed in this article?
提示:HTTP 自动跳转 HTTPS
Hint: HTTP automatic redirection to HTTPS.
+83 -106
View File
@@ -1,77 +1,75 @@
---
title: SNI fallback
title: SNI Fallback
---
# Implementing camouflage and domain-based routing through SNI fallback function
# Camouflage and Routing by Domain via SNI Fallback
VLESS is a lightweight protocol that, like Trojan, does not perform complex encryption and obfuscation on traffic. Instead, it is encrypted through the TLS protocol and mixed in with other HTTPS traffic, making it difficult to detect. In order to better disguise itself and respond to active probing, the fallback function appeared with VLESS at the same time. This tutorial will demonstrate how to use the fallback function of VLESS inbound protocol in Xray, combined with Nginx or Caddy, to achieve domain name-based traffic routing while ensuring complete disguise.
VLESS is a lightweight protocol. Like Trojan, it does not perform complex encryption and obfuscation on traffic. Instead, it "hides in plain sight" by using the TLS protocol for encryption, blending in with other HTTPS traffic to pass in and out of the firewall. To better camouflage against active probing, the **Fallbacks** feature was introduced alongside VLESS. This tutorial will demonstrate how to use the fallback function of the VLESS inbound protocol in Xray, combined with Nginx or Caddy, to achieve routing based on domain names while ensuring complete camouflage.
## Application Scenarios
## Scenarios
Due to XTLS, Xray needs to listen on port 443, which means that if there is a website running on the server, it cannot run or needs to run on another port, which is obviously unreasonable. There are three solutions to this problem:
Due to XTLS, Xray needs to listen on port 443. If a website was previously running on the server, it would no longer be able to run, or would have to run on a different port, which is obviously unreasonable. There are three solutions to this problem:
- Xray monitors other commonly used ports (such as 22, 3389, 8443).
- **Xray listens on other common ports (e.g., 22, 3389, 8443)**
This plan is the simplest, but not perfect enough.
This solution is the simplest, but not perfect.
- Nginx or HAProxy listens on port 443, uses SNI for L4 load balancing, and achieves port multiplexing through reverse proxy.
- **Nginx or HAProxy listens on port 443 and uses SNI routing for L4 reverse proxying to achieve port reuse**
This plan is relatively complicated and requires some understanding of using Nginx or HAProxy. We will not explain it in too much detail here.
This solution is relatively complex and requires a certain understanding of Nginx or HAProxy, so it will not be explained in detail here.
- Xray listens on port 443, and uses Fallbacks feature to split website traffic based on SNI and fallbacks it to Nginx or Caddy.
- **Xray listens on port 443 and uses the Fallbacks function for SNI routing to fallback website traffic to Nginx or Caddy**
This plan has a moderate level of difficulty and is the scheme that this tutorial will demonstrate next.
This solution is of moderate difficulty and is the method this tutorial intends to demonstrate.
## Introduction to SNI
Server Name Indication (SNI) is an extension protocol of TLS. Friends who are familiar with reverse proxies know that the following configuration is required if you want to proxy traffic to the correct content through a domain name:
Server Name Indication (**SNI**) is an extension of the TLS protocol. Friends familiar with reverse proxies know that to proxy traffic to the correct content based on the domain name, the following configuration is needed:
```nginx
proxy_set_header Host hostname;
```
(Note: "hostname" should be replaced with the actual hostname.)
This line sets the HTTP Header named "Host" to a specific hostname. Why do this? Generally, one server corresponds to one IP but runs multiple websites. Visitors query the IP via the domain name to access the server. The question arises: how does the server determine which website the visitor wants to access? This requires "Name-based Virtual Hosting."
This sentence sets the HTTP Header named "Host" to a certain hostname. Why do we need to do this? Generally, one server corresponds to one IP address, but it runs multiple websites. Visitors access the server by querying the IP address via domain name to visit the website. Then the question arises, how to determine which website the visitor wants to access? This requires "name-based virtual hosting".
When a Web server receives a request, it looks at the requested Host header to serve the correct website. However, when the HTTP protocol is encrypted by the TLS protocol, this simple method becomes impossible. Because the TLS handshake happens before the server sees any HTTP headers, the server cannot use the information in the HTTP Host header to decide which certificate to present, nor can it determine the visitor's target.
When a Web server receives a request, it looks at the host header to direct the visitor to the correct website. However, this simple method cannot be used when HTTP protocol is encrypted by TLS protocol. This is because the TLS handshake occurs before the server sees any HTTP headers, so the server cannot use the information in the HTTP host header to determine which certificate to present or which destination the visitor wants to access.
The principle of SNI is simple: it solves this problem by having the client send the hostname as part of the TLS negotiation. Therefore, when using Nginx for reverse proxying HTTPS, you need to add `proxy_ssl_server_name on;` to the configuration. At this point, Nginx will send SNI information to the proxied server, solving the issue of virtual hosts failing under HTTPS. Additionally, when using SNI, the website can be accessed correctly even without specifying the Host header.
The principle of SNI is also very simple. It solves the problem by allowing the client to send the hostname as part of the TLS negotiation. Therefore, when using Nginx to reverse proxy the HTTPS protocol, you need to add `proxy_ssl_server_name on;` to the configuration. At this time, Nginx will send SNI information to the proxied server, solving the problem of virtual host failure under the HTTPS protocol. In addition, when using SNI, even if the host header is not specified, the website can be accessed correctly.
## The Logic
## Idea
![Xray Fallback Flow](./fallbacks-with-sni-resources/xray-fallbacks.svg)
![Xray Fallback Process](./fallbacks-with-sni-resources/xray-fallbacks.svg)
After receiving traffic on port 443, Xray decrypts the TLS. If the first packet length is < 18, the protocol version is invalid, or authentication fails, the traffic is forwarded to the address specified in `dest` by matching `name`, `path`, and `alpn`.
After receiving traffic from port 443, Xray will decrypt the TLS and forward the traffic that has a first packet length < 18, invalid protocol version, or failed authentication through matching name, path, and alpn to the address specified by dest.
## Adding DNS Records
## Add DNS Records
![DNS Records](./fallbacks-with-sni-resources/xray-dns-records.webp)
Please modify the domain name and IP according to the actual situation.
Please modify the domain name and IP according to your actual situation.
## Applying for TLS Certificate
## Apply for TLS Certificates
As it is necessary to route traffic to different domain name prefixes, but a wildcard certificate is only valid between two dots (for example, applying for `*.example.com`, the certificate cannot be used for `example.com` and `*.*.example.com`), it is necessary to apply for a [SAN](https://en.wikipedia.org/wiki/Subject_Alternative_Name) (Subject Alternative Name) wildcard certificate. According to the information on the Let's Encrypt official website, applying for a wildcard certificate requires DNS-01 verification. Here, we demonstrate how to apply for a free TLS certificate from Let's Encrypt using [acme.sh](https://acme.sh) for a domain with NS records hosted on Cloudflare. For the application method using other domain name hosting providers, please refer to [dnsapi · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki/dnsapi).
Since we need to route traffic for domains with different prefixes, and a wildcard certificate is limited to the scope between two dots (e.g., applying for `*.example.com` covers `example.com` but not `*.*.example.com`), we need to apply for a [SAN](https://en.wikipedia.org/wiki/Subject_Alternative_Name) wildcard certificate. According to Let's Encrypt's official site[^1], applying for a wildcard certificate requires DNS-01 validation. Here, we demonstrate using [acme.sh](https://acme.sh) to apply for a free Let's Encrypt TLS certificate for a domain with NS records managed by Cloudflare. For methods using other domain registrars, please read [dnsapi · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki/dnsapi).
First, you need to go to the [Cloudflare dashboard](https://dash.cloudflare.com/profile/api-tokens) to create an API token. The parameters are as follows:
First, go to the [Cloudflare Dashboard](https://dash.cloudflare.com/profile/api-tokens) to create an API Token. The parameters are as follows:
![API Token permission settings](./fallbacks-with-sni-resources/cf-api-token-permissions-for-acme.webp)
![API Token Permissions](./fallbacks-with-sni-resources/cf-api-token-permissions-for-acme.webp)
The permission part is crucial, while other parts are optional.
The permissions section is crucial; other sections can be arbitrary.
After creating, you will receive a mysterious string of characters. Please keep it safe in a secure and non-losing place, as it will not be displayed again. This string of characters is the `CF_Token` that will be used soon.
After creation, you will get a mysterious string. Please keep it safe in a secure place where it won't be lost, as it will not be shown again. This string is the `CF_Token` used below.
::: tip Note
The following operations need to be performed under the root user. Using sudo will result in errors.
The following operations need to be performed as the root user; using sudo may cause errors.
:::
```bash
curl https://get.acme.sh | sh # Install acme.sh
curl [https://get.acme.sh](https://get.acme.sh) | sh # Install acme.sh
export CF_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" # Set API Token variable
acme.sh --issue -d example.com -d *.example.com --dns dns_cf # Apply for a certificate using DNS-01 validation method
mkdir /etc/ssl/xray # Create a directory to store the certificate
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" # Install the certificate to the specified directory and set the effective command for automatic renewal
acme.sh --issue -d example.com -d *.example.com --dns dns_cf # Apply for certificate using DNS-01 validation
mkdir /etc/ssl/xray # Create directory for certificates
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" # Install certificate to the specified directory and set the command to run after auto-renewal
```
## Xray Configuration
@@ -164,79 +162,65 @@ acme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --
}
```
The above configuration is for Nginx. Here are some details that need to be noted.
The above configuration is for Nginx. Here are some details to note:
- About Proxy Protocol
- **About Proxy Protocol**
Proxy Protocol is a protocol developed by HaProxy to solve the problem of easily losing client information during proxying. It is often used for chain proxying and reverse proxying. The traditional approach to handling this problem is often complex and has many limitations, while Proxy Protocol simply attaches the original connection quadruple information packet to the transmitted data, solving this problem in a very simple way.
Proxy Protocol is a protocol developed by HAProxy designed to solve the problem of losing client information during proxying. It is often used in chained proxies and reverse proxies. Traditional handling methods are often complex and restrictive, while Proxy Protocol simply attaches the original connection 4-tuple information to the data packet during transmission, solving this problem.
Everything has its advantages and disadvantages, and the same goes for the Proxy Protocol.
Everything has its pros and cons, and Proxy Protocol is no exception.
- If sent, it must be received; and vice versa.
- The same port cannot be compatible with both connections carrying Proxy Protocol data and those without (e.g., Nginx virtual hosts (server) on the same port essentially violate this).[^2][^3]
- If there is sending, there must be receiving, and vice versa.
- The same port cannot be compatible with connections that have Proxy Protocol data and those that don't have data (e.g., different virtual hosts (servers) on the same port in Nginx, which is essentially the previous point). [^2][^3]
If you encounter exceptions, please consider whether the configuration meets the above conditions.
Please consider whether the configuration meets the above conditions when encountering exceptions.
Here, we use Proxy Protocol to let the fallback target acquire the client's real IP.
Here, we use the Proxy Protocol to allow the fallback target to obtain the real IP address of the client.
Additionally, when `"acceptProxyProtocol": true` exists in an Xray inbound configuration, ReadV will be disabled.
In addition, when the `"acceptProxyProtocol": true` exists in a certain inbound configuration of Xray, ReadV will be invalidated.
- **About HTTP/2**
- Regarding HTTP/2
First, the order of `inbounds.streamSettings.tlsSettings.alpn` matters. `h2` should be placed before `http/1.1` to prioritize HTTP/2 while ensuring compatibility; reversing them will cause HTTP/2 to negotiate as HTTP/1.1, making it an ineffective configuration.
First, `inbounds.streamSettings.tlsSettings.alpn` has an order. `h2` should be placed before `http/1.1` to prioritize the use of HTTP/2 while ensuring compatibility. Placing them in reverse order will cause HTTP/2 to be negotiated as HTTP/1.1, resulting in an invalid configuration.
In the above configuration, each fallback rule to Nginx is split into two. This is because `h2` is an HTTP/2 connection with mandatory TLS encryption, which is beneficial for data security over the internet but unnecessary within the server; whereas `h2c` is an unencrypted HTTP/2 connection, suitable for this environment. However, Nginx cannot listen for HTTP/1.1 and h2c on the same port simultaneously. To solve this, the `alpn` item (inside `fallbacks`, not `tlsSettings`) must be specified in the fallback to attempt to match the TLS ALPN negotiation result.
In the above configuration, each `fallback` configuration that falls back to Nginx needs to be divided into two. This is because h2 is an HTTP/2 connection that requires TLS encryption, which is beneficial for the security of data transmission over the Internet, but is unnecessary within the server. On the other hand, h2c is a non-encrypted HTTP/2 connection that is suitable for this environment. However, Nginx cannot listen for HTTP/1.1 and h2c on the same port at the same time. To solve this problem, the `alpn` option (in `fallbacks` rather than `tlsSettings`) needs to be specified in the fallback to try to match the TLS ALPN negotiation result.
It is recommended to use only two types of values for the `alpn` item as needed:[^4]
- Omitted
- `"h2"`
Suggestion: Use only two types of fillings for the `alpn` item as needed: [^4]
If you use **Caddy**, you don't need to be this complicated because it **can** listen to HTTP/1.1 and h2c on the same port simultaneously. The configuration changes are as follows:
- Omitted
- `"h2"`
If you use Caddy, you don't need to be so complicated, because **it can** listen to HTTP/1.1 and h2c on the same port at the same time. The configuration changes are as follows:
```json
{
"fallbacks": [
{
"name": "example.com",
"path": "/vmessws",
"dest": 5000,
"xver": 1
},
{
"dest": 5001,
"xver": 1
},
{
"name": "blog.example.com",
"dest": 5002,
"xver": 1
}
]
}
```
(Note: This is a JSON code block. It describes fallback configurations for a service.)
```json
{
"fallbacks": [
{
"name": "example.com",
"path": "/vmessws",
"dest": 5000,
"xver": 1
},
{
"dest": 5001,
"xver": 1
},
{
"name": "blog.example.com",
"dest": 5002,
"xver": 1
}
]
}
```
## Nginx Configuration
Nginx will be installed through official sources.
This is a set of Bash commands to install Nginx on Ubuntu.
The first command installs the necessary packages for the installation process.
The second command adds the Nginx repository to the list of sources that Ubuntu uses to find software packages.
The third command downloads the Nginx signing key and adds it to the system's keyring, which verifies the authenticity of the package.
The fourth command updates the package list with the newly added Nginx repository.
Nginx will be installed via the official repository.
```bash
sudo apt install curl gnupg2 ca-certificates lsb-release
echo "deb [arch=amd64] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
echo "deb [arch=amd64] [http://nginx.org/packages/ubuntu](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 -
curl -fsSL [https://nginx.org/keys/nginx_signing.key](https://nginx.org/keys/nginx_signing.key) | sudo apt-key add -
sudo apt update
sudo apt install nginx
```
@@ -275,37 +259,30 @@ server {
## Caddy Configuration
Please refer to [Install — Caddy Documentation](https://caddyserver.com/docs/install) for installing Caddy.
To install Caddy, please refer to [Install — Caddy Documentation](https://caddyserver.com/docs/install).
To enable Caddy to obtain the real IP address of visitors, it is necessary to compile Caddy with the Proxy Protocol module. It is recommended to compile it directly on the Caddy website.
To enable Caddy to obtain the visitor's real IP, you need to compile Caddy with the Proxy Protocol module. It is recommended to compile online directly on the Caddy website.
```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 curl -o /usr/bin/caddy "[https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458](https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458)"
sudo chmod +x /usr/bin/caddy
```
This is a bash script that downloads the Caddy web server and sets the necessary permissions to run it on a Linux system.
Just replace it directly.
::: tip
It is recommended to install Caddy through the official website documentation first, and then replace the binary file. This way, there is no need to manually set the process management.
It is recommended to install Caddy via the official documentation first, and then replace the binary file. This way, you don't need to manually configure the daemon process.
:::
Edit `/etc/caddy/Caddyfile`:
This is a Caddyfile, which is a configuration file used by the Caddy web server.
In this specific configuration, there are two servers defined: one listening on `127.0.0.1:5001` and another on `127.0.0.1:5002`. Both servers have a `listener_wrapper` defined for `proxy_protocol`, which is a protocol used for passing client connection information through a proxy or load balancer. Additionally, both servers have the `allow_h2c` option enabled, which allows clients to connect using HTTP/2 cleartext (h2c) protocol.
```Caddyfile
{
servers 127.0.0.1:5001 {
listener_wrappers {
proxy_protocol
}
protocol {
protocol {
allow_h2c
}
}
@@ -313,7 +290,7 @@ In this specific configuration, there are two servers defined: one listening on
listener_wrappers {
proxy_protocol
}
protocol {
protocol {
allow_h2c
}
}
@@ -338,17 +315,17 @@ http://blog.example.com:5002 {
}
```
## Reference
## References
1. [Server Name Indication - Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Server_Name_Indication)
1. [Server Name Indication - Wikipedia](https://en.wikipedia.org/wiki/Server_Name_Indication)
2. [Home · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki)
3. [HTTP/2 - Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/HTTP/2)
3. [HTTP/2 - Wikipedia](https://en.wikipedia.org/wiki/HTTP/2)
## Quotation
## Citations
<!-- prettier-ignore-start -->
[^1]: [Frequently Asked Questions - Let's Encrypt - Free SSL/TLS Certificates](https://letsencrypt.org/docs/faq/)
[^1]: [FAQ - Let's Encrypt](https://letsencrypt.org/docs/faq/)
[^2]: [Proxy Protocol - HAProxy Technologies](https://www.haproxy.com/blog/haproxy/proxy-protocol/)
[^3]: [Introduction to Proxy Protocol and Nginx Configuration - Jianshu](https://www.jianshu.com/p/cc8d592582c9)
[^3]: [Proxy protocol introduction and nginx configuration (Chinese)](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)
<!-- prettier-ignore-end -->
+9 -7
View File
@@ -1,13 +1,15 @@
# Beginner's Tips
# Beginner Skills
**This chapter is an introductory level guide on using Xray, mainly sharing the principles of some commonly used functional modules in Xray.**
**This section shares beginner-level insights on using Xray, focusing primarily on explaining the principles behind some of Xray's commonly used functional modules.**
[Analysis of Fallbacks Function](./fallbacks-lv1.md)
[Analysis of the Fallbacks Feature](./fallbacks-lv1.md)
[Analysis of Routing Function (Part 1)](./routing-lv1-part1.md)
[Analysis of the Routing Feature (Part 1)](./routing-lv1-part1.md)
[Analysis of Routing Function (Part 2)](./routing-lv1-part2.md)
[Analysis of the Routing Feature (Part 2)](./routing-lv1-part2.md)
[Analysis of Xray's Working Mode](./work.md)
[Analysis of Xray's Working Modes](./work.md)
[Fallbacks with SNI for Disguising and Domain-based Routing](./fallbacks-with-sni.md)
[Camouflage and Routing by Domain via SNI Fallback](./fallbacks-with-sni.md)
[Accurate Traffic Splitting (Domestic/Foreign) via DNS Module](./routing-with-dns.md)
+113 -114
View File
@@ -1,34 +1,34 @@
# 路由 (routing) 功能简析(上)
# A Brief Analysis of Routing Functionality (Part 1)
如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。
If Xray's [Power] is mainly reflected in its extreme speed and broad compatibility, then Xray's [Flexibility] should be mainly attributed to its ingenious [Routing] feature. This article will briefly explain the logic and usage of this function.
## 1. 初识【路由】三兄弟
## 1. Meeting the "Routing" Trio
要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. **入站**;2. **路由**;3. **出站**。
To understand routing, one must understand that the complete routing function requires three "brothers" working together to complete: 1. **Inbound**; 2. **Routing**; 3. **Outbound**.
![路由三兄弟](./routing-lv1-img01-trio.jpg)
![The Routing Trio](./routing-lv1-img01-trio.jpg)
三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。
The three brothers took the Oath of the Peach Garden: not asking to be born on the same year, month, and day, but asking to die on the same year, month, and day.
所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。
So bear in mind: An error in any single element may cause the routing function to fail.
因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。
Because the flexibility of routing is very high, just reading the technical documentation can easily make you dizzy. Therefore, this article will use a few specific examples to explain it layer by layer.
::: warning 啰嗦君
路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。
::: warning Verbose Note
The routing function is indeed overly flexible, so the examples in this article are meant to explain the corresponding concepts. Please adjust them according to your own needs in actual use.
:::
## 2. 基本功: “兄弟一条心”
## 2. Basic Skills: "Brothers United"
下图的示例,就是在客户端的 `Xray` 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。
The example in the chart below shows the client's `Xray` **Inbound** receiving APP data, the **Routing** forwarding it 100% to the **Outbound**, and the data flowing from the Outbound to the VPS.
```mermaid
graph LR;
S(APP数据) .-> I[入站]
S(APP Data) .-> I[Inbound]
subgraph Xray
I --> R[路由] --> O[出站]
I --> R[Routing] --> O[Outbound]
end
O .-> V(VPS)
@@ -41,15 +41,15 @@
```
下面我们来逐个分析:
Let's analyze them one by one:
### 2.1 入站
### 2.1 Inbound
::: tip
**入站:** 就是流量如何流入 `Xray`
**Inbound:** How traffic flows into `Xray`.
:::
下面的入站配置示例,用大白话说就是:数据按照 `socks` 协议,通过 `10808` 端口,从本机 `127.0.0.1` 流入`Xray`。同时,`Xray` 将这个入站用 `[tag]` 命名为 `inbound-10808`。
The following inbound configuration example, in plain English, means: Data flows into `Xray` from the local machine `127.0.0.1` via port `10808` using the `socks` protocol. At the same time, `Xray` names this inbound using the `[tag]` `inbound-10808`.
```json
{
@@ -67,13 +67,13 @@
}
```
**2.2 出站**
**2.2 Outbound**
::: tip
**出站:** 就是流量如何流出 `Xray`
**Outbound:** How traffic flows out of `Xray`.
:::
下面的出站配置示例,用大白话说就是:数据按照 `VLESS` 协议,以 `tcp + xtls` 的方式、及其他相关设置,把流量发送给对应的 VPS。同时,`Xray` 将这个出站用 `[tag]` 命名为 `proxy-out-vless`:
The following outbound configuration example, in plain English, means: Data is sent to the corresponding VPS using the `VLESS` protocol, via `tcp + xtls`, and other related settings. At the same time, `Xray` names this outbound using the `[tag]` `proxy-out-vless`:
```json
{
@@ -111,13 +111,13 @@
}
```
### 2.3 路由
### 2.3 Routing
::: tip
**路由:** 就是把【入站】和【出站】之间的通道,用某种【条件】串联起来
**Routing:** Connecting the path between [Inbound] and [Outbound] using certain [Conditions].
:::
下面的路由配置示例,用大白话说就是:把所有通过 `[tag]="inbound-10808"` 入站流入 `Xray` 的流量,`100%` 全部流转导入 `[tag]="proxy-out-vless"` 的出站,没有任何分流或其他操作。
The following routing configuration example, in plain English, means: 100% of the traffic flowing into `Xray` through `[tag]="inbound-10808"` is forwarded to the outbound with `[tag]="proxy-out-vless"`, without any splitting or other operations.
```json
{
@@ -133,46 +133,46 @@
}
```
至此,我们最开始设计的极简规则【客户端的 `Xray` 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS】已经完成。
At this point, our initially designed minimalist rule [Client `Xray` Inbound receives APP data, Routing forwards 100% to Outbound, and flows from Outbound to VPS] is complete.
### 2.4 路由配置项解析之一:流量筛选的依据
### 2.4 Analysis of Routing Configuration Items Part 1: Basis for Traffic Filtering
注意观察路由配置,我们可以看到几个新名词:
Observing the routing configuration carefully, we can see several new terms:
1. "domainStrategy": "AsIs"
2. “rules”
3. "inboundTag": ["inbound-10808"]
4. "outboundTag": "proxy-out-vless"
其中 `domainStrategy` 我们暂且按下不表,先简单说明后面几个:
We will put aside `domainStrategy` for now and briefly explain the latter ones:
| 配置名称 | 配置值 | 配置说明 |
| :-------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------- |
| `“rules”` | &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | 它的内层就是【路由规则】的明细设置 |
| `"inboundTag"` | `["inbound-10808"]` | 筛选流量的 **【依据】** 是【入站 Tag】,具体 **【条件】** 现在只有一个:【入站来源是 `inbound-10808`】 |
| `"outboundTag"` | `"proxy-out-vless"` | 当上面的筛选条件成立时(即入站`[tag]="inbound-10808"`时 ),`Xray` 会将流量导入 `[tag]="proxy-out-vless"` 的出站 |
| Config Name | Config Value | Config Explanation |
| :---------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `“rules”` | | Its inner layer contains the detailed settings of [Routing Rules]. |
| `"inboundTag"` | `["inbound-10808"]` | The **[Basis]** for filtering traffic is the [Inbound Tag]. The specific **[Condition]** right now is only one: [Inbound source is `inbound-10808`]. |
| `"outboundTag"` | `"proxy-out-vless"` | When the above filtering condition is met (i.e., when inbound `[tag]="inbound-10808"`), `Xray` will import the traffic into the outbound with `[tag]="proxy-out-vless"`. |
本例中,我们只有一个入站,它的`"inboundTag" = "inbound-10808"` 。我们也只有一个出站,它的 `[tag]="proxy-out-vless"`。所以根据上面这个路由规则,从唯一入站端口 `10808` 流入`Xray`的流量,`100%` 符合筛选条件、会被路由模块选中,然后转发给唯一的出站。
In this example, we have only one inbound, and its `"inboundTag" = "inbound-10808"`. We also have only one outbound, with `[tag]="proxy-out-vless"`. Therefore, according to this routing rule, traffic flowing into `Xray` from the sole inbound port `10808` matches the filtering condition `100%`, is selected by the routing module, and is then forwarded to the sole outbound.
至此,**入站**、**路由**、**出站** 三兄弟就已经可以携手工作了。当然,现在这个 100%转发的工作并没有什么特别的意义。那么接下来,我们就看看这种分工合作的机制可以带来什么好处。
Thus, the trio of **Inbound**, **Routing**, and **Outbound** can now work hand in hand. Of course, this 100% forwarding task doesn't have any special significance yet. Next, let's see what benefits this cooperative mechanism can bring.
## 3. 小试牛刀: “三分天下” 之 “域名分流”
## 3. First Try: "Three Kingdoms" of "Domain Routing"
> `[geosite.dat]`
```mermaid
graph LR;
S(APP数据) .-> I[入站]
S(APP Data) .-> I[Inbound]
subgraph Xray
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
R[路由] -- "geosite:cn" --> O2[direct]
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
I --> R[Routing] -- "geosite:category-ads-all" --> O1[block]
R[Routing] -- "geosite:cn" --> O2[direct]
R[Routing] -- "geosite:geolocation-!cn" --> O3[proxy]
end
O2 .-> D(国内服务器)
O2 .-> D(Domestic Server)
O3 .-> V(VPS)
O1:::redclass
@@ -186,23 +186,23 @@
```
这个配置逻辑,其实就是最简单、最常用的(《小小白白话文》中也在用的)路由配置三件套:
This configuration logic is actually the simplest and most commonly used routing configuration set (also used in "Little White's Plain English Guide"):
1. 广告流量屏蔽 `[block]`
2. 国内流量直连 `[direct]`
3. 国外流量转发 VPS `[proxy]`
1. Block ad traffic `[block]`
2. Direct connection for domestic traffic `[direct]`
3. Forward foreign traffic to VPS `[proxy]`
::: warning 注意
小小白白话文中的直连配置是包括【国内域名】、【国内 IP】、【本机内部 IP】的。这里先讲解【国内域名】。
::: warning Note
The direct connection configuration in "Little White's Plain English Guide" includes [Domestic Domains], [Domestic IPs], and [Local Internal IPs]. Here we explain [Domestic Domains] first.
:::
### 3.1 入站
### 3.1 Inbound
保持上例的 `inbound-10808` 不变。
Keep `inbound-10808` from the previous example unchanged.
### 3.2 出站
### 3.2 Outbound
在上例的基础上,我们已经有了 `[proxy]` 的出站 `"proxy-out-vless"`,所以它保持不变。显而易见,我们需要加入两个新的出站方式:`[block]` 和 `[direct]`,如下:
Based on the previous example, we already have the `[proxy]` outbound `"proxy-out-vless"`, so it remains unchanged. Obviously, we need to add two new outbound methods: `[block]` and `[direct]`, as follows:
```json
{
@@ -223,15 +223,15 @@
}
```
上面的配置用大白话翻译如下:
The above configuration translated into plain English:
1. 上例中的 `[proxy-out-vless]` 出站配置保持不变
2. 加入 **`blackhole` 黑洞协议**,通过这个协议出站的流量,其实都被发送到了 `Xray` 内部的黑洞里,再也无法逃脱,于是效果就是屏蔽 `[block]`
3. 加入 **`freedom` 自由协议**,通过这个协议出站的流量,是自由的离开`Xray`去寻找原定的服务器,就像从没有来过,于是效果就是直连 `[direct]` (我这里起名叫做 `[direct-out]` 是为了强调它是一个出站)
1. The `[proxy-out-vless]` outbound configuration from the previous example remains unchanged.
2. Add **`blackhole` protocol**. Traffic exiting through this protocol is actually sent into a black hole inside `Xray` and can never escape, thus achieving the effect of blocking `[block]`.
3. Add **`freedom` protocol**. Traffic exiting through this protocol leaves `Xray` freely to find the intended server as if it had never been here, thus achieving the effect of direct connection `[direct]` (I named it `[direct-out]` here to emphasize it is an outbound).
### 3.3 路由
### 3.3 Routing
接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!
Now is the moment to witness the miracle; we can use the [Routing] configuration to connect these!
```json
{
@@ -255,87 +255,86 @@
}
```
为了理解这个配置文件,我们要稍微解释一下这里出现的几个新配置项:
To understand this configuration file, we need to slightly explain the new configuration items appearing here:
- `"domain": ["geosite:category-ads-all"]`
- `"domain": ["geosite:cn"]`
- `"domain": ["geosite:geolocation-!cn"]`
### 3.4 简析域名文件: `geosite.dat`
### 3.4 Brief Analysis of Domain File: `geosite.dat`
其实,聪明的你大概可以通过这些配置项的名称猜出来个大概:
Actually, the clever you can probably guess the gist from the names of these configuration items:
- `"domain"`:就是这次筛选流量的 **【依据】** 是 **【域名】** (而不再是入站 tag)
- `"geosite"`:就是 `Xray` 会去 `geosite.dat` 文件中寻找 **【符合条件的域名】**
- `"category-ads-all"`:就是该文件中的 **【所有广告类域名】**
- `"cn"`:就是该文件中的 **【中国域名】**
- `"geolocation-!cn"`:就是该文件中的 **【非中国域名】**
- `"domain"`: This means the **[Basis]** for filtering traffic this time is **[Domain Name]** (no longer inbound tag).
- `"geosite"`: This means `Xray` will look for **[Domains matching the condition]** in the `geosite.dat` file.
- `"category-ads-all"`: This means **[All advertising domains]** in that file.
- `"cn"`: This means **[Chinese domains]** in that file.
- `"geolocation-!cn"`: This means **[Non-Chinese domains]** in that file.
结合这些说明,3.3 中的配置用大白话翻译就是:
Combining these explanations, the configuration in 3.3 translates to plain English as:
1. APP 试图访问国外域名 `"domain": "geolocation-!cn"` 的流量,通过 `[proxy-out-vless]` 出站,转发至 VPS
2. APP 试图访问国外域名广告域名 `"domain": "geosite:category-ads-all"` 的流量,通过 `[block]` 出站,转发至黑洞进行屏蔽
3. APP 试图访问国内域名 `"domain": "geosite:cn"` 的流量,通过 `[direct-out]` 出站,自由离开完成直连
1. Traffic where the APP attempts to access foreign domains `"domain": "geolocation-!cn"` goes through `[proxy-out-vless]` outbound and is forwarded to the VPS.
2. Traffic where the APP attempts to access foreign advertising domains `"domain": "geosite:category-ads-all"` goes through `[block]` outbound and is forwarded to the black hole for blocking.
3. Traffic where the APP attempts to access domestic domains `"domain": "geosite:cn"` goes through `[direct-out]` outbound and leaves freely to complete a direct connection.
这时,才让【路由功能】的好处稍微得到了一些展现。
At this point, the benefits of the [Routing Function] are finally somewhat revealed.
### 3.5 所以 `geosite.dat` 到底是什么?不是有个 `GFWList` 吗?
### 3.5 So what exactly is `geosite.dat`? Wasn't there a `GFWList`?
你想,这世界上的域名何止千万,如果我们每写一个基于【域名】匹配的路由规则,都要自己收集、手动输入域名,那效率将会何其低下!
Think about it, there are tens of millions of domains in the world. If we had to collect and manually input domains every time we wrote a routing rule based on [Domain] matching, how inefficient that would be!
而如果所有的域名都只有一个种类,`[direct], [proxy], [block]` 只能三选其一,那又是多么的不方便!
And if all domains were just one category, and we could only choose one out of `[direct], [proxy], [block]`, how inconvenient that would be!
就如关羽需要他的青龙偃月刀,`geosite.dat` 文件便作为【路由功能】驱使的神兵利器横空出世了,它致力于为用户提供成熟完善的【域名分类表】。让用户可以简单的通过 `geosite:xxx` 这种格式方便的调用任何子类,定制符合自身需求的路由规则。
Just as Guan Yu needed his Green Dragon Crescent Blade, the `geosite.dat` file was born as a divine weapon driven by the [Routing Function]. It is dedicated to providing users with a mature and complete [Domain Classification Table]. It allows users to easily call any subclass via the `geosite:xxx` format to customize routing rules that meet their own needs.
这种模块化结构提供的灵活性,其实远超传统的一揽子防火墙域名列表 [`GFWList`](https://github.com/gfwlist/gfwlist)。为什么这么说呢?比如,你可以指定苹果的域名 `geosite:apple` 和 icloud 相关域名 `geosite:icloud` 通过代理 `[proxy]`,但是苹果的软件域名 `geosite:apple-update` 保持直连 `[direct]` 来保持最大下载速度。
The flexibility provided by this modular structure actually far exceeds the traditional blanket firewall domain list [`GFWList`](https://github.com/gfwlist/gfwlist). Why do I say that? For example, you can specify Apple's domains `geosite:apple` and iCloud related domains `geosite:icloud` to go through the proxy `[proxy]`, but keep Apple's software update domains `geosite:apple-update` on direct connection `[direct]` to maintain maximum download speed.
::: warning
**注意:** 现在,`geosite.dat` 文件其实有多种选择:
**Note:** Nowadays, there are actually multiple choices for the `geosite.dat` file:
最初,从 `Victoria Raymond` 主力维护 `Project V` 项目时期,便提供了最初的配套项目:[`domain-list-community`](https://github.com/v2ray/domain-list-community),用来收集、沉淀、分类各种常用的域名类型;
Initially, during the time when `Victoria Raymond` was the main maintainer of the `Project V` project, the original companion project was provided: [`domain-list-community`](https://github.com/v2ray/domain-list-community), used to collect, precipitate, and classify various commonly used domain types;
之后,随着 V 姐突然消失导致 `Project V` 的原项目开发陷入停滞,`v2fly` 社区维护并持续更新了社区版本的 [`domain-list-community`](https://github.com/v2fly/domain-list-community);
Later, as V disappeared and the development of the original `Project V` stalled, the `v2fly` community maintained and continued to update the community version of [`domain-list-community`](https://github.com/v2fly/domain-list-community);
同时,Loyalsoldier 维护了其个人修改增强的路由规则文件 [v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat),提供了诸多不同的选择和分类逻辑;
Meanwhile, Loyalsoldier maintains his personally modified and enhanced routing rule file [v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat), offering many different choices and classification logic;
另外,`Project X` 也计划于未来定制维护更适合 `Xray` 使用的路由规则文件 [Xray-rules-dat](https://github.com/XTLS/Xray-rules-dat)。~~(你们看,文件夹都建好了,所以快了快了)~~
In addition, `Project X` also plans to customize and maintain a routing rule file better suited for `Xray` in the future: [Xray-rules-dat](https://github.com/XTLS/Xray-rules-dat). ~~(Look, the folder is already created, so it's coming soon, coming soon)~~
甚至,你还可以定制自己的 `geosite` 文件,外挂给 `Xray` 使用,但是这个就跑题了,本文不展开。
如果你发现有些你遇到的域名没有被合理分类,请向上面的项目们提出 `issue` 甚至提交 `Pull Request` 吧!社区列表社区维护,人人为我我为人人!
You can even customize your own `geosite` file and load it externally for `Xray` to use, but that's off-topic and won't be expanded upon in this article.
If you find that some domains you encounter are not properly classified, please raise an `issue` or even submit a `Pull Request` to the projects above! Community lists are maintained by the community; one for all, all for one!
:::
### 3.6 军师锦囊藏奇兵:一条隐藏的路由规则
### 3.6 The Strategist's Hidden Card: A Hidden Routing Rule
事实上,当你认真思考上面的规则,不难发现一个问题,我们的所有规则都只规定了【当入站流量 **符合某种条件时** 应该被转发给哪个出站】,那么,如果 `geosite.dat` 文件不全面,我们的入站流量【**不符合任何条件时**】,`Xray` 会怎么处理呢?
In fact, if you think carefully about the rules above, it's not hard to spot a problem. All our rules only stipulate [which outbound to forward to **when the inbound traffic meets certain conditions**]. So, if the `geosite.dat` file is not comprehensive, how will `Xray` handle our inbound traffic **when it does not meet any conditions**?
::: warning 注意
如果你认为【不符合条件当然就无法连接啦!】的话,你可要重新思考一下哦。因为只有指定了 `[block]` 规则,才会被导入到 `blackhole` 黑洞协议从而阻断连接
::: warning Note
If you think "If it doesn't meet conditions, of course it can't connect!", you need to rethink. Because only when a `[block]` rule is specified will it be imported into the `blackhole` protocol to block the connection.
:::
事实上,`Xray` 为了避免路由规则不完全导致的规则混乱,已经贴心的提供了一条隐藏的路由规则:【**当入站流量不符合任何条件时,转发给第一个出站** 】
In fact, to avoid rule chaos caused by incomplete routing rules, `Xray` has thoughtfully provided a hidden routing rule: [**When inbound traffic does not meet any conditions, forward it to the first outbound**].
这样,就不会有任何流量被漏掉了。所以,你一定要把你最信赖的心腹大将放在【第一条出站】,让它为你守城护池。
This way, no traffic will be left out. Therefore, you must place your most trusted "general" at the [First Outbound] position to guard your city.
### 3.7 再看“三分天下”的大地图
### 3.7 Looking at the "Three Kingdoms" Big Map Again
因为我们在前面的示例中把 `[proxy-out-vless]` 放在了出站的第一位,所以隐藏规则生效时,流量会通过 `VLESS` 协议被转发至远端的 VPS。因此,`Xray` 此时的完整工作逻辑如下:
Because we placed `[proxy-out-vless]` in the first position of the outbounds in the previous example, when the hidden rule takes effect, traffic will be forwarded to the remote VPS via the `VLESS` protocol. Therefore, `Xray`'s complete working logic at this time is as follows:
```mermaid
graph LR;
S(APP数据) .-> I[入站]
S(APP Data) .-> I[Inbound]
subgraph Xray
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
R[路由] -- "geosite:cn" --> O2[direct]
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
R[路由] -. "没有命中规则的流量" .-> O4[第一条出站]
I --> R[Routing] -- "geosite:category-ads-all" --> O1[block]
R[Routing] -- "geosite:cn" --> O2[direct]
R[Routing] -- "geosite:geolocation-!cn" --> O3[proxy]
R[Routing] -. "Traffic hitting no rules" .-> O4[First Outbound]
end
O2 .-> D(国内服务器)
O2 .-> D(Domestic Server)
O3 .-> V(VPS)
O4 .-> V(VPS)
@@ -350,15 +349,15 @@
```
事实上,这就是传统所谓的 **【默认科学上网、国内网站白名单直连】** 的配置。
In fact, this is the traditional configuration known as **[Default Proxy (Science Internet), Domestic Website Whitelist Direct]**.
## 4. “三分天下” 之 “蜀魏争雄”
## 4. "Three Kingdoms" - "Shu vs Wei": Changing Priorities
现在,你已经知道了隐藏的默认路由规则:【**当入站流量不符合任何条件时,转发给第一个出站** 】。这时候,你应该能看出来,究竟是【科学上网】为王,还是【直连】称霸,全看你的第一条出站是什么!
Now, you already know the hidden default routing rule: [**When inbound traffic does not meet any conditions, forward to the first outbound**]. At this point, you should be able to see that whether [Proxy/Science Internet] rules supreme or [Direct Connection] dominates depends entirely on what your first outbound is!
上一步我们已经配置出了 **【默认科学上网、国内网站白名单直连】** 的规则。那么现在只要 **【把直连规则放在第一位】**,就立即变成了正好相反的 **【默认直连、国外网站白名单科学上网】** 规则。
In the previous step, we configured the **[Default Proxy, Domestic Whitelist Direct]** rule. Now, as long as we **[place the direct rule in the first position]**, it immediately changes to the exact opposite **[Default Direct, Foreign Website Whitelist Proxy]** rule.
是不是,非常地简单?
Isn't it very simple?
```json
{
@@ -379,22 +378,22 @@
}
```
此时,路由规则其实变成了:
At this time, the routing rules actually become:
```mermaid
graph LR;
S(APP数据) .-> I[入站]
S(APP Data) .-> I[Inbound]
subgraph Xray
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
R[路由] -- "geosite:cn" --> O2[direct]
R[路由] -. "没有命中规则的流量" .-> O4[第一条出站]
I --> R[Routing] -- "geosite:category-ads-all" --> O1[block]
R[Routing] -- "geosite:geolocation-!cn" --> O3[proxy]
R[Routing] -- "geosite:cn" --> O2[direct]
R[Routing] -. "Traffic hitting no rules" .-> O4[First Outbound]
end
O2 .-> D(国内服务器)
O2 .-> D(Domestic Server)
O3 .-> V(VPS)
O4 .-> D
@@ -408,12 +407,12 @@
```
这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。
This is the flexibility of the routing function; you can freely change its order to achieve different designs.
至此,我们已经解释完了 **【如何利用 `geosite.dat` 文件,通过路由规则,根据【域名】来分流网络流量】。**
At this point, we have finished explaining **[How to use the `geosite.dat` file to route network traffic based on [Domain Name] through routing rules].**
## 5. 攻城略池 - 多种路由匹配条件
## 5. Conquering Cities - Multiple Routing Match Conditions
请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。
Please ensure you have understood the content above, because this means you have understood the working logic of the [Routing] function. With this foundation, we can continue to analyze more detailed configuration methods and matching conditions of the [Routing] function.
等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 [《路由 (routing) 功能简析(下)》](./routing-lv1-part2.md) 吧!
Once you finish reading the subsequent content, you will be completely able to freely customize your own routing rules! What are you waiting for? Let's enter [《A Brief Analysis of Routing Functionality (Part 2)》](./routing-lv1-part2.md) together!
+143 -143
View File
@@ -1,71 +1,71 @@
# 路由 (routing) 功能简析(下)
# Brief Analysis of Routing Functions (Part 2)
欢迎继续学习 `Xray` 的【路由】功能!
Welcome back to the study of `Xray`'s **[Routing]** function!
在 [《路由 (routing) 功能简析(上)》](./routing-lv1-part1.md) 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 `geosite.dat` 文件做了简单的域名分流配置。
In [Brief Analysis of Routing Functions (Part 1)](./routing-lv1-part1.md), we gained a clear understanding of the working logic of the **[Routing]** function and set up simple domain-based shunting based on the `geosite.dat` file.
如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!
As mentioned earlier, domain-based shunting is just a small test of the **[Routing]** function's capabilities. Now, let's see what else, besides domains, can be used as a basis for shunting!
## 5. 攻城略池 - 多种路由匹配条件
## 5. Expanding Horizons - Multiple Routing Matching Conditions
> `[域名], [IP], [协议], etc.`
> `[domain], [IP], [protocol], etc.`
基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?
Shunting based on domains allows us to route network traffic in a basically reasonable way. Why do I say "basically reasonable"?
因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:
Because although "Dividing the world into three" (Block, Direct, Proxy) is the correct strategic direction, if you only use **[Domain]** to implement this strategy, it is actually full of loopholes. For example:
1. 我读了《小小白白话文》后,给 VPS 新申请了一个 `proxy.yourdomain.com` 的域名, 我希望它无论如何都代理,`geosite.dat` 里面有吗?
2. 如果我还有个 `direct.yourdomain.com` 的域名,我希望它无论如何都直连, `geosite.dat` 里面有吗?
3. 本机 `127.0.0.1` 的内部流量,是否正确直连了?(比如 `docker` 等)
4. 路由器、本地局域网 `192.168.*.*` 的流量,是否正确直连了?(比如路由器、群晖等)
5. 我的国内 DNS 查询(如 `223.5.5.5`)是否正确直连了?
6. 我的国外 DNS 查询(如 `1.1.1.1`)是否正确代理了?
7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
1. After reading the "Simple Guide for Beginners", I applied for a new domain `proxy.yourdomain.com` for my VPS. I want it to be proxied no matter what. Is it in `geosite.dat`?
2. If I have another domain `direct.yourdomain.com`, and I want it to be connected directly no matter what. Is it in `geosite.dat`?
3. Is the internal traffic of the local machine `127.0.0.1` (such as `docker`, etc.) correctly connected directly?
4. Is the traffic of the router and local LAN `192.168.*.*` correctly connected directly? (Such as routers, Synology NAS, etc.)
5. Are my domestic DNS queries (such as `223.5.5.5`) correctly connected directly?
6. Are my foreign DNS queries (such as `1.1.1.1`) correctly proxied?
7. Are other domestic websites that only have IP addresses and no domains (similar to domestic public DNS) correctly connected directly?
8. Are other foreign websites that only have IP addresses and no domains (similar to foreign public DNS) correctly proxied?
9. Although the source of BT download traffic is abroad, downloading via VPS may lead to a ban due to violation of usage terms. How can I force this to be direct?
10. ......
我之所以说只用【域名分流】会漏洞百出,是因为 `geosite.dat` 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:
The reason I say using only **[Domain Shunting]** is full of loopholes is that the `geosite.dat` file only contains a portion of commonly used domains. In other words, relying solely on it will result in:
- 无法匹配文件里没有的新域名
- 无法匹配基于 IP 地址的规则
- 无法匹配基于网络协议的规则
- Inability to match new domains not in the file.
- Inability to match rules based on IP addresses.
- Inability to match rules based on network protocols.
::: warning 啰嗦君
那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【**转发给第一个出站** 】。这其实就是说:
::: warning Mr. Wordy
Let's review: what happens when the situations above cannot be matched? That's right, the hidden routing rule will be triggered, which is **[Forward to the first outbound]**. This actually means:
- 当你的第一个出站是 `[direct-out]` 时:**需要直连的都正确了,但需要代理的则都错误**
- 当你的第一个出站是 `[proxy-out-vless]` 时:**需要代理的都正确了,但需要直连的则都错误**
:::
- When your first outbound is `[direct-out]`: **Everything needing direct connection is correct, but everything needing proxy is wrong.**
- When your first outbound is `[proxy-out-vless]`: **Everything needing proxy is correct, but everything needing direct connection is wrong.**
:::
所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?**当然存在!** 我们需要的只是【域名】之外更多的【**分流判断依据**】而已。
Therefore, we need a way to have our cake and eat it too. Does such a way exist? **Of course!** All we need are more **[Shunting Judgment Criteria]** beyond just **[Domain]**.
### 5.1 基于指定域名分流:`[domain], [full]` 等
### 5.1 Shunting Based on Specific Domains: `[domain], [full]`, etc
1. 如果需要匹配某个子域名,如 `a-name.yourdomain.com`,我们使用 `full: "a-name.yourdomain.com"`
2. 前面的 `问题1` 和 `问题2`,就可以通过给 `proxy.yourdomain.com` 指定 `[proxy-out-vless]` 出站,给 `direct.yourdomain.com` 指定 `[direct-out]` 出站来解决
3. 如果需要匹配 `yourdomain.com` 的所有子域名,我们使用 `domain: "yourdomain.com"` 实现
4. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
5. 另外,`[domain]` 还支持正则表达式等匹配方式。详情请参考 [《基础配置模块 - 路由》文档](../../config/routing.md)
1. If we need to match a specific subdomain, such as `a-name.yourdomain.com`, we use `full: "a-name.yourdomain.com"`.
2. The previous `Question 1` and `Question 2` can be solved by assigning the `[proxy-out-vless]` outbound to `proxy.yourdomain.com` and the `[direct-out]` outbound to `direct.yourdomain.com`.
3. If we need to match all subdomains of `yourdomain.com`, we use `domain: "yourdomain.com"` to implement it.
4. The above two can become two independent routing rules, achieving a configuration where some subdomains are direct and others are proxied.
5. Additionally, `[domain]` also supports matching methods like regular expressions. For details, please refer to the [[Basic Configuration Module - Routing] documentation](../../config/routing.md).
上述配置如下:
The configuration is as follows:
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 指定子域名直连
// Specify subdomain for direct connection
{
"domain": ["full:direct.yourdomain.com"],
"outboundTag": "direct-out"
},
// 指定子域名转发VPS
// Specify subdomain for forwarding to VPS
{
"domain": ["full:proxy.yourdomain.com"],
"outboundTag": "proxy-out-vless"
},
// 指定泛域名转发VPS
// Specify wildcard domain for forwarding to VPS
{
"domain": ["yourdomain.com"],
"outboundTag": "proxy-out-vless"
@@ -75,27 +75,27 @@
}
```
### 5.2 基于 IP 文件分流:`geoip.dat`
### 5.2 Shunting Based on IP Files: `geoip.dat`
除了使用 `geosite.dat` 核心自然也支持直接使用IP进行路由以满足各种需求。
Very similar to the `geosite.dat` rule file, we also have the `geoip.dat` rule file. It is dedicated to providing users with a mature and complete **[IP Classification Table]**. It allows users to simply call any subclass via the `geoip:xxx` format to customize routing rules that meet their needs.
1. 解决前面的 `[问题3], [问题4]`,我们使用 `geoip:private` 类别来指定 `[direct-out]`
2. 解决前面的 `[问题7]`,我们使用 `geoip:cn` 类别来指定 `[direct-out]`
3. 解决前面的 `[问题8]`,由于 `geoip` 中没有【非中国 IP】这个分类(因为这等于要收集全世界的 IP 段),所以我们用隐藏规则代替,也就是将 `[proxy-out-vless]` 放在第一个出站
1. To solve the previous `[Question 3]` and `[Question 4]`, we use the `geoip:private` category to specify `[direct-out]`.
2. To solve the previous `[Question 7]`, we use the `geoip:cn` category to specify `[direct-out]`.
3. To solve the previous `[Question 8]`, since `geoip` does not have a category for "Non-Chinese IPs" (because this would mean collecting IP ranges from the entire world), we use the hidden rule instead, which is placing `[proxy-out-vless]` as the first outbound.
上述配置如下:
The configuration is as follows:
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 本机内部地址、局域网地址直连
// Local internal addresses and LAN addresses direct connection
{
"ip": ["geoip:private"],
"outboundTag": "direct-out"
},
// 国内IP集直连
// Domestic IP set direct connection
{
"ip": ["geoip:cn"],
"outboundTag": "direct-out"
@@ -105,26 +105,26 @@
}
```
### 5.3 基于指定 IP 地址分流
### 5.3 Shunting Based on Specific IP Addresses
与 `geosite.dat` 规则文件十分类似的,我们还有 `geoip.dat` 这个规则文件,它是供【路由功能】驱使的**第二个神兵利器**,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 `geoip:xxx` 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。
In addition to using `geoip.dat`, the core naturally supports routing directly using IPs to meet various needs.
1. 解决前面的 `[问题5]`,我们使用 `ip: "223.5.5.5"` 来指定 `[direct-out]`
2. 解决前面的 `[问题6]`,我们使用 `ip: "1.1.1.1"` 来指定 `[proxy-out-vless]`
1. To solve the previous `[Question 5]`, we use `ip: "223.5.5.5"` to specify `[direct-out]`.
2. To solve the previous `[Question 6]`, we use `ip: "1.1.1.1"` to specify `[proxy-out-vless]`.
上述配置如下:
The configuration is as follows:
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 指定IP地址直连
// Specific IP address direct connection
{
"ip": ["223.5.5.5"],
"outboundTag": "direct-out"
},
// 指定IP地址转发VPS
// Specific IP address forwarding to VPS
{
"ip": ["1.1.1.1"],
"outboundTag": "proxy-out-vless"
@@ -134,12 +134,12 @@
}
```
### 5.4 基于协议类型分流:`[protocol]` 等
### 5.4 Shunting Based on Protocol Types: `[protocol]`, etc
1. 解决前面的 `[问题9]`,我们使用 `"protocol": ["bittorrent"]` 类别来指定 `[direct-out]`
1. To solve the previous `[Question 9]`, we use the `"protocol": ["bittorrent"]` category to specify `[direct-out]`.
::: tip
你需要打开入站代理中的 `sniffing` 才能使用此种方式分流。
You need to enable `sniffing` in the inbound proxy to use this method for shunting.
:::
```json
@@ -147,7 +147,7 @@
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 指定 BT 协议直连
// Specific BT protocol direct connection
{
"protocol": ["bittorrent"],
"outboundTag": "direct-out"
@@ -157,18 +157,18 @@
}
```
### 5.5 基于更多条件的分流
### 5.5 Shunting Based on More Conditions
到目前位置,我们仍然只讲了【路由功能】分流能力的冰山一角!因为它还支持很多其他的判断条件!我在此简单罗列如下:
Up to this point, we have only touched the tip of the iceberg of the **[Routing Function]**'s shunting capabilities! It supports many other judgment conditions! I will briefly list them below:
本文已经讲过的:
Covered in this article:
- `inboundTag`
- `domain`
- `ip`
- `protocol`
本文尚未讲到的:
Not yet covered in this article:
- `port`
- `sourcePort`
@@ -177,14 +177,14 @@
- `user`
- `attrs`
但这些内容实在是过多,全部展开就远远不是 `level-1` 的内容了,所以,需要这些复杂条件的朋友,请仔细阅读 [《基础配置模块 - 路由》文档](../../config/routing.md) 自学哦!有问题就去 TG 群里面问问吧!
However, expanding on all these would be too much content, far beyond the scope of `level-1`. Therefore, friends who need these complex conditions, please carefully read the [[Basic Configuration Module - Routing] documentation](../../config/routing.md) to learn on your own! If you have questions, ask in the Telegram group!
## 6. “霸业初定”:路由规则整体回顾
## 6. "The Empire is Set": A Comprehensive Review of Routing Rules
到现在为止,我们已经累积出了一套战略雄伟、战术精准的路由规则,为了避免混乱,现在就对它进行一次完整的整理和回顾。
So far, we have accumulated a set of routing rules with grand strategy and precise tactics. To avoid confusion, let's now organize and review them completely.
::: warning 注意
路由生效的顺序是:【从上往下,依次判断】,所以我一般推荐的规则顺序是:
::: warning Note
The order in which routing takes effect is: **[Top to bottom, judged sequentially]**. Therefore, the rule order I generally recommend is:
`[1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]`
:::
@@ -194,30 +194,30 @@
"routing": {
"domainStrategy": "AsIs",
"rules": [
// [1-block 广告流量屏蔽]
// 1.1 广告域名集屏蔽
// [1-block Ad traffic blocking]
// 1.1 Ad domain set blocking
{
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
// [2-direct 国内流量直连]
// 2.1 国内域名集、指定子域名直连
// [2-direct Domestic traffic direct connection]
// 2.1 Domestic domain set, specific subdomain direct connection
{
"domain": ["geosite:cn", "full:direct.yourdomain.com"],
"outboundTag": "direct-out"
},
// 2.2 本机内部地址+局域网、国内IP、指定IP直连
// 2.2 Local internal address + LAN, Domestic IP, Specific IP direct connection
{
"ip": ["geoip:private", "geoip:cn", "223.5.5.5"],
"outboundTag": "direct-out"
},
// 2.3 BT协议流量直连
// 2.3 BT protocol traffic direct connection
{
"protocol": ["bittorrent"],
"outboundTag": "direct-out"
},
// [3-proxy 国外流量转发VPS]
// 3.1 国外域名集、指定子域名、指定泛域名转发VPS
// [3-proxy Foreign traffic forwarding to VPS]
// 3.1 Foreign domain set, specific subdomain, specific wildcard domain forwarding to VPS
{
"domain": [
"geosite:geolocation-!cn",
@@ -226,45 +226,45 @@
],
"outboundTag": "proxy-out-vless"
},
// 3.2 指定IP转发VPS
// 3.2 Specific IP forwarding to VPS
{
"ip": ["1.1.1.1"],
"outboundTag": "proxy-out-vless"
}
// [4-default-routing 第一条出站]
// 没有匹配到任何规则的流量,默认使用第一条出站处理
// [4-default-routing First outbound]
// Traffic not matching any rules defaults to the first outbound handling
]
}
}
```
此时,路由规则其实变成了:
At this point, the routing rules have effectively become:
```mermaid
graph LR;
S(APP数据) .-> I[入站]
S(App Data) .-> I[Inbound]
subgraph Xray
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
I --> R[Routing] -- "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[Routing] -- "geosite:cn" --> O2[direct]
R[Routing] -- "direct.yourdomain.com" --> O2[direct]
R[Routing] -- "geoip:private" --> O2[direct]
R[Routing] -- "geoip:cn" --> O2[direct]
R[Routing] -- "ip:223.5.5.5" --> O2[direct]
R[Routing] -- "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[Routing] -- "geosite:geolocation-!cn" --> O3[proxy]
R[Routing] -- "proxy.yourdomain.com" --> O3[proxy]
R[Routing] -- "*.yourdomain.com" --> O3[proxy]
R[Routing] -- "ip:1.1.1.1" --> O3[proxy]
R[路由] -. "没有命中规则的流量" .-> O4[第一条出站]
R[Routing] -. "Traffic not hitting any rules" .-> O4[First Outbound]
end
O2 .-> D(国内服务器)
O2 .-> D(Domestic Server)
O3 .-> V(VPS)
O1:::redclass
@@ -277,20 +277,20 @@
```
至于第一条出站是 `[direct-out]` 还是 `[proxy-out-vless]`,这就全看你的需求了。
As for whether the first outbound is `[direct-out]` or `[proxy-out-vless]`, that depends entirely on your needs.
## 7. 路由配置常见错误
## 7. Common Routing Configuration Errors
请大家注意看,我上面每一条路由规则,都是一个独立的匹配依据,只有这样才能确保生效。而新人在自定义路由规则时常犯的一个错误就是:**在一条规则内同时匹配了多种不同的匹配依据,造成匹配无效。**
Please pay attention: every routing rule I listed above is an independent matching basis. This is the only way to ensure they take effect. A common mistake newcomers make when customizing routing rules is: **Matching multiple different matching criteria within a single rule, causing the match to fail.**
比如,他希望实现的配置是:
For example, the configuration they hope to achieve is:
1. 自己的 `direct.yourdomain.com` 直连
2. 国内 DNS 查询(如 `223.5.5.5`)直连
1. Their own `direct.yourdomain.com` connects directly.
2. Domestic DNS queries (such as `223.5.5.5`) connect directly.
### 7.1 错误示范
### 7.1 Incorrect Example
为了实现上面的目标,他写出了以下路由规则:
To achieve the above goals, they wrote the following routing rule:
```json
{
@@ -307,19 +307,19 @@
}
```
你能看出这里面的错误吗?乍一看,似乎是对的?
Can you spot the error here? At first glance, it seems correct?
::: warning 注意
**同一个规则之内,各个依据需要同时成立,才会匹配成功**,逻辑关系是 `和`,而不是 `或`。
::: warning Note
**Within the same rule, all criteria must be met simultaneously for the match to succeed.** The logical relationship is `AND`, not `OR`.
:::
换言之,这条规则的意思是:【当你访问的 `目标 = direct.yourdomain.com`, **并且** 同时还满足 `目标 = 223.5.5.5` 时,`Xray` 才会将流量转发给 `[direct-out]` 直连出站】
In other words, this rule means: **[Xray will only forward traffic to `[direct-out]` when the target = `direct.yourdomain.com` **AND** at the same time the target = `223.5.5.5`]**.
很显然,一个目标不可能同时等于两个不同的值,所以这不但是一个永远不可能实现的无效规则,更与原本的目标风马牛不相及。
Obviously, a target cannot equal two different values at the same time. So this is not only an invalid rule that can never be realized, but it also has nothing to do with the original goal.
### 7.2 正确示范
### 7.2 Correct Example
正确示范,自然就是将不同的匹配依据独立出来:
The correct example is naturally to separate the different matching criteria:
```json
{
@@ -339,78 +339,78 @@
}
```
其实,第 6 点已经是我整理过的规则了,原则就是【相同的匹配依据可以合并,不同的匹配依据保持独立】。
In fact, point 6 was already my organized rules. The principle is **[Identical matching criteria can be merged, different matching criteria must remain independent]**.
## 8. 明修栈道、暗渡陈仓
## 8. The Secret Passage
> `[domain]` 转化 `[ip]` 的密道:`domainStrategy`
> The secret path from `[domain]` to `[ip]`: `domainStrategy`
我们在 5.4 中提交了多种流量判断的【依据】,其中一种是域名 `[domain]`、一种是 `[IP]`。
In section 5.4, we presented various **[criteria]** for traffic judgment. One is domain `[domain]`, and another is `[IP]`.
如果你初步了解过 DNS 的运作过程,就会知道,我们对一个域名 `[domain]` 发起访问请求时,其实需要先向 `DNS` 发起请求来解析域名 `[domain]` 对应的 `[IP]`,在得到 `[IP]` 后再向它发起实际请求。
If you have a preliminary understanding of how DNS works, you know that when we initiate a request to a domain `[domain]`, we actually need to first initiate a request to `DNS` to resolve the `[IP]` corresponding to the domain `[domain]`, and then initiate the actual request to that `[IP]`.
所以,面对入站的一次域名请求,`Xray` 其实有两次机会去判断它的类型。那么,究竟是否要用这两次机会呢?这就是由 `domainStrategy` 这个配置来决定的。它有三个选项:
Therefore, facing an inbound domain request, `Xray` actually has two opportunities to judge its type. So, should we use these two opportunities? This is decided by the `domainStrategy` configuration. It has three options:
- `AsIs`
- `IPIfNonMatch`
- `IPOnDemand`
按么我们逐个来解释一下:
Let's explain them one by one:
### 8.1 域名策略: `"AsIs"`
### 8.1 Domain Strategy: `"AsIs"`
就是 "As Domain Is",也就是说 【域名什么样,就什么样,不多折腾】。
This means "As Domain Is", which implies **[Just let the domain be, don't fuss with it]**.
简单粗暴理解就是说【仅用 `[domain]` 来匹配】。
To understand it simply and crudely: **[Only use `[domain]` to match]**.
::: tip
`AsIs` 的实际意义为 【如原先所示,不加修改】,🍉 老师这里描述的不是很恰当。
The actual meaning of `AsIs` is "As shown in the original, without modification". Teacher Watermelon didn't describe it very precisely here.
:::
这个方式的处理都在 `Xray` 内部完成,没有与外界的数据往来,所以速度最快。它的兜底策略也很清晰:即前面所说的、无法匹配的域名自动转入第一条出站处理。所以,对于常规使用路由功能这最推荐的策略。
The processing of this method is completed within `Xray`, with no data exchange with the outside world, so it is the fastest. Its fallback strategy is also clear: that is, the unmatchable domains mentioned earlier are automatically transferred to the first outbound for processing. Therefore, this is the most recommended strategy for general routing usage.
### 8.2 域名策略: `"IPIfNonMatch"`
### 8.2 Domain Strategy: `"IPIfNonMatch"`
就是 "lookup IP if (there's) no matching rule",也就是说【如果其他所有规则都匹配不上,那就转化成 `IP` 去匹配 `IP` 规则】。
This means "lookup IP if (there's) no matching rule", which implies **[If no other rules match, then convert to `IP` to match `IP` rules]**.
简单粗暴理解就是说【先把访问目标和其他所有类型规则匹配,如果匹配不上,那就通过 `DNS` 查询转化成 `IP`,再从头和所有规则匹配一次】。
To understand it simply and crudely: **[First match the access target with all other types of rules. If there is no match, then convert it to `IP` via `DNS` query, and match it against all rules again from the beginning]**.
该策略下没有命中任何规则的这一部分域名,会需要再经历 `DNS` 查询过程、以及第二轮规则匹配的过程,其耗时会多于 `AsIs` 策略,所以并不是首选推荐的策略。
Under this strategy, domains that do not hit any rules need to go through the `DNS` query process and a second round of rule matching. It takes more time than the `AsIs` strategy, so it is not the preferred recommended strategy.
### 8.3 域名策略: `"IPOnDemand"`
### 8.3 Domain Strategy: `"IPOnDemand"`
这里其实说 `Demand IP` 更准确些,也就是说【当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配】。
It is actually more accurate to say `Demand IP` here, which implies **[When matching, if any IP-based rule is encountered, immediately resolve the domain to IP for matching]**.
简单粗暴理解就是说【只要路由规则中有 `IP` 类规则,那么所有基于域名 `[domain]` 的请求都要解析成 `[IP]` 然后去匹配 `[IP]` 类规则】。
To understand it simply and crudely: **[As long as there are `IP` type rules in the routing rules, then all requests based on domain `[domain]` must be resolved into `[IP]` and then matched against `[IP]` type rules]**.
它要对所有首次域名访问进行 `DNS` 解析,所以首次查询比较耗时。虽然由于 `Xray` 中 `DNS` 缓存机制的存在,后续对相同域名的访问速度会重回巅峰,但总体来说也不是首选推荐的策略。
It requires `DNS` resolution for all initial domain accesses, so the first query is relatively time-consuming. Although due to the existence of the `DNS` caching mechanism in `Xray`, subsequent access speeds to the same domain will return to peak performance, generally speaking, it is not the preferred recommended strategy either.
::: warning 啰嗦君
`domainStrategy` 仅对域名生效,不要搞混了哦~
::: warning Mr. Wordy
`domainStrategy` only takes effect for domains, don't get mixed up~
:::
## 9. 思考题
## 9. Thought Exercises
迄今为止,我们都是在【单入站】和【单出站】的基础上,讲解【路由】内部的各种配置逻辑。
So far, we have been explaining the various configuration logics within **[Routing]** based on **[Single Inbound]** and **[Single Outbound]**.
但是,如你所知,`Xray` 本身是支持多端口,多协议的。那么,如果我问你:
However, as you know, `Xray` itself supports multiple ports and multiple protocols. So, if I ask you:
1. 我希望 `VLESS` 协议将我日常的网页浏览和 APP 流量转发给美国的大流量服务器
2. 我希望 `trojan` 协议将我的所有 Netflix 流量转发给日本的服务器解锁各种二次元
3. 我希望 `shadowsocks` 协议将我所有的游戏流量转发给香港的服务器达到最低的延迟
4. 我希望有一个独立的端口,能够把 `telegram` 的流量全都转发给 VPS
5. 我希望有一个独立的端口,能够把 `bittorrent` 下载流量全都转发给欧洲大盘鸡
6. 我希望......
1. I want the `VLESS` protocol to forward my daily web browsing and App traffic to a high-traffic server in the US.
2. I want the `trojan` protocol to forward all my Netflix traffic to a server in Japan to unlock various anime content.
3. I want the `shadowsocks` protocol to forward all my gaming traffic to a server in Hong Kong to achieve the lowest latency.
4. I want an independent port to forward all `telegram` traffic to the VPS.
5. I want an independent port to forward all `bittorrent` download traffic to a "Big Disk Chicken" (Server with large storage) in Europe.
6. I want......
这些想法,是否能通过【路由】功能配置实现呢?
Can these ideas be realized through **[Routing]** configuration?
答案当然是 **【完全可以】** 啦! 但是这些对于 `level-1` 来说已经超纲了,就留给各位自由的探索吧!
The answer is, of course, **[Absolutely!]** But these are already beyond the scope of `level-1`, so I'll leave them for you to explore freely!
## 10. 结语
## 10. Conclusion
至此,`Xray` 的【路由】功能就介绍完了。希望本文能够对你理解 `Xray` 的灵活有所帮助。
This concludes the introduction to `Xray`'s **[Routing]** function. I hope this article helps you understand the flexibility of `Xray`.
## 11. 尾注
## 11. Endnotes
- 现在你可以重新阅读一遍 [路由](../../config/routing.md),看看是否有更加深刻的理解。
- Now you can read the [Routing](../../config/routing.md) documentation again to see if you have a deeper understanding.
- 🍉🍉🍉🍉🍉 :D
@@ -0,0 +1,286 @@
# Achieving Precise Domestic/Foreign Traffic Splitting via DNS
## Conventional Splitting Methods and Their Flaws
When you try to manually craft proxy rules, you inevitably ask yourself: Which traffic should go through the proxy, and which should go directly?
The answer is usually a Blacklist or Whitelist.
Over the past decade, the community has maintained massive rule lists, giving birth to many excellent projects:
- <https://github.com/gfwlist/gfwlist>
- <https://github.com/v2fly/domain-list-community>
- <https://github.com/Loyalsoldier/v2ray-rules-dat>
However, it is impossible for them to cover every website; they suffer from lag and cannot be 100% trusted.
Here are a few examples:
- `geosite:cn` is a hodgepodge. Anything remotely related to China gets thrown in. Even if a domain is blocked by the GFW, it might not be removed in time.
If you rely solely on whether the target domain is in this list to decide on direct connection, it won't work perfectly. For example, `ai.ytimg.com` and `login.corp.google.com` remain in the list despite being blocked.
- The [README](https://github.com/Loyalsoldier/v2ray-rules-dat) of `v2ray-rules-dat` states: Apple, Microsoft, and Google CN domains exist in both `geosite:cn` and `geosite:geolocation-!cn`. But in reality, this is not always the case. (See: [PR#328](https://github.com/Loyalsoldier/v2ray-rules-dat/pull/328))
- What if the domain isn't in any list?
This undoubtedly causes trouble for traffic splitting. If your rules aren't updated in time, traffic that should go directly might be proxied, or some websites might not open at all.
What if an unknown domain has a server in China and you want to connect directly as much as possible, but after all your efforts, you encounter the legendary [DNS Leak](https://github.com/XTLS/BBS/issues/3#issuecomment-3505661189)?
So, is there a way to achieve 99.99% secure and precise traffic splitting?
The answer is: **Absolutely.**
## Achieving Precise Splitting with Xray-core DNS Module
By making reasonable use of Xray's ~~wheelchair-like~~ powerful built-in DNS features—such as Fallbacks, ECS (EDNS Client Subnet), IP filtering, and Tagging—and carefully adjusting their order, you can obtain a much more accurate and real-time routing condition than `geosite cn/!cn`: the IP address. This works because IP geolocation, especially CN geolocation, changes much less frequently than domain lists.
Before reading further, you need to fully read and understand the "Beginner Skills: Analysis of the Routing Feature [Part 1](./routing-lv1-part1.md) & [Part 2](./routing-lv1-part2.md)".
At the same time, you should have practically memorized the official configuration guide. You must fully understand the functions of `domainStrategy` in routing/outbounds, `sniffing` options in inbounds, and the behaviors produced by their different combinations.
Ready? Please try to understand the following paragraph:
When using **socks/http inbounds**, the request is a domain name. When it reaches the **Routing** module, a `domainStrategy` other than `AsIs` can use the built-in DNS to resolve an IP specifically for routing matching. When the traffic reaches a local **direct outbound**, a `domainStrategy` other than `AsIs` in the outbound can use the built-in DNS to resolve the IP again for the actual connection. The request sent to the Xray Server (remote) contains only the domain name; which IP is actually accessed depends on the server's direct outbound.
The situation becomes more complex with **Transparent Proxy**. If inbound `sniffing` is enabled and `destOverride` includes `[http, tls]`:
- If `routeOnly = false`, the requested IP will be wiped, and the subsequent flow acts just like a socks inbound.
- If `routeOnly = true`, both the domain and IP are available. When reaching the **Routing** module, it can match against both domain and IP rules directly. The local **direct outbound** will also use this IP. The request sent to the Xray Server contains only the IP. How does the server handle it? It repeats the process described above.
Having trouble? You need to re-read the official guide and try to understand it. Otherwise, it will be difficult for you to utilize the resolution results of the DNS module in the examples below for correct traffic splitting.
---
#### Example 1: This configuration resolves precise, CDN-friendly IP addresses. It guarantees no DNS Leaks while ensuring that if a domain has a server in China, it is prioritized. This is highly suitable for realIp transparent proxy scenarios
```json
{
"dns": {
"servers": [
// Prevent Google CAPTCHA issues and prevent Google China from being monitored (since many 3rd party sites load Google Fonts, etc.)
{
"address": "1.1.1.1",
"skipFallback": true,
"domains": ["geosite:google", "geosite:google-cn"]
},
{
"address": "8.8.8.8",
"skipFallback": true,
"domains": ["geosite:google", "geosite:google-cn"],
"finalQuery": true // Terminate the query chain
},
// Resolve domains considered by the community to be in China via Direct connection.
// If the result is not as expected, it might be blocked or have left China.
// Resolve via Proxy for fallback in case it is blocked or left China.
{
"tag": "dns-direct",
"address": "114.114.114.114",
"skipFallback": true,
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
{
"tag": "dns-direct",
"address": "223.5.5.5",
"skipFallback": true,
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
{
"address": "1.1.1.1",
"skipFallback": true,
"domains": ["geosite:cn"]
},
{
"address": "8.8.8.8",
"skipFallback": true,
"domains": ["geosite:cn"],
"finalQuery": true // Terminate the query chain
},
// Resolve domains considered non-Chinese via Proxy.
// If the result is not as expected, attempt optimized direct connection.
{
"address": "1.1.1.1",
"skipFallback": true,
"domains": ["geosite:geolocation-!cn"],
"expectIPs": ["geoip:!cn"]
},
{
"address": "8.8.8.8",
"skipFallback": true,
"domains": ["geosite:geolocation-!cn"],
"expectIPs": ["geoip:!cn"]
},
{
"address": "8.8.8.8",
"clientIp": "222.85.85.85", // Provide your local ISP IP to get direct-connection optimized A/AAAA records
// e.g., if you are Henan Telecom, use a Henan Telecom DNS (pun intended / example)
// Cannot guarantee 100% China CDN friendliness as not all authoritative servers support ECS
"skipFallback": true,
"domains": ["geosite:geolocation-!cn"]
},
{
"address": "8.8.4.4",
"clientIp": "222.85.85.85", // Same as above
"skipFallback": true,
"domains": ["geosite:geolocation-!cn"],
"finalQuery": true // Terminate the query chain
// You might wonder: Are these 4 rules redundant with the 4 above? Can they be simplified?
// Actually no, this is for extreme speed and because some authoritative DNS do not support ECS.
},
// Unknown domains, prioritize China. If unexpected, attempt optimized proxy.
{
"address": "8.8.8.8",
"clientIp": "222.85.85.85", // Same as above
"expectIPs": ["geoip:cn"]
},
{
"address": "8.8.4.4",
"clientIp": "222.85.85.85", // Same as above
"expectIPs": ["geoip:cn"]
},
"1.1.1.1",
"8.8.8.8"
],
"tag": "dns-proxy",
"enableParallelQuery": true // Intelligent parallel query: All parallel, smart grouping, race within group
},
"routing": {
"domainStrategy": "Depends entirely on your needs",
"rules": [
{
// Routing for DNS queries themselves
"inboundTag": ["dns-direct"],
"outboundTag": "direct"
},
{
// Routing for DNS queries themselves
"inboundTag": ["dns-proxy"],
"outboundTag": "proxy"
}
// Your personalized routing rules
// For media unlocking, use domain routing. For domestic/foreign splitting, ALWAYS use IP routing.
]
}
// Others ignored, configure as needed...
}
```
```mermaid
graph TD
A[Receive DNS Query] --> B{Domain Classification};
B -->|geosite:google<br>Google Domains| C["Query via <b>Proxy</b><br>Foreign DNS (1.1.1.1...)"];
C --> C_OUT[Likely returns Foreign IP];
C_OUT --> Z[End Query];
B -->|geosite:cn<br>Known/Suspected CN Domains| D["Query via <b>Direct</b><br>Domestic DNS (114, AliDNS)"];
D --> E{Result is CN IP?};
E -->|"Yes (Expected)"| F_OUT[Return CN IP];
F_OUT --> Z;
E -->|"No (Polluted/Wrong/Left CN)"| G["<b>Fallback</b>: Query via <b>Proxy</b><br>Foreign DNS (1.1.1.1...)"];
G --> G_OUT[Return correct Foreign IP];
G_OUT --> Z;
B -->|geosite:geolocation-!cn<br>Known/Suspected Foreign| I["Query via <b>Proxy</b><br>Foreign DNS (1.1.1.1...)"];
I --> J{Result is Foreign IP?};
J -->|"Yes (Expected)"| K_OUT[Return Foreign IP];
K_OUT --> Z;
J -->|"No (Unexpectedly CN IP / Wrong)"| L["<b>Fallback</b>: Query via <b>Proxy+ECS</b><br>Foreign DNS (8.8.8.8...)"];
L --> L_OUT[Return optimized CN IP];
L_OUT --> Z;
B -->|Unknown Domains| N["Query via <b>Proxy+ECS</b><br>Foreign DNS (8.8.8.8...)<br>Expect CN IP"];
N --> O{Result is CN IP?};
O -->|"Yes (Has CN Server)"| P_OUT[Return CN IP];
P_OUT --> Z;
O -->|"No (Pure Foreign Site)"| Q["<b>Fallback</b>: Query via <b>Proxy</b><br>Foreign DNS (1.1.1.1...)"];
Q --> Q_OUT[Return optimized Foreign IP];
Q_OUT --> Z;
```
You can route traffic based on the IP resolved by this configuration combined with the domain name, or rely entirely on the IP.
In a realIp transparent proxy environment, you can even ensure that after hijacking DNS from various channels, you set `domainStrategy=AsIs` and `routeOnly=true` to achieve a process with no secondary DNS resolution throughout.
> Note: The "CDN-friendly" mentioned above regarding the foreign part is optimized for the location of your **proxy server**. If you are only proxying blacklisted sites rather than all foreign traffic, you need to adjust the ECS in the rules yourself.
#### Example 2: This configuration resolves correct but not necessarily foreign-CDN-friendly addresses. It guarantees no DNS Leaks while prioritizing China servers if they exist. It is suitable for fakeIp transparent proxy, socks, and http inbound scenarios
```json
{
"dns": {
"servers": [
// Prevent Google CAPTCHA issues, prevent Google China monitoring
{
"address": "1.1.1.1",
"skipFallback": true,
"domains": ["geosite:google", "geosite:google-cn"],
"finalQuery": true // Terminate query chain
},
{
// We don't fully trust geosite:cn, but if a domain is in this list,
// we try resolving it first. If it returns a China IP, it means it's not blocked.
// Conversely, if not, it's highly likely blocked. Fallback to 8.8.8.8 to resolve again, solving potential DNS pollution.
// We prioritize this because the cost is minimal; direct connection takes only ~10ms.
"tag": "dns-direct",
"address": "223.5.5.5",
"skipFallback": true,
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
{
// If a domain is not in geosite:cn, or fell back from the rule above, use this server.
// Here we use ECS to try and get China A/AAAA records.
"address": "8.8.8.8",
"clientIp": "222.85.85.85", // Provide local ISP IP to get direct-connection optimized A/AAAA records
// e.g., if you are Henan Telecom, use a Henan Telecom DNS
// Cannot guarantee 100% China CDN friendliness as not all authoritative servers support ECS
"skipFallback": false
}
],
"tag": "dns-proxy"
},
"routing": {
"domainStrategy": "Must be NON-AsIs, depends on your needs",
"rules": [
{
// Routing for DNS queries themselves
"inboundTag": ["dns-direct"],
"outboundTag": "direct"
},
{
// Routing for DNS queries themselves
"inboundTag": ["dns-proxy"],
"outboundTag": "proxy"
}
// Your personalized routing rules
// For media unlocking, use domain routing. For domestic/foreign splitting, ALWAYS use IP routing.
]
}
// Others ignored, configure as needed...
}
```
In this scenario, since all requests sent to the Xray Server are domain names, there is no need to use DNS to repeatedly probe for the optimal result. We only need to quickly identify if the domain is polluted and resolve a Chinese CDN-friendly IP as much as possible.
The China IP resolved by the DNS module in this example is already 99% China CDN friendly. Therefore, you can set `domainStrategy` in the direct outbound to **non-AsIs** to utilize the cache if you wish.
<br>
If you pursue 100% China CDN friendliness, you can set it to `AsIs` to use the OS configured DNS to resolve it again. This adds about 1ms to hundreds of ms of latency; it is recommended to enable optimistic caching to further reduce latency.
## Postscript
It is known that many unscrupulous domestic Apps probe your overseas exit IP and correlate it with your sensitive information such as GPS location, phone number, and food delivery address, leaking it to social engineering databases. ~~Big brother is watching u!!!~~
Some people mistakenly believe this is caused by traffic splitting and that simply switching to Blacklist mode (only proxying blocked sites) will avoid it.
In reality, this is not the case. First, blacklists are very easy to poison; they can intentionally create bait websites and submit them to the list to probe your overseas IP.
Secondly, as long as any website in the blacklist is hosted on Cloudflare, they don't even need bait. Just try accessing: `https://chatgpt.com/cdn-cgi/trace`
Clever as you are, you might think: "Can't I just find another public proxy to layer on top?" The premise is that you must completely trust that this proxy keeps no logs and won't sell you out, and that it is heavily used by people in your country. If an overseas IP is correlated with thousands of people per unit of time, it is impossible to trace back to you via that IP. As for the annoying CAPTCHAs that come with such "dirty IPs," you just have to deal with them.
Doesn't the cyber-philanthropist Cloudflare's Warp fit all these characteristics perfectly? Unfortunately, for websites hosted on CF, Warp cannot completely hide your IP; it is only effective for non-CF servers.
Can Tor do it? It's not suitable for daily use. The IPs are too dirty, and the exit nodes jump frequently, causing many websites to ban your accounts.
Therefore, unless the client you use can split traffic by App (which is only possible on mobile phones and computers), any other method of wall-crossing will lead to your overseas IP leaking.
In short, for conventional wall-crossing methods, overseas IP leakage is almost inevitable. If you need high-level privacy protection, please use tools like Tor. Xray-core, as an anti-censorship tool, focuses on resisting blocking to help you cross the firewall, and its capabilities in privacy protection are very limited.
+23 -23
View File
@@ -1,37 +1,37 @@
# Xray 的工作模式
# Xray Working Modes
## 单服务器模式
## Single Server Mode
与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。
Like other network proxy tools, you need a server configured with Xray. Then, install and configure the Xray client on your device to access the Internet smoothly.
```mermaid
graph LR;
A(PC) -.- B(防火墙);
B -.-> C(墙外网站);
A(PC) -.- B(Firewall);
B -.-> C(Foreign Websites);
A --> D(Xray/VPS);
D --> C;
A --> E(墙内网站);
A --> E(Domestic Websites);
```
一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。
A single Xray server can support multiple devices accessing via different proxy protocols simultaneously. Meanwhile, with reasonable configuration, Xray can identify and distinguish traffic that needs proxying from traffic that doesn't; direct traffic does not need to take a detour.
## 桥接模式
## Bridge Mode
如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。
If you don't want to configure routing on every single device, you can set up a relay (transit) server. This server receives all traffic sent from clients and then makes forwarding decisions within the server itself.
```mermaid
graph LR;
A(PC) -.-> B(防火墙);
B -.-> C(墙外网站);
A --> D(墙内 VPS);
D --> E(墙外 VPS);
A(PC) -.-> B(Firewall);
B -.-> C(Foreign Websites);
A --> D(Domestic VPS);
D --> E(Foreign VPS);
E --> C;
D --> F(墙内网站);
D --> F(Domestic Websites);
```
## 工作原理
## Working Principle
在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。
Before configuring Xray, it is helpful to look at how Xray works. The following is a schematic diagram of the internal structure of a single Xray process. Multiple Xray instances are independent of each other and do not affect one another.
```mermaid
graph LR;
@@ -45,10 +45,10 @@ D --> B3(outbound);
D --> B4(outbound);
```
- 需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。
- 入站连接负责与客户端(如浏览器)通信:
- 入站连接通常可以配置用户认证,如 ID 和密码等;
- 入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;
- 出站连接负责将数据发给服务器,如另一台主机上的 Xray。
- 当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。
- 路由会在必要时查询 DNS 以获取更多信息来进行判断。
- You need to configure at least one **Inbound** and one **Outbound** connection for it to work properly.
- **Inbound** connections are responsible for communicating with clients (such as browsers):
- Inbound connections can usually be configured with user authentication, such as IDs and passwords.
- After receiving data, the inbound connection hands it over to the **Dispatcher** for distribution.
- **Outbound** connections are responsible for sending data to the destination, such as Xray on another host.
- When there are multiple outbound connections, you can configure **Routing** to specify that a certain category of traffic is sent via a specific outbound connection.
- The Router will query DNS when necessary to obtain more information for decision-making.