关于 XRAY 路由规则的补充和问题排查案例

在服务器或本地客户端根据域名配置路由分流规则时, domainStrategy 为必要配置项,由于 XRAY 内置 DNS 模块注:如果没有在配置文件中配置此项,则使用系统的 DNS 设置」,可以实现根据域名分流。 XRAY 的 domainStrategy 仅对域名生效,选项有 AsIsIPIfNonMatchIPOnDemand 三种,其中的区别 XRAY 的官方文档 有明确描述,但容易混淆,故在本文进行记录。

  • AsIs : 仅使用域名做匹配,无法匹配的域名走默认规则(即第一条出站规则)。

  • IPIfNonMatch : 请求一个域名时,先进行路由里面的 domain 进行匹配,若无法匹配到结果,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行 IP 路由匹配。【即:先匹配域名,匹配不到域名再解析成 IP 匹配 IP 】

  • IPOnDemand : 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。【即:只要路由规则中有 IP 类规则,那么所有基于域名 domain 的请求都要解析成 IP 然后去匹配 IP 类规则】

在配置文件中有关于 log 的配置项,大致配置如下,正式环境下配置日志等级为 warning 即可,当需要排查问题时,可以将日志等级设置为 info

info 类型的日志会占用较大的存储空间,建议完成排查后调整日志记录等级。

json

"log": {
        "loglevel": "info",
        // 注释掉则会默认把日志输出到Terminal中,如果下面两行都注释则 Terminal 只显示 access.log 内容
        "access": "D:\\Xray\\access.log", 
        // "error": "D:\\Xray\\error.log",
        "dnsLog": true
    },

access.log 为访问成功日志,一般只记录访问的域名和路由 tag 。此处我们重点关注错误日志 error.log,默认情况下,该文件位于 Linux Server 中 /var/log/xray/error.log,内容包括连接信息、DNS解析记录、路由匹配等,可以使用 tail -f /var/log/xray/error.log 命令进行实时查看,Windows 下按照上述配置,在 Terminal 中开启 XRAY 后会直接在 Terminal 输出。

注:排查过程中的配置文件即《通过 WARP Socks5 代理及 XRAY 路由规则实现解锁 ChatGPT》文中出现的配置文件。

问题描述:为了验证 Server 端是否禁用了回国流量,将 Client 端的分流规则暂时禁用,使得访问国内网站的流量经过 XRAY Server,观察流量日志,发现访问 www.baidu.com 的流量未被 Server Block 掉,浏览器可以通过 XRAY 正常访问百度。

Client 端日志截图如下(此处禁用了 Client 的分流规则,则 Client 表现为对所有流量都转发):

image-20240424103343074

排查过程:查看 Server 配置文件,确认 domainStrategy 是 IPIfNonMatch 。排查 Server 日志,截图如下,发现 www.baidu.com 对应的流量走的是 default route (即:freedom),

image-20240424102116391

搜索发现这个 Issue ,出现上述情况单纯是 XRAY Server 端的 DNS 将 www.baidu.com 解析到了百度香港服务器的 IP 上,配置文件没有问题。如果尝试 www.douban.com 等只解析到国内IP的服务器或者私有地址,会发现正常的回国流量和私有 IP 段流量是被 Server Block 的,确认分流规则没有问题

image-20240424103446819

image-20240424103532043

问题描述:访问 chat.openai.com 域名不通,当时猜测是因为 openai 对常见的 VPS 商家地址段进行了封禁, 因此配置域名分流规则,通过 WARP 访问 ChatGPT(即上一篇文章内容)。偶然发现不配置任何分流规则,也不使用 WARP,流量经过服务器可以直接访问 chat.openai.com 。

排查过程:排查日志发现流量是在 Server 端被 Block 的,但分流规则就只 Block 了国内 IP 和私有 IP 。

image-20240424110418122

解析 chat.openai.com 域名,发现其实际解析到了一个 B 类私有地址。猜测是 VPS 商家为了绕过 openai 的限制,通过修改 DNS 解析结果让这个域名解析到了 VPS 运营商的特定 IP,VPS 运营商再通过内部策略更换访问出口,从而实现解锁 ChatGPT。但这样刚好触发了 Block 私有地址的策略,从而导致流量被封禁。这个 Issue 中有详细描述。

注:XRAY 内置 DNS 模块 ,但若未在配置文件中配置 DNS 项,则XRAY会使用系统配置中的 DNS 服务器,且不记录 DNS 日志。

image-20240424110812705

解决方法

方法1:可以修改 Server 端操作系统的 /etc/resolv.conf 中的 DNS 配置。发现该配置文件中配置了一个私网 DNS 服务器,在还有其他公网 DNS 配置的情况下,将该行注释掉即可。这样 chat.openai.com 就不会被解析到私有地址,从而不会触发分流规则。

方法2:为 Server 端 XRAY 添加 DNS 配置,使 XRAY 进行域名解析时使用特定的 DNS 服务器而不调用系统配置的 DNS 服务器。在 Server 配置文件与 routing 同级别下,添加如下内容

json

"dns": {
        "servers": ["8.8.8.8"]
    },

不同 DNS Server 的配置方式会决定 DNS 流量是否经过路由,详见 此处 ,上述配置 DNS 流量经过路由组件,并走路由中的第一个出站(直连),通过 XRAY 内置的 DNS 模块解析到 chat.openai.com 的地址即为正常的公网地址,不会触发分流规则。

image-20240424161236987

方法3:定义单独的域名分流规则,在 Server 配置文件中 routing 下的 rules 中添加如下配置,让特定域名的流量走直连 。由于 IPIfNonMatch 策略会先匹配域名,匹配不到后再解析为 IP 并进行 IP 策略的匹配,所以这条策略在"禁止私有 IP 段策略"的前后都可以。

json

{
    // 问题 : VPS 运营商为了解锁 ChatGPT,会将 chat.openai.com 解析到一个私有地址
    // 但是我们的上面的策略禁止了私有网段流量,解析到的地址直接被 XRAY BLOCK 掉,反而不能访问使用 ChatGPT
    // 解决办法就是:单独为这个域名添加路由,让他走直连,(我们是直接指定了域名,IPIfNonMatch 策略会先匹配域名,匹配不到后再解析为 IP,所以这条策略在禁止私有IP段策略的前后都可以)
    "domain": [
        "chat.openai.com"
    ],
    "outboundTag": "direct"
},