DNS 与规则集:解析走哪台服务器,分流靠哪套规则

DNS 规则管解析、路由规则管出站;规则集分 inline、本地与远程三种,旧 GeoIP 写法要迁到规则集。

两个规则,别混成一个

  • DNS 规则(dns.rules):域名解析时,用哪台 DNS 服务器。还可以设解析策略,例如只用 IPv4、优先 IPv4 等。
  • 路由规则(route.rules):连接建立时,走哪个出站。按域名、IP、端口、协议等条件匹配。

一个常见误解是“DNS 走了代理,流量就一定走了代理”,其实不是:解析和连接是两步,DNS 服务器选错了,可能出现域名解析到了不该去的地址;路由规则没命中,流量也可能走了默认出站。排查时要分开看:先看域名解析结果对不对,再看连接走了哪个出站。

DNS 的基本结构

官方 DNS 结构里,关键字段是这几个:

{
  "dns": {
    "servers": [],
    "rules": [],
    "final": "",
    "strategy": ""
  }
}
  • servers:DNS 服务器列表,每个服务器有一个 tag,供规则引用。
  • rules:按条件把域名指给某台服务器。
  • final:没有规则命中时的默认服务器,空着就用第一台。
  • strategy:默认解析策略,可选 prefer_ipv4、prefer_ipv6、ipv4_only、ipv6_only 等。

写 DNS 规则时,先想清楚两类域名要不要分开解析:需要走代理的域名,和可以直接解析的域名。如果全部域名都用同一台服务器,就不需要写复杂规则;只有确实需要分开时,才加规则。规则越多,出错面越大。

规则集的三种写法

规则集(rule-set)从 1.8.0 开始引入,用来替代旧的 GeoIP、Geosite 写法。三种类型:

  • inline:规则直接写在配置里,适合条数少、自己维护的小规则。
  • local:规则存在本地文件里,配置里只写 tag、format(source 或 binary)和 path;文件改动后,1.10.0 起会自动重载。
  • remote:规则从 URL 下载,配置里写 tag、format、url,还可以设 update_interval(默认 1d,即一天);远程规则集有缓存,启动时没有缓存可用时,可以用 initial_path 里的初始内容顶一下。

路由里引用规则集时,在 route.rule_set 里先声明这些规则集,再在 route.rules 里用规则集的 tag 去匹配。声明了却没在规则里引用,等于没写;规则里引用了却没声明,启动会报错。

旧 GeoIP、Geosite 怎么迁

旧写法在 1.8.0 弃用、1.12.0 移除,现在不能再用 route.geoip、route.geosite 这两个字段。迁移不是改名,而是换结构:

  1. 把原来按国家、按域名分类的规则,改写成规则集:IP 类规则放进 IP 规则集,域名类规则放进域名规则集。
  2. 在 route.rule_set 里声明这些规则集,在 route.rules 里引用它们的 tag。
  3. 改完先 sing-box check,再启动验证;不要只把旧字段删掉就启动,删字段会改变分流行为,可能出现“本来该直连的走了代理”或反过来。

排查 DNS 与分流问题

  • 只看“能不能打开”不够:先确认域名解析到了哪个 IP,再确认连接走了哪个出站。
  • 改了规则集文件或远程规则集 URL 后,要确认客户端真的重新加载了:本地文件改动会自动重载,远程规则集按更新间隔拉取,手动刷新不一定立即生效。
  • 一次只改一类规则:先改 DNS 规则验证解析,再改路由规则验证出站,两类一起改,出问题定位不了。
  • 远程规则集下载失败时,先看 URL、网络和缓存状态,不要直接把规则集换成 inline 凑合,换结构等于换了分流逻辑。

访问官网 →