Xray 分流实战:让特定域名走 WARP、其余直连
Xray 分流实战:让特定域名走 WARP、其余直连
从“全走代理”到“按域名分流”
一台沙箱机器要同时干两件事:大部分流量直连最快、最稳,但有几个域名只有换出口 IP 才不被目标站点限流或拦截。一开始我图省事让所有流量都走同一个代理,结果直连本该很快的国内服务也绕了一圈,延迟上去不说,一旦代理抖动,所有服务一起受影响。改成按域名分流之后,问题收敛到一句话:命中规则的域名走 WARP 出口,其余全部直连,互不干扰。
我的环境是这样:本机跑一个 Xray-core,监听 127.0.0.1:3129 做 HTTP/SOCKS 入口;WARP 由本地 wireproxy 提供,监听 127.0.0.1:40000 的 SOCKS5。需要走 WARP 的域名很少,开始时只有一类:某个模型服务商的域名,因为默认出口 IP 在它那里频繁触发限流。
第一步:出站写两个,规则写在前面
Xray 的出站(outbounds)至少要两个:一个 direct,一个是到 WARP 的 SOCKS5 出站。关键点是 tag 要起得一眼能分清,规则里引用的是 tag,拼错一个字母就静默走默认出站,查起来很费时间。
{
"outbounds": [
{ "protocol": "freedom", "tag": "direct" },
{
"protocol": "socks",
"tag": "warp",
"settings": {
"servers": [{ "address": "127.0.0.1", "port": 40000 }]
}
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{ "type": "field", "domain": ["opencode.ai"], "outboundTag": "warp" },
{ "type": "field", "outboundTag": "direct" }
]
}
}
规则顺序就是匹配顺序:第一条命中域名后缀就走 WARP,最后一条是兜底直连。这里我踩过一个坑:把兜底规则写在前面,后面的域名规则永远匹配不到——Xray 的路由是第一条命中即停,不是“最精确优先”。写完规则先用 xray run -test 校验配置能加载,再启动,不要凭感觉直接上生产流量。
第二步:DNS 必须走真实解析,不能用 Fake-IP
分流成败的一半在 DNS。沙箱默认的系统 DNS 是 Fake-IP 机制:所有域名都返回一段虚拟 IP,程序拿着虚拟 IP 去连,直连出站必然超时,WARP 那条路也会因为连的是虚拟地址而失败。我的做法是让 Xray 自己的 DNS 固定走本地的真实解析服务(doh-stub,127.0.0.1),只解析出真实 IP 再决定走哪条出站:
{
"dns": {
"servers": ["127.0.0.1"]
}
}
验证方法很直接:先用 doh-stub 查一次目标域名,确认返回的是公网真实 IP;再让走 WARP 的客户端请求一次,确认出口 IP 变成了 WARP 的地址;最后让一个直连域名请求一次,确认出口还是本机地址。三条都对,分流才算通,只看“能打开”是不够的——全走 WARP 时页面一样能打开。
第三步:启动时的环境变量,是最隐蔽的坑
这次分流真正卡了我最久的地方,不是配置文件,而是启动命令的环境变量。沙箱运行环境会注入一套系统代理变量(HTTP_PROXY、HTTPS_PROXY 等),指向平台的统一出口。如果启动 Xray 或它的上层网关时不先清掉这四个变量,程序实际走的就不是我写的 3129 分流,而是平台代理——表面上一切正常,实际上分流规则根本没生效,限流问题换个 IP 也照样出现。
我的启动方式是先清变量、再显式指定分流入口:
env -u HTTP_PROXY -u HTTPS_PROXY -u http_proxy -u https_proxy \
HTTPS_PROXY=http://127.0.0.1:3129 HTTP_PROXY=http://127.0.0.1:3129 \
./magpie-gateway
还有一个同类坑:有些程序是 wrapper 套壳,子进程不继承父进程的环境变量。我在排查时一度以为“已经设置了代理”,结果用 /proc/<pid>/environ 一查,子进程的环境里根本没有我设的变量,面板上显示的却是平台代理的出口。教训是:配完代理一定要去实证——要么看进程的真实环境,要么看面板的出口 IP,不要只看启动命令写了什么。
第四步:三个验证命令,分流才算落地
分流上线前,我固定跑三组验证,缺一组都不算完成:
# 1. 配置能加载
xray run -test -c config.json
# 2. 走 WARP 的域名,出口应为 WARP 地址
curl -x http://127.0.0.1:3129 https://api.opencode.ai/ -s -o /dev/null -w "%{http_code}\n"
# 3. 直连域名,出口应为本机地址,且不经过 WARP
curl -x http://127.0.0.1:3129 https://example.com/ -s -o /dev/null -w "%{http_code}\n"
另外要确认 WARP 本身还活着:curl --socks5-hostname 127.0.0.1:40000 去请求一个外网地址。这里必须用 --socks5-hostname,让域名由远端解析;用普通的 --socks5 会在本地解析,拿到 Fake-IP 虚拟地址,WARP 去连虚拟 IP 必然超时——这个错误现象和“WARP 挂了”一模一样,我第一次就误判过。
小结
按域名分流本身不复杂,复杂的是让每一层都按你以为的方式工作:路由规则按顺序匹配、DNS 要返回真实 IP、启动环境变量不能被平台注入覆盖、子进程的环境变量要实证。把这四处都钉死之后,新增一个要走 WARP 的域名,就只是在规则里加一行域名,改动范围小,出问题也只影响这一条线,不会把整台机器的流量都拖下水。
- 点赞
- 收藏
- 关注作者
评论(0)