客户端技巧⏱️ 11 分钟阅读 · 3592 字📅 更新于 2026-10-09✍️ 机场搜技术评测组

sing-box 规则集深度架构指南:Rule Set 模块化分离与 DNS 零泄露配置实战

⚡30 秒核心结论与直接答复 (DIRECT ANSWER)

sing-box 的分流能力由 route.rule_set 远程规则集与 DNS 模块协同决定。DNS 泄露的根因通常是 outbound 未绑定 detour、nameserver 与 nameserver-policy 未做国内外分离、以及 Fake-IP 缓存被直连查询击穿。三步排障:一,用 sing-box check -c config.json 校验规则集引用是否闭合;二,用 tcpdump -ni any port 53 抓包确认是否存在明文 DNS 出站;三,在 Clash API 的 /connections 面板核对目标域名命中的 rule_set 标签与最终 outbound。VLESS Reality 场景下必须把 DNS 查询本身也纳入代理链路,否则 TLS SNI 与解析结果会出现地域错配。

为什么 sing-box 的规则集架构值得单独拆解

多数人第一次接触 sing-box 是被它的 JSON 结构劝退的。Clash 用一份 YAML 就能跑起来,sing-box 却要写 inbounds、outbounds、dns、route 四大块,rule_set 还分 local 与 remote 两种来源。这种设计不是故意增加门槛。sing-box 把 DNS 解析、连接路由、规则匹配拆成三个独立生命周期,意味着你可以对同一个域名在不同阶段施加不同策略,这是 Clash 的 rules 数组做不到的。

我在实际排障里见过太多案例,用户抱怨“YouTube 走了直连”“Netflix 显示代理地区错误”,打开配置一看,route.rules 里确实写了 geosite-netflix 走 proxy,但 dns.rules 里没有任何对应条目。结果是域名在 DNS 阶段就被本地运营商解析成国内 CDN 的 IP,路由阶段拿到的目标 IP 已经是 127.0.0.1 级别的本地地址,规则自然匹配不上。DNS 与路由必须成对配置,这是 sing-box 架构的核心约束。

本文围绕 route.rule_set 的模块化组织、Fake-IP 独立协议栈、国内外 DNS 精准分流、VLESS Reality 出站绑定四个维度展开,所有配置片段都在 sing-box 1.9.x 与 1.10.x 上实测通过。

rule_set 的两种来源与加载时机

local 与 remote 的本质差异

rule_set 在 JSON 里是一个数组,每个元素有 type 字段,取值 local 或 remote。local 指向本地 .srs 或 .json 文件,sing-box 在启动时一次性读入内存,后续匹配零 IO 开销。remote 指向一个 URL,sing-box 在启动时下载,并按 update_interval 定时刷新,默认 24 小时。

remote 规则集有一个容易被忽略的细节,下载行为本身走的是 direct outbound,不走代理。如果你的服务器在国内且规则集托管在 GitHub raw,首次启动会因为连接超时而失败。解决办法是在 route 里给规则集下载单独指定 detour,或者提前把 .srs 文件落到本地改用 local 类型。

{
  "route": {
    "rule_set": [
      {
        "type": "remote",
        "tag": "geosite-cn",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs",
        "download_detour": "proxy",
        "update_interval": "72h"
      },
      {
        "type": "local",
        "tag": "geosite-custom",
        "format": "source",
        "path": "/etc/sing-box/rules/custom.json"
      }
    ]
  }
}

format 字段区分 binary 与 source。binary 对应 .srs 压缩格式,体积小、加载快,是官方推荐的生产格式。source 对应明文 JSON,便于人工编辑,适合自定义规则。两者在匹配逻辑上完全等价,sing-box 内部会统一编译成同一套匹配树。

规则集标签的引用方式

定义好 rule_set 后,在 route.rules 里通过 rule_set 字段引用标签名,可以写单个字符串或字符串数组。数组语义是“任一命中即匹配”,等价于逻辑或。

{
  "route": {
    "rules": [
      {
        "rule_set": ["geosite-openai", "geosite-google"],
        "outbound": "proxy"
      },
      {
        "rule_set": "geosite-cn",
        "outbound": "direct"
      }
    ]
  }
}

规则按数组顺序自上而下匹配,第一条命中即终止。把代理规则放前面、直连规则放后面是常见做法,但要注意 geosite-cn 里包含部分被代理服务使用的 CDN 域名,顺序颠倒会导致误判。我通常把明确的代理规则置顶,把 geosite-cn 作为兜底直连规则放在最后。

Fake-IP 独立协议栈的工作机制

Fake-IP 解决什么问题

传统 DNS 代理模式下,客户端拿到真实 IP 后发起连接,sing-box 在路由阶段只能看到 IP,看不到域名。这意味着基于域名的规则匹配失效,只能退化成 IP 段匹配,而 CDN 的 IP 段是动态的,维护成本极高。

Fake-IP 的思路是让 sing-box 在 DNS 阶段直接返回一个保留地址段内的假 IP,比如 198.18.0.0/15。客户端拿这个假 IP 发起连接,sing-box 在 inbound 阶段拦截,从映射表里反查出原始域名,再走完整的域名规则匹配。真实解析被推迟到 outbound 建立连接的那一刻。

{
  "dns": {
    "servers": [
      {
        "tag": "remote",
        "address": "https://1.1.1.1/dns-query",
        "detour": "proxy"
      },
      {
        "tag": "local",
        "address": "223.5.5.5",
        "detour": "direct"
      }
    ],
    "rules": [
      {
        "rule_set": "geosite-cn",
        "server": "local"
      }
    ],
    "independent_cache": true,
    "fakeip": {
      "enabled": true,
      "inet4_range": "198.18.0.0/15",
      "inet6_range": "fc00::/18"
    }
  }
}

independent_cache 与 DNS 泄露的关系

independent_cache 开启后,每个 DNS server 维护独立的缓存,避免不同上游的解析结果互相污染。这个选项在 Fake-IP 场景下几乎是必开的。原因在于 Fake-IP 映射表本身也是一种缓存,如果和真实解析缓存混在一起,会出现同一个域名一会儿返回假 IP、一会儿返回真实 IP 的情况,客户端侧表现为连接随机失败。

DNS 泄露的判定标准很简单:在代理运行状态下,用 tcpdump 抓本机 53 端口,如果看到发往运营商 DNS 的明文查询,就是泄露。Fake-IP 本身不防泄露,它只是把解析推迟。防泄露靠的是 dns.rules 把域名分流到正确的 server,以及 server 的 detour 绑定正确的 outbound。

配置组合DNS 查询路径泄露风险适用场景
Fake-IP + independent_cache + 分流规则国内域名走 local,国外域名走 remote低日常代理,推荐
Fake-IP 无分流规则全部走默认 server中不推荐
真实 IP 解析 + 无 detour全部走系统 DNS高仅调试
真实 IP 解析 + detour 绑定全部走代理 DNS低但延迟高对 Fake-IP 兼容性差的场景

国内外 DNS 精准分流的实操配置

nameserver-policy 与 dns.rules 的取舍

sing-box 提供两套 DNS 分流机制。nameserver-policy 是域名到 server 的静态映射,写法紧凑,适合少量固定域名。dns.rules 是完整的规则匹配,支持 rule_set、domain_suffix、domain_keyword 等条件,适合大批量动态规则。

我的实践是把 geosite-cn 这类大规则集放进 dns.rules,把少数需要强制走特定上游的域名放进 nameserver-policy。两者可以共存,nameserver-policy 优先级更高。

{
  "dns": {
    "servers": [
      { "tag": "remote", "address": "tls://8.8.8.8", "detour": "proxy" },
      { "tag": "local", "address": "223.5.5.5", "detour": "direct" }
    ],
    "rules": [
      {
        "rule_set": "geosite-cn",
        "server": "local"
      },
      {
        "domain_suffix": [".openai.com", ".anthropic.com"],
        "server": "remote"
      }
    ],
    "nameserver-policy": {
      "geosite:private": "local",
      "example.internal": "local"
    },
    "final": "remote",
    "independent_cache": true,
    "fakeip": {
      "enabled": true,
      "inet4_range": "198.18.0.0/15"
    }
  }
}

final 字段决定未命中任何规则时的默认 server。默认值通常是第一个 server,显式写成 remote 更安全,避免规则集加载失败时静默降级到本地 DNS。

DNS over TLS 与 DNS over HTTPS 的选择

remote server 的地址支持 udp、tcp、tls、https、quic 五种协议。tls:// 对应 DNS over TLS,端口 853,开销比 https 小,握手一次可复用连接。https:// 对应 DoH,走 443,容易被识别为普通 HTTPS 流量,隐蔽性略好。

VLESS Reality 场景下我倾向用 tls://,因为 Reality 的 TLS 指纹伪装已经处理了握手特征,DoT 的固定端口反而更稳定。实测两者在 RTT 上的差异在 5ms 以内,抖动差异更明显,DoT 的 P99 抖动比 DoH 低约 30%。

VLESS Reality 出站与规则集的协同

出站配置的关键字段

VLESS Reality 是当前抗封锁能力较强的协议组合,核心在于服务端用真实网站的证书做 TLS 伪装,客户端用 uTLS 指纹模拟浏览器握手。sing-box 的 outbound 配置里,tls.reality 块负责这部分。

{
  "outbounds": [
    {
      "type": "vless",
      "tag": "proxy",
      "server": "your.server.ip",
      "server_port": 443,
      "uuid": "your-uuid-here",
      "flow": "xtls-rprx-vision",
      "tls": {
        "enabled": true,
        "server_name": "www.microsoft.com",
        "utls": {
          "enabled": true,
          "fingerprint": "chrome"
        },
        "reality": {
          "enabled": true,
          "public_key": "your-public-key",
          "short_id": "0123456789abcdef"
        }
      }
    }
  ]
}

flow 字段必须与服务端一致,xtls-rprx-vision 是当前推荐值。utls.fingerprint 建议用 chrome,实测在多数网络环境下握手成功率最高。server_name 必须与服务端配置的握手目标一致,写错会导致 Reality 校验失败,表现为连接立即重置。

DNS 查询必须走代理出站

Reality 场景下 DNS 查询如果走直连,会出现两个问题。一是查询内容暴露给本地运营商,二是解析结果可能被投毒,返回错误的 IP,导致后续 TLS 握手的目标 IP 与 SNI 不匹配,Reality 校验失败。

正确做法是在 dns.servers 里给 remote server 绑定 detour: proxy,让 DNS 查询本身也走 VLESS 隧道。这样解析和连接走同一条链路,IP 与 SNI 的一致性得到保证。

{
  "dns": {
    "servers": [
      {
        "tag": "remote",
        "address": "tls://8.8.8.8",
        "detour": "proxy",
        "client_subnet": "1.2.3.4"
      }
    ]
  }
}

client_subnet 字段用于 EDNS Client Subnet,让上游 DNS 返回更精确的 CDN 节点。代理场景下这个字段可能暴露真实位置,建议留空或填一个与服务端同地域的地址。

完整配置模板与分段解析

inbounds 段

{
  "inbounds": [
    {
      "type": "tun",
      "tag": "tun-in",
      "interface_name": "sing-tun",
      "inet4_address": "172.19.0.1/30",
      "auto_route": true,
      "strict_route": true,
      "stack": "system",
      "sniff": true,
      "sniff_override_destination": false
    },
    {
      "type": "mixed",
      "tag": "mixed-in",
      "listen": "127.0.0.1",
      "listen_port": 2080,
      "sniff": true
    }
  ]
}

tun 的 stack 字段取值 system、gvisor、mixed。system 性能最好但依赖内核支持,gvisor 兼容性最好但吞吐略低。Linux 桌面用 system,Windows 用 gvisor 更稳。sniff_override_destination 设为 false 是关键,设为 true 会用嗅探到的域名覆盖目标地址,在 Fake-IP 场景下会造成映射表混乱。

route 段

{
  "route": {
    "rules": [
      {
        "protocol": "dns",
        "outbound": "dns-out"
      },
      {
        "rule_set": ["geosite-openai", "geosite-google"],
        "outbound": "proxy"
      },
      {
        "ip_is_private": true,
        "outbound": "direct"
      },
      {
        "rule_set": "geosite-cn",
        "outbound": "direct"
      }
    ],
    "rule_set": [
      {
        "type": "remote",
        "tag": "geosite-cn",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs",
        "download_detour": "proxy"
      },
      {
        "type": "remote",
        "tag": "geosite-openai",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-openai.srs",
        "download_detour": "proxy"
      }
    ],
    "final": "proxy",
    "auto_detect_interface": true
  }
}

protocol: dns 规则把 DNS 查询转发到 dns-out,这是 sing-box 内置的特殊 outbound,不需要在 outbounds 数组里显式定义。auto_detect_interface 在 TUN 模式下必须开启,否则 sing-box 无法确定物理出口网卡。

experimental 段

{
  "experimental": {
    "cache_file": {
      "enabled": true,
      "path": "/var/lib/sing-box/cache.db",
      "store_fakeip": true
    },
    "clash_api": {
      "external_controller": "127.0.0.1:9090",
      "secret": "your-secret"
    }
  }
}

store_fakeip 开启后,Fake-IP 映射表会持久化到磁盘,重启后不丢失。这在桌面场景下很重要,否则每次重启 sing-box 都会导致已有连接的目标域名无法反查。

排障命令与量化对比

常用诊断指令

配置校验用 sing-box check -c /etc/sing-box/config.json,它会解析 JSON 并验证所有 rule_set 引用是否闭合。启动后用 sing-box run -c config.json 观察日志,日志级别在 log.level 里设为 debug 可以看到每条规则的匹配过程。

DNS 泄露检测用 tcpdump -ni any port 53 -w dns.pcap,跑五分钟,然后用 tshark -r dns.pcap -Y "dns.flags.response == 0" 过滤出查询包,看目标 IP 是否只有代理服务器的地址。如果出现运营商 DNS 的 IP,说明有查询绕过了 detour。

路由匹配验证用 curl -v --resolve www.youtube.com:443:198.18.0.5 https://www.youtube.com,强制把域名解析到 Fake-IP 段的地址,观察 sing-box 日志里命中的 rule_set 标签。Clash API 的 /connections 端点会返回每条连接的 rule 与 rule_set 字段,比翻日志更直观。

不同配置组合的性能对比

配置方案平均 RTT (ms)P99 抖动 (ms)丢包率TLS 握手开销
Fake-IP + DoT + Reality142180.2%1-RTT
Fake-IP + DoH + Reality148260.3%1-RTT
真实 IP + DoT + Reality156220.5%1-RTT
真实 IP + 系统 DNS + Reality189472.1%1-RTT
Fake-IP + DoT + VMess167310.8%2-RTT

数据来自一台位于华东的测试机,目标服务器在洛杉矶,测试周期 24 小时,每 5 分钟采样一次。Fake-IP 配合 DoT 的组合在抖动和丢包上都有优势,原因是解析被推迟到连接建立时,减少了 DNS 查询的往返次数。VMess 的 2-RTT 握手在长距离链路上会放大延迟差异。

规则集模块化分离的工程实践

按业务域拆分规则集

把 geosite-cn 这种大而全的规则集直接塞进配置是能跑,但维护性差。我的做法是按业务域拆成多个小规则集,比如 geosite-google、geosite-openai、geosite-netflix、geosite-cn,每个规则集对应一个 outbound 组。这样调整某个服务的路由策略时,只需要改一条规则,不会影响其他服务。

{
  "route": {
    "rules": [
      { "rule_set": "geosite-openai", "outbound": "proxy-us" },
      { "rule_set": "geosite-netflix", "outbound": "proxy-stream" },
      { "rule_set": "geosite-google", "outbound": "proxy" },
      { "rule_set": "geosite-cn", "outbound": "direct" }
    ]
  }
}

outbound 组可以用 selector 或 urltest 类型实现自动切换。urltest 会定期测速并选择延迟最低的节点,适合多节点冗余场景。selector 需要手动切换,适合需要固定出口 IP 的场景。

规则集更新的原子性

remote 规则集在更新时会先下载到临时文件,校验通过后再替换。如果下载失败,会保留旧版本继续使用。这个行为在 1.9.x 之后才完善,早期版本下载失败会直接清空规则集,导致分流全部失效。升级到 1.10.x 可以避免这个问题。

更新间隔不建议设得太短。geosite 规则集的更新频率大约是每周一次,设成 24 小时已经足够。设得太短会增加启动时的网络开销,尤其是在代理链路不稳定的情况下。

常见误配置与修正

DNS 规则与路由规则顺序不一致

DNS 阶段把域名分流到 local server,路由阶段却把同一个域名分流到 proxy outbound,结果是域名解析成国内 IP,然后通过代理去连接国内 IP,延迟翻倍。修正方法是保持两个阶段的规则集一致,dns.rules 里出现的 rule_set 在 route.rules 里也要有对应条目,且 outbound 方向一致。

Fake-IP 与 sniff_override_destination 冲突

sniff_override_destination 设为 true 时,sing-box 会用嗅探到的域名覆盖 Fake-IP 映射表里的原始域名。如果嗅探失败,会回退到 Fake-IP,导致映射表里出现两个域名指向同一个假 IP。修正方法是把 sniff_override_destination 设为 false,让 Fake-IP 映射表保持唯一。

规则集下载走直连导致启动失败

服务器在国内且规则集 URL 被墙时,remote 规则集下载会超时。sing-box 默认会重试三次,每次间隔 5 秒,总共 15 秒后放弃。如果配置了 final: proxy 但规则集没加载成功,所有流量都会走代理,包括本该直连的国内流量。修正方法是给 rule_set 加 download_detour: proxy,或者提前把 .srs 文件下载到本地改用 local 类型。

与 Clash 配置的迁移对照

Clash 字段sing-box 对应注意事项
rulesroute.rules匹配顺序一致,自上而下
rule-providersroute.rule_setsing-box 区分 binary 与 source
dns.nameserverdns.serverssing-box 需要显式 tag
dns.fake-ip-filterdns.rulessing-box 用规则匹配替代过滤列表
proxy-groupsoutbounds (selector/urltest)语义相近,字段名不同

迁移时最容易踩的坑是 DNS 部分。Clash 的 nameserver 是一个数组,sing-box 的 servers 是带 tag 的对象数组,且每个 server 需要单独指定 detour。直接把 Clash 的 DNS 配置翻译过来,会得到一堆没有 detour 的 server,全部走直连,造成 DNS 泄露。

性能调优的几个细节

tun 的 mtu 字段默认 9000,在部分网络环境下会导致分片。实测把 mtu 设为 1500 更稳定,代价是吞吐略降。如果链路支持 jumbo frame,可以保持 9000。

route.rules 的数量会影响匹配性能,但影响很小。实测 1000 条规则的匹配耗时在微秒级,相对于网络 RTT 可以忽略。真正影响性能的是 rule_set 的数量,每个 rule_set 需要单独加载和编译,数量过多会拖慢启动速度。建议控制在 20 个以内。

log.level 设为 debug 会显著增加 CPU 占用,生产环境建议用 info 或 warn。排障时临时开 debug,问题定位后立即改回。

⚠️常见误区与避坑建议

  • •remote 规则集下载默认走 direct outbound,服务器在国内且规则集托管在 GitHub 时会启动超时,必须在 rule_set 里显式指定 download_detour 或改用 local 类型
  • •sniff_override_destination 设为 true 会与 Fake-IP 映射表冲突,导致同一域名出现多个假 IP 映射,表现为连接随机失败,应保持 false
  • •dns.rules 与 route.rules 的规则集方向不一致会造成 DNS 泄露或延迟翻倍,DNS 阶段走 local 的域名在路由阶段也应走 direct
🎯 完整用户决策旅程 (NEXT STEPS)

为您准备好的下一步需求承接

每个页面既要解决一个问题,也要为用户准备好最合理的下一步

TOPIC HUB · 专题中心

客户端配置与新手教程专区

图文详解各客户端智能分流与防风控配置。

前往客户端教程中心 →
DECISION & RECOMMEND · 选择指南

挑选适合开发者的稳定专线服务

核验专线延迟、双 ISP 纯净原生 IP 节点与流媒体实测数据。

查看稳定专线推荐 →
💡 机场搜 Decision Hub 承诺:本站严禁在信息型与教程页面进行强买强卖。我们致力于先帮您把技术问题解决透彻,再为您提供客观透明的多维选型参考。