sing-box DNS 设置:从最小配置到分流、TUN 与 FakeIP
简答:如果 sing-box DNS 不生效,先确认配置顶层有 dns 对象,再用 servers 定义上游、rules 选择 server tag、final 指定默认服务器;启用 TUN 时,route.rules 里的 action: hijack-dns 才负责把经过路由的 DNS 请求交给 sing-box DNS 模块。最稳妥的路径是先用 local 配置通过 sing-box check,再逐步加入 DoH、分流和 FakeIP,最后用日志与抓包验证,而不是只看 nslookup 结果。
定义:sing-box DNS 设置是对 dns.servers、dns.rules、final、strategy 以及 TUN 场景下 route.rules 的组合配置,用来决定 DNS 请求由谁解析、通过哪条路径发送,以及是否返回 FakeIP。
先试这一步:最小 local DNS 配置与成功判据
如果你只是想先让 sing-box 能解析域名,不要一开始就加入 FakeIP、TUN 和多组分流规则。sing-box 配置文件使用 JSON,顶层可以包含 dns、inbounds、outbounds 和 route 等对象;官方文档也提供了 sing-box check 用于配置检查。参考 sing-box 配置结构与检查命令。
{
"$schema": "https://sing-box.sagernet.org/schema.json",
"log": {
"level": "info",
"timestamp": true
},
"dns": {
"servers": [
{
"type": "local",
"tag": "local"
}
],
"final": "local",
"strategy": "prefer_ipv4"
},
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"final": "direct"
}
}- 将示例保存为配置文件,并确认 JSON 的逗号、引号和括号完整。
- 在该文件所在目录执行
sing-box check -c config.json;不同客户端的检查按钮或命令入口可能不同,应以当前客户端说明为准。 - 启动后查看日志,确认没有 DNS server、JSON 字段或出站连接错误。
- 成功判据不是“网页暂时能打开”,而是配置检查通过、进程正常启动,并且 DNS 查询没有持续报错。
回滚:保留原配置副本,只替换当前测试文件;如果检查失败,先删除最近加入的字段,再重新检查。
四个字段先分清:servers、rules、final、strategy
dns.servers 是 DNS server 定义列表,每个 server 通常用 type 和 tag 描述;dns.rules 根据域名、查询类型或其他条件选择某个 server;final 是没有规则命中时使用的默认 server;strategy 控制默认域名解析策略,例如优先 IPv4 或优先 IPv6。字段定义可对照 DNS 官方文档、DNS Server 官方文档 和 DNS Rule 官方文档。
| 层次 | 主要字段 | 解决的问题 | 常见误解 |
|---|---|---|---|
| 定义 | dns.servers | 有哪些 DNS 上游,以及每个上游的类型和 tag | 定义 server 不等于所有查询都会使用它 |
| 选择 | dns.rules | 哪些域名或查询交给哪个 tag | 规则顺序和匹配条件会影响最终选择 |
| 默认 | dns.final | 没有规则命中时使用哪个 server | 留空时通常使用列表中的第一个 server |
| 策略 | dns.strategy | 优先 IPv4、优先 IPv6 或限制地址族 | 它不是 DNS 上游地址,也不是 TUN 接管开关 |
| 接管 | route.rules 的 hijack-dns | 把经过路由的 DNS 请求交给 sing-box DNS 模块 | 它不负责定义 DoH 或 FakeIP server |
从 local 扩展到 UDP、TLS、DoH:先选传输方式再排查路径
新格式的 DNS server 使用不同的 type 表示传输方式。官方迁移文档显示,旧版把地址写进 address 的写法已经迁移到以 type、server 等字段描述的新格式;旧 DNS server 格式在 sing-box 1.14.0 已移除。参考 sing-box Migration 和 Deprecated 功能列表。
| 类型 | 适合先解决什么问题 | 配置核对点 |
|---|---|---|
local | 先验证本机或系统已有 DNS 是否可用 | 平台客户端可能通过系统接口获取解析能力,行为以当前平台和客户端为准 |
udp | 测试基础 DNS 连通性 | 核对 server 地址及路由路径 |
tcp | UDP 查询异常时测试 TCP DNS | 确认网络允许到达目标 TCP 端口 |
tls | 需要加密 DNS 传输时使用 | 核对服务器地址和 TLS 相关字段 |
https / http3 | 使用 DoH 或 HTTP/3 DNS | 如果上游使用域名,必须为其设置可用的 domain_resolver |
quic | 需要 QUIC DNS 传输时测试 | 确认当前核心和客户端支持该类型 |
当 DNS server 或其他出站的服务器地址写成域名时,domain_resolver 用来解析这个服务器地址;官方 Dial Fields 文档说明,也可以通过 route.default_domain_resolver 提供默认解析器。它解决的是“先解析上游服务器域名”,不是普通网页域名的分流规则。DoH 的具体字段可参考 HTTPS DNS Server。
DNS 分流:用 server tag 指向不同上游
DNS 分流的核心是:先在 dns.servers 中定义多个带 tag 的 server,再在 dns.rules 中把匹配条件指向对应 tag。下面是结构示例,地址和域名仅作占位,必须替换为你实际可访问且符合当前核心 schema 的配置。
{
"dns": {
"servers": [
{
"type": "local",
"tag": "local"
},
{
"type": "https",
"tag": "remote",
"server": "example-dns.invalid",
"path": "/dns-query",
"domain_resolver": "local"
}
],
"rules": [
{
"domain_suffix": [".lan", ".local"],
"server": "local"
},
{
"query_type": ["A", "AAAA"],
"server": "remote"
}
],
"final": "local",
"strategy": "prefer_ipv4"
}
}这个片段不是可直接启动的完整配置,因为 example-dns.invalid 是占位地址。它只展示字段关系:局域网后缀优先交给 local,其他 A/AAAA 查询交给 remote,未命中时回到 final。实际使用前必须替换上游、确认当前版本支持字段,并用 check 检查。
TUN 模式:DNS 解析选择与 DNS 请求接管是两件事
启用 TUN 后,仍要分别检查两层:第一层是 dns.servers 和 dns.rules 决定如何解析;第二层是 TUN 与 route 规则决定系统 DNS 请求是否进入 sing-box。官方 Route Action 文档将 action: hijack-dns 定义为把 DNS 请求交给 sing-box DNS 模块,官方 TUN 文档则说明 auto_route、strict_route 和平台差异会影响接管范围。参考 Route Rule Action 与 TUN。
{
"$schema": "https://sing-box.sagernet.org/schema.json",
"log": {
"level": "info",
"timestamp": true
},
"dns": {
"servers": [
{
"type": "local",
"tag": "local"
}
],
"final": "local",
"strategy": "prefer_ipv4"
},
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"address": ["172.19.0.1/30"],
"auto_route": true,
"strict_route": true
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
}
],
"final": "direct",
"auto_detect_interface": true
}
}适用范围:这是用于说明字段关系的最小 TUN 结构,不保证适用于每个系统、权限模型或图形客户端。address、strict_route、auto_route、dns_mode 和 dns_address 等字段应以当前核心的 schema、TUN 文档和客户端实际版本为准;本文不把未在当前配置中使用的字段写成通用必填项。
排查顺序:先确认 TUN 已获得系统权限,再确认日志出现入站流量;之后检查 DNS 请求是否匹配 protocol: dns 规则;最后检查 DNS server 是否能完成查询。Linux 上本机接口地址的 DNS 请求存在官方文档描述的未被 hijack 情况,不能仅凭“启用了 TUN”断言不存在 DNS 泄漏。
FakeIP 怎么用:适用场景、局域网排除与回滚
FakeIP 是 DNS 模块返回一段映射地址:客户端查询域名时得到 FakeIP,sing-box 保存域名与该地址的对应关系,后续连接再依据映射识别原域名。它适合需要通过 IP 连接仍保留域名识别能力的场景,但会增加排查复杂度;局域网设备、路由器管理地址和依赖真实内网解析的域名通常应优先排除。官方 FakeIP 文档显示,FakeIP server 使用 type: "fakeip",并配置 inet4_range、inet6_range。参考 FakeIP 官方文档。
{
"dns": {
"servers": [
{
"type": "local",
"tag": "local"
},
{
"type": "fakeip",
"tag": "fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "2001:2::/48"
}
],
"rules": [
{
"domain_suffix": [".lan", ".local"],
"server": "local"
},
{
"query_type": ["A", "AAAA"],
"server": "fakeip"
}
],
"final": "local"
}
}这段 FakeIP 片段仍需合并到完整配置,并根据实际局域网域名补充规则。重点是:FakeIP server 负责“返回映射地址”,TUN 的 hijack-dns 负责“把 DNS 请求交给 DNS 模块”,两者不是同一个开关,也不能互相替代。
- 先用 local 配置启动并验证真实解析。
- 再加入 fakeip server 和只匹配目标查询类型的规则。
- 把
.lan、.local或你实际使用的内网后缀放在 FakeIP 规则之前,交给 local。 - 检查局域网设备、打印机、NAS 和路由器地址是否仍能访问。
- 若出现内网打不开、应用识别异常或映射残留,删除 FakeIP server 和对应规则,恢复到 local 配置,再清理客户端 DNS 缓存或重启 sing-box。
版本迁移:1.12、1.14、1.15 与 1.17 要怎么判断
版本迁移不能只看教程发布日期。根据当前检索到的 sing-box 官方 Migration 和 Deprecated 页面:1.12.0 引入了新的 DNS server 格式;官方 Deprecated 页面写明旧 DNS server 格式在 1.14.0 已移除。1.14.0 页面还列出 independent_cache、旧 DNS rule action strategy 等废弃项,并写明旧字段计划在 1.16.0 移除。1.15.0 起 TUN 使用新的 sing-tun 栈,stack 被标记为废弃,官方页面写明计划在 1.17.0 移除。由于本文检索到的是迁移和废弃说明,不是你本机核心的实际版本输出,所以 1.16.0、1.17.0 的当前执行状态仍需用实际核心版本和 check 结果核实。
| 版本线索 | 官方资料能确认的内容 | 写配置时的处理 |
|---|---|---|
| 1.12.0 | DNS server 格式开始迁移到 type、tag、server 等结构 | 新配置优先使用新格式,不继续复制旧 address 写法 |
| 1.14.0 | 旧 DNS server 格式已移除;多个 DNS 字段进入废弃或迁移状态 | 检查 independent_cache、旧 strategy 和旧地址过滤字段 |
| 1.15.0 | TUN 使用新的 sing-tun 栈,stack 废弃 | 新配置不要主动加入 stack;旧配置先备份再测试删除 |
| 1.17.0 | 官方 Deprecated 页面仍写明 stack 将在该版本移除 | 实际是否已发生以当前核心版本、schema 和 check 输出核实 |
建议先执行当前核心提供的版本查看命令,再运行 sing-box check -c config.json。如果客户端内置核心而不是独立命令行核心,版本应在客户端关于页面、日志或配置检查界面中确认;找不到具体版本时,标记为“需核实”,不要凭菜单名称判断。
验证与排错:check 通过不等于 DNS 一定没有泄漏
sing-box check 主要用于发现配置结构、字段和格式问题;它通过后,仍要验证运行时流量是否按预期经过 DNS 模块。不要只依据系统 DNS 设置、浏览器能打开网页或日志里出现查询,就断言没有 DNS 泄漏。
- 先看进程和日志:确认 sing-box 启动后没有 DNS server、TUN 权限、路由或出站连接错误。
- 再看接管:开启 TUN 后,对比关闭和开启时的 DNS 请求路径;检查请求是否命中
hijack-dns,并注意 Linux 本机接口地址存在官方说明的例外。 - 抓包确认上游:在你有权限的设备和网络上观察 DNS 请求是否直接发往本地路由器、系统解析器或其他未预期地址。抓包结果比单次
nslookup更能说明实际外连路径。 - 排除应用自带解析:浏览器 DoH、应用内 DNS、缓存和系统代理可能绕过普通系统 DNS;关闭或单独核对这些功能后再复测。
- 复测并回滚:先用 local、关闭 FakeIP 和 TUN 得到基线,再逐项开启,每次只改一组字段。出现问题时恢复上一份配置。
| 现象 | 先查什么 | 判断与处理 |
|---|---|---|
| check 失败 | JSON、字段名称、版本 schema | 删除最近改动,确认核心版本和官方文档对应关系 |
| check 通过但网页打不开 | outbound、route.final、TUN 权限 | 先关闭 TUN,用 local 和 direct 验证基础连通 |
| DNS 查询有日志但仍走错上游 | dns.rules 顺序、final、detour 或 domain_resolver | 逐条减少规则,确认 server tag 是否拼写一致 |
| 局域网域名打不开 | FakeIP 规则和 local 排除规则 | 把内网后缀规则放在 FakeIP 规则之前,必要时回滚 FakeIP |
| Windows 开启 TUN 后部分软件异常 | strict_route、系统代理、应用自带 DNS | 按官方 TUN 说明逐项测试,必要时暂时关闭 strict_route 或回退到非 TUN 模式 |
常见问题
sing-box 的 DNS 配置应该放在哪里?
放在配置文件顶层的 dns 对象中,而不是放进某个 outbound 或 tun inbound。DNS server、DNS rule、final 和 strategy 都属于 DNS 配置层;TUN 是否接管请求,则还要看 route.rules 中是否配置了对应动作。
只配置 dns.servers,为什么系统 DNS 可能没有被 sing-box 接管?
因为 dns.servers 只定义解析模块如何工作,不等于系统所有 DNS 请求都会进入该模块。TUN 场景需要检查 route 规则、TUN 参数、系统权限和平台限制;官方文档把 hijack-dns 单独定义为 DNS 请求接管动作。
DoH 上游使用域名时为什么需要 domain_resolver?
sing-box 需要先解析 DoH 服务器自身的域名,才能建立连接。如果配置中只有一个 DNS server,某些情况下可以使用默认解析器;为了减少歧义,建议明确设置 domain_resolver,并确认它不会形成解析环。
FakeIP 是不是开启 TUN 后必须配置?
不是。FakeIP 是一种 DNS 返回和域名映射方案,TUN 接管与 FakeIP 是两个不同层次。先用真实解析跑通,再根据应用兼容性和分流需求决定是否加入 FakeIP;局域网域名应优先配置排除规则。
sing-box 1.17.0 是否已经移除了 stack?
本次检索到的官方 Deprecated 页面仍以“将在 1.17.0 移除”的方式描述 stack。这能确认官方迁移方向,但不能替代你本机核心的版本输出,因此应使用实际版本、当前 schema 和 sing-box check 结果核实。
nslookup 或 dig 显示正常,能证明没有 DNS 泄漏吗?
不能单独证明。命令结果可能受本地缓存、系统代理、浏览器 DoH、应用自带 DNS 或测试时机影响。应结合 TUN 开关前后对比、运行日志和有权限条件下的抓包结果判断。
常见问题
sing-box DNS 的最小配置是什么?
先在顶层配置 dns,使用 servers 定义 type: local 的 server,并设置 final 指向 local;同时保留可用的 outbounds 和 route.final。先通过 sing-box check,再启动观察日志。
sing-box DNS 分流怎么写?
在 dns.servers 中定义多个带 tag 的 server,再在 dns.rules 中用 domain_suffix、query_type 等条件把请求指向对应 tag,最后用 final 处理未命中的查询。
TUN 模式为什么还要配置 hijack-dns?
dns.servers 只定义解析方式,TUN 是否把系统 DNS 请求交给 sing-box,还要检查 route.rules 中的 action: hijack-dns,以及 auto_route、strict_route、权限和平台限制。
FakeIP 应该放在哪里配置?
FakeIP 是 dns.servers 中 type: fakeip 的 server,再通过 dns.rules 选择它。局域网后缀应放在 FakeIP 规则之前交给 local,出现内网异常时可删除 FakeIP 规则回滚。
版本升级后 DNS 配置启动失败怎么办?
先确认实际核心版本,再对照官方 Migration 和 Deprecated 页面检查旧 address 格式、independent_cache、旧 DNS rule action strategy 以及 TUN stack,保留备份并用 sing-box check 逐步恢复。