sing-box规则怎么配置:可校验 JSON、规则顺序与 rule_set 排错
简答:先定义 direct、proxy 等 outbounds,再按顺序写 route.rules,最后用 final 兜底;DNS 劫持要单独匹配 DNS 请求。按本文配置并检查日志后,可区分规则未命中、标签错误、代理端口不可用和版本字段不兼容。
定义:sing-box 路由规则是根据域名、IP、端口、进程或规则集匹配流量,再用 route、reject 或 hijack-dns 等动作决定处理方式的配置。
先照抄一份可校验配置:直连、代理、拒绝和 DNS 劫持
先给结论:sing-box 规则配置可以按“定义入站和出站→配置 DNS→写 route.rules→设置 final”的顺序完成。下面的 JSON 语法完整,server_port 使用合法数字;但 127.0.0.1:2080 只是本机 SOCKS 服务的示例地址,不能证明代理链路已经可用。保存后,应先用你当前核心或图形客户端提供的配置检查功能验证。
本站是第三方使用指南站,不是 sing-box 官方站。字段含义以官方 Route 文档、官方 Route Rule 文档和官方 Rule Action 文档为准。
完整示例:
{"log":{"level":"info","timestamp":true},"dns":{"servers":[{"type":"local","tag":"local-dns"}],"final":"local-dns"},"inbounds":[{"type":"mixed","tag":"mixed-in","listen":"127.0.0.1","listen_port":2081}],"outbounds":[{"type":"direct","tag":"direct"},{"type":"socks","tag":"proxy","server":"127.0.0.1","server_port":2080}],"route":{"rules":[{"action":"sniff"},{"protocol":"dns","action":"hijack-dns"},{"ip_is_private":true,"action":"route","outbound":"direct"},{"domain_suffix":["ads.example"],"action":"reject"},{"domain_suffix":["example.com"],"action":"route","outbound":"proxy"}],"final":"direct"}}
mixed-in提供本机混合入站,监听端口为2081。direct处理局域网地址和默认兜底流量。proxy只处理example.com后缀域名,前提是本机确实有 SOCKS 服务监听127.0.0.1:2080。ads.example只是演示明确域名的拒绝写法,不是广告规则集。protocol: dns让hijack-dns只针对已识别的 DNS 请求生效,不把它当作普通网页流量代理动作。
如果你的代理服务监听端口不是 2080,只修改 server_port;如果没有本机 SOCKS 服务,配置检查仍可能通过,但访问命中 proxy 的域名时会连接失败。不要把示例中的域名、端口或说明文字当成真实服务信息。
规则顺序怎么理解:先匹配具体条件,再由 final 兜底
route 中的 rules 是规则列表,规则字段负责匹配,action 负责说明命中后的处理方式,final 指定没有被前面规则处理时使用的默认出站。官方规则动作文档把 route、bypass、reject 和 hijack-dns列为最终动作,把 route-options、sniff 和 resolve列为非最终动作;因此不能把所有 action 都概括成同一种“命中后立刻结束”。
| 配置位置 | 作用 | 常见写法 | 验证重点 |
|---|---|---|---|
| outbounds | 定义可被规则调用的出站 | direct、socks | 规则里的 outbound 必须对应 tag |
| route.rules | 匹配流量并执行动作 | domain_suffix、ip_cidr、rule_set | 条件是否真的命中目标流量 |
| action: route | 把连接送到指定出站 | outbound: proxy | outbound 标签不能拼错 |
| action: reject | 拒绝连接 | method: drop或默认方法 | 确认规则命中,而不是误判为网络故障 |
| action: hijack-dns | 把 DNS 请求交给 sing-box DNS 模块 | protocol: dns配合使用 | 必须有可用的 dns.servers |
| final | 指定默认出站 | direct或proxy | 未命中规则时观察其结果 |
覆盖示例:假如先放一个很宽的规则集,后面再放指定域名规则,前面的最终动作可能已经处理了流量,后面的指定域名规则就不会达到预期。因此建议先放局域网、明确域名和拒绝条件,再放较宽的规则集,最后设置 final。这是配置组织上的排查原则;具体动作是否继续执行,要以该 action 在当前核心版本中的官方语义为准。
sniff 属于非最终动作,可以用于识别协议;hijack-dns 属于最终动作,作用范围是 DNS 请求。若要在 TUN 场景使用 DNS 劫持,应同时核对官方 TUN 文档中的 DNS 模式、端口 53 处理和权限要求,不要直接把基础 mixed 入站示例当成完整 TUN 配置。
国内直连、指定代理和规则集:四种需求怎么落到字段
sing-box 规则不需要把所有条件都写进一个复杂逻辑表达式。可以先把需求拆成“匹配什么、执行什么、送到哪个出站”三部分:
- 局域网直连:使用
ip_is_private: true,执行action: route,目标为direct。 - 指定域名直连:使用
domain或domain_suffix,目标为direct。 - 指定域名代理:使用
domain、domain_suffix或rule_set,目标为已定义的proxy。 - 明确域名拒绝:使用
action: reject,不需要额外创建一个名为block的出站。 - 其余流量:交给
final。少数域名需要代理时,通常把final设为direct;默认多数流量需要代理时,再考虑把final设为proxy。
旧配置中可能存在 type: block 出站,并通过 outbound: block拒绝流量。官方迁移文档给出的新版方向是删除这个特殊出站,改为在规则中使用 action: reject。因此,block 可以作为旧配置迁移时的识别对象,但不应在新的完整示例中保留一个没有被引用的 block 出站。
规则集适合承载较多的域名或 IP 条件。官方rule-set 文档列出 inline、local 和 remote 三类写法。一个可校验的 inline 片段如下,适用于 sing-box 1.10.0 及以后版本:
{"log":{"level":"info"},"inbounds":[{"type":"mixed","tag":"in","listen":"127.0.0.1","listen_port":2081}],"outbounds":[{"type":"direct","tag":"direct"},{"type":"socks","tag":"proxy","server":"127.0.0.1","server_port":2080}],"route":{"rule_set":[{"type":"inline","tag":"local-domains","rules":[{"domain_suffix":["example.cn"]}]}],"rules":[{"rule_set":["local-domains"],"action":"route","outbound":"direct"}],"final":"proxy"}}
本地规则集则需要在 route.rule_set 中写明 type: local、format和path,文件内容还必须符合对应的 source 或 binary 格式。远程规则集需要 type: remote、format和url;1.14.0 起还应核对 initial_path与http_client,旧的 download_detour已被标记为废弃。没有核对过来源和格式的远程列表,不建议直接用于正式配置。
版本迁移速查:哪些旧字段要优先检查
下面只列出与规则、路由、DNS 和 TUN 配置直接相关、且能在官方迁移文档或字段文档中核对的变化。图形客户端可能内置不同核心版本,实际使用前先确认客户端显示的 sing-box 核心版本。
| 版本 | 官方变更 | 配置动作 | 来源 |
|---|---|---|---|
| 1.8.0 | GeoIP、Geosite 迁移到 rule-set;route.rule_set 开始支持。 | 新配置优先使用 rule_set,不再扩展旧 geoip、geosite 字段。 | 官方迁移文档 |
| 1.10.0 | 支持 inline rule-set;TUN 地址字段合并。 | inline 规则集使用 type: inline;旧的 inet4、inet6 地址字段改为统一 address 等字段。 | rule-set 文档、迁移文档 |
| 1.11.0 | 特殊出站、部分入站字段、direct 目标覆盖和 WireGuard outbound 进入迁移路径;route rule 的 outbound 字段已标记废弃。 | 拒绝流量检查 action: reject;目标地址覆盖检查 route-options;旧 WireGuard outbound 检查 endpoint 迁移。 | 1.11.0 官方迁移章节、Route Rule 文档 |
| 1.12.0 | DNS server 格式重构,旧的 address 写法迁移到 type、server 等字段。 | 例如本地 DNS 使用 type: local;UDP DNS 使用 type: udp和server,不要把旧格式原样复制。 | DNS 迁移章节、DNS 配置文档 |
| 1.14.0 | remote rule-set 增加或调整 initial_path、http_client 使用方式,download_detour 废弃。 | 远程规则集优先检查缓存初始文件、HTTP 客户端和废弃字段。 | rule-set 文档、迁移文档 |
| 1.15.0 | TUN 的 stack 选项废弃,官方迁移说明要求移除以使用新的 sing-tun stack。 | 复制旧 TUN 配置时删除 stack,并重新检查系统权限和路由行为。 | 1.15.0 TUN 迁移章节 |
版本迁移不要只看配置检查是否通过。配置能解析,只代表字段结构被接受;规则是否命中、代理出站是否能连接、TUN 是否获得必要权限,还需要通过日志和本机端口检查继续确认。
不生效怎么排查:JSON、标签、命中和端口四层检查
- 先查 JSON。确认双引号、逗号、数组和布尔值正确;
server_port必须是数字。命令行版本可在终端执行当前版本支持的sing-box check,图形客户端则使用它的配置检查入口。 - 再查标签。规则中的
outbound必须和outbounds[].tag完全一致。proxy、direct大小写不同也会导致目标出站找不到。 - 再查规则命中。先暂时只保留一个明确的
domain或domain_suffix规则,不要同时叠加多个远程规则集、正则和逻辑规则。把明确规则放在宽泛规则前,便于从日志观察结果。 - 最后查代理端口。如果直连正常、只有代理规则失败,先确认本机是否真的有服务监听
127.0.0.1:2080。Windows PowerShell 中执行Test-NetConnection 127.0.0.1 -Port 2080;Linux 或 macOS 终端执行nc -vz 127.0.0.1 2080。端口可连接不等于上游认证一定成功。
日志位置取决于配置。若设置了 log.output,到该文件查看;没有设置时,官方日志配置通常输出到控制台。排查期间可临时使用 level: debug,观察入站、识别出的域名或协议、命中的规则和最终出站。不要把 Cookie、订阅令牌、密码或完整认证信息复制到公开日志。
如果错误只出现在远程 rule-set,先改为 inline 或 local 规则集验证规则逻辑;本地能命中后,再检查远程 URL、format、缓存路径、HTTP client 和目标核心版本。若错误出现在 DNS 劫持,先确认 dns.servers存在,再确认规则匹配的是 DNS 请求,而不是把 hijack-dns写成无条件的普通流量规则。
常见问题
sing-box 规则为什么写了却不生效?
先检查规则是否位于正确的 route.rules 中,再检查匹配字段是否对应真实流量,之后核对 action 和 outbound 标签。建议先用一个明确域名做最小测试,并查看日志中的入站、匹配结果和最终出站。
sing-box 的 final 应该写 direct 还是 proxy?
如果只有少数域名需要代理,可以把 final 设为 direct,再为指定域名写 route 到 proxy;如果大多数流量都需要代理,可以把 final 设为 proxy,同时把局域网和明确直连域名放在前面。
hijack-dns 能不能当普通网页流量的代理规则?
不能这样使用。hijack-dns 的官方语义是把 DNS 请求交给 sing-box DNS 模块,建议用 protocol: dns 等条件限定范围,并同时配置至少一个 dns.servers 条目。
新版为什么不建议继续使用 block 出站?
官方迁移文档给出了从旧 block 特殊出站迁移到 action: reject 的写法。新配置可直接使用 reject 动作,删除没有被引用的 block 出站,避免读者误以为拒绝规则会流向某个出站。
rule_set 远程下载失败怎么判断?
先换成 inline 或 local 规则集测试 route.rules,确认逻辑本身能命中;再检查 remote 的 url、format、缓存文件、http_client 和目标版本。1.14.0 以后还要核对 initial_path,并避免继续使用已废弃的 download_detour。
sing-box 配置检查通过但代理仍然连接失败怎么办?
配置检查只说明结构能被解析,不代表代理链路可用。先确认 proxy 出站的 server、server_port 和认证字段,再检查本机代理监听端口;Windows PowerShell 使用 Test-NetConnection,Linux 或 macOS 使用 nc -vz。