sing-box DNS 设置方法:节点解析失败与 TUN DNS 排查
简答:节点连不上时,先让节点域名通过 dns-local 解析,默认 DNS 上游优先填可直接访问的 IP;FakeIP 只接管 A、AAAA 查询,TUN 还要配置 sniff 与 hijack-dns,strict_route 则按系统需要启用。
定义:sing-box DNS 配置由 DNS 服务器、匹配规则、默认服务器和解析策略组成,节点服务器域名还应通过独立的 domain_resolver 避免循环解析。
先看结论:节点解析失败时按这 5 项检查
如果 sing-box 配置后出现节点服务器无法解析、连接超时或 TUN 开启后断网,先不要同时修改多个字段。按下面顺序检查,通常能先区分是 DNS 标签、节点解析、FakeIP 还是 TUN 路由问题。
- 检查节点域名:代理 outbound 的
server如果填写域名,应明确设置domain_resolver,建议先指向dns-local。 - 检查默认 DNS:
dns.final填的是服务器tag,不是 IP、URL 或服务器名称。 - 检查 FakeIP 范围:FakeIP 规则只匹配
A、AAAA,并把.lan等内网后缀放在它之前交给dns-local。 - 检查 TUN 路由:启用
auto_route时,route 中应配置auto_detect_interface: true或default_interface,避免 direct 和 DNS 查询回到 TUN 形成回环。参考:Route - sing-box 官方文档。 - 检查 DNS 劫持:TUN 配置中加入
sniff和protocol: dns配合hijack-dns,让系统 DNS 请求进入 sing-box DNS 模块。参考:Rule Action - sing-box 官方文档。
| 问题现象 | 先看什么 | 正常判定 |
|---|---|---|
| 配置无法启动 | sing-box check、JSON 格式、标签拼写 | 检查命令不返回字段或格式错误 |
| 节点域名解析失败 | outbound 的 domain_resolver | 节点解析不再命中 FakeIP,日志不再出现 resolve 失败 |
| TUN 后全部断网 | auto_detect_interface、DNS 劫持规则、权限 | 普通域名能解析,direct 流量不会循环进入 TUN |
| Windows 仍有 DNS 外发 | strict_route、其他网卡和 DNS 软件 | 非 TUN 接口不持续出现未经配置的 53 端口请求 |
本文与 sing-box 项目及开发者无隶属关系。内容依据 sing-box 官方配置文档整理,截至 2026-10-24;不同图形客户端可能隐藏或改写字段,最终应以当前核心版本的官方 schema 和检查结果为准。
先理解 DNS 请求流向,再修改配置
在普通模式下,应用发起域名查询后,sing-box 根据 dns.rules 选择 DNS 服务器,未命中的请求使用 dns.final。在 TUN 模式下,系统 DNS 请求还需要先经过路由规则识别并执行 hijack-dns,否则请求可能绕过 sing-box DNS 模块。
| 阶段 | 字段或动作 | 作用 |
|---|---|---|
| 应用发起查询 | TUN inbound | 接收系统或应用流量 |
| 识别协议 | {"action":"sniff"} | 为后续路由识别 DNS 等协议 |
| 拦截 DNS | protocol: ["dns"]+hijack-dns | 把 DNS 请求交给 sing-box DNS 模块 |
| 选择上游 | dns.rules、dns.final | 按域名或查询类型选择 local、UDP、TLS、HTTPS 或 FakeIP |
| 建立连接 | detour、domain_resolver | 分别决定 DNS 请求走哪个出站,以及服务器域名先由哪个 DNS 解析 |
detour 和 domain_resolver 不负责同一件事:前者决定 DNS 上游连接通过哪个出站发送,后者决定某个服务器域名由哪个 DNS 解析。代理节点本身依赖 DNS 时,应先用 dns-local 解析节点域名,避免“代理 DNS 依赖代理节点、代理节点又依赖代理 DNS”的循环。参考:Dial Fields - sing-box 官方文档。
基础版:先让 DNS 和节点域名正常工作
下面是可作为起点的配置片段。代码使用普通空格,适合复制后再修改;node.example.com、端口和代理类型都是占位内容,请替换为你的真实节点参数。合并时保留原有的 inbounds、其他 outbounds 和客户端需要的字段,不要用这段内容直接覆盖完整配置。
{
"dns": {
"servers": [
{
"type": "local",
"tag": "dns-local"
},
{
"type": "udp",
"tag": "dns-udp",
"server": "1.1.1.1",
"server_port": 53
}
],
"final": "dns-udp",
"strategy": "prefer_ipv4"
},
"route": {
"final": "proxy",
"default_domain_resolver": "dns-local"
},
"outbounds": [
{
"type": "direct",
"tag": "direct"
},
{
"type": "socks",
"tag": "proxy",
"server": "node.example.com",
"server_port": 443,
"domain_resolver": "dns-local"
}
]
}- 把
node.example.com替换为节点服务器域名;如果节点直接填写 IP,可删除domain_resolver。 - 把
server_port和 outbound 类型改为现有节点实际使用的值。 - 检查
dns.final是否指向已存在的tag。 - 用与运行客户端相同或兼容的 sing-box 核心执行
sing-box check。 - 检查通过后启动,观察节点连接是否至少越过 DNS 解析阶段。
sing-box 官方 DNS 文档说明,final 是默认 DNS 服务器标签,未填写时使用服务器列表中的第一个;strategy 可使用 prefer_ipv4、prefer_ipv6、ipv4_only 或 ipv6_only。参考:DNS - sing-box 官方文档。
如果检查命令提示未知字段,不要直接从旧教程补字段。当前官方 DNS Server 结构使用 type、tag 和对应服务器字段;旧式图形界面或旧版本资料中的 address 写法不一定适用于当前 JSON 配置,应以当前官方页面和 schema 为准。参考:DNS Server - sing-box 官方文档。
DNS 上游怎么选:local、UDP、TLS 和 HTTPS
| 类型 | 适合先做什么 | 配置重点 |
|---|---|---|
local | 节点域名、局域网域名和基础排查 | 行为受操作系统和网络环境影响,适合先验证节点服务器是否能解析 |
udp | 验证最基础的 DNS 链路 | 优先填写可直接访问的 IP;如果服务器填写域名,要处理它自身的解析依赖 |
tls | 需要 DNS over TLS 的场景 | 核对服务器、端口和 TLS 参数,不把公共上游的可用性写成保证 |
https | 需要 DNS over HTTPS 的场景 | 核对服务器地址、路径、TLS 和 domain_resolver |
官方文档列出 local、UDP、TLS、HTTPS 和 FakeIP 等 DNS 服务器类型。服务器本身如果使用域名,应该检查其拨号字段中的解析依赖;排障时先使用 IP 形式的上游,可以减少第一层 DNS 依赖。参考:DNS Server - sing-box 官方文档、UDP DNS Server - sing-box 官方文档、HTTPS DNS Server - sing-box 官方文档。
一项实用判定是:先只保留 dns-local 和一个 IP 形式的 UDP 上游。如果基础版正常,再一次只加入 TLS、HTTPS、detour 或分流规则。这样可以判断故障来自 DNS 上游本身,还是来自路由和代理依赖。
分流版:用 dns.rules 按域名选择 DNS
DNS 分流的核心不是反复修改 final,而是让规则先匹配域名,再通过规则动作中的 server 指向具体 DNS 标签。下面示例只演示后缀匹配;.lan 和 .example 是占位后缀,请替换为你确实需要处理的域名。
{
"dns": {
"servers": [
{
"type": "local",
"tag": "dns-local"
},
{
"type": "udp",
"tag": "dns-udp",
"server": "1.1.1.1",
"server_port": 53
},
{
"type": "https",
"tag": "dns-https",
"server": "dns.example.com",
"path": "/dns-query",
"domain_resolver": "dns-local"
}
],
"rules": [
{
"domain_suffix": [
".lan"
],
"action": "route",
"server": "dns-local"
},
{
"domain_suffix": [
".example"
],
"action": "route",
"server": "dns-https"
}
],
"final": "dns-udp"
}
}- 替换
dns.example.com为你确认存在且支持 DoH 的服务器地址;无法核实地址时,先删除 HTTPS 服务器和对应规则。 - 确认每条规则中的
server都对应dns.servers里的标签。 - 把内网后缀规则放在 FakeIP 规则之前,避免局域网域名收到虚拟地址。
- 执行
sing-box check,再用一个明确属于该后缀的域名测试。 - 如果规则没有生效,检查请求是否真的进入 sing-box DNS 模块,而不是被系统或应用缓存直接返回。
DNS Rule 官方文档支持 domain、domain_suffix、domain_keyword 等匹配字段,并通过规则动作选择 DNS 服务器。参考:DNS Rule - sing-box 官方文档。
FakeIP 与 TUN:完整联动写法
FakeIP 会返回虚拟地址并维护地址与域名的映射,因此它不是普通的 DNS 上游。配置时应把内网域名和节点域名排除在 FakeIP 规则之外,再只让 A、AAAA 查询进入 FakeIP。下面是 DNS、路由规则和 TUN inbound 的关键片段;请合并到原有配置,并保留原有的其他入站、出站和平台权限字段。
{
"dns": {
"servers": [
{
"type": "local",
"tag": "dns-local"
},
{
"type": "udp",
"tag": "dns-udp",
"server": "1.1.1.1",
"server_port": 53
},
{
"type": "fakeip",
"tag": "dns-fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
}
],
"rules": [
{
"domain_suffix": [
".lan"
],
"action": "route",
"server": "dns-local"
},
{
"query_type": [
"A",
"AAAA"
],
"action": "route",
"server": "dns-fakeip"
}
],
"final": "dns-udp"
},
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": [
"dns"
],
"action": "hijack-dns"
}
],
"auto_detect_interface": true,
"default_domain_resolver": "dns-local",
"final": "proxy"
},
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"address": [
"172.19.0.1/30",
"fdfe:dcba:9876::1/126"
],
"auto_route": true,
"strict_route": true
}
]
}- 将
node.example.com的节点 outbound 设置为domain_resolver: dns-local;示例中没有列出完整 outbounds,请保留你的实际节点出站。 - 如果有更多内网后缀,把它们加入 FakeIP 规则之前的
dns-local排除规则。 - 保留
sniff规则,并让protocol: ["dns"]的规则执行hijack-dns。 auto_detect_interface: true用于让出站绑定默认网卡,减少 TUN 路由回环;如果明确知道接口名称,也可以改用default_interface,二者不要同时依赖。参考:Route - sing-box 官方文档。strict_route不应被理解为所有系统的必需项。Windows 上它会阻止经过非 TUN 接口的 53 端口流量,但可能影响部分虚拟化或特殊网络环境;出现兼容问题时,可先关闭它做对照测试。参考:Tun - sing-box 官方文档。
FakeIP 的意义在于让应用先获得虚拟地址,再由 sing-box 根据保存的域名映射继续进行路由。若所有流量最终都走 direct,FakeIP 不能自动产生代理分流效果;仍需结合 route 规则或代理出站决定后续连接去向。
防 DNS 泄漏与连接失败:按命令逐项验证
- 先校验配置:使用与客户端相同或兼容的核心执行
sing-box check。正常标准是没有未知字段、JSON 错误、标签不存在或类型不匹配提示。 - 验证节点解析:检查节点 outbound 的
server、domain_resolver和route.default_domain_resolver。如果日志显示节点服务器被解析成198.18.x.x,先检查它是否错误命中了 FakeIP,再确认dns-local是否被明确指定。 - 验证 TUN 劫持:临时打开
"log": {"level": "debug"},复现一次后恢复为info。搜索dns、resolve、hijack、timeout和domain_resolver。出现 DNS 请求进入模块的记录,且没有持续超时,才说明链路基本正常。 - Linux 抓包:先执行
sudo tcpdump -ni any 'udp port 53 or tcp port 53'。如果使用 DoH 或 DoT,还要观察对应的 HTTPS 或 TLS 连接,不能只用 53 端口判断。正常标准是,启用 TUN 后不应持续看到未经配置的物理网卡外发 53 请求。 - Windows 对照:按需启用
strict_route,关闭其他 VPN、虚拟网卡和系统级 DNS 工具后再复测。官方文档明确说明,Windows 开启strict_route时,经过 TUN 以外接口的 53 端口流量会被阻止。参考:Tun - sing-box 官方文档。
| 观察到的结果 | 更可能的原因 | 下一步 |
|---|---|---|
sing-box check 报未知字段 | 核心版本与示例字段不一致 | 删除最近新增字段,依据当前 schema 逐项加回 |
| 节点域名变成 198.18.x.x | 节点解析命中 FakeIP | 给节点 outbound 和 route 默认解析器指定 dns-local |
| TUN 后全部断网 | 路由回环、DNS 未劫持或权限不足 | 先关闭 FakeIP,只保留 local+UDP+sniff+hijack-dns |
| 仍有非 TUN 的 53 请求 | 系统或其他网卡绕过 TUN | 检查 strict_route、其他 VPN、虚拟网卡和系统 DNS 工具 |
版本字段与缓存选项:不要把旧教程直接照抄
基础排障不需要先启用所有缓存和高级字段。cache_capacity、reverse_mapping、client_subnet 等选项应在明确知道用途后再调整;排查节点解析失败时,保持默认通常更容易定位问题。
官方 DNS 文档直接标注:optimistic 和 DNS 全局 timeout 自 sing-box 1.14.0 起提供;independent_cache 已在 sing-box 1.14.0 废弃,并计划在 sing-box 1.16.0 移除。由于这些字段存在版本差异,不建议把它们放进跨版本基础配置;请以你正在运行的核心 schema 和 sing-box check 结果为准。参考:DNS - sing-box 官方文档。
IPv4 或 IPv6 连接异常时,只改一个变量:依次对比 prefer_ipv4、prefer_ipv6、ipv4_only 或 ipv6_only。每次记录“是否能解析、返回 A 还是 AAAA、节点是否能握手”三项结果,避免把 DNS 策略、TUN 路由和节点线路问题混在一起。
如果基础版仍无法解析,先撤回 FakeIP、HTTPS、DNS detour 和复杂分流,只保留 dns-local、一个 IP 形式的基础上游、节点 domain_resolver 和必要的 TUN 劫持规则。确认基础链路正常后,再按单变量顺序恢复功能。
下一步:从 DNS 配置继续排查连接问题
完成基础 DNS 配置后,建议继续检查路由错误、节点延迟和连接超时。排查时保留一次只改一个字段的记录,能够更快判断问题属于 DNS、TUN、节点出站还是网络线路。
常见问题
sing-box 的 dns.final 应该填服务器地址还是 tag?
应填写 DNS 服务器的 tag,例如 dns-udp 或 dns-https,而不是 IP、URL 或服务器名称。未填写时,官方文档说明会使用 servers 中的第一个服务器。
sing-box 节点域名为什么要单独设置 domain_resolver?
节点 outbound 需要先把 server 中的域名解析成 IP。如果解析又依赖正在建立的代理出站,可能形成循环;为节点指定 dns-local,可以把节点解析与 FakeIP、代理 DNS 分开。
FakeIP 规则为什么要限制 query_type?
FakeIP 适合接管 A 和 AAAA 查询。若不限制查询类型,节点解析、内网域名或其他 DNS 查询可能得到不适合连接的虚拟结果,因此应把内网排除规则放在前面,再用 query_type 限定 FakeIP。
TUN 模式下 sniff 和 hijack-dns 都要配置吗?
对于需要把系统 DNS 请求交给 sing-box DNS 模块的 TUN 配置,建议保留 sniff 规则,并用 protocol: dns 匹配后执行 hijack-dns。只配置 FakeIP 服务器而没有 DNS 劫持规则时,系统请求可能不会进入 sing-box DNS 模块。
auto_detect_interface 和 strict_route 是否都必须开启?
不是同一类开关。auto_detect_interface 用于让出站绑定默认网卡、减少 TUN 路由回环;strict_route 用于执行更严格的路由规则,Windows 上还可阻止非 TUN 接口的 53 端口流量。strict_route 应结合系统、权限和虚拟网卡做对照测试。
sing-box DNS 设置后仍然无法解析,先看什么?
先执行 sing-box check,再检查 dns.final 是否指向存在的 tag、节点 outbound 是否设置 domain_resolver,以及日志中的 timeout、resolve 和 hijack。TUN 场景先关闭 FakeIP,只保留 local、一个基础上游和 DNS 劫持规则做单变量验证。