Skip to main content

sing-box 配置格式详解:JSON 结构、分流逻辑与常见坑

· 5 min read
Jiang
Operator

很多人从 Clash 迁移到 sing-box,第一反应是:

  • 配置为什么是 JSON?
  • outboundsroute.rulesdns.rules 到底谁先起作用?
  • selector/urltest 跟 Clash 的策略组有什么对应关系?
  • 为什么照着旧教程写会遇到 deprecated?

这篇文章专门讲 sing-box 配置格式本身,目标是让你能看懂结构、知道该改哪一段、避免踩版本坑。

本文以 sing-box 官方文档为准。

1. 先记住总结构

官方给出的配置骨架是:

{
"log": {},
"dns": {},
"ntp": {},
"certificate": {},
"endpoints": [],
"inbounds": [],
"outbounds": [],
"route": {},
"services": [],
"experimental": {}
}

你可以这样理解:

  • inbounds:入口(本地代理端口、TUN 等)
  • outbounds:出口(直连、节点、selector、urltest)
  • route:流量匹配规则,把流量导向某个 outbound
  • dns:域名解析与 DNS 分流(独立的一套规则)

2. 一份可读的最小示例

下面是一份“结构正确、便于理解”的最小配置(示意):

{
"log": { "level": "info" },
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"outbounds": [
{
"type": "selector",
"tag": "select",
"outbounds": ["auto", "proxy-a", "direct"],
"default": "auto"
},
{
"type": "urltest",
"tag": "auto",
"outbounds": ["proxy-a", "proxy-b"],
"url": "https://www.gstatic.com/generate_204",
"interval": "3m",
"tolerance": 50
},
{ "type": "vmess", "tag": "proxy-a", "server": "1.2.3.4", "server_port": 443, "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" },
{ "type": "vmess", "tag": "proxy-b", "server": "5.6.7.8", "server_port": 443, "uuid": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" },
{ "type": "direct", "tag": "direct" },
{ "type": "block", "tag": "block" }
],
"route": {
"final": "select",
"rules": [
{ "ip_is_private": true, "outbound": "direct" },
{ "domain_suffix": [".cn"], "outbound": "direct" }
]
}
}

关键点:

  • route.final 是兜底出口
  • selector / urltest 本质都是 outbound
  • outbound 引用的是 outbounds[].tag

3. Outbound:sing-box 的“策略组”在这里

很多 Clash 用户会先找 proxy-groups,但 sing-box 的思路是:

  • selector 是手动选路
  • urltest 是自动测速选路
  • 它们都在 outbounds

这也是为什么官方文档里 selector 明确说明可通过 Clash API 控制。

实战建议:

  • 给每个 outbound 都起清晰 tag
  • selector 里把 direct 放进去作为兜底
  • urltest 的测试 URL 用稳定目标(默认 generate_204

4. Route:主分流规则(最常改)

你日常最常动的是 route.rules

常见匹配字段(按官方):

  • domain / domain_suffix / domain_keyword / domain_regex
  • ip_cidr / ip_is_private
  • port / port_range
  • source_ip_cidr / source_ip_is_private
  • rule_set

核心原则:

  • 规则从上到下匹配,先命中先用
  • 最后靠 route.final 兜底

高频错误:

  • 先写了大范围规则,后面精确规则永远进不去
  • rule_set 写了但对应规则集没加载成功
  • final 空着导致结果依赖“第一个 outbound”,行为不可预期

5. DNS:独立配置、独立规则

sing-box 的 DNS 不是“随便填两个上游”那么简单,它有自己结构:

  • dns.servers
  • dns.rules
  • dns.final
  • dns.strategy

如果你只盯 route.rules,会忽略 DNS 本身的分流,最终表现就是“规则看起来对,但命中很怪”。

另外,官方在 1.12.0 对 DNS server 结构做了重构,legacy 格式已经进入弃用周期。


6. TUN:不是必须,但常是体验分水岭

type: tun inbound 常见于全局接管流量场景,常见字段包括:

  • auto_route
  • strict_route
  • route_address / route_exclude_address
  • Linux 下的 auto_redirect(官方明确推荐)

但别盲开:

  • 桌面系统、路由器、Android 行为不同
  • auto_route / 接口绑定配置不当会路由环路

7. 版本变化是“配置失效”的头号原因

sing-box 更新很快,deprecated 变化也快。常见场景:

  • 旧 DNS server 格式逐步淘汰
  • 旧 special outbounds(如 legacy dns)进入移除周期
  • 某些旧字段在新版本不再生效

所以你要养成两个习惯:

  1. 升级前看官方 Deprecated / Migration
  2. 每次改完跑一次:
sing-box check

必要时再用:

sing-box format -w -c config.json

8. 从 Clash 迁移到 sing-box 的快速映射

Clash/Mihomo 概念sing-box 对应
proxies普通节点 outbound(vmess/vless/trojan/hysteria2...)
proxy-groups: selectoutbounds[].type = "selector"
proxy-groups: url-testoutbounds[].type = "urltest"
rulesroute.rules
MATCH,xxxroute.final = "xxx"(兜底)
DNS 分流dns.rules

9. 一句话排错清单

出现“能启动但分流不对”时,按这顺序查:

  1. sing-box check 是否通过
  2. outboundstag 是否写对、引用是否一致
  3. route.rules 顺序是否合理
  4. route.final 是否明确
  5. dns.rules 是否与 route.rules 冲突
  6. 当前版本是否命中 deprecated 变更

官方参考(主来源)