From d1b09ea0174f3dd61b2b4b2ea298596086e92d23 Mon Sep 17 00:00:00 2001 From: Meow <197331664+Meo597@users.noreply.github.com> Date: Sun, 17 May 2026 06:52:35 +0800 Subject: [PATCH] Update VLESS Reverse Proxy Again https://github.com/XTLS/Xray-core/pull/6110#issuecomment-4467638188 --- docs/document/level-2/vless_reverse.md | 277 ++++++++++++++++++++-- docs/en/document/level-2/vless_reverse.md | 277 ++++++++++++++++++++-- docs/ru/document/level-2/vless_reverse.md | 277 ++++++++++++++++++++-- 3 files changed, 774 insertions(+), 57 deletions(-) diff --git a/docs/document/level-2/vless_reverse.md b/docs/document/level-2/vless_reverse.md index 47b4791e..6420098d 100644 --- a/docs/document/level-2/vless_reverse.md +++ b/docs/document/level-2/vless_reverse.md @@ -1,9 +1,10 @@ # VLESS 反向代理示例 -本文演示如何使用 Xray 的 VLESS 反向代理能力,通过公网服务器把流量送回远程内网。这里给出两种常见用法: +本文演示如何使用 Xray 的 VLESS 反向代理能力,通过公网服务器把流量送回远程内网,或者再借家庭宽带继续访问公网。这里给出三种常见用法: - `入口转发`:远程端口映射,将公网入口端口映射到远程内网 Web 服务; -- `远程回家`:远程内网漫游,用户通过公网服务器中转,回到家里的内网继续访问资源。 +- `远程回家`:远程内网漫游,用户通过公网服务器中转,回到家里的内网继续访问资源; +- `家宽落地`:用户通过公网服务器中转,把特定流量送回家中设备,再从家庭宽带出口访问公网。 ## 入口转发 @@ -212,13 +213,12 @@ sequenceDiagram ### 场景说明 -这一部分不是把某个公网端口暴露给外部访问,而是让用户先连接公网服务器上的 VLESS,再借助已经建立好的反向通道,把这个用户的流量继续送回家里的内网设备处理。 +这一部分不是把某个公网端口暴露给外部访问,而是让用户先接入公网的 Xray 服务器,再借助已经建立好的反向通道,把这个用户的流量继续送回家里的内网设备处理。 这种用法更接近: - 在外漫游时访问家里的局域网资源; -- 把特定用户的出口放回家里; -- 通过公网服务器中转,回到家庭网络继续访问 NAS、路由器面板、家庭 DNS 或其他内网服务。 +- 通过公网服务器中转,回到家庭网络继续访问 NAS、路由器面板或其他内网服务。 ```mermaid flowchart LR @@ -228,7 +228,7 @@ flowchart LR H[家庭局域网资源] I -- 主动建立 VLESS 反向连接 --> S - U -- 连接公网服务器上的 VLESS 入口 --> S + U -- 接入公网服务器上的 Xray 入口 --> S S -- 用户流量经 reverse 转发 --> I I -- 再访问家庭局域网 --> H ``` @@ -238,9 +238,9 @@ flowchart LR 和第一篇相比,这里最大的区别不在于反向连接本身,而在于公网侧的路由目标: - 第一篇是 `inboundTag -> reverse-out`,把某个入口端口映射回内网; -- 第二篇是 `user -> reverse-out`,把某个用户的代理流量交给内网设备继续处理。 +- 这一篇是 `user -> reverse-out`,把某个用户的代理流量交给内网设备继续处理。 -也就是说,公网服务器在这里更像一个中转站。用户并不是直接“访问公网端口映射到的服务”,而是“先接入公网服务器上的 VLESS 入口,再从家里的设备继续出发”。 +也就是说,公网服务器在这里更像一个中转站。用户并不是直接“访问公网端口映射到的服务”,而是“先接入公网服务器上的 Xray 入口,再从家里的设备继续出发”。 ### 公网服务器配置 @@ -407,7 +407,7 @@ sequenceDiagram U->>S: 使用 roam@example.com 接入公网服务器 S->>S: user 路由命中 reverse-out S->>I: 将用户流量送入 reverse 通道 - I->>H: 访问 NAS / 路由器 / 家庭 DNS / 内网服务 + I->>H: 访问 NAS / 路由器 / 内网服务 H-->>I: 返回响应 I-->>S: 经反向通道返回 S-->>U: 响应用户 @@ -416,36 +416,271 @@ sequenceDiagram ### 这种用法和第一篇的区别 - 第一篇是“把公网一个入口端口映射到远程内网某个固定服务”,无需额外身份验证,全世界谁都可以访问此服务; -- 第二篇是“让某个用户先拨入公网的 Xray 服务器,再借道反向代理回家继续访问”; +- 这一篇是“让某个用户先接入公网的 Xray 服务器,再借道反向代理回家继续访问”; - 第一篇更像远程端口映射,也称内网穿透; -- 第二篇更像远程漫游或轻量异地组网。 +- 这一篇更像远程漫游或轻量异地组网。 ### 安全建议 - 如果有多个漫游用户,建议每个用户使用独立 UUID 或独立标识; - 示例配置为追求简化仅用了 VLESS-enc 实际使用时可能需要使用 REALITY/XHTTP 等伪装流量。 +::: tip 延申 +如果你想要的不是“访问几个固定内网资源”这种点到站模式,而是需要站到站的 L4 组网,那么可以配合路由表 + TUN,或者让 Xray 作为网关来做透明代理。 +::: + +## 家宽落地 + +把特定流量送回家中设备,再从家庭宽带出口继续访问公网。 + +### 场景说明 + +这一部分不是为了访问家里的 NAS、路由器面板或其他内网服务,而是让用户先接入公网的 Xray 服务器,再借助已经建立好的反向通道,把其中一部分流量送回家中设备,最后通过家庭宽带继续访问公网。 + +这种用法更接近: + +- 让特定流量使用家里的住宅宽带出口 IP; +- 家里没有独享公网 IP,或者没有权限做 IPv4 端口映射、放通 IPv6 防火墙,或者不想暴露端口、折腾 DDNS; +- 由公网服务器承接用户接入,再把需要家宽落地的流量送回家中设备处理。 + +::: tip +一个具体的场景是,想要用家宽来保障 ChatGPT 不降智。跟流媒体解锁不同的是,前者需要真正独享的住宅宽带出口。而现实中“24K·真家宽”的提供者往往是你的朋友,设置他们的光猫、路由器极其地不方便。所以最便捷的做法是给他一个设备连上网就能用,VLESS 反向代理正契合这种场景。 + +格局打开,你好~~大冤种~~朋友正在使用的手机也可以 7 × 24 小时运行 Xray 作为落地设备!蜂窝网络解锁效果是一样的,考验你们友情的时候到了~ +::: + +```mermaid +flowchart LR + U[外部用户设备] + S[公网服务器] + I[家中设备] + P[公网目标] + + I -- 主动建立 VLESS 反向连接 --> S + U -- 接入公网服务器上的 Xray 入口 --> S + S -- 指定流量经 reverse 转发 --> I + I -- 通过家庭宽带访问公网 --> P +``` + +### 配置思路 + +跟第二篇基本相同,只是路由的对象不同。第二篇是 `user -> reverse-out`,这一篇则是 `特定域名 -> reverse-out`。公网服务器和家中设备之间的反向连接方式本身不变。 + +### 公网服务器配置 + +这个示例里: + +- 第一个 UUID 仍然用于家中设备建立反向连接; +- 第二个 UUID 用于外部用户接入公网服务器; +- 路由把接入用户访问 `geosite:openai` 的流量转发到 `reverse-out`。 + +公网服务器这一侧和第二篇基本相同,只是把上一节按 `user` 分流,改成了按 `domain` 分流。 + +```json +{ + "inbounds": [ + { + "listen": "0.0.0.0", + "port": 8443, + "protocol": "vless", + // 这里建议开启嗅探,否则按 domain 路由时可能看不到目标域名 + "sniffing": { + "enabled": true, + "destOverride": ["http", "tls", "quic"] + }, + "settings": { + "decryption": "mlkem768x25519plus.native.600s.aCF82eKiK6g0DIbv0_nsjbHC4RyKCc9NRjl-X9lyi0k", + "clients": [ + { + "id": "ac04551d-6ebf-4685-86e2-17c12491f7f4", + "flow": "xtls-rprx-vision", + "reverse": { + "tag": "reverse-out" + } + }, + { + "id": "e8758aff-d830-4d08-a59e-271df65b995a", + "flow": "xtls-rprx-vision" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "domain": ["geosite:openai"], + "outboundTag": "reverse-out" + } + ] + }, + "outbounds": [ + { + "protocol": "freedom" + } + ] +} +``` + +上面这组规则的含义是: + +- 家中设备通过第一个 UUID 回连公网服务器; +- 外部用户通过第二个 UUID 接入公网服务器; +- 这条公网入站建议开启 `sniffing`,否则按域名分流时可能看不到目标域名; +- 只要访问目标命中 `geosite:openai`,流量就会被送进 `reverse-out`; +- 其他没有命中的流量继续走默认 `freedom`,也就是留在公网服务器本地出站。 + +### 家中设备配置 + +家中设备这一侧也和第二篇基本相同,只是这次不再放行某个内网网段,而是放行所有非私有地址,让流量从家庭宽带继续访问公网。 + +```json +{ + "routing": { + "rules": [ + { + "inboundTag": ["reverse-in"], + "outboundTag": "home-direct" + } + ] + }, + "outbounds": [ + { + "protocol": "freedom" + }, + { + "protocol": "freedom", + "tag": "home-direct", + "settings": { + "finalRules": [ + { + "action": "allow", + "network": "tcp,udp", + "ip": ["!geoip:private"] + } + ] + } + }, + { + "protocol": "vless", + "settings": { + "address": "yourserver.com", + "port": 8443, + "encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk", + "id": "ac04551d-6ebf-4685-86e2-17c12491f7f4", + "flow": "xtls-rprx-vision", + "reverse": { + "tag": "reverse-in" + } + } + } + ] +} +``` + +上面这组规则的含义是: + +- 只要流量是从 `reverse-in` 进入的,就转给 `home-direct`; +- `home-direct` 通过 `finalRules` 只放行公网流量。 + +### 用户设备配置 + +用户设备这一侧用经典的“`cn -> direct,其它全代理`”即可: + +```json +{ + "routing": { + "rules": [ + { + "domain": ["geosite:cn"], + "outboundTag": "direct" + }, + { + "ip": ["geoip:private", "geoip:cn"], + "outboundTag": "direct" + } + ] + }, + "outbounds": [ + { + "protocol": "vless", + "tag": "to-server", + "settings": { + "address": "yourserver.com", + "port": 8443, + "encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk", + "id": "e8758aff-d830-4d08-a59e-271df65b995a", + "flow": "xtls-rprx-vision" + } + }, + { + "protocol": "freedom", + "tag": "direct" + } + ] +} +``` + +上面这组规则的含义是: + +- 国内域名和国内 IP 继续本地直连; +- 其他没有命中的流量默认都走 `to-server`,也就是发往公网服务器; +- 到了公网服务器之后,再由上一节的 `geosite:openai -> reverse-out` 决定哪些流量需要走家宽。 + +### 请求流向 + +```mermaid +sequenceDiagram + participant U as 外部用户设备 + participant S as 公网服务器 + participant I as 家中设备 + participant P as 公网目标 + + I->>S: 建立 VLESS 反向连接 + U->>S: 接入公网服务器 + U->>S: 命中需要家宽落地的流量 + S->>S: 路由命中 reverse-out + S->>I: 将指定流量送入 reverse 通道 + I->>P: 通过家庭宽带访问公网 + P-->>I: 返回响应 + I-->>S: 经反向通道返回 + S-->>U: 响应用户 +``` + +### 这种用法和第二篇的区别 + +- 第二篇是“回家访问内网资源”; +- 这一篇是“回家借用家宽出口访问公网”; +- 第二篇路由的重点是“哪些用户需要回家”; +- 这一篇路由的重点是“哪些域名需要走家宽”。 + ## 小结 -VLESS 反向代理至少可以覆盖两类场景: +至此本文介绍了 VLESS 反向代理的三类主场景和一类延申能力: -- 把公网入口端口映射到远程内网固定服务; -- 让用户接入公网服务器后再通过反向通道漫游回家。 +- 远程端口映射:把公网入口端口映射到远程内网特定服务; +- 点到站 VPN:让用户接入公网服务器后再通过反向通道漫游回家; +- 站到站 VPN:作为站到站的 L4 组网基础能力使用; +- 家宽落地:让特定流量经由公网服务器回到家里,再从家庭宽带出口访问公网。 -两者使用的是同一套反向连接机制,区别主要在公网侧如何路由流量,以及内网侧如何继续处理这些流量。理解这一点之后,就可以按自己的场景在“端口映射”和“远程漫游”之间自由扩展。 +这些场景使用的都是同一套反向连接机制,区别主要在公网侧如何路由流量,以及内网侧如何继续处理这些流量。本文只是列出了几类常见用法,更重要的是理解这套机制本身;吃透原理之后,还可以按自己的需求继续挖掘和扩展。 ## 进阶技巧:高级负载均衡 +如果你有多入口、多出口、异地多点回连的需求,希望同一组反向代理线路能够自动容灾、自动分摊流量,那么可以让多条连接共用同一个 `reverse.tag`,把它们放进同一个可用池。 + 如果公网端存在多个入站使用相同的 reverse tag,最终也只会对应产生一个出站;可以把它理解为多条线路同时挂在同一个可用池中,每次使用时随机选一路。 -这种方式可以实现更灵活的多对多配置。假如某条线路暂时不可用,例如对应的内网端还没有连上来,那么它就不会进入当前可用池,后续流量会自动转发到其它仍然在线的线路上,无需手动切换。 +假如某条线路暂时不可用,例如对应的内网端还没有连上来,那么它就不会进入当前可用池,后续流量会自动转发到其它仍然在线的线路上,无需手动切换。 -不难看出,`reverse.tag` 在两侧都是“同 tag 合并为一个连接池”的语义: +内网侧同样允许这样重名:多个 VLESS 出站也可以共用同一个 `reverse-in`。 + +不难看出,`reverse.tag` 在两侧都允许重名,重名后就会并到一起: - 公网侧多个 client 共用同一个 `reverse-out`,会收敛为同一个出站池; - 内网侧多个 VLESS 出站共用同一个 `reverse-in`,会收敛为同一个入口池。 -所以它天然可以扩展成 N 对 N。更常见的实际部署是:对外只有一个业务域名,例如 `www.example.com`,再通过 GeoDNS 把访客就近分配到美西和东京两台公网服务器;而内网端则分别回连 `us-reverse.example.com` 和 `jp-reverse.example.com` 这两个公网节点。再部署两个内网端:家里和办公室。家里、办公室都分别连到美西和东京,于是每个公网端都会维护一个“家里 + 办公室”的可用池。实际转发时,会从当前已建立的连接里随机选一条可用线路;某一端离线后,它会自动从池里消失。 +所以它天然可以扩展成 N 对 N。更常见的实际部署是:对外只有一个业务域名,例如 `www.example.com`,再通过 GeoDNS 把访客就近分配到美西和东京两台公网服务器;而内网端则分别回连 `us-reverse.example.com` 和 `jp-reverse.example.com` 这两个公网节点。再部署两个内网端:家里和办公室,都分别连到美西和东京,于是每个公网端都会维护一个“家里 + 办公室”的可用池。实际转发时,会从当前已建立的连接里随机选一条可用线路;某一端离线后,它会自动从池里消失。 下面给一个极简片段,只保留 reverse 相关部分,继续沿用“公网入口端口映射到内网服务”的写法。 @@ -558,6 +793,10 @@ VLESS 反向代理至少可以覆盖两类场景: 和家里内网端完全同理,只是把 UUID 换成 `us-office-uuid` 和 `jp-office-uuid`,并把 `redirect` 改成办公室要暴露的内网服务。 +::: tip 延申 +如果你希望这里的选路不只是“从当前可用连接里随机挑一条”,而是进一步按延迟、稳定性或观测结果做更细的路由决策,可以再结合 [`routing.balancer`](../../config/routing.md#balancerobject) 能力来设计出站选择策略。 +::: + ## 进阶技巧:透传真实访客 IP 如果你希望内网 Web 服务看到真实访客 IP,而不是把访问来源识别成内网侧 Xray 那台机器的 IP 地址,可以在内网侧的 `freedom` 出站里开启 `proxyProtocol`。不开启时,后端 WebServer 看到的源地址通常就是内网侧 Xray 的 IP;开启后,Xray 在把连接转发到 `redirect` 指定的后端时,会先发送一段 PROXY protocol 头,把真实源地址一并传给 WebServer。 @@ -731,4 +970,4 @@ server { - 承接反向代理流量的内网 `freedom`(也就是常说的 `direct`)出站,建议按最小权限原则配置。把默认出站设为 `blackhole`,只把允许访问的目标显式路由到专用 `freedom`。再通过 `finalRules` 只放行必要的地址和端口。 - 如果你使用的是别人提供的穿透服务用于远程回家,或者你并不完全信任公网 VPS,建议不要让反向代理流量直接落到真实内网业务。可以在内网再部署一个带 `VLESS Encryption` 的服务端专门承接这部分流量,再由它转发给实际业务,以补上身份认证和数据保护,否则有权限接触到公网服务器的人可以漫游你的内网。 - 通过 `VLESS` 等入站协议把流量送到内网端时,路由系统里看到的 `Source` / `Local` 所属协议,不一定与最终 `Target` 一致。涉及 `source`、`local`、`network` 等条件时,应以实际流量形态为准,不要想当然地把它们等同起来。 -- `XHTTP`、`WebSocket` 等基于 HTTP 的入站当前会默认读取 `X-Forwarded-For`。如果前面没有你自己信任的 HTTP 反向代理,这个头可以被客户端伪造,因此不要直接拿它做严格的安全判断,例如 IP 白名单、黑名单或审计归因。 +- `XHTTP`、`WebSocket`、`HTTPUpgrade` 这三个基于 HTTP 的入站默认会读取 `X-Forwarded-For`。如果你的前面链路里没有可信的 HTTP 反代,建议配合 [`sockopt.trustedXForwardedFor`](../../config/transports/sockopt.md#trustedxforwardedfor) 限制何时信任它,避免客户端伪造来源 IP。 diff --git a/docs/en/document/level-2/vless_reverse.md b/docs/en/document/level-2/vless_reverse.md index f2080a82..0deb95a3 100644 --- a/docs/en/document/level-2/vless_reverse.md +++ b/docs/en/document/level-2/vless_reverse.md @@ -1,9 +1,10 @@ # VLESS Reverse Proxy Examples -This article demonstrates how to use Xray's VLESS reverse proxy capability to send traffic back into a remote private network through a public server. Two common use cases are covered here: +This article demonstrates how to use Xray's VLESS reverse proxy capability to send traffic back into a remote private network through a public server, or even continue out to the public internet through a home broadband connection. Three common use cases are covered here: - `Ingress forwarding`: remote port mapping that maps a public entry port to a remote internal Web service; -- `Remote return home`: remote private-network roaming where a user relays through a public server and continues accessing resources inside the home network. +- `Remote return home`: remote private-network roaming where a user relays through a public server and continues accessing resources inside the home network; +- `Home broadband egress`: the user relays through a public server, sends selected traffic back to a device at home, and then accesses the public internet through the home broadband uplink. ## Ingress Forwarding @@ -212,13 +213,12 @@ Remote private-network roaming where the user relays through a public server and ### Scenario Description -This part is not about exposing a public port for external access. Instead, the user first connects to VLESS on the public server, then uses the already-established reverse tunnel to send that user's traffic back to the internal device at home for further handling. +This part is not about exposing a public port for external access. Instead, the user first connects to the public Xray server, then uses the already-established reverse tunnel to send that user's traffic back to the internal device at home for further handling. This usage is closer to: - Accessing home LAN resources while roaming outside; -- Sending a specific user's egress back through the home network; -- Relaying through a public server, then returning to the home network to access a NAS, router panel, home DNS, or other internal services. +- Relaying through a public server, then returning to the home network to access a NAS, router panel, or other internal services. ```mermaid flowchart LR @@ -228,7 +228,7 @@ flowchart LR H[Home LAN Resources] I -- Actively establishes a VLESS reverse connection --> S - U -- Connects to the VLESS inbound on the public server --> S + U -- Connects to the Xray entry on the public server --> S S -- User traffic forwarded through reverse --> I I -- Accesses the home LAN again --> H ``` @@ -238,9 +238,9 @@ flowchart LR Compared with the first part, the biggest difference here is not the reverse connection itself, but the routing target on the public side: - The first part uses `inboundTag -> reverse-out` to map a specific entry port back into the private network; -- The second part uses `user -> reverse-out` to hand a specific user's proxied traffic over to the internal device for continued processing. +- This part uses `user -> reverse-out` to hand a specific user's proxied traffic over to the internal device for continued processing. -In other words, the public server acts more like a relay station here. The user is not directly "accessing a service exposed through a public port mapping," but rather "first connecting to the VLESS inbound on the public server, then continuing from the device at home." +In other words, the public server acts more like a relay station here. The user is not directly "accessing a service exposed through a public port mapping," but rather "first connecting to the Xray entry on the public server, then continuing from the device at home." ### Public Server Configuration @@ -407,7 +407,7 @@ sequenceDiagram U->>S: Connect using roam@example.com S->>S: user route matches reverse-out S->>I: Send user traffic into reverse tunnel - I->>H: Access NAS / router / home DNS / internal services + I->>H: Access NAS / router / internal services H-->>I: Return response I-->>S: Return through reverse tunnel S-->>U: Respond to user @@ -416,36 +416,271 @@ sequenceDiagram ### How This Differs from the First Part - The first part is "map a public entry port to a fixed service in a remote private network"; without extra authentication, anyone on the internet can access that service. -- The second part is "let a specific user first connect to the public Xray server, then use the reverse proxy to continue back home." +- This part is "let a specific user first connect to the public Xray server, then use the reverse proxy to continue back home." - The first part is more like remote port mapping, also known as private network penetration; -- The second part is more like remote roaming or lightweight cross-site networking. +- This part is more like remote roaming or lightweight cross-site networking. ### Security Recommendations - If there are multiple roaming users, it is recommended that each user have an independent UUID or identifier; - The sample configuration uses only VLESS-enc for simplicity. In real deployments, you may need REALITY, XHTTP, or similar traffic camouflage methods. +::: tip Extension +If what you need is not a "visit a few fixed internal resources" point-to-site pattern, but rather site-to-site L4 networking, you can combine this with routing tables plus TUN, or let Xray act as a gateway for transparent proxying. +::: + +## Home Broadband Egress + +Send selected traffic back to a device at home, then continue out to the public internet through the home broadband uplink. + +### Scenario Description + +This part is not about accessing a NAS, router panel, or other internal services at home. Instead, the user first connects to the public Xray server, then uses the already-established reverse tunnel to send part of the traffic back to a device at home, and finally continues out to the public internet through the home broadband connection. + +This usage is closer to: + +- Making selected traffic use the residential egress IP of your home broadband; +- Situations where your home does not have a dedicated public IP, where you cannot do IPv4 port forwarding or open the IPv6 firewall, or where you simply do not want to expose ports and maintain DDNS; +- Letting the public server handle user access first, then sending only the traffic that needs home-broadband egress back to the device at home. + +::: tip +One concrete use case is wanting home broadband egress so ChatGPT does not get "dumber." Unlike streaming unlocks, this requires a genuinely dedicated residential egress IP. In reality, the person who can offer that "real home broadband" is often your friend, and changing settings on their ONT or router is extremely inconvenient. The easiest option is often to hand them a device that works as long as it has internet access, which is exactly the kind of scenario where VLESS reverse proxy fits. + +Thinking bigger, even the phone your very generous friend uses every day can run Xray 24 x 7 as the egress device. The effect is the same on cellular. This is where friendship gets tested. +::: + +```mermaid +flowchart LR + U[External User Device] + S[Public Server] + I[Home Device] + P[Public Target] + + I -- Actively establishes a VLESS reverse connection --> S + U -- Connects to the Xray entry on the public server --> S + S -- Selected traffic forwarded through reverse --> I + I -- Accesses the public internet through home broadband --> P +``` + +### Configuration Idea + +This is almost the same as the second part. The only difference is what the routing targets. The second part uses `user -> reverse-out`, while this part uses `specific domains -> reverse-out`. The reverse connection itself between the public server and the home device does not change. + +### Public Server Configuration + +In this example: + +- The first UUID is still used by the home device to establish the reverse connection; +- The second UUID is used by the external user to access the public server; +- Routing forwards traffic for `geosite:openai` to `reverse-out`. + +The public-server side is almost the same as in the second part. The only change is that routing is now based on `domain` instead of `user`. + +```json +{ + "inbounds": [ + { + "listen": "0.0.0.0", + "port": 8443, + "protocol": "vless", + // Enable sniffing here, otherwise domain-based routing may not see the target domain name + "sniffing": { + "enabled": true, + "destOverride": ["http", "tls", "quic"] + }, + "settings": { + "decryption": "mlkem768x25519plus.native.600s.aCF82eKiK6g0DIbv0_nsjbHC4RyKCc9NRjl-X9lyi0k", + "clients": [ + { + "id": "ac04551d-6ebf-4685-86e2-17c12491f7f4", + "flow": "xtls-rprx-vision", + "reverse": { + "tag": "reverse-out" + } + }, + { + "id": "e8758aff-d830-4d08-a59e-271df65b995a", + "flow": "xtls-rprx-vision" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "domain": ["geosite:openai"], + "outboundTag": "reverse-out" + } + ] + }, + "outbounds": [ + { + "protocol": "freedom" + } + ] +} +``` + +What these rules mean: + +- The home device calls back to the public server with the first UUID; +- The external user connects to the public server with the second UUID; +- This public inbound is recommended to enable `sniffing`, otherwise domain-based routing may not see the target domain name; +- Any request that matches `geosite:openai` is sent into `reverse-out`; +- Other traffic that does not match continues through the default `freedom`, meaning it stays on the public server for local egress. + +### Home Device Configuration + +The home-device side is also almost the same as in the second part. This time, however, it no longer allows only one internal subnet. Instead, it allows all non-private addresses so traffic can continue to the public internet through the home broadband connection. + +```json +{ + "routing": { + "rules": [ + { + "inboundTag": ["reverse-in"], + "outboundTag": "home-direct" + } + ] + }, + "outbounds": [ + { + "protocol": "freedom" + }, + { + "protocol": "freedom", + "tag": "home-direct", + "settings": { + "finalRules": [ + { + "action": "allow", + "network": "tcp,udp", + "ip": ["!geoip:private"] + } + ] + } + }, + { + "protocol": "vless", + "settings": { + "address": "yourserver.com", + "port": 8443, + "encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk", + "id": "ac04551d-6ebf-4685-86e2-17c12491f7f4", + "flow": "xtls-rprx-vision", + "reverse": { + "tag": "reverse-in" + } + } + } + ] +} +``` + +What these rules mean: + +- Any traffic that enters from `reverse-in` is handed to `home-direct`; +- `home-direct` uses `finalRules` to allow only public-internet traffic. + +### User Device Configuration + +On the user-device side, a classic "`cn -> direct`, everything else proxied" setup is enough: + +```json +{ + "routing": { + "rules": [ + { + "domain": ["geosite:cn"], + "outboundTag": "direct" + }, + { + "ip": ["geoip:private", "geoip:cn"], + "outboundTag": "direct" + } + ] + }, + "outbounds": [ + { + "protocol": "vless", + "tag": "to-server", + "settings": { + "address": "yourserver.com", + "port": 8443, + "encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk", + "id": "e8758aff-d830-4d08-a59e-271df65b995a", + "flow": "xtls-rprx-vision" + } + }, + { + "protocol": "freedom", + "tag": "direct" + } + ] +} +``` + +What these rules mean: + +- Domestic domains and domestic IPs continue to connect directly from the local network; +- Other traffic that does not match goes through `to-server` by default, meaning it is sent to the public server; +- Once it reaches the public server, the `geosite:openai -> reverse-out` rule from the previous section decides which traffic should use home broadband. + +### Request Flow + +```mermaid +sequenceDiagram + participant U as External User Device + participant S as Public Server + participant I as Home Device + participant P as Public Target + + I->>S: Establish VLESS reverse connection + U->>S: Connect to the public server + U->>S: Request traffic that needs home broadband egress + S->>S: Route matches reverse-out + S->>I: Send selected traffic into the reverse tunnel + I->>P: Access the public internet through home broadband + P-->>I: Return response + I-->>S: Return through the reverse tunnel + S-->>U: Respond to user +``` + +### How This Differs from the Second Part + +- The second part is "return home to access internal resources"; +- This part is "return home to borrow the home broadband egress for public internet access"; +- In the second part, routing is mainly about "which users need to go home"; +- In this part, routing is mainly about "which domains need to use home broadband". + ## Summary -VLESS reverse proxy can cover at least two types of scenarios: +At this point, the article has covered three primary scenarios and one extension capability for VLESS reverse proxy: -- Map a public entry port to a fixed service inside a remote private network; -- Let users connect to a public server and then roam back home through the reverse tunnel. +- Remote port mapping: map a public entry port to a specific service in a remote private network; +- Point-to-site VPN: let users connect to a public server and then roam back home through the reverse tunnel; +- Site-to-site VPN: use the same mechanism as a building block for site-to-site L4 networking; +- Home broadband egress: send selected traffic back home through a public server, then continue out through the home broadband connection. -Both use the same reverse connection mechanism. The main difference lies in how the public side routes the traffic and how the private side continues processing it. Once you understand that, you can freely extend the model between "port mapping" and "remote roaming" according to your own needs. +All of these use the same reverse connection mechanism. The main difference lies in how the public side routes the traffic and how the private side continues processing it. This article only lists several common patterns; the more important part is understanding the mechanism itself. Once you really grasp it, you can keep extending it to fit your own needs. ## Advanced Technique: Advanced Load Balancing +If you have multiple ingress points, multiple egress points, or multi-site call-backs from different regions, and you want a group of reverse-proxy paths to fail over and spread traffic automatically, you can make multiple connections share the same `reverse.tag` and place them into one availability pool. + If multiple inbounds on the public side use the same reverse tag, they still end up producing only one outbound. You can think of this as multiple lines hanging off the same availability pool, with one live line chosen at random each time it is used. -This makes more flexible many-to-many setups possible. If one line is temporarily unavailable, for example because the corresponding internal device has not connected yet, it simply does not enter the current availability pool. Subsequent traffic is then forwarded automatically to other lines that are still online, with no manual switching required. +If one line is temporarily unavailable, for example because the corresponding internal device has not connected yet, it simply does not enter the current availability pool. Subsequent traffic is then forwarded automatically to other lines that are still online, with no manual switching required. -In other words, `reverse.tag` has the same "same tag means merge into one connection pool" semantics on both sides: +The same naming rule is allowed on the internal side as well: multiple VLESS outbounds can also share one `reverse-in`. + +In other words, `reverse.tag` allows duplicates on both sides, and duplicate tags are merged together: - Multiple clients on the public side that share the same `reverse-out` converge into one outbound pool; - Multiple VLESS outbounds on the internal side that share the same `reverse-in` converge into one inbound pool. -So it naturally scales to N-to-N. A more common real deployment looks like this: externally there is only one service domain, for example `www.example.com`, and GeoDNS sends visitors to the nearest public server in Los Angeles or Tokyo. On the internal side, connections are established back to `us-reverse.example.com` and `jp-reverse.example.com`. Then deploy two internal devices, one at home and one in the office. Both home and office connect to both Los Angeles and Tokyo, so each public node maintains an availability pool of "home + office". During actual forwarding, one available line is selected at random from the currently established connections. If one endpoint goes offline, it disappears from the pool automatically. +So it naturally scales to N-to-N. A more common real deployment looks like this: externally there is only one service domain, for example `www.example.com`, and GeoDNS sends visitors to the nearest public server in Los Angeles or Tokyo. On the internal side, connections are established back to `us-reverse.example.com` and `jp-reverse.example.com`. Then deploy two internal devices, one at home and one in the office, and have both connect to both Los Angeles and Tokyo. Each public node then maintains an availability pool of "home + office". During actual forwarding, one available line is selected at random from the currently established connections. If one endpoint goes offline, it disappears from the pool automatically. Below is a minimal snippet that keeps only the reverse-related parts and continues using the "public entry port mapped to an internal service" style. @@ -558,6 +793,10 @@ Exactly the same idea, except that the UUIDs are changed to `jp-home-uuid` and ` Exactly the same as the home internal device, except that the UUIDs are changed to `us-office-uuid` and `jp-office-uuid`, and `redirect` is changed to the internal service that the office side should expose. +::: tip Extension +If you want selection here to be more than "pick a random line from the currently available connections," and instead make finer decisions based on latency, stability, or observations, you can combine this further with [`routing.balancer`](../../config/routing.md#balancerobject) to design the outbound selection policy. +::: + ## Advanced Technique: Preserve the Real Visitor IP If you want the internal Web service to see the real visitor IP instead of identifying the source as the internal-side Xray machine, you can enable `proxyProtocol` on the internal-side `freedom` outbound. If it is not enabled, the backend Web server usually sees the source address of the internal-side Xray machine. If it is enabled, Xray sends a PROXY protocol header first when forwarding the connection to the backend specified by `redirect`, so that the real source address is passed along to the Web server. @@ -731,4 +970,4 @@ The following points are more about deployment safety and boundary control. It i - The internal `freedom` outbound that receives reverse proxy traffic, often called the `direct` outbound, should be configured according to the principle of least privilege. Set the default outbound to `blackhole`, only route explicitly allowed targets to a dedicated `freedom`, and then use `finalRules` to allow only the necessary addresses and ports. - If you are using a penetration service provided by someone else for remote access home, or if you do not fully trust the public VPS, it is recommended not to let reverse proxy traffic land directly on your real internal services. Instead, deploy another server on the internal side with `VLESS Encryption` enabled specifically to receive that traffic, and let it forward traffic to the actual service. This adds authentication and data protection; otherwise anyone with sufficient access to the public server may be able to roam through your internal network. - When traffic is delivered to the internal side through inbound protocols such as `VLESS`, the protocol shown by `Source` or `Local` in the routing system is not necessarily the same as the final `Target`. When using conditions such as `source`, `local`, or `network`, rely on the actual traffic shape instead of assuming they are all equivalent. -- HTTP-based inbounds such as `XHTTP` and `WebSocket` currently read `X-Forwarded-For` by default. If there is no HTTP reverse proxy in front that you trust, the header can be forged by the client. Therefore, do not use it directly for strict security decisions such as IP whitelists, blacklists, or audit attribution. +- The three HTTP-based inbounds `XHTTP`, `WebSocket`, and `HTTPUpgrade` trust `X-Forwarded-For` by default. If there is no HTTP reverse proxy in front that you trust, consider combining this with [`sockopt.trustedXForwardedFor`](../../config/transports/sockopt.md#trustedxforwardedfor) to control when it is trusted and to avoid client-forged source IPs. diff --git a/docs/ru/document/level-2/vless_reverse.md b/docs/ru/document/level-2/vless_reverse.md index 979295a1..0e51dfd5 100644 --- a/docs/ru/document/level-2/vless_reverse.md +++ b/docs/ru/document/level-2/vless_reverse.md @@ -1,9 +1,10 @@ # Примеры обратного проксирования VLESS -В этой статье показано, как использовать возможность обратного проксирования VLESS в Xray, чтобы через публичный сервер возвращать трафик в удаленную внутреннюю сеть. Ниже рассмотрены два распространенных сценария: +В этой статье показано, как использовать возможность обратного проксирования VLESS в Xray, чтобы через публичный сервер возвращать трафик в удаленную внутреннюю сеть или даже продолжать выход во внешний интернет через домашний широкополосный канал. Ниже рассмотрены три распространенных сценария: - `Проброс входа`: удаленный проброс порта, то есть сопоставление публичного входного порта с Web-сервисом в удаленной внутренней сети; -- `Удаленно домой`: удаленный роуминг по внутренней сети, когда пользователь проходит через публичный сервер и затем продолжает доступ к ресурсам домашней сети. +- `Удаленно домой`: удаленный роуминг по внутренней сети, когда пользователь проходит через публичный сервер и затем продолжает доступ к ресурсам домашней сети; +- `Выход через домашний канал`: пользователь проходит через публичный сервер, отправляет выбранный трафик обратно на домашнее устройство, а затем выходит во внешний интернет через домашний широкополосный канал. ## Проброс Входа @@ -212,13 +213,12 @@ sequenceDiagram ### Описание Сценария -Здесь речь не о том, чтобы открыть какой-то публичный порт для внешнего доступа. Вместо этого пользователь сначала подключается к VLESS на публичном сервере, а затем с помощью уже установленного обратного туннеля его трафик отправляется обратно на домашнее внутреннее устройство для дальнейшей обработки. +Здесь речь не о том, чтобы открыть какой-то публичный порт для внешнего доступа. Вместо этого пользователь сначала подключается к публичному Xray-серверу, а затем с помощью уже установленного обратного туннеля его трафик отправляется обратно на домашнее внутреннее устройство для дальнейшей обработки. Этот вариант ближе к следующим сценариям: - Доступ к ресурсам домашней локальной сети во время поездок; -- Возврат исходящего трафика конкретного пользователя домой; -- Переход через публичный сервер с последующим доступом к NAS, панели роутера, домашнему DNS или другим внутренним сервисам. +- Переход через публичный сервер с последующим доступом к NAS, панели роутера или другим внутренним сервисам. ```mermaid flowchart LR @@ -228,7 +228,7 @@ flowchart LR H[Ресурсы домашней локальной сети] I -- Самостоятельно устанавливает обратное VLESS-соединение --> S - U -- Подключается к VLESS inbound на публичном сервере --> S + U -- Подключается к входу Xray на публичном сервере --> S S -- Пользовательский трафик пересылается через reverse --> I I -- Повторно обращается к домашней локальной сети --> H ``` @@ -238,9 +238,9 @@ flowchart LR По сравнению с первой частью, главное отличие здесь не в самой обратной связи, а в цели маршрутизации на публичной стороне: - В первой части используется `inboundTag -> reverse-out`, чтобы сопоставить определенный входной порт с внутренней сетью; -- Во второй части используется `user -> reverse-out`, чтобы передать проксируемый трафик конкретного пользователя внутреннему устройству для дальнейшей обработки. +- В этой части используется `user -> reverse-out`, чтобы передать проксируемый трафик конкретного пользователя внутреннему устройству для дальнейшей обработки. -Иными словами, здесь публичный сервер больше похож на транзитный узел. Пользователь не "обращается напрямую к сервису, проброшенному через публичный порт", а "сначала подключается к VLESS inbound на публичном сервере, а затем продолжает путь через домашнее устройство". +Иными словами, здесь публичный сервер больше похож на транзитный узел. Пользователь не "обращается напрямую к сервису, проброшенному через публичный порт", а "сначала подключается к входу Xray на публичном сервере, а затем продолжает путь через домашнее устройство". ### Конфигурация Публичного Сервера @@ -407,7 +407,7 @@ sequenceDiagram U->>S: Подключается с использованием roam@example.com S->>S: user-маршрут попадает в reverse-out S->>I: Отправляет пользовательский трафик в reverse-туннель - I->>H: Обращается к NAS / роутеру / домашнему DNS / внутренним сервисам + I->>H: Обращается к NAS / роутеру / внутренним сервисам H-->>I: Возвращает ответ I-->>S: Возвращает через обратный туннель S-->>U: Отвечает пользователю @@ -416,36 +416,271 @@ sequenceDiagram ### Чем Этот Вариант Отличается От Первого - Первый вариант - это "сопоставить один публичный входной порт с фиксированным сервисом в удаленной внутренней сети"; без дополнительной аутентификации такой сервис может быть доступен любому пользователю из интернета. -- Второй вариант - это "дать конкретному пользователю сначала подключиться к публичному Xray-серверу, а затем через обратный прокси вернуться домой и продолжить доступ"; +- Эта часть - это "дать конкретному пользователю сначала подключиться к публичному Xray-серверу, а затем через обратный прокси вернуться домой и продолжить доступ"; - Первый вариант больше похож на удаленный проброс порта, то есть на проникновение во внутреннюю сеть; -- Второй вариант больше похож на удаленный роуминг или легкую межплощадочную сеть. +- Эта часть больше похожа на удаленный роуминг или легкую межплощадочную сеть. ### Рекомендации По Безопасности - Если у вас несколько роуминговых пользователей, рекомендуется выдавать каждому отдельный UUID или отдельный идентификатор; - В примере ради упрощения используется только VLESS-enc. В реальной эксплуатации могут понадобиться REALITY, XHTTP или другие способы маскировки трафика. +::: tip Расширение +Если вам нужен не режим "доступа к нескольким фиксированным внутренним ресурсам" в формате point-to-site, а межсайтовая L4-сеть, это можно сочетать с таблицами маршрутизации и TUN, либо использовать Xray как шлюз для прозрачного проксирования. +::: + +## Выход Через Домашний Канал + +Отправить выбранный трафик обратно на домашнее устройство, а затем продолжить выход во внешний интернет через домашний широкополосный канал. + +### Описание Сценария + +Эта часть не про доступ к домашнему NAS, панели роутера или другим внутренним сервисам. Вместо этого пользователь сначала подключается к публичному Xray-серверу, затем по уже установленному обратному туннелю часть трафика отправляется обратно на домашнее устройство, а уже оттуда продолжается выход во внешний интернет через домашний широкополосный канал. + +Этот вариант ближе к следующим сценариям: + +- Когда нужно, чтобы выбранный трафик выходил с IP домашнего широкополосного подключения; +- Когда дома нет выделенного публичного IP, нет возможности сделать IPv4-проброс порта, открыть IPv6 firewall или просто не хочется выставлять порт наружу и возиться с DDNS; +- Когда публичный сервер сначала принимает пользователей, а затем отправляет обратно домой только тот трафик, которому нужен домашний выход. + +::: tip +Один из конкретных сценариев - использовать домашний широкополосный выход, чтобы ChatGPT не становился "глупее". В отличие от разблокировки стримингов, здесь нужен действительно выделенный резидентский выход. На практике поставщиком такого "настоящего домашнего канала" часто оказывается ваш друг, а перенастраивать его ONT или роутер крайне неудобно. Поэтому самый простой вариант - дать ему устройство, которому достаточно доступа в интернет, и запустить на нем Xray. VLESS reverse proxy очень хорошо ложится на такой сценарий. + +Если смотреть шире, даже телефон вашего очень терпеливого друга может работать 7 x 24 как устройство выхода. Для сотовой сети эффект тот же. Здесь уже проверяется дружба. +::: + +```mermaid +flowchart LR + U[Внешнее устройство пользователя] + S[Публичный сервер] + I[Домашнее устройство] + P[Публичная цель] + + I -- Самостоятельно устанавливает обратное VLESS-соединение --> S + U -- Подключается к входу Xray на публичном сервере --> S + S -- Выбранный трафик пересылается через reverse --> I + I -- Выходит во внешний интернет через домашний канал --> P +``` + +### Идея Конфигурации + +Почти все то же самое, что и во второй части. Меняется только то, на что именно смотрит маршрутизация. Во второй части используется `user -> reverse-out`, а здесь - `определенные домены -> reverse-out`. Сам механизм обратного соединения между публичным сервером и домашним устройством не меняется. + +### Конфигурация Публичного Сервера + +В этом примере: + +- Первый UUID по-прежнему используется домашним устройством для установления обратного соединения; +- Второй UUID используется внешним пользователем для подключения к публичному серверу; +- Маршрутизация отправляет трафик к `geosite:openai` в `reverse-out`. + +Сторона публичного сервера почти совпадает со второй частью. Разница только в том, что теперь маршрутизация идет по `domain`, а не по `user`. + +```json +{ + "inbounds": [ + { + "listen": "0.0.0.0", + "port": 8443, + "protocol": "vless", + // Здесь рекомендуется включить sniffing, иначе доменное правило может не увидеть целевой домен + "sniffing": { + "enabled": true, + "destOverride": ["http", "tls", "quic"] + }, + "settings": { + "decryption": "mlkem768x25519plus.native.600s.aCF82eKiK6g0DIbv0_nsjbHC4RyKCc9NRjl-X9lyi0k", + "clients": [ + { + "id": "ac04551d-6ebf-4685-86e2-17c12491f7f4", + "flow": "xtls-rprx-vision", + "reverse": { + "tag": "reverse-out" + } + }, + { + "id": "e8758aff-d830-4d08-a59e-271df65b995a", + "flow": "xtls-rprx-vision" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "domain": ["geosite:openai"], + "outboundTag": "reverse-out" + } + ] + }, + "outbounds": [ + { + "protocol": "freedom" + } + ] +} +``` + +Смысл этих правил: + +- Домашнее устройство возвращается на публичный сервер с первым UUID; +- Внешний пользователь подключается к публичному серверу со вторым UUID; +- Для этого публичного inbound рекомендуется включить `sniffing`, иначе доменное правило может не увидеть целевой домен; +- Любой запрос, попавший под `geosite:openai`, отправляется в `reverse-out`; +- Остальной трафик, не попавший под правило, идет через `freedom` по умолчанию, то есть остается на локальном выходе публичного сервера. + +### Конфигурация Домашнего Устройства + +Домашняя сторона тоже почти совпадает со второй частью. На этот раз она больше не ограничивается одной внутренней подсетью, а разрешает все адреса, кроме приватных, чтобы трафик мог дальше выходить во внешний интернет через домашний канал. + +```json +{ + "routing": { + "rules": [ + { + "inboundTag": ["reverse-in"], + "outboundTag": "home-direct" + } + ] + }, + "outbounds": [ + { + "protocol": "freedom" + }, + { + "protocol": "freedom", + "tag": "home-direct", + "settings": { + "finalRules": [ + { + "action": "allow", + "network": "tcp,udp", + "ip": ["!geoip:private"] + } + ] + } + }, + { + "protocol": "vless", + "settings": { + "address": "yourserver.com", + "port": 8443, + "encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk", + "id": "ac04551d-6ebf-4685-86e2-17c12491f7f4", + "flow": "xtls-rprx-vision", + "reverse": { + "tag": "reverse-in" + } + } + } + ] +} +``` + +Смысл этих правил: + +- Любой трафик, входящий из `reverse-in`, передается в `home-direct`; +- `home-direct` через `finalRules` разрешает только трафик во внешний интернет. + +### Конфигурация Устройства Пользователя + +На стороне пользователя достаточно классической схемы "`cn -> direct`, все остальное через прокси": + +```json +{ + "routing": { + "rules": [ + { + "domain": ["geosite:cn"], + "outboundTag": "direct" + }, + { + "ip": ["geoip:private", "geoip:cn"], + "outboundTag": "direct" + } + ] + }, + "outbounds": [ + { + "protocol": "vless", + "tag": "to-server", + "settings": { + "address": "yourserver.com", + "port": 8443, + "encryption": "mlkem768x25519plus.native.0rtt.2PcBa3Yz0zBdt4p8-PkJMzx9hIj2Ve-UmrnmZRPnpRk", + "id": "e8758aff-d830-4d08-a59e-271df65b995a", + "flow": "xtls-rprx-vision" + } + }, + { + "protocol": "freedom", + "tag": "direct" + } + ] +} +``` + +Смысл этих правил: + +- Доменные имена и IP внутри Китая продолжают идти напрямую из локальной сети; +- Остальной трафик, не попавший под правила, по умолчанию идет через `to-server`, то есть отправляется на публичный сервер; +- Уже на публичном сервере правило `geosite:openai -> reverse-out` из предыдущего раздела решает, какой трафик нужно пустить через домашний канал. + +### Поток Запроса + +```mermaid +sequenceDiagram + participant U as Внешнее устройство пользователя + participant S as Публичный сервер + participant I as Домашнее устройство + participant P as Публичная цель + + I->>S: Устанавливает обратное VLESS-соединение + U->>S: Подключается к публичному серверу + U->>S: Отправляет трафик, которому нужен домашний выход + S->>S: Маршрут попадает в reverse-out + S->>I: Отправляет выбранный трафик в reverse-туннель + I->>P: Выходит во внешний интернет через домашний канал + P-->>I: Возвращает ответ + I-->>S: Возвращает через обратный туннель + S-->>U: Отвечает пользователю +``` + +### Чем Этот Вариант Отличается От Второй Части + +- Во второй части цель - "вернуться домой и получить доступ к внутренним ресурсам"; +- В этой части цель - "вернуться домой и воспользоваться домашним каналом для выхода во внешний интернет"; +- Во второй части основная логика маршрутизации - "каких пользователей нужно вернуть домой"; +- В этой части основная логика маршрутизации - "какие домены должны идти через домашний канал". + ## Итоги -Обратный прокси VLESS как минимум покрывает два типа сценариев: +К этому моменту статья охватывает три основных сценария и одну производную возможность для обратного прокси VLESS: -- Сопоставление публичного входного порта с фиксированным сервисом в удаленной внутренней сети; -- Подключение пользователя к публичному серверу с последующим возвратом домой через обратный туннель. +- Удаленный проброс порта: сопоставление публичного входного порта с конкретным сервисом в удаленной внутренней сети; +- Point-to-site VPN: подключение пользователя к публичному серверу с последующим возвратом домой через обратный туннель; +- Site-to-site VPN: использование того же механизма как строительного блока для L4-сети между площадками; +- Выход через домашний канал: возврат выбранного трафика домой через публичный сервер с последующим выходом во внешний интернет через домашний широкополосный канал. -Оба сценария используют один и тот же механизм обратного соединения. Основное различие состоит в том, как публичная сторона маршрутизирует трафик и как внутренняя сторона продолжает его обрабатывать. Поняв это, можно свободно расширять схему между "пробросом порта" и "удаленным возвращением домой" под свои задачи. +Во всех случаях используется один и тот же механизм обратного соединения. Основное различие состоит в том, как публичная сторона маршрутизирует трафик и как внутренняя сторона продолжает его обрабатывать. Эта статья только перечисляет несколько типовых схем; гораздо важнее понять сам механизм. Когда принцип станет понятен, его можно дальше расширять под свои задачи. ## Продвинутые Приемы: Расширенная Балансировка Нагрузки +Если у вас есть несколько входов, несколько выходов или обратные соединения из разных регионов, и вы хотите, чтобы группа линий обратного прокси автоматически переживала отказы и распределяла трафик, можно заставить несколько соединений использовать один и тот же `reverse.tag`, то есть объединить их в единый пул доступности. + Если на публичной стороне несколько входящих подключений используют один и тот же reverse tag, в итоге все равно будет создан только один outbound. Это можно понимать как несколько линий, подвешенных к одному общему пулу доступности, где при каждом использовании случайно выбирается одна из живых линий. -Такой подход позволяет строить более гибкие конфигурации many-to-many. Если какая-то линия временно недоступна, например потому что соответствующее внутреннее устройство еще не подключилось, она просто не попадет в текущий пул доступности. Последующий трафик будет автоматически перенаправляться на другие линии, которые все еще в сети, без ручного переключения. +Если какая-то линия временно недоступна, например потому что соответствующее внутреннее устройство еще не подключилось, она просто не попадет в текущий пул доступности. Последующий трафик будет автоматически перенаправляться на другие линии, которые все еще в сети, без ручного переключения. -Иначе говоря, у `reverse.tag` с обеих сторон одна и та же семантика: "одинаковый tag объединяется в один пул соединений": +Та же логика именования разрешена и на внутренней стороне: несколько VLESS outbound тоже могут использовать один и тот же `reverse-in`. + +Иначе говоря, `reverse.tag` допускает одинаковые имена на обеих сторонах, и одинаковые теги будут объединяться: - Несколько клиентов на публичной стороне, использующих один и тот же `reverse-out`, сходятся в один пул outbound; - Несколько VLESS outbound на внутренней стороне, использующих один и тот же `reverse-in`, сходятся в один пул inbound. -Поэтому схема естественно масштабируется до N-к-N. Более типичный реальный сценарий выглядит так: снаружи есть только один сервисный домен, например `www.example.com`, а GeoDNS отправляет посетителей на ближайший публичный сервер в Лос-Анджелесе или Токио. На внутренней стороне при этом устанавливаются соединения назад к `us-reverse.example.com` и `jp-reverse.example.com`. Затем разворачиваются два внутренних устройства: дома и в офисе. И дом, и офис подключаются и к Лос-Анджелесу, и к Токио, поэтому каждый публичный узел поддерживает пул доступности вида "дом + офис". При реальной переадресации случайно выбирается одна доступная линия из уже установленных соединений. Если одна из точек уходит офлайн, она автоматически исчезает из пула. +Поэтому схема естественно масштабируется до N-к-N. Более типичный реальный сценарий выглядит так: снаружи есть только один сервисный домен, например `www.example.com`, а GeoDNS отправляет посетителей на ближайший публичный сервер в Лос-Анджелесе или Токио. На внутренней стороне при этом устанавливаются соединения назад к `us-reverse.example.com` и `jp-reverse.example.com`. Затем разворачиваются два внутренних устройства: дома и в офисе, и оба подключаются и к Лос-Анджелесу, и к Токио. Каждый публичный узел тогда поддерживает пул доступности вида "дом + офис". При реальной переадресации случайно выбирается одна доступная линия из уже установленных соединений. Если одна из точек уходит офлайн, она автоматически исчезает из пула. Ниже приведен минимальный фрагмент, в котором оставлены только части, связанные с reverse, и по-прежнему используется модель "публичный входной порт отображается на внутренний сервис". @@ -558,6 +793,10 @@ sequenceDiagram Полностью аналогично домашнему внутреннему устройству, только UUID меняются на `us-office-uuid` и `jp-office-uuid`, а `redirect` нужно заменить на тот внутренний сервис, который должен публиковаться из офиса. +::: tip Расширение +Если вы хотите, чтобы выбор здесь был не просто "случайно взять одну из доступных линий", а зависел от задержки, стабильности или результатов наблюдений, это можно дополнительно сочетать с [`routing.balancer`](../../config/routing.md#balancerobject) и спроектировать более тонкую политику выбора outbound. +::: + ## Продвинутые Приемы: Передача Реального IP Посетителя Если вы хотите, чтобы внутренний Web-сервис видел реальный IP посетителя, а не определял источник как IP машины с Xray на внутренней стороне, можно включить `proxyProtocol` у outbound `freedom` на внутренней стороне. Если он выключен, backend Web-сервер обычно видит адрес самой внутренней машины с Xray. Если он включен, Xray перед пересылкой соединения на backend, указанный в `redirect`, сначала отправляет заголовок PROXY protocol, чтобы вместе с ним передать Web-серверу и реальный исходный адрес. @@ -731,4 +970,4 @@ server { - Внутренний outbound `freedom`, который принимает трафик обратного прокси, то есть привычный `direct`, желательно настраивать по принципу минимально необходимых привилегий. Сделайте outbound по умолчанию равным `blackhole`, явно маршрутизируйте только разрешенные цели в выделенный `freedom`, а затем через `finalRules` открывайте только действительно нужные адреса и порты. - Если вы используете сервис проникновения, предоставленный кем-то другим, для удаленного доступа домой, или если вы не полностью доверяете публичному VPS, лучше не направлять трафик обратного прокси напрямую на реальные внутренние сервисы. Вместо этого можно развернуть на внутренней стороне еще один сервер с включенным `VLESS Encryption`, специально для приема такого трафика, и уже через него пересылать трафик к настоящему сервису. Это добавляет аутентификацию и защиту данных; иначе любой, кто имеет достаточный доступ к публичному серверу, потенциально сможет перемещаться по вашей внутренней сети. - Когда трафик доставляется на внутреннюю сторону через входящие протоколы вроде `VLESS`, протокол, который routing system показывает у `Source` или `Local`, не обязательно совпадает с итоговым `Target`. При использовании условий вроде `source`, `local` или `network` ориентируйтесь на реальную форму трафика, а не на предположение, что они эквивалентны. -- HTTP-ориентированные inbounds, такие как `XHTTP` и `WebSocket`, сейчас по умолчанию читают `X-Forwarded-For`. Если перед ними нет HTTP reverse proxy, которому вы доверяете, этот заголовок может быть подделан клиентом. Поэтому не используйте его напрямую для строгих решений безопасности, например для IP whitelist, blacklist или аудиторской атрибуции. +- Три HTTP-ориентированных inbound `XHTTP`, `WebSocket` и `HTTPUpgrade` по умолчанию доверяют `X-Forwarded-For`. Если перед ними нет доверенного HTTP reverse proxy, рекомендуется сочетать это с [`sockopt.trustedXForwardedFor`](../../config/transports/sockopt.md#trustedxforwardedfor), чтобы ограничить случаи доверия и не допустить подделки исходного IP клиентом.