sing-box 9大核心配置项全解析(100%匹配1.14.0+最新官方文档) 以下内容严格基于 sing-box 官方最新文档定义,先讲全链路执行总框架,再逐个拆解每个配置项的官方定义、生效边界、优先级与坑点,最后梳理它们的相互影响关系,并通过完整场景串联所有配置。
dns.servers[].domain_resolver
outbounds[].domain_resolver
route.default_domain_resolver
dns.servers[].detour
outbound.detour
dns.rules[]
route.rules[]
dns.final
route.final

一、全局执行总框架
sing-box 从启动到用户访问的完整生命周期,分为两大核心阶段,所有配置项都在这两个阶段里各司其职,顺序不可逆:
【第一阶段:sing-box 启动初始化】
↓
1. 解析所有域名形式的出站(代理节点):优先用 outbound 自己的 domain_resolver,兜底用 route.default_domain_resolver
↓
2. 按 outbound.detour 建立链式代理隧道,完成代理网络初始化
↓
3. 初始化 DNS 模块,加载 dns.servers、dns.rules、dns.final
【第二阶段:用户访问运行时】
↓
1. 用户发起域名访问 → 进入 DNS 模块
↓
2. dns.rules 从上到下匹配,命中即停止,决定用哪个 dns.server 解析;全不命中走 dns.final
↓
3. 选中的 dns.server 执行解析:
a. 若DNS服务器是域名(如DoH),先用自己的 domain_resolver 解析自身域名,解决鸡生蛋死锁
b. 按 dns.server.detour 指定的出站,发送DNS查询请求,拿到目标域名的IP
↓
4. 拿到IP后,进入路由模块
↓
5. route.rules 从上到下匹配,命中即停止,决定流量走哪个 outbound;全不命中走 route.final
↓
6. 按 outbound.detour 完成链式代理转发,最终访问目标服务
graph TD A[启动初始化] –> B[解析代理节点域名] B –> C{outbound是否配置domain_resolver?} C –>|是| D[用outbound.domain_resolver解析] C –>|否| E[用route.default_domain_resolver解析] D & E –> F[建立链式代理隧道] F –> G[用户访问google.com]
G --> H[DNS规则匹配]
H --> I[选择remote_doh]
I --> J[解析cloudflare-dns.com]
J --> K{remote_doh是否配置detour?}
K -->|是 ✅| L[强制走代理隧道]
L --> M[拿到真实境外IP]
K -->|否 ⚠️| N[进入路由模块匹配]
N --> O{规则是否匹配?}
O -->|是| P[侥幸走代理]
O -->|否| Q[直连导致DNS泄漏]
P & Q --> R[拿到解析结果]
M & R --> S[业务流量路由]
S --> T[按outbound.detour转发]
T --> U{最终结果}
U -->|安全配置| V[✅ 正常访问]
U -->|风险配置| W[❌ 泄漏/劫持]
二、每个配置项的官方定义与核心详解
(一)域名解析铁三角:3个 domain_resolver 相关配置
这三个配置是整个代理体系的「前置基建」,专门解决**「鸡生蛋、蛋生鸡」的死锁问题**,优先级最高,完全绕过常规DNS/路由规则。
1. dns.servers[].domain_resolver
官方定义:属于DNS服务器的拨号(Dial)字段,专门用于解析当前DNS服务器自身的域名(如DoH的cloudflare-dns.com、DoT的dns.alidns.com)。
- 生效对象:仅对当前DNS服务器自己的域名生效,和用户访问的目标域名完全无关。
- 优先级:最高级,仅对自身生效,不会被全局配置覆盖。
- 核心作用:解决死锁——要给
cloudflare-dns.com发DoH查询,必须先知道它的IP,这个配置就是专门用来解析这个DNS服务器域名的,避免陷入「要解析域名先得解析域名」的死循环。 - 官方强制要求:如果DNS服务器用了域名作为地址,必须配置该字段,否则配置不生效。
- 坑点:该配置仅解析自身域名,不会解析用户请求的其他域名。
2. outbounds[].domain_resolver
官方定义:属于出站的拨号(Dial)字段,专门用于解析当前出站的服务器域名(如域名形式的代理节点jp-node.example.com);仅direct类型出站例外,它解析的是用户请求里的目标域名。
- 生效对象:
- 代理类出站(vmess/vless/trojan等):仅解析出站自己的服务器域名(代理节点域名)。
direct直连出站:解析用户请求的目标域名(用于直连场景的域名解析)。
- 优先级:高于全局
route.default_domain_resolver,只要出站自己配了,就不会用全局兜底。 - 核心作用:解决代理节点域名的解析死锁——要连接
jp-node.example.com节点,必须先知道它的IP,这个配置就是专门解析节点域名的。 - 官方强制要求:1.14.0版本起,只要出站用了域名作为服务器地址,必须配置该字段,要么出站自己配,要么配置全局
route.default_domain_resolver兜底,否则配置校验不通过。 - 坑点:如果出站配置了
detour(链式代理),则该字段会被完全忽略,所有拨号字段都会失效。
3. route.default_domain_resolver
官方定义:路由段的全局兜底域名解析器,当出站没有配置自己的domain_resolver时,自动用它解析出站的服务器域名。
- 生效对象:所有未单独配置
domain_resolver的出站(代理节点)。 - 优先级:最低,仅做兜底,出站自己配了
domain_resolver的话,完全不生效。 - 核心作用:简化配置,给所有域名形式的节点提供统一的兜底解析器,避免每个出站都重复配置
domain_resolver。 - 官方说明:当配置里只有1个DNS服务器时,该字段可选;当有多个DNS服务器时,必须配置该字段或给每个出站单独配解析器。
- 坑点:该配置在
route路由段,不是DNS段,很多人会写错位置导致不生效。
(二)流量路径总指挥:2个 detour 相关配置
detour的核心是指定流量的上游出站,决定「流量从哪个口子出去」,是实现代理隧道、防DNS污染、链式代理的核心。
1. dns.servers[].detour
官方定义:属于DNS服务器的拨号(Dial)字段,指定当前DNS服务器的查询流量,通过哪个出站发出去。
- 生效对象:仅对当前DNS服务器发出的DNS查询流量生效。
- 核心作用:
- 防DNS污染:给境外DoH配置
detour: "proxy_outbound",让DNS查询全程走代理隧道,运营商完全看不到、也无法污染你的DNS请求。 - 国内解析优化:给国内DoH配置
detour: "direct_outbound",让DNS查询直连国内服务器,保证CDN调度到最近的国内节点。
- 防DNS污染:给境外DoH配置
- 优先级与坑点:只要配置了该字段,当前DNS服务器的其他所有拨号字段(
bind_interface、routing_mark等)都会被完全忽略。 - 关键误区:该配置只影响「DNS查询的流量路径」,不影响「解析后业务流量的路径」——业务流量走哪个出站,由
route.rules决定。 - 👉 DNS 查询本质也是“流量”
所以:
- 要么你: 用 detour 控死它
- 要么: 让 route 管它(但你要完全理解后果)
2. outbounds[].detour
官方定义:属于出站的核心字段,指定当前出站的上游出站,实现链式代理(也叫嵌套代理、跳板代理)。
- 生效对象:当前出站的所有流量,包括连接节点的握手流量、转发的业务流量。
- 核心作用:实现多级代理,比如
节点A的detour设为节点B,则所有流量会先发到节点B,再从节点B转发到节点A,最终访问目标服务。 - 优先级与坑点:只要配置了该字段,当前出站的所有其他拨号字段(
domain_resolver、bind_interface、server/server_port等)全部失效。- 例:你给
proxy_outbound配置了detour: "socks_outbound",则proxy_outbound自己的节点地址、端口、uuid等全部不生效,所有流量都会直接转发给socks_outbound。
- 例:你给
- 关键误区:该配置是「出站的上游」,和DNS服务器的
detour完全隔离,互不干扰。
(三)规则分流双核心:2个 rules 规则配置
这两个规则是分流的核心,分别管控「DNS解析分流」和「业务流量分流」,均遵循从上到下顺序匹配,命中即停止的核心逻辑。
1. dns.rules[]
官方定义:DNS规则列表,决定用户发起的目标域名解析请求,用哪个DNS服务器处理,或执行什么动作。
- 匹配逻辑:数组从上到下依次匹配,第一个匹配成功的规则直接生效,后续所有规则不再执行。
- 核心作用:
- 域名分流:国内域名用国内DNS解析,境外域名用境外DNS解析,保证解析速度与CDN调度。
- 广告/恶意域名拦截:匹配广告规则集,直接执行
reject动作拒绝解析。 - 特殊域名处理:内网域名用路由器DNS解析,ECH相关域名用专用DNS解析。
- FakeIP分发:匹配符合条件的域名,用FakeIP服务器秒级返回虚拟IP,加速连接。
- 官方支持动作:
route(指定DNS服务器)、reject(拒绝解析)、predefined(返回预设响应码,如NXDOMAIN/NOTIMP)等。 - 坑点:无匹配条件的规则会匹配所有查询,直接拦截后续所有规则,必须把无匹配条件的规则放在最末尾。
2. route.rules[]-DNS查询
官方定义:路由规则列表,决定IP流量,通过哪个出站转发。
此处的流量分DNS查询和实际访问两种。
未设置detour的DNS查询就是普通的流量。
一、DNS 查询流量的完整路由逻辑(100% 准确)
sing-box 中 DNS 查询流量的路由,遵循**「有 detour 优先用 detour,没 detour 就走 route.rules」**的核心逻辑,官方文档虽未明确单列,但代码实现和实际运行逻辑完全符合这一点。
完整决策树
DNS 查询发起
↓
【判断1】该 DNS 服务器是否配置了 dns.servers[].detour?
├─ 是 → 【路径A】DNS 查询流量强制走该 detour 指定的出站,**完全绕过 route.rules**
└─ 否 → 【判断2】进入路由模块,匹配 route.rules[]
├─ 命中某条路由规则 → 【路径B】走该规则指定的 outbound
└─ 未命中任何规则 → 【路径C】走 route.final 指定的兜底 outbound
二、三种路径的详细说明与配置示例
路径A:DNS 服务器配置了 detour(最常见,防污染核心)
这是最推荐的境外 DNS 配置方式,也是防 DNS 污染的核心。
- 核心逻辑:DNS 查询流量强制走 detour 指定的出站,完全不看
route.rules,优先级最高。 - 适用场景:境外 DoH/DoT 配置,强制 DNS 查询走代理隧道,彻底防污染。
- 配置示例:
{
"tag": "remote_doh",
"type": "https",
"server": "cloudflare-dns.com",
"domain_resolver": "local_udp",
"detour": "proxy_outbound", // 强制走代理,完全绕过 route.rules
"path": "/dns-query"
}
路径B:DNS 服务器没配置 detour,匹配 route.rules
这是容易被忽略的场景,也是很多玄学问题的根源。
- 核心逻辑:DNS 查询流量会被当成普通业务流量,进入路由模块匹配
route.rules,根据规则决定走哪个出站。 - 适用场景:
- 国内 DNS 配置,希望 DNS 查询流量和国内业务流量走一样的路径。
- 内网 DNS 配置,希望 DNS 查询流量走内网路由。
- 潜在坑点:如果
route.rules配置不当,可能导致境外 DNS 查询流量被误判为国内流量,走直连,从而被污染。 - 配置示例:
{
"tag": "direct_doh",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "local_udp"
// 没配置 detour,进入 route.rules 匹配
}
对应的 route.rules:
{
"route": {
"rules": [
// 国内域名/IP 走直连
{ "rule_set": ["geosite-cn"], "outbound": "direct_outbound" },
// 境外走代理
{ "rule_set": ["geosite-!cn"], "outbound": "proxy_outbound" }
]
}
}
此时,direct_doh 的 DNS 查询流量会匹配 geosite-cn 规则,走 direct_outbound 直连。
路径C:DNS 服务器没配置 detour,也没匹配到 route.rules
这是兜底场景。
- 核心逻辑:DNS 查询流量没匹配到任何
route.rules,走route.final指定的兜底出站。 - 潜在坑点:如果
route.final配置为代理,可能导致国内 DNS 查询流量走代理,影响 CDN 调度;如果配置为直连,可能导致境外 DNS 查询流量被污染。
三、关键补充:DNS 查询流量的匹配维度
当 DNS 查询流量进入 route.rules 匹配时,它的匹配维度和普通业务流量略有不同:
- 域名维度:匹配的是「DNS 服务器的地址」,而不是「用户访问的目标域名」。
- 例:你用
dns.alidns.com解析baidu.com,此时route.rules匹配的是dns.alidns.com,而不是baidu.com。
- 例:你用
- IP 维度:匹配的是「DNS 服务器解析后的 IP」。
- 端口维度:匹配的是 DNS 服务器的端口(通常是 53/UDP、443/TCP)。
四、最佳实践建议
为了避免玄学问题,强烈建议遵循以下配置原则:
- 境外 DNS 必须配置 detour:给所有境外 DoH/DoT 配置
detour: "proxy_outbound",强制 DNS 查询走代理,彻底防污染,完全不依赖route.rules。 - 国内 DNS 推荐配置 detour:给国内 DoH/DoT 配置
detour: "direct_outbound",强制 DNS 查询直连,保证 CDN 调度,避免被route.rules误判。 - 内网 DNS 必须配置 detour:给路由器 DNS 配置
detour: "direct_outbound",强制 DNS 查询走内网直连。
五、最终总结
- 有 detour 优先用 detour:DNS 服务器配置了
detour,流量强制走该出站,完全绕过 route.rules。 - 没 detour 就走 route.rules:DNS 服务器没配置
detour,流量进入路由模块,匹配route.rules,根据规则决定走哪个出站。 - 最佳实践:给所有 DNS 服务器都配置明确的
detour,避免依赖route.rules,减少玄学问题,保证 DNS 查询路径的确定性。
3. route.rules[]-网站访问
- 匹配逻辑:和DNS规则完全一致,数组从上到下依次匹配,命中即停止。
- 核心作用:流量的最终调度,国内流量直连,境外流量走代理,内网流量不走代理,广告流量直接阻断。
- 匹配维度:支持域名、IP段、端口、协议、进程名、入站标签、规则集等几乎所有流量特征,是sing-box精细化流量管控的核心。
- 坑点:规则顺序直接决定分流效果,必须把「精确规则」放在前面,「模糊规则」放在后面;比如内网IP规则放最前,通用代理规则放最后。
(四)兜底双保险:2个 final 配置
这两个配置是规则体系的兜底,保证所有没匹配到规则的流量/解析请求,都有明确的处理方式,避免流量失控。
1. dns.final
官方定义:DNS规则的兜底默认值,当dns.rules里的所有规则都没有匹配到当前DNS查询时,自动使用该字段指定的DNS服务器处理。
- 生效场景:所有未命中任何DNS规则的域名解析请求。
- 核心作用:防DNS泄漏的最后一道保险,通常设置为带代理detour的境外DNS,保证未知域名的解析全程走代理,不会被运营商污染。
- 坑点:如果不配置该字段,未匹配规则的请求会默认使用
dns.servers里的第一个服务器,容易导致DNS泄漏。
2. route.final
官方定义:路由规则的兜底默认出站,当route.rules里的所有规则都没有匹配到当前流量时,自动将流量转发到该字段指定的出站。
- 生效场景:所有未命中任何路由规则的业务流量。
- 核心作用:流量的最终兜底,通常设置为
direct直连或proxy代理,根据你的分流策略决定。 - 坑点:如果不配置该字段,未匹配规则的流量会默认走
tag为direct的出站,如果没有这个出站,会直接连接失败。
三、所有配置项的优先级与相互影响关系总表
| 配置项 | 优先级 | 核心互斥/依赖关系 |
|---|---|---|
outbounds[].domain_resolver | 最高(出站解析) | 覆盖route.default_domain_resolver;若出站配置了detour,则完全失效 |
dns.servers[].domain_resolver | 最高(DNS自身解析) | 仅对自身生效,完全独立,不被任何其他配置覆盖 |
route.default_domain_resolver | 最低(兜底解析) | 仅对未配置domain_resolver的出站生效 |
outbounds[].detour | 最高(出站流量) | 配置后,当前出站的所有其他拨号字段(含domain_resolver)全部失效 |
dns.servers[].detour | 最高(DNS查询流量) | 配置后,当前DNS服务器的其他拨号字段全部失效;仅影响DNS查询流量,不影响业务流量 |
dns.rules[] | 按顺序,越靠前优先级越高 | 命中即停止,后续规则完全不生效;解析结果会影响route.rules的匹配 |
route.rules[] | 按顺序,越靠前优先级越高 | 命中即停止,后续规则完全不生效;仅在DNS解析完成后执行 |
dns.final | 最低(DNS兜底) | 仅当所有dns.rules都未命中时生效 |
route.final | 最低(流量兜底) | 仅当所有route.rules都未命中时生效 |
四、📊 优先级规则速查表
| 场景 | 决定因素 | 优先级 |
|---|---|---|
| DNS 服务器域名的解析 | dns.servers[].domain_resolver | 最高 |
| 出站节点域名的解析 | outbounds[].domain_resolver | 最高 |
| 出站节点域名的解析(全局) | route.default_domain_resolver | 最低(仅当未配置时) |
| DNS 查询流量的出站 | dns.servers[].detour | 最高 |
| DNS 查询流量的出站(未配置 detour) | route.rules[] → route.final | 中等 |
| 普通网络流量的出站 | route.rules[] → route.final | 中等 |
五、全链路完整场景示例(包含所有9个配置项)
场景前提
- 代理节点:域名形式
jp-node.example.com,链式代理,先过香港中转节点hk-node.example.com,再到日本节点。 - 国内域名:用阿里DoH
dns.alidns.com直连解析。 - 境外域名:用Cloudflare DoH
cloudflare-dns.com走代理解析。 - 内网域名:用路由器DNS
192.168.3.1解析。 - 兜底:未知域名走代理DNS,未知流量直连。
精简完整配置(仅保留核心字段)
{
"dns": {
"servers": [
{ "tag": "local_udp", "type": "udp", "server": "223.5.5.5", "detour": "direct_outbound" },
{ "tag": "router_dns", "type": "udp", "server": "192.168.3.1", "detour": "direct_outbound" },
{
"tag": "remote_doh",
"type": "https",
"server": "cloudflare-dns.com",
"domain_resolver": "local_udp", // 【dns.servers.domain_resolver】解析自身域名
"detour": "jp_proxy", // 【dns.servers.detour】DNS查询走日本代理
"path": "/dns-query"
},
{
"tag": "direct_doh",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "local_udp",
"detour": "direct_outbound" // DNS查询直连,如果这里不设置任何outbound作为detour,那就根据route来判断,dns.alidns.com符合route里的哪天规则,就走哪个outbound
}
],
"rules": [ // 【dns.rules】DNS分流规则
{ "domain_suffix": ["home"], "server": "router_dns" },
{ "rule_set": ["geosite-cn"], "server": "direct_doh" },
{ "rule_set": ["geosite-!cn"], "server": "remote_doh" },
{ "rule_set": ["category-ads"], "action": "reject" }
],
"final": "remote_doh" // 【dns.final】DNS兜底
},
"outbounds": [
{
"tag": "jp_proxy",
"type": "vmess",
"server": "jp-node.example.com", // 域名形式节点
"server_port": 443,
"uuid": "xxx",
"domain_resolver": "local_udp", // 【outbounds.domain_resolver】解析日本节点域名
"detour": "hk_proxy" // 【outbounds.detour】链式代理,先走香港节点
},
{
"tag": "hk_proxy",
"type": "vmess",
"server": "hk-node.example.com",
"server_port": 443,
"uuid": "xxx"
// 没配domain_resolver,用全局default_domain_resolver兜底
},
{ "tag": "direct_outbound", "type": "direct", "domain_resolver": "local_udp" },
{ "tag": "block_outbound", "type": "block" }
],
"route": {
"default_domain_resolver": "local_udp", // 【route.default_domain_resolver】全局解析兜底
"rules": [ // 【route.rules】流量分流规则
{ "ip_cidr": ["192.168.3.0/24"], "outbound": "direct_outbound" },
{ "rule_set": ["geosite-cn"], "outbound": "direct_outbound" },
{ "rule_set": ["geosite-!cn"], "outbound": "jp_proxy" },
{ "rule_set": ["category-ads"], "outbound": "block_outbound" }
],
"final": "direct_outbound", // 【route.final】流量兜底
"rule_set": [/* 规则集配置,省略 */]
}
}
完整执行流程(覆盖所有配置项)
第一阶段:sing-box 启动初始化
- 读取
hk_proxy出站,发现是域名形式,且没配自己的domain_resolver,自动用route.default_domain_resolver: "local_udp"解析hk-node.example.com,拿到香港节点IP。 - 读取
jp_proxy出站,发现配置了detour: "hk_proxy",所以自己的节点地址、domain_resolver全部失效,直接把hk_proxy作为上游。 - 先连接香港节点,再通过香港节点连接日本节点,链式代理隧道建立完成。
- 初始化DNS模块,加载所有DNS服务器、规则、兜底配置。
第二阶段:用户访问google.com(境外域名)
- 用户发起
google.com的解析请求,进入DNS模块。 - 匹配
dns.rules,命中geosite-!cn规则,决定用remote_doh解析。 remote_doh是域名形式,先用自己的domain_resolver: "local_udp"解析cloudflare-dns.com,拿到IP。- 按
remote_doh.detour: "jp_proxy",把DoH查询通过日本代理隧道发出去,拿到google.com的境外IP。 - 拿到IP后,进入路由模块,匹配
route.rules,命中geosite-!cn规则,决定流量走jp_proxy出站。 - 按
jp_proxy.detour: "hk_proxy",业务流量先到香港节点,再转发到日本节点,最终访问google.com,流程完成。
第三阶段:用户访问baidu.com(国内域名)
- 解析请求匹配
dns.rules,命中geosite-cn,用direct_doh解析,直连阿里DNS拿到国内IP。 - 路由规则匹配
geosite-cn,流量走direct_outbound直连,完成访问。
第四阶段:用户访问my-nas.home(内网域名)
- 解析请求匹配
dns.rules,命中内网域名规则,用router_dns解析,拿到NAS的内网IP。 - 路由规则匹配内网IP段,流量直连,完成访问。
第五阶段:用户访问未知域名xxx.com
- 所有
dns.rules都未命中,走dns.final: "remote_doh",通过代理解析IP。 - 所有
route.rules都未命中,走route.final: "direct_outbound"直连访问。
这些配置项共同构成了 sing-box 从 “谁来解析” 到 “怎么连出去” 的完整控制链路。它们的核心逻辑可以总结为下图:
flowchart TD
subgraph L1 [第一层:基础组件]
A[DNS 服务器<br>dns.servers[]]
B[出站连接<br>outbounds[]]
end
subgraph L2 [第二层:DNS 解析的规则与兜底]
C[DNS 规则<br>dns.rules[]]
D[DNS 最终兜底<br>dns.final]
end
subgraph L3 [第三层:流量路由的规则与兜底]
E[路由规则<br>route.rules[]]
F[路由最终兜底<br>route.final]
end
A -->|决定域名解析结果| C
B -->|决定流量最终出口| E
C -->|未匹配| D
E -->|未匹配| F
🔍 典型案例:从 DNS 解析到流量出站
以 google.com 的访问为例,完整的解析与路由流程如下:
- DNS 规则匹配:
dns.rules根据域名google.com命中规则,选择remote_dns服务器。 - DNS 服务器自举:
remote_dns的服务器域名为cloudflare-dns.com,使用domain_resolver指向hosts_dns进行解析,获得其 IP 地址。 - DNS 查询流量路由:
- 若
remote_dns配置了detour: "proxy",DNS 查询流量直接通过proxy出站发送,完全绕过route.rules。 - 若未配置
detour,DNS 查询流量将作为普通 UDP 流量进入route.rules匹配,可能命中protocol: dns规则。
- 若
- 获得解析结果:DNS 查询返回
google.com的真实 IP。 - 网络流量路由:浏览器使用该 IP 发起访问,进入
route.rules匹配,根据规则走对应出站(如proxy或direct)。