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

2026-04-03-sing-box的dns与route-deepseek_mermaid_20260403_2cae5a-2026-04-04-04-51-00 2026-04-03-sing-box的dns与route-deepseek_mermaid_20260403_1331c8-2026-04-04-04-51-23

一、全局执行总框架

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服务器的其他所有拨号字段(bind_interfacerouting_mark等)都会被完全忽略。
  • 关键误区:该配置只影响「DNS查询的流量路径」,不影响「解析后业务流量的路径」——业务流量走哪个出站,由route.rules决定。
  • 👉 DNS 查询本质也是“流量” 所以:
    • 要么你: 用 detour 控死它
    • 要么: 让 route 管它(但你要完全理解后果)

2. outbounds[].detour

官方定义:属于出站的核心字段,指定当前出站的上游出站,实现链式代理(也叫嵌套代理、跳板代理)。

  • 生效对象:当前出站的所有流量,包括连接节点的握手流量、转发的业务流量。
  • 核心作用:实现多级代理,比如节点Adetour设为节点B,则所有流量会先发到节点B,再从节点B转发到节点A,最终访问目标服务。
  • 优先级与坑点只要配置了该字段,当前出站的所有其他拨号字段(domain_resolverbind_interfaceserver/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查询和实际访问两种。 未设置detourDNS查询就是普通的流量。


一、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 匹配时,它的匹配维度和普通业务流量略有不同:

  1. 域名维度:匹配的是「DNS 服务器的地址」,而不是「用户访问的目标域名」。
    • 例:你用 dns.alidns.com 解析 baidu.com,此时 route.rules 匹配的是 dns.alidns.com,而不是 baidu.com
  2. IP 维度:匹配的是「DNS 服务器解析后的 IP」。
  3. 端口维度:匹配的是 DNS 服务器的端口(通常是 53/UDP、443/TCP)。

四、最佳实践建议

为了避免玄学问题,强烈建议遵循以下配置原则:

  1. 境外 DNS 必须配置 detour:给所有境外 DoH/DoT 配置 detour: "proxy_outbound",强制 DNS 查询走代理,彻底防污染,完全不依赖 route.rules
  2. 国内 DNS 推荐配置 detour:给国内 DoH/DoT 配置 detour: "direct_outbound",强制 DNS 查询直连,保证 CDN 调度,避免被 route.rules 误判。
  3. 内网 DNS 必须配置 detour:给路由器 DNS 配置 detour: "direct_outbound",强制 DNS 查询走内网直连。

五、最终总结
  1. 有 detour 优先用 detour:DNS 服务器配置了 detour,流量强制走该出站,完全绕过 route.rules
  2. 没 detour 就走 route.rules:DNS 服务器没配置 detour,流量进入路由模块,匹配 route.rules,根据规则决定走哪个出站。
  3. 最佳实践:给所有 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代理,根据你的分流策略决定。
  • 坑点:如果不配置该字段,未匹配规则的流量会默认走tagdirect的出站,如果没有这个出站,会直接连接失败。

三、所有配置项的优先级与相互影响关系总表

配置项优先级核心互斥/依赖关系
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,再到日本节点。
  • 国内域名:用阿里DoHdns.alidns.com直连解析。
  • 境外域名:用Cloudflare DoHcloudflare-dns.com走代理解析。
  • 内网域名:用路由器DNS192.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 启动初始化

  1. 读取hk_proxy出站,发现是域名形式,且没配自己的domain_resolver,自动用route.default_domain_resolver: "local_udp"解析hk-node.example.com,拿到香港节点IP。
  2. 读取jp_proxy出站,发现配置了detour: "hk_proxy",所以自己的节点地址、domain_resolver全部失效,直接把hk_proxy作为上游。
  3. 先连接香港节点,再通过香港节点连接日本节点,链式代理隧道建立完成。
  4. 初始化DNS模块,加载所有DNS服务器、规则、兜底配置。

第二阶段:用户访问google.com(境外域名)

  1. 用户发起google.com的解析请求,进入DNS模块。
  2. 匹配dns.rules,命中geosite-!cn规则,决定用remote_doh解析。
  3. remote_doh是域名形式,先用自己的domain_resolver: "local_udp"解析cloudflare-dns.com,拿到IP。
  4. remote_doh.detour: "jp_proxy",把DoH查询通过日本代理隧道发出去,拿到google.com的境外IP。
  5. 拿到IP后,进入路由模块,匹配route.rules,命中geosite-!cn规则,决定流量走jp_proxy出站。
  6. jp_proxy.detour: "hk_proxy",业务流量先到香港节点,再转发到日本节点,最终访问google.com,流程完成。

第三阶段:用户访问baidu.com(国内域名)

  1. 解析请求匹配dns.rules,命中geosite-cn,用direct_doh解析,直连阿里DNS拿到国内IP。
  2. 路由规则匹配geosite-cn,流量走direct_outbound直连,完成访问。

第四阶段:用户访问my-nas.home(内网域名)

  1. 解析请求匹配dns.rules,命中内网域名规则,用router_dns解析,拿到NAS的内网IP。
  2. 路由规则匹配内网IP段,流量直连,完成访问。

第五阶段:用户访问未知域名xxx.com

  1. 所有dns.rules都未命中,走dns.final: "remote_doh",通过代理解析IP。
  2. 所有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 的访问为例,完整的解析与路由流程如下:

  1. DNS 规则匹配dns.rules 根据域名 google.com 命中规则,选择 remote_dns 服务器。
  2. DNS 服务器自举remote_dns 的服务器域名为 cloudflare-dns.com,使用 domain_resolver 指向 hosts_dns 进行解析,获得其 IP 地址。
  3. DNS 查询流量路由
    • remote_dns 配置了 detour: "proxy",DNS 查询流量直接通过 proxy 出站发送,完全绕过 route.rules
    • 若未配置 detour,DNS 查询流量将作为普通 UDP 流量进入 route.rules 匹配,可能命中 protocol: dns 规则。
  4. 获得解析结果:DNS 查询返回 google.com 的真实 IP。
  5. 网络流量路由:浏览器使用该 IP 发起访问,进入 route.rules 匹配,根据规则走对应出站(如 proxydirect)。