sing-box 配置格式详解:JSON 结构、分流逻辑与常见坑
· 5 min read
很多人从 Clash 迁移到 sing-box,第一反应是:
- 配置为什么是 JSON?
outbounds、route.rules、dns.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:流量匹配规则,把流量导向某个 outbounddns:域名解析与 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本质都是 outboundoutbound引用的是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_regexip_cidr/ip_is_privateport/port_rangesource_ip_cidr/source_ip_is_privaterule_set
核心原则:
- 规则从上到下匹配,先命中先用
- 最后靠
route.final兜底
高频错误:
- 先写了大范围规则,后面精确规则永远进不去
rule_set写了但对应规则集没加载成功final空着导致结果依赖“第一个 outbound”,行为不可预期
5. DNS:独立配置、独立规则
sing-box 的 DNS 不是“随便填两个上游”那么简单,它有自己结构:
dns.serversdns.rulesdns.finaldns.strategy
如果你只盯 route.rules,会忽略 DNS 本身的分流,最终表现就是“规则看起来对,但命中很怪”。
另外,官方在 1.12.0 对 DNS server 结构做了重构,legacy 格式已经进入弃用周期。
6. TUN:不是必须,但常是体验分水岭
type: tun inbound 常见于全局接管流量场景,常见字段包括:
auto_routestrict_routeroute_address/route_exclude_address- Linux 下的
auto_redirect(官方明确推荐)
但别盲开:
- 桌面系统、路由器、Android 行为不同
auto_route/ 接口绑定配置不当会路由环路
7. 版本变化是“配置失效”的头号原因
sing-box 更新很快,deprecated 变化也快。常见场景:
- 旧 DNS server 格式逐步淘汰
- 旧 special outbounds(如 legacy
dns)进入移除周期 - 某些旧字段在新版本不再生效
所以你要养成两个习惯:
- 升级前看官方
Deprecated/Migration - 每次改完跑一次:
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: select | outbounds[].type = "selector" |
proxy-groups: url-test | outbounds[].type = "urltest" |
rules | route.rules |
MATCH,xxx | route.final = "xxx"(兜底) |
| DNS 分流 | dns.rules |
9. 一句话排错清单
出现“能启动但分流不对”时,按这顺序查:
sing-box check是否通过outbounds的tag是否写对、引用是否一致route.rules顺序是否合理route.final是否明确dns.rules是否与route.rules冲突- 当前版本是否命中 deprecated 变更
官方参考(主来源)
- Configuration Introduction
https://sing-box.sagernet.org/configuration/ - Outbound
https://sing-box.sagernet.org/configuration/outbound/ - Selector
https://sing-box.sagernet.org/configuration/outbound/selector/ - URLTest
https://sing-box.sagernet.org/configuration/outbound/urltest/ - Route
https://sing-box.sagernet.org/configuration/route/ - Route Rule
https://sing-box.sagernet.org/configuration/route/rule/ - DNS
https://sing-box.sagernet.org/configuration/dns/ - DNS server (HTTPS/TLS/QUIC)
https://sing-box.sagernet.org/configuration/dns/server/https/
https://sing-box.sagernet.org/configuration/dns/server/tls/
https://sing-box.sagernet.org/configuration/dns/server/quic/ - TUN inbound
https://sing-box.sagernet.org/configuration/inbound/tun/ - Deprecated list
https://sing-box.sagernet.org/deprecated/