Skip to content

Commit d1b09ea

Browse files
committed
Update VLESS Reverse Proxy Again
XTLS/Xray-core#6110 (comment)
1 parent d89dfc9 commit d1b09ea

3 files changed

Lines changed: 774 additions & 57 deletions

File tree

docs/document/level-2/vless_reverse.md

Lines changed: 258 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# VLESS 反向代理示例
22

3-
本文演示如何使用 Xray 的 VLESS 反向代理能力,通过公网服务器把流量送回远程内网。这里给出两种常见用法
3+
本文演示如何使用 Xray 的 VLESS 反向代理能力,通过公网服务器把流量送回远程内网,或者再借家庭宽带继续访问公网。这里给出三种常见用法
44

55
- `入口转发`:远程端口映射,将公网入口端口映射到远程内网 Web 服务;
6-
- `远程回家`:远程内网漫游,用户通过公网服务器中转,回到家里的内网继续访问资源。
6+
- `远程回家`:远程内网漫游,用户通过公网服务器中转,回到家里的内网继续访问资源;
7+
- `家宽落地`:用户通过公网服务器中转,把特定流量送回家中设备,再从家庭宽带出口访问公网。
78

89
## 入口转发
910

@@ -212,13 +213,12 @@ sequenceDiagram
212213

213214
### 场景说明
214215

215-
这一部分不是把某个公网端口暴露给外部访问,而是让用户先连接公网服务器上的 VLESS,再借助已经建立好的反向通道,把这个用户的流量继续送回家里的内网设备处理。
216+
这一部分不是把某个公网端口暴露给外部访问,而是让用户先接入公网的 Xray 服务器,再借助已经建立好的反向通道,把这个用户的流量继续送回家里的内网设备处理。
216217

217218
这种用法更接近:
218219

219220
- 在外漫游时访问家里的局域网资源;
220-
- 把特定用户的出口放回家里;
221-
- 通过公网服务器中转,回到家庭网络继续访问 NAS、路由器面板、家庭 DNS 或其他内网服务。
221+
- 通过公网服务器中转,回到家庭网络继续访问 NAS、路由器面板或其他内网服务。
222222

223223
```mermaid
224224
flowchart LR
@@ -228,7 +228,7 @@ flowchart LR
228228
H[家庭局域网资源]
229229
230230
I -- 主动建立 VLESS 反向连接 --> S
231-
U -- 连接公网服务器上的 VLESS 入口 --> S
231+
U -- 接入公网服务器上的 Xray 入口 --> S
232232
S -- 用户流量经 reverse 转发 --> I
233233
I -- 再访问家庭局域网 --> H
234234
```
@@ -238,9 +238,9 @@ flowchart LR
238238
和第一篇相比,这里最大的区别不在于反向连接本身,而在于公网侧的路由目标:
239239

240240
- 第一篇是 `inboundTag -> reverse-out`,把某个入口端口映射回内网;
241-
- 第二篇是 `user -> reverse-out`,把某个用户的代理流量交给内网设备继续处理。
241+
- 这一篇是 `user -> reverse-out`,把某个用户的代理流量交给内网设备继续处理。
242242

243-
也就是说,公网服务器在这里更像一个中转站。用户并不是直接“访问公网端口映射到的服务”,而是“先接入公网服务器上的 VLESS 入口,再从家里的设备继续出发”。
243+
也就是说,公网服务器在这里更像一个中转站。用户并不是直接“访问公网端口映射到的服务”,而是“先接入公网服务器上的 Xray 入口,再从家里的设备继续出发”。
244244

245245
### 公网服务器配置
246246

@@ -407,7 +407,7 @@ sequenceDiagram
407407
U->>S: 使用 roam@example.com 接入公网服务器
408408
S->>S: user 路由命中 reverse-out
409409
S->>I: 将用户流量送入 reverse 通道
410-
I->>H: 访问 NAS / 路由器 / 家庭 DNS / 内网服务
410+
I->>H: 访问 NAS / 路由器 / 内网服务
411411
H-->>I: 返回响应
412412
I-->>S: 经反向通道返回
413413
S-->>U: 响应用户
@@ -416,36 +416,271 @@ sequenceDiagram
416416
### 这种用法和第一篇的区别
417417

418418
- 第一篇是“把公网一个入口端口映射到远程内网某个固定服务”,无需额外身份验证,全世界谁都可以访问此服务;
419-
- 第二篇是“让某个用户先拨入公网的 Xray 服务器,再借道反向代理回家继续访问”;
419+
- 这一篇是“让某个用户先接入公网的 Xray 服务器,再借道反向代理回家继续访问”;
420420
- 第一篇更像远程端口映射,也称内网穿透;
421-
- 第二篇更像远程漫游或轻量异地组网
421+
- 这一篇更像远程漫游或轻量异地组网
422422

423423
### 安全建议
424424

425425
- 如果有多个漫游用户,建议每个用户使用独立 UUID 或独立标识;
426426
- 示例配置为追求简化仅用了 VLESS-enc 实际使用时可能需要使用 REALITY/XHTTP 等伪装流量。
427427

428+
::: tip 延申
429+
如果你想要的不是“访问几个固定内网资源”这种点到站模式,而是需要站到站的 L4 组网,那么可以配合路由表 + TUN,或者让 Xray 作为网关来做透明代理。
430+
:::
431+
432+
## 家宽落地
433+
434+
把特定流量送回家中设备,再从家庭宽带出口继续访问公网。
435+
436+
### 场景说明
437+
438+
这一部分不是为了访问家里的 NAS、路由器面板或其他内网服务,而是让用户先接入公网的 Xray 服务器,再借助已经建立好的反向通道,把其中一部分流量送回家中设备,最后通过家庭宽带继续访问公网。
439+
440+
这种用法更接近:
441+
442+
- 让特定流量使用家里的住宅宽带出口 IP;
443+
- 家里没有独享公网 IP,或者没有权限做 IPv4 端口映射、放通 IPv6 防火墙,或者不想暴露端口、折腾 DDNS;
444+
- 由公网服务器承接用户接入,再把需要家宽落地的流量送回家中设备处理。
445+
446+
::: tip
447+
一个具体的场景是,想要用家宽来保障 ChatGPT 不降智。跟流媒体解锁不同的是,前者需要真正独享的住宅宽带出口。而现实中“24K·真家宽”的提供者往往是你的朋友,设置他们的光猫、路由器极其地不方便。所以最便捷的做法是给他一个设备连上网就能用,VLESS 反向代理正契合这种场景。
448+
449+
格局打开,你好~~大冤种~~朋友正在使用的手机也可以 7 × 24 小时运行 Xray 作为落地设备!蜂窝网络解锁效果是一样的,考验你们友情的时候到了~
450+
:::
451+
452+
```mermaid
453+
flowchart LR
454+
U[外部用户设备]
455+
S[公网服务器]
456+
I[家中设备]
457+
P[公网目标]
458+
459+
I -- 主动建立 VLESS 反向连接 --> S
460+
U -- 接入公网服务器上的 Xray 入口 --> S
461+
S -- 指定流量经 reverse 转发 --> I
462+
I -- 通过家庭宽带访问公网 --> P
463+
```
464+
465+
### 配置思路
466+
467+
跟第二篇基本相同,只是路由的对象不同。第二篇是 `user -> reverse-out`,这一篇则是 `特定域名 -> reverse-out`。公网服务器和家中设备之间的反向连接方式本身不变。
468+
469+
### 公网服务器配置
470+
471+
这个示例里:
472+
473+
- 第一个 UUID 仍然用于家中设备建立反向连接;
474+
- 第二个 UUID 用于外部用户接入公网服务器;
475+
- 路由把接入用户访问 `geosite:openai` 的流量转发到 `reverse-out`
476+
477+
公网服务器这一侧和第二篇基本相同,只是把上一节按 `user` 分流,改成了按 `domain` 分流。
478+
479+
```json
480+
{
481+
"inbounds": [
482+
{
483+
"listen": "0.0.0.0",
484+
"port": 8443,
485+
"protocol": "vless",
486+
// 这里建议开启嗅探,否则按 domain 路由时可能看不到目标域名
487+
"sniffing": {
488+
"enabled": true,
489+
"destOverride": ["http", "tls", "quic"]
490+
},
491+
"settings": {
492+
"decryption": "mlkem768x25519plus.native.600s.aCF82eKiK6g0DIbv0_nsjbHC4RyKCc9NRjl-X9lyi0k",
493+
"clients": [
494+
{
495+
"id": "ac04551d-6ebf-4685-86e2-17c12491f7f4",
496+
"flow": "xtls-rprx-vision",
497+
"reverse": {
498+
"tag": "reverse-out"
499+
}
500+
},
501+
{
502+
"id": "e8758aff-d830-4d08-a59e-271df65b995a",
503+
"flow": "xtls-rprx-vision"
504+
}
505+
]
506+
}
507+
}
508+
],
509+
"routing": {
510+
"rules": [
511+
{
512+
"domain": ["geosite:openai"],
513+
"outboundTag": "reverse-out"
514+
}
515+
]
516+
},
517+
"outbounds": [
518+
{
519+
"protocol": "freedom"
520+
}
521+
]
522+
}
523+
```
524+
525+
上面这组规则的含义是:
526+
527+
- 家中设备通过第一个 UUID 回连公网服务器;
528+
- 外部用户通过第二个 UUID 接入公网服务器;
529+
- 这条公网入站建议开启 `sniffing`,否则按域名分流时可能看不到目标域名;
530+
- 只要访问目标命中 `geosite:openai`,流量就会被送进 `reverse-out`
531+
- 其他没有命中的流量继续走默认 `freedom`,也就是留在公网服务器本地出站。
532+
533+
### 家中设备配置
534+
535+
家中设备这一侧也和第二篇基本相同,只是这次不再放行某个内网网段,而是放行所有非私有地址,让流量从家庭宽带继续访问公网。
536+
537+
```json
538+
{
539+
"routing": {
540+
"rules": [
541+
{
542+
"inboundTag": ["reverse-in"],
543+
"outboundTag": "home-direct"
544+
}
545+
]
546+
},
547+
"outbounds": [
548+
{
549+
"protocol": "freedom"
550+
},
551+
{
552+
"protocol": "freedom",
553+
"tag": "home-direct",
554+
"settings": {
555+
"finalRules": [
556+
{
557+
"action": "allow",
558+
"network": "tcp,udp",
559+
"ip": ["!geoip:private"]
560+
}
561+
]
562+
}
563+
},
564+
{
565+
"protocol": "vless",
566+
"settings": {
567+
"address": "yourserver.com",
568+
"port": 8443,
569+
"encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk",
570+
"id": "ac04551d-6ebf-4685-86e2-17c12491f7f4",
571+
"flow": "xtls-rprx-vision",
572+
"reverse": {
573+
"tag": "reverse-in"
574+
}
575+
}
576+
}
577+
]
578+
}
579+
```
580+
581+
上面这组规则的含义是:
582+
583+
- 只要流量是从 `reverse-in` 进入的,就转给 `home-direct`
584+
- `home-direct` 通过 `finalRules` 只放行公网流量。
585+
586+
### 用户设备配置
587+
588+
用户设备这一侧用经典的“`cn -> direct,其它全代理`”即可:
589+
590+
```json
591+
{
592+
"routing": {
593+
"rules": [
594+
{
595+
"domain": ["geosite:cn"],
596+
"outboundTag": "direct"
597+
},
598+
{
599+
"ip": ["geoip:private", "geoip:cn"],
600+
"outboundTag": "direct"
601+
}
602+
]
603+
},
604+
"outbounds": [
605+
{
606+
"protocol": "vless",
607+
"tag": "to-server",
608+
"settings": {
609+
"address": "yourserver.com",
610+
"port": 8443,
611+
"encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk",
612+
"id": "e8758aff-d830-4d08-a59e-271df65b995a",
613+
"flow": "xtls-rprx-vision"
614+
}
615+
},
616+
{
617+
"protocol": "freedom",
618+
"tag": "direct"
619+
}
620+
]
621+
}
622+
```
623+
624+
上面这组规则的含义是:
625+
626+
- 国内域名和国内 IP 继续本地直连;
627+
- 其他没有命中的流量默认都走 `to-server`,也就是发往公网服务器;
628+
- 到了公网服务器之后,再由上一节的 `geosite:openai -> reverse-out` 决定哪些流量需要走家宽。
629+
630+
### 请求流向
631+
632+
```mermaid
633+
sequenceDiagram
634+
participant U as 外部用户设备
635+
participant S as 公网服务器
636+
participant I as 家中设备
637+
participant P as 公网目标
638+
639+
I->>S: 建立 VLESS 反向连接
640+
U->>S: 接入公网服务器
641+
U->>S: 命中需要家宽落地的流量
642+
S->>S: 路由命中 reverse-out
643+
S->>I: 将指定流量送入 reverse 通道
644+
I->>P: 通过家庭宽带访问公网
645+
P-->>I: 返回响应
646+
I-->>S: 经反向通道返回
647+
S-->>U: 响应用户
648+
```
649+
650+
### 这种用法和第二篇的区别
651+
652+
- 第二篇是“回家访问内网资源”;
653+
- 这一篇是“回家借用家宽出口访问公网”;
654+
- 第二篇路由的重点是“哪些用户需要回家”;
655+
- 这一篇路由的重点是“哪些域名需要走家宽”。
656+
428657
## 小结
429658

430-
VLESS 反向代理至少可以覆盖两类场景
659+
至此本文介绍了 VLESS 反向代理的三类主场景和一类延申能力
431660

432-
- 把公网入口端口映射到远程内网固定服务;
433-
- 让用户接入公网服务器后再通过反向通道漫游回家。
661+
- 远程端口映射:把公网入口端口映射到远程内网特定服务;
662+
- 点到站 VPN:让用户接入公网服务器后再通过反向通道漫游回家;
663+
- 站到站 VPN:作为站到站的 L4 组网基础能力使用;
664+
- 家宽落地:让特定流量经由公网服务器回到家里,再从家庭宽带出口访问公网。
434665

435-
两者使用的是同一套反向连接机制,区别主要在公网侧如何路由流量,以及内网侧如何继续处理这些流量。理解这一点之后,就可以按自己的场景在“端口映射”和“远程漫游”之间自由扩展
666+
这些场景使用的都是同一套反向连接机制,区别主要在公网侧如何路由流量,以及内网侧如何继续处理这些流量。本文只是列出了几类常见用法,更重要的是理解这套机制本身;吃透原理之后,还可以按自己的需求继续挖掘和扩展
436667

437668
## 进阶技巧:高级负载均衡
438669

670+
如果你有多入口、多出口、异地多点回连的需求,希望同一组反向代理线路能够自动容灾、自动分摊流量,那么可以让多条连接共用同一个 `reverse.tag`,把它们放进同一个可用池。
671+
439672
如果公网端存在多个入站使用相同的 reverse tag,最终也只会对应产生一个出站;可以把它理解为多条线路同时挂在同一个可用池中,每次使用时随机选一路。
440673

441-
这种方式可以实现更灵活的多对多配置。假如某条线路暂时不可用,例如对应的内网端还没有连上来,那么它就不会进入当前可用池,后续流量会自动转发到其它仍然在线的线路上,无需手动切换。
674+
假如某条线路暂时不可用,例如对应的内网端还没有连上来,那么它就不会进入当前可用池,后续流量会自动转发到其它仍然在线的线路上,无需手动切换。
442675

443-
不难看出,`reverse.tag` 在两侧都是“同 tag 合并为一个连接池”的语义:
676+
内网侧同样允许这样重名:多个 VLESS 出站也可以共用同一个 `reverse-in`
677+
678+
不难看出,`reverse.tag` 在两侧都允许重名,重名后就会并到一起:
444679

445680
- 公网侧多个 client 共用同一个 `reverse-out`,会收敛为同一个出站池;
446681
- 内网侧多个 VLESS 出站共用同一个 `reverse-in`,会收敛为同一个入口池。
447682

448-
所以它天然可以扩展成 N 对 N。更常见的实际部署是:对外只有一个业务域名,例如 `www.example.com`,再通过 GeoDNS 把访客就近分配到美西和东京两台公网服务器;而内网端则分别回连 `us-reverse.example.com``jp-reverse.example.com` 这两个公网节点。再部署两个内网端:家里和办公室。家里、办公室都分别连到美西和东京,于是每个公网端都会维护一个“家里 + 办公室”的可用池。实际转发时,会从当前已建立的连接里随机选一条可用线路;某一端离线后,它会自动从池里消失。
683+
所以它天然可以扩展成 N 对 N。更常见的实际部署是:对外只有一个业务域名,例如 `www.example.com`,再通过 GeoDNS 把访客就近分配到美西和东京两台公网服务器;而内网端则分别回连 `us-reverse.example.com``jp-reverse.example.com` 这两个公网节点。再部署两个内网端:家里和办公室,都分别连到美西和东京,于是每个公网端都会维护一个“家里 + 办公室”的可用池。实际转发时,会从当前已建立的连接里随机选一条可用线路;某一端离线后,它会自动从池里消失。
449684

450685
下面给一个极简片段,只保留 reverse 相关部分,继续沿用“公网入口端口映射到内网服务”的写法。
451686

@@ -558,6 +793,10 @@ VLESS 反向代理至少可以覆盖两类场景:
558793

559794
和家里内网端完全同理,只是把 UUID 换成 `us-office-uuid``jp-office-uuid`,并把 `redirect` 改成办公室要暴露的内网服务。
560795

796+
::: tip 延申
797+
如果你希望这里的选路不只是“从当前可用连接里随机挑一条”,而是进一步按延迟、稳定性或观测结果做更细的路由决策,可以再结合 [`routing.balancer`](../../config/routing.md#balancerobject) 能力来设计出站选择策略。
798+
:::
799+
561800
## 进阶技巧:透传真实访客 IP
562801

563802
如果你希望内网 Web 服务看到真实访客 IP,而不是把访问来源识别成内网侧 Xray 那台机器的 IP 地址,可以在内网侧的 `freedom` 出站里开启 `proxyProtocol`。不开启时,后端 WebServer 看到的源地址通常就是内网侧 Xray 的 IP;开启后,Xray 在把连接转发到 `redirect` 指定的后端时,会先发送一段 PROXY protocol 头,把真实源地址一并传给 WebServer。
@@ -731,4 +970,4 @@ server {
731970
- 承接反向代理流量的内网 `freedom`(也就是常说的 `direct`)出站,建议按最小权限原则配置。把默认出站设为 `blackhole`,只把允许访问的目标显式路由到专用 `freedom`。再通过 `finalRules` 只放行必要的地址和端口。
732971
- 如果你使用的是别人提供的穿透服务用于远程回家,或者你并不完全信任公网 VPS,建议不要让反向代理流量直接落到真实内网业务。可以在内网再部署一个带 `VLESS Encryption` 的服务端专门承接这部分流量,再由它转发给实际业务,以补上身份认证和数据保护,否则有权限接触到公网服务器的人可以漫游你的内网。
733972
- 通过 `VLESS` 等入站协议把流量送到内网端时,路由系统里看到的 `Source` / `Local` 所属协议,不一定与最终 `Target` 一致。涉及 `source``local``network` 等条件时,应以实际流量形态为准,不要想当然地把它们等同起来。
734-
- `XHTTP``WebSocket` 等基于 HTTP 的入站当前会默认读取 `X-Forwarded-For`如果前面没有你自己信任的 HTTP 反向代理,这个头可以被客户端伪造,因此不要直接拿它做严格的安全判断,例如 IP 白名单、黑名单或审计归因
973+
- `XHTTP``WebSocket``HTTPUpgrade` 这三个基于 HTTP 的入站默认会读取 `X-Forwarded-For`如果你的前面链路里没有可信的 HTTP 反代,建议配合 [`sockopt.trustedXForwardedFor`](../../config/transports/sockopt.md#trustedxforwardedfor) 限制何时信任它,避免客户端伪造来源 IP。

0 commit comments

Comments
 (0)