mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-09-28 18:08:01 +03:00
Add: document level-1&2
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# 入门技巧
|
||||
|
||||
**这个章节是入门级的Xray使用心得分享,主要分享一些Xray常用功能模块的原理说明。**
|
||||
|
||||
[回落 (fallbacks) 功能简析](./fallbacks-lv1.md)
|
||||
|
||||
|
||||
[路由 (routing) 功能简析(上)](./routing-lv1-part1.md)
|
||||
|
||||
|
||||
[路由 (routing) 功能简析(下)](./routing-lv1-part2.md)
|
||||
|
||||
|
||||
[Xray的工作模式简析](./work.md)
|
||||
|
||||
|
||||
[通过 SNI 回落功能实现伪装与按域名分流](./fallbacks-with-sni.md)
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
# 回落 (fallbacks) 功能简析
|
||||
|
||||
在使用Xray的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。
|
||||
|
||||
## 1. 回顾《小小白白话文》中的回落
|
||||
|
||||
如果你用了《小小白白话文》中的[Xray配置](../level-0/ch07-xray-server#_7-4-配置xray),并完成了[HTTP自动跳转HTTPS优化](../level-0/ch07-xray-server#_7-8-服务器优化之二-开启http自动跳转https),那么你已经有了基于 `VLESS` 协议的简易回落:
|
||||
|
||||
|
||||
```
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
...
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": 8080 // 默认回落到防探测的代理
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
...
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
这一段配置用人话要怎么解释呢?
|
||||
|
||||
1. **`Xray` 的入站端口 `[inbound port]` 是 `443`**
|
||||
|
||||
即由 `Xray` 负责监听 `443` 端口的 `HTTPS` 流量
|
||||
|
||||
2. **`Xray` 的入站协议 `[inbound protocol]` 是 `vless`**
|
||||
|
||||
只有 `vless` 协议的流量才会流入 `Xray` 中做后续处理。
|
||||
|
||||
::: warning
|
||||
**注:** `VLESS` 这个轻量协议开发的初衷就是给 `xray` 及 `v2fly` 等核心引入回落功能、并同时减少冗余校验/加密。(当然,到目前为止,`xray` 中的 `trojan` 协议也已完整支持回落功能。)
|
||||
:::
|
||||
|
||||
3. **回落目标端口 `[fallback dest]` 是 `8080`**
|
||||
|
||||
`Xray` 接受 `443` 端口的访问流量后,属于 `vless` 协议的流量、由 `Xray` 进行内部处理并转发至出站模块。而其他非 `vless` 协议的流量,则转发至 `8080` 端口。
|
||||
|
||||
::: warning
|
||||
**问:到底是单数还是复数?**
|
||||
|
||||
答:一定有聪明的同学发现,配置文件中,明明是复数 `inbounds`, `fallbacks`,为什么我解释的时候都是单数:`inbound`, `fallback` 呢?
|
||||
|
||||
因为,配置文件中用复数,说明 `xray` 支持 N 个同等级的元素(即N个入站,M个回落等等),上面的示例解析中仅仅是其中一个,所以我用了单数。
|
||||
:::
|
||||
|
||||
4. **回落给 `8080` 端口的流量,由后续程序处理**
|
||||
|
||||
小小白白话文中的示例,就是 `8080` 端口由 `Nginx` 处理,根据配置找到并展示小熊猫的网页。
|
||||
|
||||
5. **总结,小小白白话文示例中的最简单回落,完整数据路线如下:**
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
W(外部 HTTP:80 请求) --> N80(HTTP:80)
|
||||
|
||||
subgraph Nginx 外部监听
|
||||
N80 -.- N301(301转写) -.- N443(HTTPS:443)
|
||||
end
|
||||
|
||||
N443 --> X(Xray 监听 443) .- X1{入站判断}
|
||||
X1 --> |接收 VLESS 流量| X2(Xray内部规则)
|
||||
X2 --> O(Xray Outbounds 出站)
|
||||
X1 ==> |回落 非VLESS 流量| N8080(Nginx:8080)
|
||||
N8080:::nginxclass ==> H(index.html)
|
||||
|
||||
H:::nginxclass
|
||||
classDef nginxclass fill:#FFFFDE
|
||||
|
||||
```
|
||||
|
||||
|
||||
## 2. 重新认识回落 (WHAT, HOW `v1`)
|
||||
|
||||
基于上面的示例,你应该就可以明白什么是回落(What)和怎么回落(How)了,简单地说就是下面这几个要素:
|
||||
|
||||
1. 回落的时间是流量进入 `Xray监听端口` 后
|
||||
2. 回落的依据是 `协议类型` 等流量特征
|
||||
3. 回落的目标是某个 `端口`
|
||||
4. 被回落的流量由监听 `回落端口` 的后续程序接手
|
||||
|
||||
|
||||
|
||||
## 3. 为什么要回落 (WHY `v1`)
|
||||
最初,是为了防御 **【主动探测】** (Active Probing)
|
||||
|
||||
**主动探测:** 简单粗暴的理解,就是指外部通过发送特定的网络请求,并解读服务器的回应内容,来推测服务器端是否运行了 `xray`, `v2fly`, `shadowsocks` 等代理工具。一旦可以准确认定,则服务器可能受到干扰或阻断。
|
||||
|
||||
之所以可以根据服务器回应内容进行解读,就是因为一次完整的数据请求,其实有很多数据交换的步骤,每一个步骤,都会产生一些软件特征。用大白话说就是:
|
||||
|
||||
- 正常的网站的回应,一定【会有】类似 `Nginx`, `Apache`, `MySQL` 的Web服务、数据库等工具的特征
|
||||
- 正常的网站的回应,一定【不会有】类似 `xray`, `v2fly`, `shadowsocks` 等代理工具的特征
|
||||
|
||||
于是,当我们给 `Xray` 提供了【回落】功能后(如上例,回落给 `Nginx`),面对任何用来探测的请求,产生的结果是:
|
||||
|
||||
- 探测流量无法掌握你的 `VLESS` 要素,故都会被回落至 `Nginx`
|
||||
- 探测流量全都回落进入 `Nginx` ,故VPS服务器的回应一定【会有】 `Nginx` 的特征
|
||||
- 因为 `Xray` 本身不对探测流量做任何回应 ,所以VPS的回应一定【不会有】 `Xray` 的特征
|
||||
|
||||
至此,【回落】功能就从数据交互逻辑上解决了服务器被 **【主动探测】** 的安全隐患。
|
||||
|
||||
|
||||
|
||||
## 4. 重新认识【回落の完全体】 (WHAT, WHY, HOW `v2`)
|
||||
|
||||
为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。
|
||||
|
||||
在 [rprx](https://github.com/rprx) 不断开发迭代 `VLESS` 协议及 `fallback` 功能的过程种,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 `path`, `alpn` 等)
|
||||
|
||||
基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 `纯伪装 --> ws分流 --> 多协议多特征分流` 的进化。最终版甚至完全替代了以前要用Web服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。
|
||||
|
||||
**因此,现在 `Xray` 中【完整体的回落功能】,同时具备下述属性:**
|
||||
|
||||
- **安全:** 充分抵御主动探测攻击
|
||||
- **高效:** 几乎毫无性能损失
|
||||
- **灵活:** 数据灵活分流、常用端口复用(如443)
|
||||
|
||||
::: tip 啰嗦君
|
||||
这样多轮介绍虽然略显繁琐,但只有这样层层深入展开,才能充分的说明【回落の完全体】独有的强大!
|
||||
:::
|
||||
|
||||
|
||||
## 5. 多层回落示例及解读
|
||||
|
||||
理解了【回落の完全体】是什么,那就可以动手操作配置多层回落了。其实,项目已经提供了非常完整的示例,即官方模板中的 [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/)。
|
||||
|
||||
### 5.1 首先,我将服务器端配置的 443 监听段摘抄如下:
|
||||
|
||||
```
|
||||
{
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // 填写你的 UUID
|
||||
"flow": "xtls-rprx-direct",
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": 1310, // 默认回落到 Xray 的 Trojan 协议
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"path": "/websocket", // 必须换成自定义的 PATH
|
||||
"dest": 1234,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"path": "/vmesstcp", // 必须换成自定义的 PATH
|
||||
"dest": 2345,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"path": "/vmessws", // 必须换成自定义的 PATH
|
||||
"dest": 3456,
|
||||
"xver": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "xtls",
|
||||
"xtlsSettings": {
|
||||
"alpn": [
|
||||
"http/1.1"
|
||||
],
|
||||
"certificates": [
|
||||
{
|
||||
"certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径
|
||||
"keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
这一段配置用人话要怎么解释呢?
|
||||
|
||||
1. **`Xray` 的入站端口 (`inbound port`) 是 `443`**
|
||||
|
||||
即由 `Xray` 负责监听 `443` 端口的 `HTTPS` 流量,并使用 `certificates` 项下设定的 `TLS` 证书来进行验证
|
||||
|
||||
2. **`Xray` 的入站协议 (`inbound protocol`) 是 `vless`**
|
||||
|
||||
`vless` 协议流量直接流入 `Xray` 中做后续处理
|
||||
|
||||
3. **非 `VLESS` 协议流量有4个不同的回落目标:**
|
||||
|
||||
1. `path` 为 `websocket` 的流量,回落给端口 `1234` 后续处理
|
||||
2. `path` 为 `vmesstcp` 的流量,回落给端口 `2345` 后续处理
|
||||
3. `path` 为 `vmessws` 的流量,回落给端口 `3456` 后续处理
|
||||
4. 其它所有流量,回落给端口 `1310` 后续处理
|
||||
|
||||
4. **`xver` 为 `1` 表示开启 `proxy protocol` 功能,向后传递来源真实IP**
|
||||
|
||||
5. **上述回落结构如下图所示:**
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
W443(外部 HTTP:443 请求) --> X443(Xray-inbound: 443) .- X1{入站判断}
|
||||
X1 --> |协议 = VLESS 的流量| X2(Xray内部规则)
|
||||
X2 --> O(Xray Outbounds 出站)
|
||||
|
||||
X1 --> |path = /websocket 的流量| X1234(Xray-inbound:1234)
|
||||
X1 --> |path = /vmesstcp 的流量| X2345(Xray-inbound:2345)
|
||||
X1 --> |path = /vmessws 的流量| X3456(Xray-inbound:3456)
|
||||
X1 --> |其它所有流量| X1310(Xray-inbound:1310)
|
||||
|
||||
```
|
||||
|
||||
6. **网页回落不见了!**
|
||||
|
||||
没错,聪明的同学应该发现了,防御【主动探测】的 `nginx回落` 不见了!!!这是为什么呢?会不会不安全?别急,我们继续分析:
|
||||
|
||||
|
||||
### 5.2 后续监听处理的配置段摘抄如下:
|
||||
|
||||
1. 后续处理回落至 `1310` 端口的流量,按照下面的配置验证、处理:
|
||||
```
|
||||
{
|
||||
"port": 1310,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "trojan",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"password": "", // 填写你的密码
|
||||
"level": 0,
|
||||
"email": "love@example.com"
|
||||
}
|
||||
],
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": 80 // 或者回落到其它也防探测的代理
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "none",
|
||||
"tcpSettings": {
|
||||
"acceptProxyProtocol": true
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
看,神奇的事情发生了, `trojan` 协议这里又出现了一个新的 `fallbacks`。前面已经说过,`xray` 中的 `trojan` 协议也具有完整的回落能力,所以,此时 `trojan` 协议可以再次做判断和回落(这也就是传说中的套娃回落了):
|
||||
|
||||
- 所有 `trojan` 协议的流量,流入 `Xray` 中做后续处理
|
||||
- 所有非 `trojan` 协议的流量,转发至 `80` 端口,【主动探测】的防御,完成!
|
||||
|
||||
2. 后续处理回落至 `1234` 端口的流量,仔细看!它其实是 `vless+ws`:
|
||||
```
|
||||
{
|
||||
"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,需要和分流的一致
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
3. 后续处理回落至 `2345` 端口的流量,仔细看!它其实是 `vmess直连`:
|
||||
```
|
||||
{
|
||||
"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,需要和分流的一致
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
4. 后续处理回落至 `3456` 端口的流量,再仔细看!它其实是是 `vmess+ws(+cdn)`。
|
||||
|
||||
::: warning
|
||||
**说明:** 你没看错,这就是 v2fly 曾经的推荐组合之一,并可完整支持 `CDN`。现已加入完美回落套餐哦!
|
||||
:::
|
||||
|
||||
```
|
||||
{
|
||||
"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,需要和分流的一致
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
5. 至此,我们就能够完整的画出模板的回落路线了:
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
W443(外部 HTTP:443 请求) --> X443(Xray-inbound: 443) .- X1{入站判断}
|
||||
X1 --> |协议 = VLESS 的流量| X2(Xray内部规则)
|
||||
X2 --> XO(Xray Outbounds 出站)
|
||||
|
||||
X1 --> |path = /websocket 的流量| X1234(Xray-inbound:1234)
|
||||
X1 --> |path = /vmesstcp 的流量| X2345(Xray-inbound:2345)
|
||||
X1 --> |path = /vmessws 的流量| X3456(Xray-inbound:3456)
|
||||
X1 --> |其它所有流量| X1310(Xray-inbound:1310)
|
||||
|
||||
X1234 --> X2
|
||||
X2345 --> X2
|
||||
X3456 --> X2
|
||||
|
||||
X1310 --> |协议 = trojan 的流量| X2
|
||||
X1310 --> |其他所有流量| N80(Nginx:80)
|
||||
|
||||
N80:::nginxclass --> H(index.html)
|
||||
|
||||
H:::nginxclass
|
||||
classDef nginxclass fill:#FFFFDE
|
||||
```
|
||||
|
||||
|
||||
## 6. 结语
|
||||
|
||||
至此,`Xray` 的【回落】功能就介绍完了。希望本文能够对你理解 `Xray` 的强大有所帮助。
|
||||
|
||||
|
||||
## 7. 附加题
|
||||
|
||||
我再无耻的留一个附加题:本文详解的 [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/) 模板?是否有可以优化的地方?
|
||||
|
||||
提示:HTTP自动跳转HTTPS
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,330 @@
|
||||
# 通过 SNI 回落功能实现伪装与按域名分流
|
||||
|
||||
VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中,在墙内外穿进穿出。为了更好的伪装以应对主动探测,Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。
|
||||
|
||||
## 应用情景
|
||||
|
||||
由于 XTLS,Xray 需要监听 443 端口,这导致如果之前有网站运行在服务器上,那么此时网站无法运行或需要运行在其他端口上,这显然是不合理的。有以下三种方案可以解决这个问题:
|
||||
|
||||
- Xray 监听其他常用端口(如 22、3389、8443)
|
||||
|
||||
这个方案是最简单的,但不够完美。
|
||||
|
||||
- Nginx 或 HAProxy 监听 443 端口,通过 SNI 分流做 L4 反向代理,实现端口复用
|
||||
|
||||
这个方案比较复杂,需要对 Nginx 或 HAProxy 的使用有一定了解,此处不作过多解释。
|
||||
|
||||
- Xray 监听 443 端口,通过 Fallbacks 功能 SNI 分流将网站流量回落到 Nginx 或 Caddy
|
||||
|
||||
这个方案难度适中,也是此教程接下来想要演示的方案。
|
||||
|
||||
## SNI 简介
|
||||
|
||||
服务器名称指示(英语:**S**erver **N**ame **I**ndication,缩写:**SNI**)是 TLS 的一个扩展协议。熟悉反向代理的朋友都知道,如果想要通过域名将流量代理到正确的内容上,需要以下配置:
|
||||
|
||||
```nginx
|
||||
proxy_set_header Host 主机名;
|
||||
```
|
||||
|
||||
这句的作用是将名为 “Host” 的 HTTP Header 设定为某个主机名。为什么要这样做?一般而言,一台服务器对应一个 IP,但却运行多个网站,访问者通过域名查询到 IP 以访问服务器,那么问题来了,如何确定访问者想要访问的是哪一个网站?这需要“基于名称的虚拟主机”。
|
||||
|
||||
当 Web 服务器收到访问请求后,它会查看请求的主机头,使访问者访问正确的网站。然而当 HTTP 协议被 TLS 协议加密后,这种简单的方法就无法实现了。因为 TLS 握手发生在服务器看到任何 HTTP 头之前,因此,服务器不可能使用 HTTP 主机头中的信息来决定呈现哪个证书,更无法决定访问者的访问目标。
|
||||
|
||||
SNI 的原理也很简单,它通过让客户端发送主机名作为 TLS 协商的一部分来解决此问题。所以在使用 Nginx 对 HTTPS 协议进行反向代理时,需要在配置中加入 `proxy_ssl_server_name on;`,此时 Nginx 会向被代理的服务器发送 SNI 信息,解决了 HTTPS 协议下虚拟主机失效的问题。另外,使用 SNI 时,即使不指定主机头,也可以正确访问网站。
|
||||
|
||||
## 思路
|
||||
|
||||

|
||||
|
||||
从 443 端口接收到流量后,Xray 会把 TLS 解密后首包长度 < 18、协议版本无效或身份认证失败的流量通过对 name、path、alpn 的匹配转发到 dest 指定的地址。
|
||||
|
||||
## 添加 DNS 记录
|
||||
|
||||

|
||||
|
||||
请按实际情况修改域名和 IP。
|
||||
|
||||
## 申请 TLS 证书
|
||||
|
||||
由于要对不同前缀的域名进行分流,但一个通配符证书的作用域仅限于两“.”之间(例如:申请 `*.example.com`,`example.com` 和 `*.*.example.com` 并不能使用该证书),故需申请 [SAN](https://zh.wikipedia.org/wiki/%E4%B8%BB%E9%A2%98%E5%A4%87%E7%94%A8%E5%90%8D%E7%A7%B0) 通配符证书。根据 Let's Encrypt 官网信息[^1],申请通配符证书要求 DNS-01 验证方式,此处演示 NS 记录为 Cloudflare 的域名通过 [acme.sh](https://acme.sh) 申请 Let's Encrypt 的免费 TLS 证书。使用其他域名托管商的申请方法请阅读 [dnsapi · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki/dnsapi)。
|
||||
|
||||
首先需要到 [Cloudflare 面板](https://dash.cloudflare.com/profile/api-tokens)创建 API Token。参数如下:
|
||||
|
||||

|
||||
|
||||
权限部分至关重要,其他部分任意。
|
||||
|
||||
创建完毕后,你会得到一串神秘字符,请将其妥善保管到安全且不会丢失的地方,因为它不再会显示。这串字符就是即将用到的 `CF_Token`。
|
||||
|
||||
::: tip 注意
|
||||
以下操作需要在 root 用户下进行,使用 sudo 会出现错误。
|
||||
:::
|
||||
|
||||
```bash
|
||||
curl https://get.acme.sh | sh # 安装 acme.sh
|
||||
export CF_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" # 设定 API Token 变量
|
||||
acme.sh --issue -d example.com -d *.example.com --dns dns_cf # 使用 DNS-01 验证方式申请证书
|
||||
mkdir /etc/ssl/xray # 新建证书存放目录
|
||||
acme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --key-file /etc/ssl/xray/privkey.key --reloadcmd "chown nobody:nogroup -R /etc/ssl/xray && systemctl restart xray" # 安装证书到指定目录并设定自动续签生效指令
|
||||
```
|
||||
|
||||
## Xray 配置
|
||||
|
||||
```json
|
||||
{
|
||||
"log": {
|
||||
"loglevel": "warning"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "UUID",
|
||||
"flow": "xtls-rprx-direct"
|
||||
}
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"path": "/vmessws",
|
||||
"dest": 5000,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"dest": 5001,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"alpn": "h2",
|
||||
"dest": 5002,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"name": "blog.example.com",
|
||||
"dest": 5003,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"name": "blog.example.com",
|
||||
"alpn": "h2",
|
||||
"dest": 5004,
|
||||
"xver": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "xtls",
|
||||
"xtlsSettings": {
|
||||
"alpn": [
|
||||
"h2",
|
||||
"http/1.1"
|
||||
],
|
||||
"certificates": [
|
||||
{
|
||||
"certificateFile": "/etc/ssl/xray/cert.pem",
|
||||
"keyFile": "/etc/ssl/xray/privkey.key"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "127.0.0.1",
|
||||
"port": 5000,
|
||||
"protocol": "vmess",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "UUID"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "ws",
|
||||
"wsSettings": {
|
||||
"acceptProxyProtocol": true,
|
||||
"path": "/vmessws"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
以上配置针对于 Nginx,以下是需要注意的一些细节。
|
||||
|
||||
- 有关 Proxy Protocol
|
||||
|
||||
Proxy Protocol 是 HaProxy 开发的一种旨在解决代理时容易丢失客户端信息问题的协议,常用于链式代理和反向代理。传统的处理方法往往较为复杂且有诸多限制,而 Proxy Protocol 非常简单地在传输数据时附带上原始连接四元组信息的数据包,解决了这个问题。
|
||||
|
||||
凡事皆有利弊,Proxy Protocol 也是如此。
|
||||
|
||||
- 有发送必须有接收,反之亦然
|
||||
- 同一端口不能既兼容带 Proxy Protocol 数据的连接又兼容不带数据的连接(如:Nginx 同端口的不同虚拟主机(server),本质是上一条)[^2][^3]
|
||||
|
||||
在遇到异常时,请考虑配置是否符合上述条件。
|
||||
|
||||
此处,我们使用 Proxy Protocol 让被回落到的目标获取到客户端的真实 IP。
|
||||
|
||||
另外,当 Xray 的某个入站配置存在 `"acceptProxyProtocol": true` 时,ReadV 将失效。
|
||||
|
||||
- 有关 HTTP/2
|
||||
|
||||
首先,`inbounds.streamSettings.xtlsSettings.alpn` 有顺序,应将 `h2` 放前,`http/1.1` 放后,在优先使用 HTTP/2 的同时保证兼容性;反过来会导致 HTTP/2 在协商时变为 HTTP/1.1,成为无效配置。
|
||||
|
||||
在上述配置中,每条回落到 Nginx 的配置都要分成两个。这是因为 h2 是强制 TLS 加密的 HTTP/2 连接,这有益于数据在互联网中传输的安全,但在服务器内部没有必要;而 h2c 是非加密的 HTTP/2 连接,适合该环境。然而,Nginx 不能在同一端口上同时监听 HTTP/1.1 和 h2c,为了解决这个问题,需要在回落中指定 `alpn` 项(是 `fallbacks` 而不是 `xtlsSettings` 里面的),以尝试匹配 TLS ALPN 协商结果。
|
||||
|
||||
建议 `alpn` 项只按需用两种填法:[^4]
|
||||
|
||||
- 省略
|
||||
- `"h2"`
|
||||
|
||||
如果使用 Caddy 就大可不必如此繁杂了,因为它**可以**在同一端口上同时监听 HTTP/1.1 和 h2c,配置改动如下:
|
||||
|
||||
```json
|
||||
"fallbacks": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"path": "/vmessws",
|
||||
"dest": 5000,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"dest": 5001,
|
||||
"xver": 1
|
||||
},
|
||||
{
|
||||
"name": "blog.example.com",
|
||||
"dest": 5002,
|
||||
"xver": 1
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Nginx 配置
|
||||
|
||||
Nginx 将通过官方源进行安装。
|
||||
|
||||
```bash
|
||||
sudo apt install curl gnupg2 ca-certificates lsb-release
|
||||
echo "deb [arch=amd64] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
|
||||
| sudo tee /etc/apt/sources.list.d/nginx.list
|
||||
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
|
||||
sudo apt update
|
||||
sudo apt install nginx
|
||||
```
|
||||
删除 `/etc/nginx/conf.d/default.conf` 并创建 `/etc/nginx/conf.d/fallbacks.conf`,内容如下:
|
||||
|
||||
```nginx
|
||||
set_real_ip_from 127.0.0.1;
|
||||
real_ip_header proxy_protocol;
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:5001 proxy_protocol default_server;
|
||||
listen 127.0.0.1:5002 proxy_protocol default_server http2;
|
||||
|
||||
location / {
|
||||
root /srv/http/default;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:5003 proxy_protocol;
|
||||
listen 127.0.0.1:5004 proxy_protocol http2;
|
||||
|
||||
server_name blog.example.com;
|
||||
|
||||
location / {
|
||||
root /srv/http/blog.example.com;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
## Caddy 配置
|
||||
|
||||
安装 Caddy 请参阅 [Install — Caddy Documentation](https://caddyserver.com/docs/install)。
|
||||
|
||||
为了使 Caddy 能获取到访问者的真实 IP,需要编译带有 Proxy Protocol 模块的 Caddy。建议直接在 Caddy 官网上在线编译。
|
||||
|
||||
```bash
|
||||
sudo curl -o /usr/bin/caddy "https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458"
|
||||
sudo chmod +x /usr/bin/caddy
|
||||
```
|
||||
|
||||
直接替换即可。
|
||||
|
||||
::: tip
|
||||
建议先通过官网文档安装 Caddy,再替换二进制文件。这样做无需手动设定进程守护。
|
||||
:::
|
||||
|
||||
编辑 `/etc/caddy/Caddyfile`:
|
||||
|
||||
```Caddyfile
|
||||
{
|
||||
servers 127.0.0.1:5001 {
|
||||
listener_wrappers {
|
||||
proxy_protocol
|
||||
}
|
||||
protocol {
|
||||
allow_h2c
|
||||
}
|
||||
}
|
||||
servers 127.0.0.1:5002 {
|
||||
listener_wrappers {
|
||||
proxy_protocol
|
||||
}
|
||||
protocol {
|
||||
allow_h2c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:5001 {
|
||||
root * /srv/http/default
|
||||
file_server
|
||||
log
|
||||
bind 127.0.0.1
|
||||
}
|
||||
|
||||
http://blog.example.com:5002 {
|
||||
root * /srv/http/blog.example.com
|
||||
file_server
|
||||
log
|
||||
bind 127.0.0.1
|
||||
}
|
||||
|
||||
:80 {
|
||||
redir https://{host}{uri} permanent
|
||||
}
|
||||
```
|
||||
|
||||
## 参考
|
||||
|
||||
1. [服务器名称指示 - 维基百科,自由的百科全书](https://zh.wikipedia.org/wiki/%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%8D%E7%A7%B0%E6%8C%87%E7%A4%BA)
|
||||
2. [Home · acmesh-official/acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki)
|
||||
3. [HTTP/2 - 维基百科,自由的百科全书](https://zh.wikipedia.org/wiki/HTTP/2)
|
||||
|
||||
## 引用
|
||||
|
||||
[^1]: [常见问题 - Let's Encrypt - 免费的SSL/TLS证书](https://letsencrypt.org/zh-cn/docs/faq/)
|
||||
|
||||
[^2]: [Proxy Protocol - HAProxy Technologies](https://www.haproxy.com/blog/haproxy/proxy-protocol/)
|
||||
|
||||
[^3]: [proxy protocol介绍及nginx配置 - 简书](https://www.jianshu.com/p/cc8d592582c9)
|
||||
|
||||
[^4]: [v2fly-github-io/vless.md at master · rprx/v2fly-github-io](https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,445 @@
|
||||
# 路由 (routing) 功能简析(上)
|
||||
|
||||
如果说Xray的【强大】主要体现在它极致的速度和广泛的兼容性。那么Xray的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。
|
||||
|
||||
## 1. 初识【路由】三兄弟
|
||||
|
||||
要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. **入站**;2. **路由**;3. **出站**。
|
||||
|
||||
<img src="./routing-lv1-img01-trio.png" alt="路由三兄弟"/>
|
||||
|
||||
三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。
|
||||
|
||||
所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。
|
||||
|
||||
因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。
|
||||
|
||||
::: warning 啰嗦君
|
||||
路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。
|
||||
:::
|
||||
|
||||
|
||||
## 2. 基本功: “兄弟一条心”
|
||||
|
||||
下图的示例,就是在客户端的 `Xray` 入站接收APP数据、在路由100%转发给出站,并从出站流向VPS。
|
||||
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
S(APP数据) .-> I[入站]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[路由] --> O[出站]
|
||||
end
|
||||
|
||||
O .-> V(VPS)
|
||||
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE
|
||||
|
||||
```
|
||||
|
||||
下面我们来逐个分析:
|
||||
|
||||
### 2.1 入站
|
||||
|
||||
::: tip
|
||||
**入站:** 就是流量如何流入 `Xray`
|
||||
:::
|
||||
|
||||
下面的入站配置示例,用大白话说就是:数据按照 `socks` 协议,通过 `10808` 端口,从本机 `127.0.0.1` 流入`Xray`。同时,`Xray` 将这个入站用 `[tag]` 命名为 `inbound-10808`。
|
||||
|
||||
```
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "inbound-10808",
|
||||
"protocol": "socks",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 10808,
|
||||
"settings": {
|
||||
"udp": true
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**2.2 出站**
|
||||
|
||||
::: tip
|
||||
**出站:** 就是流量如何流出 `Xray`
|
||||
:::
|
||||
|
||||
下面的出站配置示例,用大白话说就是:数据按照 `VLESS` 协议,以 `tcp + xtls (direct)` 的方式、及其他相关设置,把流量发送给对应的VPS。同时,`Xray` 将这个出站用 `[tag]` 命名为 `proxy-out-vless`:
|
||||
|
||||
```
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "proxy-out-vless",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "a-name.yourdomain.com",
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid",
|
||||
"flow": "xtls-rprx-direct",
|
||||
"encryption": "none",
|
||||
"level": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "xtls",
|
||||
"xtlsSettings": {
|
||||
"serverName": "a-name.yourdomain.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.3 路由
|
||||
|
||||
::: tip
|
||||
**路由:** 就是把【入站】和【出站】之间的通道,用某种【条件】串联起来
|
||||
:::
|
||||
|
||||
下面的路由配置示例,用大白话说就是:把所有通过 `[tag]="inbound-10808"` 入站流入 `Xray` 的流量,`100%` 全部流转导入 `[tag]="proxy-out-vless"` 的出站,没有任何分流或其他操作。
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"inboundTag": [
|
||||
"inbound-10808"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
至此,我们最开始设计的极简规则【客户端的 `Xray` 入站接收APP数据、在路由100%转发给出站,并从出站流向VPS】已经完成。
|
||||
|
||||
|
||||
|
||||
|
||||
### 2.4 路由配置项解析之一:流量筛选的依据
|
||||
|
||||
注意观察路由配置,我们可以看到几个新名词:
|
||||
|
||||
1. `"domainStrategy": "AsIs"`
|
||||
2. `“rules”`
|
||||
3. `"type": "field"`
|
||||
4. `"inboundTag": ["inbound-10808"]`
|
||||
5. `"outboundTag": "proxy-out-vless"`
|
||||
|
||||
其中 `domainStrategy` 我们暂且按下不表,先简单说明后面几个:
|
||||
|
||||
| 配置名称 | 配置值 | 配置说明 |
|
||||
|:--:|:--:|:--|
|
||||
| `“rules”` | | 它的内层就是【路由规则】的明细设置 |
|
||||
| `"type"` | `"field"` | 该项暂时没有特别定义,但是不能省略,所以记得写上就好 |
|
||||
| `"inboundTag"` | `["inbound-10808"]` | 筛选流量的 **【依据】** 是【入站Tag】,具体 **【条件】** 现在只有一个:【入站来源是 `inbound-10808`】 |
|
||||
| `"outboundTag"` | `"proxy-out-vless"` | 当上面的筛选条件成立时(即入站`[tag]="inbound-10808"`时 ),`Xray` 会将流量导入 `[tag]="proxy-out-vless"` 的出站 |
|
||||
|
||||
本例中,我们只有一个入站,它的`"inboundTag" = "inbound-10808"` 。我们也只有一个出站,它的 `[tag]="proxy-out-vless"`。所以根据上面这个路由规则,从唯一入站端口 `10808` 流入`Xray`的流量,`100%` 符合筛选条件、会被路由模块选中,然后转发给唯一的出站。
|
||||
|
||||
至此,**入站**、**路由**、**出站** 三兄弟就已经可以携手工作了。当然,现在这个100%转发的工作并没有什么特别的意义。那么接下来,我们就看看这种分工合作的机制可以带来什么好处。
|
||||
|
||||
|
||||
|
||||
|
||||
## 3. 小试牛刀: “三分天下” 之 “域名分流”
|
||||
|
||||
> `[geosite.dat]`
|
||||
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
S(APP数据) .-> I[入站]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
|
||||
R[路由] -- "geosite:cn" --> O2[direct]
|
||||
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
|
||||
end
|
||||
|
||||
O2 .-> D(国内服务器)
|
||||
O3 .-> V(VPS)
|
||||
|
||||
O1:::redclass
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
|
||||
classDef redclass fill:#FF0000
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
这个配置逻辑,其实就是最简单、最常用的(《小小白白话文》中也在用的)路由配置三件套:
|
||||
|
||||
1. 广告流量屏蔽 `[block]`
|
||||
2. 国内流量直连 `[direct]`
|
||||
3. 国外流量转发VPS `[proxy]`
|
||||
|
||||
::: warning 注意
|
||||
小小白白话文中的直连配置是包括【国内域名】、【国内IP】、【本机内部IP】的。这里先讲解【国内域名】。
|
||||
:::
|
||||
|
||||
### 3.1 入站
|
||||
|
||||
保持上例的 `inbound-10808` 不变。
|
||||
|
||||
|
||||
### 3.2 出站
|
||||
|
||||
在上例的基础上,我们已经有了 `[proxy]` 的出站 `"proxy-out-vless"`,所以它保持不变。显而易见,我们需要加入两个新的出站方式:`[block]` 和 `[direct]`,如下:
|
||||
|
||||
```
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "proxy-out-vless",
|
||||
......
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"protocol": "blackhole"
|
||||
},
|
||||
{
|
||||
"tag": "direct-out",
|
||||
"protocol": "freedom"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
上面的配置用大白话翻译如下:
|
||||
1. 上例中的 `[proxy-out-vless]` 出站配置保持不变
|
||||
2. 加入 **`blackhole` 黑洞协议**,通过这个协议出站的流量,其实都被发送到了 `Xray` 内部的黑洞里,再也无法逃脱,于是效果就是屏蔽 `[block]`
|
||||
3. 加入 **`freedom` 自由协议**,通过这个协议出站的流量,是自由的离开`Xray`去寻找原定的服务器,就像从没有来过,于是效果就是直连 `[direct]` (我这里起名叫做 `[direct-out]` 是为了强调它是一个出站)
|
||||
|
||||
|
||||
### 3.3 路由
|
||||
|
||||
接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:category-ads-all"
|
||||
],
|
||||
"outboundTag": "block"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:cn"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:geolocation-!cn"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
为了理解这个配置文件,我们要稍微解释一下这里出现的几个新配置项:
|
||||
|
||||
- `"domain": ["geosite:category-ads-all"]`
|
||||
- `"domain": ["geosite:cn"]`
|
||||
- `"domain": ["geosite:geolocation-!cn"]`
|
||||
|
||||
|
||||
|
||||
### 3.4 简析域名文件: `geosite.dat`
|
||||
|
||||
其实,聪明的你大概可以通过这些配置项的名称猜出来个大概:
|
||||
|
||||
- `"domain"`:就是这次筛选流量的 **【依据】** 是 **【域名】** (而不再是入站tag)
|
||||
- `"geosite"`:就是 `Xray` 会去 `geosite.dat` 文件中寻找 **【符合条件的域名】**
|
||||
- `"category-ads-all"`:就是该文件中的 **【所有广告类域名】**
|
||||
- `"cn"`:就是该文件中的 **【中国域名】**
|
||||
- `"geolocation-!cn"`:就是该文件中的 **【非中国域名】**
|
||||
|
||||
|
||||
结合这些说明,3.3 中的配置用大白话翻译就是:
|
||||
|
||||
1. APP试图访问国外域名 `"domain": "geolocation-!cn"` 的流量,通过 `[proxy-out-vless]` 出站,转发至VPS
|
||||
2. APP试图访问国外域名广告域名 `"domain": "geosite:category-ads-all"` 的流量,通过 `[block]` 出站,转发至黑洞进行屏蔽
|
||||
3. APP试图访问国内域名 `"domain": "geosite:cn"` 的流量,通过 `[direct-out]` 出站,自由离开完成直连
|
||||
|
||||
这时,才让【路由功能】的好处稍微得到了一些展现。
|
||||
|
||||
|
||||
|
||||
### 3.5 所以 `geosite.dat` 到底是什么?不是有个 `GFWList` 吗?
|
||||
|
||||
你想,这世界上的域名何止千万,如果我们每写一个基于【域名】匹配的路由规则,都要自己收集、手动输入域名,那效率将会何其低下!
|
||||
|
||||
而如果所有的域名都只有一个种类,`[direct], [proxy], [block]` 只能三选其一,那又是多么的不方便!
|
||||
|
||||
就如关羽需要他的青龙偃月刀,`geosite.dat` 文件便作为【路由功能】驱使的神兵利器横空出世了,它致力于为用户提供成熟完善的【域名分类表】。让用户可以简单的通过 `geosite:xxx` 这种格式方便的调用任何子类,定制符合自身需求的路由规则。
|
||||
|
||||
这种模块化结构提供的灵活性,其实远超传统的一揽子防火墙域名列表 [`GFWList`](https://github.com/gfwlist/gfwlist)。为什么这么说呢?比如,你可以指定苹果的域名 `geosite:apple` 和icloud相关域名 `geosite:icloud` 通过代理 `[proxy]`,但是苹果的软件域名 `geosite:apple-update` 保持直连 `[direct]` 来保持最大下载速度。
|
||||
|
||||
::: warning
|
||||
**注意:** 现在,`geosite.dat` 文件其实有多种选择:
|
||||
|
||||
最初,从 `Victoria Raymond` 主力维护 `Project V` 项目时期,便提供了最初的配套项目:[`domain-list-community`](https://github.com/v2ray/domain-list-community),用来收集、沉淀、分类各种常用的域名类型;
|
||||
|
||||
之后,随着V姐突然消失导致 `Project V` 的原项目开发陷入停滞,`v2fly` 社区维护并持续更新了社区版本的 [`domain-list-community`](https://github.com/v2fly/domain-list-community);
|
||||
|
||||
同时,[@Loyalsoldier](Loyalsoldier) 维护了其个人修改增强的路由规则文件 [v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat),提供了诸多不同的选择和分类逻辑;
|
||||
|
||||
另外,`Project X` 也计划于未来定制维护更适合 `Xray` 使用的路由规则文件 [Xray-rules-dat](https://github.com/XTLS/Xray-rules-dat)。~~(你们看,文件夹都建好了,所以快了快了)~~
|
||||
|
||||
甚至,你还可以定制自己的 `geosite` 文件,外挂给 `Xray` 使用,但是这个就跑题了,本文不展开。
|
||||
|
||||
如果你发现有些你遇到的域名没有被合理分类,请向上面的项目们提出 `issue` 甚至提交 `Pull Request` 吧!社区列表社区维护,人人为我我为人人!
|
||||
|
||||
:::
|
||||
|
||||
|
||||
|
||||
### 3.6 军师锦囊藏奇兵:一条隐藏的路由规则
|
||||
|
||||
事实上,当你认真思考上面的规则,不难发现一个问题,我们的所有规则都只规定了【当入站流量 **符合某种条件时** 应该被转发给哪个出站】,那么,如果 `geosite.dat` 文件不全面,我们的入站流量【**不符合任何条件时**】,`Xray` 会怎么处理呢?
|
||||
|
||||
::: warning 注意
|
||||
如果你认为【不符合条件当然就无法连接啦!】的话,你可要重新思考一下哦。因为只有指定了 `[block]` 规则,才会被导入到 `blackhole` 黑洞协议从而阻断连接
|
||||
:::
|
||||
|
||||
事实上,`Xray` 为了避免路由规则不完全导致的规则混乱,已经贴心的提供了一条隐藏的路由规则:【**当入站流量不符合任何条件时,转发给第一个出站** 】
|
||||
|
||||
这样,就不会有任何流量被漏掉了。所以,你一定要把你最信赖的心腹大将放在【第一条出站】,让它为你守城护池。
|
||||
|
||||
|
||||
|
||||
### 3.7 再看“三分天下”的大地图
|
||||
|
||||
因为我们在前面的示例中把 `[proxy-out-vless]` 放在了出站的第一位,所以隐藏规则生效时,流量会通过 `VLESS` 协议被转发至远端的VPS。因此,`Xray` 此时的完整工作逻辑如下:
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
S(APP数据) .-> I[入站]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
|
||||
R[路由] -- "geosite:cn" --> O2[direct]
|
||||
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
R[路由] -. "没有命中规则的流量" .-> O4[第一条出站]
|
||||
|
||||
end
|
||||
|
||||
O2 .-> D(国内服务器)
|
||||
O3 .-> V(VPS)
|
||||
O4 .-> V(VPS)
|
||||
|
||||
O1:::redclass
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
|
||||
classDef redclass fill:#FF0000
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||||
|
||||
```
|
||||
|
||||
|
||||
事实上,这就是传统所谓的 **【默认科学上网、国内网站白名单直连】** 的配置。
|
||||
|
||||
|
||||
## 4. “三分天下” 之 “蜀魏争雄”
|
||||
|
||||
现在,你已经知道了隐藏的默认路由规则:【**当入站流量不符合任何条件时,转发给第一个出站** 】。这时候,你应该能看出来,究竟是【科学上网】为王,还是【直连】称霸,全看你的第一条出站是什么!
|
||||
|
||||
上一步我们已经配置出了 **【默认科学上网、国内网站白名单直连】** 的规则。那么现在只要 **【把直连规则放在第一位】**,就立即变成了正好相反的 **【默认直连、国外网站白名单科学上网】** 规则。
|
||||
|
||||
是不是,非常的简单?
|
||||
|
||||
```
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "direct-out",
|
||||
"protocol": "freedom"
|
||||
},
|
||||
{
|
||||
"tag": "proxy-out-vless",
|
||||
......
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"protocol": "blackhole"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
此时,路由规则其实变成了:
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
S(APP数据) .-> I[入站]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
|
||||
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
R[路由] -- "geosite:cn" --> O2[direct]
|
||||
R[路由] -. "没有命中规则的流量" .-> O4[第一条出站]
|
||||
|
||||
end
|
||||
|
||||
O2 .-> D(国内服务器)
|
||||
O3 .-> V(VPS)
|
||||
O4 .-> D
|
||||
|
||||
O1:::redclass
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
classDef redclass fill:#FF0000
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||||
|
||||
```
|
||||
|
||||
这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。
|
||||
|
||||
至此,我们已经解释完了 **【如何利用 `geosite.dat` 文件,通过路由规则,根据【域名】来分流网络流量】。**
|
||||
|
||||
|
||||
## 5. 攻城略池 - 多种路由匹配条件
|
||||
|
||||
请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。
|
||||
|
||||
等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 [《路由 (routing) 功能简析(下)》](./routing-lv1-part2) 吧!
|
||||
@@ -0,0 +1,486 @@
|
||||
# 路由 (routing) 功能简析(下)
|
||||
|
||||
欢迎继续学习 `Xray` 的【路由】功能!
|
||||
|
||||
在 [《路由 (routing) 功能简析(上)》](./routing-lv1-part1) 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 `geosite.dat` 文件做了简单的域名分流配置。
|
||||
|
||||
如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!
|
||||
|
||||
|
||||
## 5. 攻城略池 - 多种路由匹配条件
|
||||
> `[域名], [IP], [协议], etc.`
|
||||
|
||||
|
||||
基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?
|
||||
|
||||
因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:
|
||||
|
||||
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下载很可能导致违规使用被封,这该如何强制直连?
|
||||
10. ......
|
||||
|
||||
我之所以说只用【域名分流】会漏洞百出,是因为 `geosite.dat` 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:
|
||||
|
||||
- 无法匹配文件里没有的新域名
|
||||
- 无法匹配基于IP地址的规则
|
||||
- 无法匹配基于网络协议的规则
|
||||
|
||||
::: warning 啰嗦君
|
||||
那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【**转发给第一个出站** 】。这其实就是说:
|
||||
|
||||
- 当你的第一个出站是 `[direct-out]` 时:**需要直连的都正确了,但需要代理的则都错误**
|
||||
- 当你的第一个出站是 `[proxy-out-vless]` 时:**需要代理的都正确了,但需要直连的则都错误**
|
||||
:::
|
||||
|
||||
|
||||
所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?**当然存在!** 我们需要的只是【域名】之外更多的【**分流判断依据**】而已。
|
||||
|
||||
|
||||
### 5.1 基于指定域名分流:`[domain], [full]` 等
|
||||
|
||||
1. 如果需要匹配某个子域名,如 `a-name.yourdomain.com`,我们使用 `full: "a-name.yourdomain.com"`
|
||||
2. 前面的 `问题1` 和 `问题2`,就可以通过给 `proxy.yourdomain.com` 指定 `[proxy-out-vless]` 出站,给 `direct.yourdomain.com` 指定 `[direct-out]` 出站来解决
|
||||
3. 如果需要匹配 `yourdomain.com` 的所有子域名,我们使用 `domain: "yourdomain.com"` 实现
|
||||
4. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
|
||||
5. 另外,`[domain]` 还支持正则表达式等匹配方式。详情请参考 [《基础配置模块 - 路由》文档](../../../config/base/routing/)
|
||||
|
||||
上述配置如下:
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
// 指定子域名直连
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"full:direct.yourdomain.com"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
// 指定子域名转发VPS
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"full:proxy.yourdomain.com"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
},
|
||||
// 指定泛域名转发VPS
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"yourdomain.com"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 5.2 基于IP文件分流:`geoip.dat`
|
||||
|
||||
与 `geosite.dat` 规则文件十分类似的,我们还有 `geoip.dat` 这个规则文件,它致力于为用户提供成熟完善的【IP分类表】。让用户可以简单的通过 `geoip:xxx` 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。
|
||||
|
||||
1. 解决前面的 `[问题3], [问题4]`,我们使用 `geoip:private` 类别来指定 `[direct-out]`
|
||||
2. 解决前面的 `[问题7]`,我们使用 `geoip:cn` 类别来指定 `[direct-out]`
|
||||
3. 解决前面的 `[问题8]`,由于 `geoip` 中没有【非中国IP】这个分类(因为这等于要收集全世界的IP段),所以我们用隐藏规则代替,也就是将 `[proxy-out-vless]` 放在第一个出站
|
||||
|
||||
上述配置如下:
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
// 本机内部地址、局域网地址直连
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"geoip:private"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
// 国内IP集直连
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"geoip:cn"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 5.3 基于指定IP地址分流
|
||||
|
||||
与 `geosite.dat` 规则文件十分类似的,我们还有 `geoip.dat` 这个规则文件,它是供【路由功能】驱使的**第二个神兵利器**,它致力于为用户提供成熟完善的【IP分类表】。让用户可以简单的通过 `geoip:xxx` 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。
|
||||
|
||||
1. 解决前面的 `[问题5]`,我们使用 `ip: "223.5.5.5"` 来指定 `[direct-out]`
|
||||
2. 解决前面的 `[问题6]`,我们使用 `ip: "1.1.1.1"` 来指定 `[proxy-out-vless]`
|
||||
|
||||
上述配置如下:
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
// 指定IP地址直连
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"223.5.5.5"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
// 指定IP地址转发VPS
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"1.1.1.1"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 5.4 基于协议类型分流:`[protocol]` 等
|
||||
|
||||
1. 解决前面的 `[问题9]`,我们使用 `"protocol": ["bittorrent"]` 类别来指定 `[direct-out]`
|
||||
|
||||
::: tip
|
||||
你需要打开入站代理中的 `sniffing` 才能使用此种方式分流。
|
||||
:::
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
// 指定 BT 协议直连
|
||||
{
|
||||
"type": "field",
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 5.5 基于更多条件的分流
|
||||
|
||||
到目前位置,我们仍然只讲了【路由功能】分流能力的冰山一角!因为它还支持很多其他的判断条件!我在此简单罗列如下:
|
||||
|
||||
本文已经讲过的:
|
||||
- `inboundTag`
|
||||
- `domain`
|
||||
- `ip`
|
||||
- `protocol`
|
||||
|
||||
本文尚未讲到的:
|
||||
- `port`
|
||||
- `sourcePort`
|
||||
- `network`
|
||||
- `source`
|
||||
- `user`
|
||||
- `attrs`
|
||||
|
||||
但这些内容实在是过多,全部展开就远远不是 `level-1` 的内容了,所以,需要这些复杂条件的朋友,请仔细阅读 [《基础配置模块 - 路由》文档](../../config/base/routing/) 自学哦!有问题就去 TG 群里面问问吧!
|
||||
|
||||
|
||||
|
||||
|
||||
## 6. “霸业初定”:路由规则整体回顾
|
||||
|
||||
到现在为止,我们已经累积出了一套战略雄伟、战术精准的路由规则,为了避免混乱,现在就对它进行一次完整的整理和回顾。
|
||||
|
||||
::: warning 注意
|
||||
路由生效的顺序是:【从上往下,依次判断】,所以我一般推荐的规则顺序是:
|
||||
|
||||
`[1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]`
|
||||
:::
|
||||
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
// [1-block 广告流量屏蔽]
|
||||
// 1.1 广告域名集屏蔽
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:category-ads-all"
|
||||
],
|
||||
"outboundTag": "block"
|
||||
},
|
||||
// [2-direct 国内流量直连]
|
||||
// 2.1 国内域名集、指定子域名直连
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:cn",
|
||||
"full:direct.yourdomain.com"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
// 2.2 本机内部地址+局域网、国内IP、指定IP直连
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"geoip:private",
|
||||
"geoip:cn",
|
||||
"223.5.5.5"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
// 2.3 BT协议流量直连
|
||||
{
|
||||
"type": "field",
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
// [3-proxy 国外流量转发VPS]
|
||||
// 3.1 国外域名集、指定子域名、指定泛域名转发VPS
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:geolocation-!cn",
|
||||
"full:proxy.yourdomain.com",
|
||||
"yourdomain.com"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
},
|
||||
// 3.2 指定IP转发VPS
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"1.1.1.1"
|
||||
],
|
||||
"outboundTag": "proxy-out-vless"
|
||||
}
|
||||
// [4-default-routing 第一条出站]
|
||||
// 没有匹配到任何规则的流量,默认使用第一条出站处理
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
此时,路由规则其实变成了:
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
|
||||
S(APP数据) .-> I[入站]
|
||||
|
||||
subgraph Xray
|
||||
I --> R[路由] -- "geosite:category-ads-all" --> O1[block]
|
||||
|
||||
R[路由] -- "geosite:cn" --> O2[direct]
|
||||
R[路由] -- "direct.yourdomain.com" --> O2[direct]
|
||||
R[路由] -- "geoip:private" --> O2[direct]
|
||||
R[路由] -- "geoip:cn" --> O2[direct]
|
||||
R[路由] -- "ip:223.5.5.5" --> O2[direct]
|
||||
R[路由] -- "protocol:bittorrent" --> O2[direct]
|
||||
|
||||
R[路由] -- "geosite:geolocation-!cn" --> O3[proxy]
|
||||
R[路由] -- "proxy.yourdomain.com" --> O3[proxy]
|
||||
R[路由] -- "*.yourdomain.com" --> O3[proxy]
|
||||
R[路由] -- "ip:1.1.1.1" --> O3[proxy]
|
||||
|
||||
R[路由] -. "没有命中规则的流量" .-> O4[第一条出站]
|
||||
|
||||
end
|
||||
|
||||
O2 .-> D(国内服务器)
|
||||
O3 .-> V(VPS)
|
||||
|
||||
O1:::redclass
|
||||
V:::greyclass
|
||||
S:::greyclass
|
||||
R:::routingclass
|
||||
classDef redclass fill:#FF0000
|
||||
classDef greyclass fill:#C0C0C0
|
||||
classDef routingclass fill:#FFFFDE,stroke:#000000
|
||||
|
||||
```
|
||||
|
||||
至于第一条出站是 `[direct-out]` 还是 `[proxy-out-vless]`,这就全看你的需求了。
|
||||
|
||||
|
||||
|
||||
|
||||
## 7. 路由配置常见错误
|
||||
|
||||
请大家注意看,我上面每一条路由规则,都是一个独立的匹配依据,只有这样才能确保生效。而新人在自定义路由规则时常犯的一个错误就是:**在一条规则内同时匹配了多种不同的匹配依据,造成匹配无效。**
|
||||
|
||||
比如,他希望实现的配置是:
|
||||
1. 自己的 `direct.yourdomain.com` 直连
|
||||
2. 国内DNS查询(如 `223.5.5.5`)直连
|
||||
|
||||
|
||||
|
||||
### 7.1 错误示范
|
||||
|
||||
为了实现上面的目标,他写出了以下路由规则:
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"223.5.5.5"
|
||||
],
|
||||
"domain": [
|
||||
"full:direct.yourdomain.com"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
你能看出这里面的错误吗?乍一看,似乎是对的?
|
||||
|
||||
::: warning 注意
|
||||
**同一个规则之内,各个依据需要同时成立,才会匹配成功**,逻辑关系是 `和`,而不是 `或`。
|
||||
:::
|
||||
|
||||
换言之,这条规则的意思是:【当你访问的 ` 目标 = direct.yourdomain.com`, **并且** 同时还满足 ` 目标 = 223.5.5.5` 时,`Xray` 才会将流量转发给 `[direct-out]` 直连出站】
|
||||
|
||||
很显然,一个目标不可能同时等于两个不同的值,所以这不但是一个永远不可能实现的无效规则,更与原本的目标风马牛不相及。
|
||||
|
||||
|
||||
|
||||
### 7.2 正确示范
|
||||
|
||||
正确示范,自然就是将不同的匹配依据独立出来:
|
||||
|
||||
```
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"223.5.5.5"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"full:direct.yourdomain.com"
|
||||
],
|
||||
"outboundTag": "direct-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
其实,第6点已经是我整理过的规则了,原则就是【相同的匹配依据可以合并,不同的匹配依据保持独立】。
|
||||
|
||||
|
||||
|
||||
|
||||
## 8. 明修栈道、暗渡陈仓
|
||||
> `[domain]` 转化 `[ip]` 的密道:`domainStrategy`
|
||||
|
||||
我们在 5.4 中提交了多种流量判断的【依据】,其中一种是域名 `[domain]`、一种是 `[IP]`。
|
||||
|
||||
如果你初步了解过DNS的运作过程,就会知道,我们对一个域名 `[domain]` 发起访问请求时,其实需要先向 `DNS` 发起请求来解析域名 `[domain]` 对应的 `[IP]`,在得到 `[IP]` 后再向它发起实际请求。
|
||||
|
||||
所以,面对入站的一次域名请求,`Xray` 其实有两次机会去判断它的类型。那么,究竟是否要用这两次机会呢?这就是由 `domainStrategy` 这个配置来决定的。它有三个选项:
|
||||
|
||||
- `AsIs`
|
||||
- `IPIfNonMatch`
|
||||
- `IPOnDemand`
|
||||
|
||||
按么我们逐个来解释一下:
|
||||
|
||||
|
||||
|
||||
### 8.1 域名策略: `"AsIs"`
|
||||
|
||||
就是 "As Domain Is",也就是说 【域名什么样,就什么样,不多折腾】。
|
||||
|
||||
简单粗暴理解就是说【仅用 `[domain]` 来匹配】。
|
||||
|
||||
::: tip
|
||||
`AsIs` 的实际意义为 【如原先所示,不加修改】,🍉老师这里描述的不是很恰当。
|
||||
:::
|
||||
|
||||
这个方式的处理都在 `Xray` 内部完成,没有与外界的数据往来,所以速度最快。它的兜底策略也很清晰:即前面所说的、无法匹配的域名自动转入第一条出站处理。所以,对于常规使用路由功能这最推荐的策略。
|
||||
|
||||
|
||||
|
||||
### 8.2 域名策略: `"IPIfNonMatch"`
|
||||
|
||||
就是 "lookup IP if (there's) no matching rule",也就是说【如果其他所有规则都匹配不上,那就转化成 `IP` 去匹配 `IP` 规则】。
|
||||
|
||||
简单粗暴理解就是说【先把访问目标和其他所有类型规则匹配,如果匹配不上,那就通过 `DNS` 查询转化成 `IP`,再从头和所有规则匹配一次】。
|
||||
|
||||
该策略下没有命中任何规则的这一部分域名,会需要再经历 `DNS` 查询过程、以及第二轮规则匹配的过程,其耗时会多于 `AsIs` 策略,所以并不是首选推荐的策略。
|
||||
|
||||
|
||||
### 8.3 域名策略: `"IPOnDemand"`
|
||||
|
||||
这里其实说 `Demand IP` 更准确些,也就是说【当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配】。
|
||||
|
||||
简单粗暴理解就是说【只要路由规则中有 `IP` 类规则,那么所有基于域名 `[domain]` 的请求都要解析成 `[IP]` 然后去匹配 `[IP]` 类规则】。
|
||||
|
||||
它要对所有首次域名访问进行 `DNS` 解析,所以首次查询比较耗时。虽然由于 `Xray` 中 `DNS` 缓存机制的存在,后续对相同域名的访问速度会重回巅峰,但总体来说也不是首选推荐的策略。
|
||||
|
||||
::: warning 啰嗦君
|
||||
`domainStrategy` 仅对域名生效,不要搞混了哦~
|
||||
:::
|
||||
|
||||
|
||||
|
||||
## 9. 思考题
|
||||
|
||||
迄今为止,我们都是在【单入站】和【单出站】的基础上,讲解【路由】内部的各种配置逻辑。
|
||||
|
||||
但是,如你所知,`Xray` 本身是支持多端口,多协议的。那么,如果我问你:
|
||||
|
||||
1. 我希望 `VLESS` 协议将我日常的网页浏览和APP流量转发给美国的大流量服务器
|
||||
2. 我希望 `trojan` 协议将我的所有Netflix流量转发给日本的服务器解锁各种二次元
|
||||
3. 我希望 `shadowsocks` 协议将我所有的游戏流量转发给香港的服务器达到最低的延迟
|
||||
4. 我希望有一个独立的端口,能够把 `telegram` 的流量全都转发给VPS
|
||||
5. 我希望有一个独立的端口,能够把 `bittorrent` 下载流量全都转发给欧洲大盘鸡
|
||||
6. 我希望......
|
||||
|
||||
这些想法,是否能通过【路由】功能配置实现呢?
|
||||
|
||||
答案当然是 **【完全可以】** 啦! 但是这些对于 `level-1` 来说已经超纲了,就留给各位自由的探索吧!
|
||||
|
||||
|
||||
## 10. 结语
|
||||
|
||||
至此,`Xray` 的【路由】功能就介绍完了。希望本文能够对你理解 `Xray` 的灵活有所帮助。
|
||||
|
||||
## 11. 尾注
|
||||
|
||||
- 现在你可以重新阅读一遍 [路由](../../config/routing.md),看看是否有更加深刻的理解。
|
||||
- 🍉🍉🍉🍉🍉 :D
|
||||
@@ -0,0 +1,58 @@
|
||||
# Xray的工作模式
|
||||
|
||||
## 单服务器模式
|
||||
|
||||
|
||||
与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
A(PC) -.- B(防火墙);
|
||||
B -.-> C(墙外网站);
|
||||
A --> D(Xray/VPS);
|
||||
D --> C;
|
||||
A --> E(墙内网站);
|
||||
```
|
||||
|
||||
一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。
|
||||
|
||||
|
||||
## 桥接模式
|
||||
|
||||
|
||||
如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
A(PC) -.-> B(防火墙);
|
||||
B -.-> C(墙外网站);
|
||||
A --> D(墙内 VPS);
|
||||
D --> E(墙外 VPS);
|
||||
E --> C;
|
||||
D --> F(墙内网站);
|
||||
```
|
||||
|
||||
|
||||
## 工作原理
|
||||
|
||||
在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。
|
||||
|
||||
``` mermaid
|
||||
graph LR;
|
||||
A1(inbound) --> D(Dispatcher / Router / DNS);
|
||||
A2(inbound) --> D;
|
||||
A3(inbound) --> D;
|
||||
A4(inbound) --> D;
|
||||
D --> B1(outbound);
|
||||
D --> B2(outbound);
|
||||
D --> B3(outbound);
|
||||
D --> B4(outbound);
|
||||
```
|
||||
|
||||
- 需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。
|
||||
- 入站连接负责与客户端(如浏览器)通信:
|
||||
- 入站连接通常可以配置用户认证,如 ID 和密码等;
|
||||
- 入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;
|
||||
- 出站连接负责将数据发给服务器,如另一台主机上的 Xray。
|
||||
- 当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。
|
||||
- 路由会在必要时查询 DNS 以获取更多信息来进行判断。
|
||||
Reference in New Issue
Block a user