sing-box DNS 配置怎么写?从基础配置到分流排错
简答:sing-box 的 DNS 配置写在顶层的 <code>dns</code> 对象中:先用带 <code>type</code> 和 <code>tag</code> 的 <code>servers</code> 配置一个 <code>local</code> DNS,再设置 <code>final</code>;需要分流时使用 <code>rules</code> 和 <code>action: route</code>。如果是 TUN 模式,还要让路由规则使用 <code>action: hijack-dns</code>,否则只修改 <code>dns</code> 不一定能接管系统 DNS 请求。
定义:sing-box DNS 配置是由 <code>servers</code> 定义 DNS 上游、<code>rules</code> 决定匹配后的处理方式、<code>final</code> 指定默认服务器,并由 TUN 与路由规则决定请求是否进入 DNS 模块的一组 JSON 设置。
先判断场景:只解析、TUN 接管,还是 FakeIP
本文按 sing-box 当前官方配置文档整理,核验日期为 2026-10-31。本文是第三方使用指南,不代表 sing-box 或任何客户端的官方页面。配置字段仍应以你实际使用的 sing-box 版本和客户端包装器为准。
| 你的目标 | 先使用什么 | 不要先做什么 |
|---|---|---|
| 只想确认 DNS 配置能启动 | type: local、唯一 tag、final | 不要一开始加入 FakeIP、复杂规则和 TUN |
| 让 TUN 接管系统 DNS | route.rules 中加入 action: hijack-dns | 不要把“配置检查通过”当成系统 DNS 已被接管 |
| 按域名或上游分流 | 多个 DNS server 加 action: route 规则 | 不要把 DNS 服务器地址直接写成规则中的 server |
| 需要 FakeIP | 单独的 type: fakeip 服务器和明确排除规则 | 不要把所有请求无条件指向 FakeIP |
最短排查顺序是:备份配置 → 保留一个 local DNS → 运行 check → 启动并看日志 → 再逐项加入分流、TUN 或 FakeIP。官方配置结构说明 sing-box 使用 JSON,并将 dns、inbounds、outbounds 与 route 作为顶层对象。查看 sing-box 配置结构与检查命令
最小完整示例:先让 sing-box 读取 local DNS
下面不是可以连接任意代理节点的完整上网配置,而是一份包含入站、出站和 DNS 的最小结构示例,适合先验证 JSON 结构和本机 DNS 查询。它只使用 direct 出站,不包含代理节点。
{"log":{"level":"info"},"dns":{"servers":[{"type":"local","tag":"local"}],"final":"local","strategy":"prefer_ipv4"},"inbounds":[{"type":"mixed","tag":"mixed-in","listen":"127.0.0.1","listen_port":2080}],"outbounds":[{"type":"direct","tag":"direct"}]}
- 将示例保存为配置文件,或只把其中的
dns对象合并进已有配置。 - 确认没有覆盖原配置中的
inbounds、outbounds和route。 - 运行
sing-box check -c config.json,其中config.json替换为实际文件名。 - 检查通过后再启动 sing-box,并观察日志中是否出现 DNS 初始化错误。
停止条件:如果配置检查通过、进程能够启动,并且没有持续出现 DNS 初始化或解析超时,就先不要加入第二个 DNS 上游。final 是默认 DNS server tag;官方文档说明它为空时会使用第一个服务器,因此本文仍显式填写 final,减少配置歧义。查看 DNS 顶层字段 查看 DNS server 类型与 tag
servers、rules、final、strategy 分别做什么
| 字段 | 作用 | 排错时看什么 |
|---|---|---|
servers | 声明可用的 DNS 服务器,每个服务器可用 tag 标识 | 规则引用的 tag 是否真实存在且拼写一致 |
rules | 根据域名、查询类型或其他条件选择处理动作 | 是否使用了合法的 action |
final | 没有规则命中时使用的默认 DNS server tag | 是否引用了 servers 中已有的 tag |
strategy | 控制默认解析策略,如优先 IPv4 或优先 IPv6 | 它只影响解析策略,不等于切换出站线路 |
timeout | 当前版本 DNS 查询的默认超时 | 只在确认版本支持时调整,默认值通常可先不写 |
当前官方文档将 DNS 规则的目标服务器写在动作中,例如 {"action":"route","server":"local"}。DNS 规则中的 server 必须引用 servers 中的 tag,而不是直接填写 IP 地址或 DoH URL。查看 DNS Rule Action 官方字段
需要注意版本迁移:官方迁移文档显示,旧版 DNS server 可能使用 address,新版服务器对象应明确写出 type;DNS 规则中的旧顶层 server 等字段也已经迁移到规则动作。不要只把旧配置中的字段名称机械替换,最好根据服务器类型重新核对整个对象。查看 DNS 配置迁移说明
DNS 分流怎么写:local 与 DoH 的角色要分开
DNS 分流至少需要两个部分:一是 servers 中定义不同上游,二是 rules 中通过 action: route 将匹配请求交给对应 tag。下面的 DoH 地址、域名和出站标签都是示例占位符,不能直接复制后期待可用。
{"dns":{"servers":[{"type":"local","tag":"local"},{"type":"https","tag":"remote-doh","server":"dns.example.com","server_port":443,"path":"/dns-query","domain_resolver":"local","detour":"proxy"}],"rules":[{"domain_suffix":[".lan"],"action":"route","server":"local"},{"domain_suffix":["example.net"],"action":"route","server":"remote-doh"}],"final":"local"}}
local:调用本机或平台提供的本地解析能力,适合先验证基础配置。https:使用 DoH,上游的server使用域名时,需要配置domain_resolver。detour:决定 DNS 请求通过哪个出站连接。domain_resolver:负责先解析 DoH 服务器自身的域名。
detour 和 domain_resolver 不是同一个字段:前者解决“DNS 请求走哪条出站”,后者解决“DoH 上游域名如何获得 IP”。当前 DoH 官方文档还特别区分了新旧服务器格式:新版使用 Dial Fields 中的 domain_resolver,旧版教程中的 address_resolver 不能直接照搬。查看 DoH 官方字段与新旧格式说明
停止条件:如果加入 DoH 后出现所有域名都解析失败,先删除分流规则,恢复到单个 local server;确认基础解析正常后,再检查 DoH 上游域名、domain_resolver、detour 和实际存在的出站 tag。
TUN 模式为什么还要配置 hijack-dns
DNS 模块和系统 DNS 接管是两个层面。dns.servers 定义“sing-box 收到请求后怎么解析”,而路由动作 hijack-dns 才表示“把匹配到的 DNS 请求交给 sing-box DNS 模块”。官方文档对该动作的定义就是将 DNS 请求劫持到 sing-box DNS 模块。查看 hijack-dns 官方说明
将下面片段合并进已有的 route.rules,不要直接覆盖原路由:
{"route":{"rules":[{"protocol":"dns","action":"hijack-dns"}],"auto_detect_interface":true}}
- 备份原配置,记录修改前的 TUN 和 route 内容。
- 确认
dns.servers至少有一个带 tag 的服务器,并且final指向该 tag。 - 在已有路由规则中加入 DNS 匹配和
hijack-dns动作。 - 运行配置检查并启动,查看日志是否持续出现 DNS timeout、循环或 server tag 不存在。
- 分别验证“域名能否解析”和“解析成功后连接是否成功”。后者失败时,问题可能在出站、路由、MTU 或节点,而不是 DNS。
平台差异不能用一个菜单路径概括:Windows、Linux 和 macOS 的 TUN 权限、系统 DNS 接管方式及客户端界面可能不同;Android 图形客户端的 local DNS 还会使用平台接口获取上游。若是图形客户端,请优先使用其导出的配置和日志,不要假设命令行配置文件路径一定相同。查看 local DNS 的平台说明 查看 TUN 官方说明
FakeIP 怎么写:先限定范围,再考虑兼容性
FakeIP 是一种 DNS server 类型,会为域名返回配置范围内的虚拟地址,并依靠内部映射继续识别原域名。它不是所有 sing-box 场景的必选项。基础 DNS、TUN 路由和应用兼容性未确认前,建议不要启用。
FakeIP 服务器的基本结构如下:
{"type":"fakeip","tag":"fakeip","inet4_range":"198.18.0.0/15","inet6_range":"2001:2::/48"}
如果要使用 FakeIP,至少要把它作为单独 server,并通过规则明确限定查询类型或域名范围。例如:
{"dns":{"servers":[{"type":"fakeip","tag":"fakeip","inet4_range":"198.18.0.0/15","inet6_range":"2001:2::/48"},{"type":"local","tag":"local"}],"rules":[{"domain_suffix":[".lan",".local"],"action":"route","server":"local"},{"query_type":["A","AAAA"],"action":"route","server":"fakeip"}],"final":"local"}}
这仍然只是配置片段,不能替代针对你设备和应用的完整兼容性验证。局域网域名、单标签主机名、系统服务和不兼容 FakeIP 的应用,可能需要继续增加排除规则;官方字段文档只定义 FakeIP 地址范围,并不替你判断每个应用是否兼容。查看 FakeIP 官方字段
回滚方法:删除或停用 FakeIP 规则,保留 local 作为 final,重新运行 sing-box check 并启动。若回滚后解析恢复,说明故障范围集中在 FakeIP 规则、TUN 回程映射或应用兼容性,不要继续修改 DoH 和出站配置。
版本迁移:1.14.0 相关字段怎么核对
官方更新日志显示,sing-box 1.14.0 增加了 DNS 乐观缓存、DNS 查询超时、evaluate DNS 规则动作和响应匹配等能力;同时,independent_cache 等字段进入弃用阶段。DNS 规则文档还标明,旧的地址过滤字段和规则动作中的旧 strategy 已在 1.14.0 弃用,计划在 1.16.0 移除。查看 sing-box 更新日志 查看 DNS 规则版本标记
| 旧配置现象 | 优先检查 | 处理方式 |
|---|---|---|
服务器对象只写 address | 是否仍在使用旧 DNS server 格式 | 按类型改为 type、server 等新版字段 |
规则把 server 直接写在规则顶层 | 是否缺少 action | 改为 action: route,并在动作中引用 server tag |
使用规则级旧 strategy | 版本是否已进入 1.14.0 及以后 | 优先使用顶层 dns.strategy 或当前规则动作支持的字段 |
| 启动时提示地址过滤字段冲突 | 是否同时使用新 query_type 或 ip_version | 按官方 migration 文档迁移到响应匹配,避免混用旧字段 |
| 配置检查通过但实际无网 | 上游可达性、TUN 权限、出站与系统 DNS | 把配置语法问题和运行时连通问题分开排查 |
不要把“官方文档存在字段”理解为“你的客户端一定支持该字段”。客户端可能固定版本、裁剪功能或使用自己的配置转换器;若版本号未核实,应以实际运行的 sing-box 核心版本和启动日志为准。
DNS 连接问题速查:现象、字段和下一步
| 现象 | 优先检查 | 下一步动作 |
|---|---|---|
| 启动直接失败 | JSON 格式、未知字段、重复 tag | 恢复备份后运行 sing-box check -c config.json |
| 所有域名都超时 | final、上游 server、domain_resolver | 暂时只保留一个 local server |
| 规则命中但没有解析结果 | action 是否为 route,server tag 是否存在 | 把规则改成一个明确的 route 动作再测试 |
| TUN 开启但系统 DNS 未改变 | 是否有 protocol: dns 与 hijack-dns | 检查 TUN 权限、系统 DNS 和启动日志 |
| 网页能开但部分应用失败 | FakeIP、应用兼容性、IPv6 策略 | 回滚 FakeIP,测试 prefer_ipv4 或基础 local 配置 |
| 解析成功但连接失败 | 出站、路由、MTU、丢包和节点连接 | 不要继续改 DNS,转到连接层排查 |
检查命令只说明配置能否被解析和接受,不能证明 DNS 上游可达、TUN 已接管、代理出站可用或不存在系统旁路请求。每次只增加一个变量,并保留回滚点。
如果你需要继续排查配置导入和连接范围,可先看sing-box 导入订阅教程,再根据“解析失败”或“连接失败”选择下一步,不要把两类故障混在一起。
回滚清单与使用边界
- 复制原配置,保留可以启动的备份。
- 恢复到单个
localserver 加final。 - 运行
sing-box check -c config.json。 - 启动后确认日志没有持续 DNS 错误。
- 一次只加入一个 DoH、分流规则、TUN 劫持或 FakeIP 功能。
- 出现异常时,删除最后一次改动,而不是同时修改多个模块。
本文示例中的 dns.example.com、proxy、example.net 都是占位符;它们不是可直接使用的真实服务地址。本文不提供未经核实的节点、线路、测速或可用性结论。配置字段、版本行为和平台支持以官方文档及你实际安装的核心版本为准。
如果你还要继续排查跨境办公中的 DNS、延迟或丢包问题,可了解边界云加速的线路与连接诊断服务。
常见问题
sing-box DNS 配置应该写在哪里?
写在完整 JSON 配置顶层的 <code>dns</code> 对象中,与 <code>inbounds</code>、<code>outbounds</code>、<code>route</code> 等顶层字段并列。合并片段时不要覆盖原有入站、出站和路由。
最简单的 sing-box DNS 配置怎么写?
先在 <code>dns.servers</code> 中添加 <code>{"type":"local","tag":"local"}</code>,再设置 <code>"final":"local"</code>。确认能检查和启动后,再增加其他上游或规则。
为什么配置了 DNS,TUN 模式仍然没有效果?
因为 DNS server 定义和系统 DNS 接管是两个层面。TUN 场景通常还需要在 <code>route.rules</code> 中加入匹配 DNS 请求的 <code>action: hijack-dns</code>,同时检查 TUN 权限和启动日志。
DoH 配置中的 detour 和 domain_resolver 有什么区别?
<code>detour</code> 决定 DoH 请求通过哪个出站连接;<code>domain_resolver</code> 用于先解析 DoH 服务器自身的域名。上游 <code>server</code> 使用域名时,当前官方 DoH 文档要求配置 <code>domain_resolver</code>。
sing-box 旧版 DNS 配置还能直接使用吗?
不能默认认为可以。旧版可能使用 <code>address</code> 等 legacy server 格式,较新的配置应明确写出 <code>type</code>;DNS 规则的旧顶层字段也可能已经迁移或弃用。应按实际版本查看官方 migration 文档。
FakeIP 是不是所有 sing-box 配置都需要?
不是。FakeIP 只适合经过 TUN、路由和应用兼容性验证的场景。基础排错建议先使用 <code>local</code> 或明确的 UDP、DoT、DoH 上游,出现局域网或应用异常时先回滚 FakeIP。
sing-box check 通过就代表 DNS 一定可用吗?
不代表。check 主要用于检查配置是否能被解析和接受;上游 DNS 是否可达、系统请求是否进入 sing-box、TUN 是否获得权限,以及出站是否连接成功,都需要启动后结合日志和实际现象继续验证。