DNS设置
{
"dns": {
"servers": [
{
"server": "223.5.5.5",
"type": "udp",
"tag": "local_local"
},
{
"server": "cloudflare-dns.com",
"domain_resolver": "hosts_dns",
"path": "/dns-query",
"type": "https",
"tag": "remote_dns",
"detour": "🚀 节点选择"
},
{
"server": "dns.alidns.com",
"domain_resolver": "hosts_dns",
"path": "/dns-query",
"type": "https",
"tag": "direct_dns"
},
{
"predefined": {
"dns.google": [
"8.8.8.8",
"8.8.4.4",
"2001:4860:4860::8888",
"2001:4860:4860::8844"
],
"dns.alidns.com": [
"223.5.5.5",
"223.6.6.6",
"2400:3200::1",
"2400:3200:baba::1"
],
"one.one.one.one": [
"1.1.1.1",
"1.0.0.1",
"2606:4700:4700::1111",
"2606:4700:4700::1001"
],
"1dot1dot1dot1.cloudflare-dns.com": [
"1.1.1.1",
"1.0.0.1",
"2606:4700:4700::1111",
"2606:4700:4700::1001"
],
"cloudflare-dns.com": [
"104.16.249.249",
"104.16.248.249",
"2606:4700::6810:f8f9",
"2606:4700::6810:f9f9"
],
"dns.cloudflare.com": [
"104.16.132.229",
"104.16.133.229",
"2606:4700::6810:84e5",
"2606:4700::6810:85e5"
],
"dot.pub": [
"1.12.12.12",
"120.53.53.53"
],
"doh.pub": [
"1.12.12.12",
"120.53.53.53"
],
"dns.quad9.net": [
"9.9.9.9",
"149.112.112.112",
"2620:fe::fe",
"2620:fe::9"
],
"dns.yandex.net": [
"77.88.8.8",
"77.88.8.1",
"2a02:6b8::feed:0ff",
"2a02:6b8:0:1::feed:0ff"
],
"dns.sb": [
"185.222.222.222",
"2a09::"
],
"dns.umbrella.com": [
"208.67.220.220",
"208.67.222.222",
"2620:119:35::35",
"2620:119:53::53"
],
"dns.sse.cisco.com": [
"208.67.220.220",
"208.67.222.222",
"2620:119:35::35",
"2620:119:53::53"
],
"engage.cloudflareclient.com": [
"162.159.192.1"
]
},
"type": "hosts",
"tag": "hosts_dns"
},
{
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18",
"type": "fakeip",
"tag": "fake_dns"
},
{
"type": "udp",
"server_port": 53,
"tag": "Router-DNS",
"server": "192.168.3.1"
},
{
"server": "doh.cmliussss.net",
"domain_resolver": "local_local",
"path": "/CMLiussss",
"type": "https",
"tag": "ech_dns"
},
{
"tag": "opendns-udp-443",
"type": "udp",
"server": "208.67.220.220",
"server_port": 443
}
],
"rules": [
{
"query_type":[12, "PTR"],
"domain_suffix":[
"168.192.in-addr.arpa"
],
"server": "Router-DNS"
},
{
"query_type": [
12,
"PTR"
],
"action": "predefined",
"rcode": "NXDOMAIN"
},
{
"server": "hosts_dns",
"ip_accept_any": true
},
{
"server": "ech_dns",
"domain": [
"sitebox.tomeetu.us.ci",
"sitebox.tomeetu.indevs.in",
"sitebox.cjz.indevs.in",
"cloudflare-ech.com"
],
"query_type": [
64,
65
]
},
{
"domain": [//此处多余,上面的存在导致这个永远不会匹配到,也就导致"opendns-udp-443"是一个冗余的存在
"sitebox.tomeetu.eu.cc",
"cloudflare-ech.com"
],
"query_type": [
64,
65
],
"server": "opendns-udp-443"
},
{
"rule_set": [
"Category-Ads"
],
"action": "reject"
},
{
"server": "remote_dns",
"clash_mode": "Global"
},
{
"server": "direct_dns",
"clash_mode": "Direct",
"strategy": "prefer_ipv4"
},
{
"action": "predefined",
"rcode": "NOTIMP",
"query_type": [
64,
65
]
},
{
"server": "fake_dns",
"type": "logical",
"mode": "and",
"rewrite_ttl": 1,
"rules": [
{
"query_type": [
1,
28
]
},
{
"invert": true,
"domain": [
"amobile.music.tc.qq.com",
"api-jooxtt.sanook.com",
"api.joox.com",
"aqqmusic.tc.qq.com",
"dl.stream.qqmusic.qq.com",
"ff.dorado.sdo.com",
"heartbeat.belkin.com",
"isure.stream.qqmusic.qq.com",
"joox.com",
"lens.l.google.com",
"localhost.ptlogin2.qq.com",
"localhost.sec.qq.com",
"mesu.apple.com",
"mobileoc.music.tc.qq.com",
"music.taihe.com",
"musicapi.taihe.com",
"na.b.g-tun.com",
"proxy.golang.org",
"ps.res.netease.com",
"shark007.net",
"songsearch.kugou.com",
"static.adtidy.org",
"streamoc.music.tc.qq.com",
"swcdn.apple.com",
"swdist.apple.com",
"swdownload.apple.com",
"swquery.apple.com",
"swscan.apple.com",
"turn.cloudflare.com",
"trackercdn.kugou.com",
"xnotify.xboxlive.com"
],
"domain_suffix": [
"126.net",
"3gppnetwork.org",
"battle.net",
"battlenet.com.cn",
"cdn.nintendo.net",
"cmbchina.com",
"cmbimg.com",
"ff14.sdo.com",
"ffxiv.com",
"finalfantasyxiv.com",
"gcloudcs.com",
"home.arpa",
"invalid",
"kuwo.cn",
"lan",
"linksys.com",
"linksyssmartwifi.com",
"local",
"localdomain",
"localhost",
"market.xiaomi.com",
"mcdn.bilivideo.cn",
"media.dssott.com",
"msftconnecttest.com",
"msftncsi.com",
"music.163.com",
"music.migu.cn",
"n0808.com",
"nflxvideo.net",
"oray.com",
"orayimg.com",
"router.asus.com",
"sandai.net",
"square-enix.com",
"srv.nintendo.net",
"steamcontent.com",
"uu.163.com",
"wargaming.net",
"wggames.cn",
"wotgame.cn",
"wowsgame.cn",
"xiami.com",
"y.qq.com"
],
"domain_keyword": [
"ntp",
"stun",
"time"
],
"domain_regex": [
"^[^.]+$",
"^[^.]+\\.[^.]+\\.xboxlive\\.com$",
"^localhost\\.[^.]+\\.weixin\\.qq\\.com$",
"^mijia\\scloud$",
"^xbox\\.[^.]+\\.microsoft\\.com$",
"^xbox\\.[^.]+\\.[^.]+\\.microsoft\\.com$"
]
}
]
},
{
"server": "remote_dns",
"rule_set": [
"geosite-google"
]
},
{
"server": "Router-DNS",
"rule_set": [
"GeoSite-Private"
],
"strategy": "prefer_ipv4"
},
{
"server": "direct_dns",
"domain_suffix": [
"alidns.com",
"doh.pub",
"dot.pub",
"360.cn",
"onedns.net"
],
"strategy": "prefer_ipv4"
},
{
"server": "direct_dns",
"rule_set": [
"GeoSite-CN"
],
"strategy": "prefer_ipv4"
}
],
"final": "remote_dns",
"disable_cache": false,
"disable_expire": false,
"independent_cache": true
}
}
DNS解析
兼顾“防泄漏、极速解析、局域网直连与增强抗封锁能力”。
整个框架分析可以分为三大核心:服务器的作用(Who)、规则的执行顺序(When)、以及背后的核心设计思想(Why)。
第一部分:DNS 服务器的分工与作用(服务器矩阵)
配置了多组 DNS 服务器,它们各司其职,没有一个是多余的:
- 核心解析双雄:
remote_dns(Cloudflare DoH): 负责所有需要走代理的国外域名。它被强制打上了"detour": "🚀 节点选择"的标签,这意味着它的查询全程被加密包裹在节点隧道里,极大降低了 ISP(运营商)的 DNS 污染和窥探。direct_dns(阿里 DoH): 负责国内域名。通过国内服务器解析,保证国内 CDN 能够分配到最近、最快的国内真实 IP。
- 底层基石与防死锁:
hosts_dns(海量预设 IP): 它的作用是**“查字典”**。因为前两个 DNS 都是基于 HTTPS 域名的(比如cloudflare-dns.com),如果不知道 Cloudflare 的 IP,就无法发起查询,从而陷入死循环(先有鸡还是先有蛋)。hosts_dns直接内置了这些 DNS 的真实 IP,打破了死锁。
- 性能引擎:
fake_dns(198.18.x.x 等): 它是全配置的核心引擎。遇到符合条件的请求:- DNS 返回 FakeIP(如 198.18.x.x)
- 客户端连接这个 IP
- sing-box:
- 查
fakeip mapping表 - 找回真实域名
- 再去走代理连接真实目标
- 查
- 这样可以提前进入代理连接流程,避免等待真实 DNS + 分流判断,从而提升首屏加载速度
- 特殊作战部队(抗封锁与内网):
ech_dns&opendns-udp-443: 这是针对特殊环境(如阻断 SNI)设立的。专门解析支持 ECH 的特定节点域名,增强在恶劣网络下依然能连上代理节点的能力。Router-DNS(192.168.3.1): 专门负责内网设备解析,确保通过域名打得开路由器和 NAS 后台。
第二部分:DNS 规则的执行顺序及原因(从上到下严格匹配)
sing-box 的规则是**“瀑布流从上往下、命中即停止”**。规则排序依照“先过滤垃圾,再处理特殊,最后大面积分流”的规则。
- 第 1 阶段:底层优化与垃圾拦截(最高优先级)
- 放行内网 PTR(如有添加): 允许路由器去反查内网 IP 的名字。
- 阻断公网 PTR (
NXDOMAIN): 遇到198.18.x.x(FakeIP) 的反向查询立刻掐断,防止卡顿。 - 广告屏蔽 (
Category-Ads->reject): 广告域名没资格往下走,直接在门口毙掉,节省网络资源。
- 第 2 阶段:针对 ECH(Type 64/65)的“白名单放行”
- 遇到特定的特殊节点域名(如
cloudflare-ech.com),且是 Type 64/65 查询时,交给专属的ech_dns或opendns。因为这些域名必须依靠这些高级查询来建立底层加密通道。
- 遇到特定的特殊节点域名(如
- 第 3 阶段:全局屏蔽新型查询(Type 64/65 核心防漏)
- 返回
NOTIMP: 拦截绝大多数常规域名的 Type 64/65 (HTTPS/SVCB) 查询。原因: 逼迫浏览器降级使用 Type 1 (A 记录),这样才能防止绕过 FakeIP 机制,防止真实 IP 泄漏。
- 返回
- 第 4 阶段:FakeIP 核心分发系统
fake_dns白名单排除法: 通过长长的"invert": true名单(包含系统服务、微软连通性测试、国内音乐、游戏 P2P、迅雷、内网局域网等)。原因: 只要不在这些“不能用假IP”的名单里且是A或AAAA查询,统统秒发 FakeIP 走代理。极大减少了玄学断网问题。
- 第 5 阶段:传统分流(直连与局域网)
- 漏网之鱼(比如被上面 FakeIP 黑名单排除出来的国内域名或内网域名)来到了这里。
GeoSite-Private->Router-DNS: 内网地址交给路由器查真实内网 IP。GeoSite-CN->direct_dns: 国内网站交给阿里 DNS 查真实的国内 IP,并且强制prefer_ipv4(防止 IPv6 路由绕路变慢)。
- 第 6 阶段:兜底 fallback
final: "remote_dns": 如果上面的规则全都没匹配上,说明这是一个未知的境外域名,默认直接扔给 Cloudflare DoH,并通过代理节点发送。安全,防漏。
第三部分:核心设计思想总结
- “拒绝 DNS 污染”是第一要务: 所有的国外解析都是通过 DoH (HTTPS) 并且强制通过代理隧道
detour出去,国内运营商即使想污染或者记录看过什么网站,也无能为力。 - FakeIP 白名单逻辑(求稳不求全): 如果 FakeIP 把“所有流量都给假 IP”,这会导致 QQ 扫码登录不上、网易云音乐听不了、内网 NAS 连不上。这里反其道而行,建立了一个庞大的“排除名单”,把容易出问题的功能全部分流到了真实 IP,兼顾了速度与极高的稳定性。
- 对 DNS 查询类型的精细掌控: 普通配置只管域名,而这个配置精细到了底层的
query_type(拦截 12 反向查询防卡顿,拦截 64/65 高级查询防泄漏)。
⚠️ 缺陷
clash_mode 规则的局限性
配置中有:
{ "server": "remote_dns", "clash_mode": "Global" },
{ "server": "direct_dns", "clash_mode": "Direct", "strategy": "prefer_ipv4" }
clash_mode仅在 sing-box 运行于 Clash API 兼容模式 且主动切换了global/direct模式时才生效。在普通代理模式下(例如使用规则路由),这两个规则不会被匹配,因此对大多数的实际 DNS 流程无影响。
Type 64/65 返回 NOTIMP 规则的位置影响
该规则(第9条)位于 clash_mode 规则之后。
- 如果
clash_mode: Global或Direct命中,那么 Type 64/65 查询可能会被直接发往remote_dns或direct_dns,绕过 NOTIMP 拦截。 - 不过,在 Clash 模式下通常不会同时需要精细的 DNS 防泄漏,所以影响不大。但理论上存在一个小窗口。
fake_dns 排除列表中的 invert: true 逻辑
需注意:排除列表中还包含了 query_type: [1,28] 条件,也就是说只有 A/AAAA 查询才可能进入 FakeIP。其他类型(如 MX、TXT)不会走 FakeIP,会继续向下匹配。
Fake IP模式,域名的真实IP到底怎么获得
对该域名发起真实 DNS 解析,这个动作直接参照的是 dns.rule(DNS 规则),但是,到底会不会触发这个解析动作,是由 route.rule(路由规则)决定的。
这两个规则在整个流量处理的生命周期中是先后配合的关系。为了更清晰地理解,我们可以把流量到达 sing-box 后的底层流程拆解开来看:
1. 恢复域名阶段(前置动作)
客户端已经通过DNS模块获得了fakeip,然后客户端对这个假IP发起链接,客户端发出的 TCP/UDP 流量(目标地址为 Fake IP,例如 198.18.0.5)进入 sing-box 的 TUN 接口。sing-box 通过内部的 Fake IP 映射表进行反向查询,发现这个 IP 对应的是 www.example.com。
此时,sing-box 成功恢复了真实的域名。
2. 路由分发阶段:参照 route.rule
手里有了域名后,sing-box 首先会去匹配 route.rules (路由规则)。
这一步决定了流量的去向(Outbound),同时也间接决定了后续是否需要在本地发起真实的 DNS 解析:
- 情况 A(走代理节点): 如果
routerule命中规则,决定将www.example.com交给proxy(代理节点)出站。通常情况下,sing-box 会直接把域名封装打包,发送给远端代理服务器,由远端的服务器在墙外去解析它的真实 IP。在这种情况下,本地根本就不会触发“发起真实 DNS 解析”的行为。 - 情况 B(走本地直连): 如果
routerule命中规则(或者作为兜底),决定将www.example.com交给direct(直连)出站。因为是要从你的本地网络直接向目标发起连接,底层网络协议必须知道目标的真实 IP。这时候就会触发向本地 DNS 模块请求真实 IP 的动作。 (注:如果你的 proxy 出站配置了特定的domain_strategy,例如要求强制解析出 IP 后再发送,也会触发解析请求。)
3. 真实解析阶段:参照 dns.rule
一旦在第 2 步中,路由出站要求必须获取目标的真实 IP,sing-box 就会向内部的 DNS 模块发起查询指令。
从这一刻起,完全由 dns.rules (DNS 规则) 接管:
- DNS 模块会拿
www.example.com这个域名去匹配你的dns.rules。 - 根据匹配结果,决定将这个 DNS 请求发给哪个具体的上游 DNS 服务器(例如:命中
geosite:cn发给阿里的223.5.5.5;命中其它域名发给 Cloudflare 的1.1.1.1)。 - 拿到真实的物理 IP 后,交还给出站模块,正式建立 TCP/UDP 连接。
总结
- 到底要不要去查这个真实 IP? —— 参照
route.rule(以及对应出站的策略)。 - 如果必须查,用哪里的 DNS 服务器去查真实 IP? —— 参照
dnsrule。
在 Fake IP 模式下,整个流量的逻辑链条是严格按照这个顺序执行的:Fake IP 被拦截 → 还原出真实域名 → Route.rule 判定去向 → (如果去向需要 IP) Dns.rule 决定如何解析真实 IP → 建立出站连接。
“ip_accept_any”: true
官方说法: 地址过滤字段仅对 A/AAAA/HTTPS 等地址类请求生效。当查询结果不匹配地址过滤规则时,当前规则会被跳过,继续匹配下一条规则;ip_accept_any: true 表示匹配查询响应中的任意 IP 地址。 这三个单词直译过来就是:“接受任何返回的 IP”。
在 sing-box 的 DNS 规则里,"ip_accept_any": true 是一个**“条件触发开关”**。它的核心意思是:
“不管这个域名对应的是什么具体的 IP,只要服务器能给我查出一个(或多个)真实的 IP 地址,这条规则就算生效了;如果查不到任何 IP,这条规则就当不存在。”
为了瞬间秒懂,我们用一个生活中的例子来打比方:
🏪 通俗易懂的比喻:保安看白板
假设 hosts_dns 是你小区门口的保安大爷,他手边有一块小黑板(相当于你配置里预设的那十几个 DNS 域名和 IP,比如 Google、Cloudflare 等)。
当你想去一个地方(查询域名),你按照规则先去问保安大爷。
如果不加
"ip_accept_any": true(强行匹配): 你问:“大爷,YouTube 怎么走?” 大爷看了看黑板,发现没写,于是直接对你说:“查无此地,你回家吧!”(返回错误,导致你断网)。加了
"ip_accept_any": true(有结果才算数): 这条代码等于给大爷下达了一个新指令:“只要黑板上有答案,你才管;黑板上没写的,你别瞎指挥,让他去问别人。”- 场景 1(查得到): 你问:“大爷,Cloudflare 的 DoH 怎么走?”大爷看了一眼黑板,有!告诉你:“IP 是 1.1.1.1”。此时满足了“给出了任何有效IP”的条件,拦截成功,你直接拿到结果。
- 场景 2(查不到): 你问:“大爷,YouTube 怎么走?”大爷看黑板上没有,返回空。此时触发了条件判定——没拿到 IP。于是这条规则直接作废,你无视了大爷,继续往下走,去问后面的
fake_dns或者remote_dns。
💻 总结它的专业作用
在配置里,"ip_accept_any": true 把 hosts_dns 变成了一个**“非强制性的前置缓存字典”**。
它能做到:
- 精准打击: 把预先写好的网站域名按照预期解析出来,也就是为了做特定域名的DNS解析劫持。比如把
example.com映射成1.2.3.4。 - 绝不误伤: 对正常上网访问的其他所有域名(由于在本地 Hosts 字典里查不到 IP),它会“悄悄地让开路”,把这些请求放行到后面的 FakeIP 规则和分流规则去处理。
- 它的作用其实并不是为了解析DoH的真实ip,DoH的ip获取是通过
"domain_resolver"。只是本例中,预设的正好全部是DoH对应的ip。 如果没有这短短的一行代码,网络就全瘫痪了。
DNS安全强化
中国有四大行,还有六大国有银行(漏了交行、邮储),以及很多常用的股份制商业银行(如平安、中信、浦发)和重要的支付底层(如微信支付的财付通)。
为了做到“万无一失”,补全国内主流的金融/网银列表。
⚠️ 一个非常重要的小提醒:关键词过短会误杀
像 "boc"(中国银行)这个词太短了,如果你把它放在 "domain_keyword"(域名包含该关键词)里,有可能会误杀其他正常网站(比如某个英文网站叫 robotics-boc.com 也会被强行直连)。
因此,最科学的写法是:独特的长名字用 domain_keyword,容易重复的官方域名用 domain_suffix(域名后缀)。
下面为你提供一份终极防风控补全版,你可以直接复制替换你刚才的那两段配置。
第一处修改:在 FakeIP 的绕过列表里补全
找到 dns -> rules 里面的 fake_dns 那一段,把 "invert": true 下面的规则替换或补充为这样:
{
"invert": true,
"domain": [
// ... 你原本的精确域名列表保持不变 ...
],
"domain_suffix":[
// ... 你原本的后缀列表保持不变,在最下面加上这几行:
"boc.cn", // 中国银行
"bankcomm.com", // 交通银行
"psbc.com", // 邮储银行
"citicbank.com", // 中信银行
"pingan.com", // 平安银行/保险
"pingan.com.cn", // 平安银行/保险
"cib.com.cn", // 兴业银行
"cmbc.com.cn", // 民生银行
"hxb.com.cn", // 华夏银行
"jdpay.com" // 京东支付
],
"domain_keyword":[
"ntp",
"stun",
"time",
"alipay", // 支付宝
"taobao", // 淘宝
"tenpay", // 财付通 (微信支付核心底层)
"icbc", // 工商银行
"cmbchina", // 招商银行
"abchina", // 农业银行
"ccb", // 建设银行
"unionpay", // 云闪付/银联
"95516", // 银联客服
"cebbank", // 光大银行
"spdb", // 浦发银行
"cgbchina" // 广发银行
]
// ... 下面的保持不变 ...
}
第二处修改:在 DNS 及 Route 中指派国内直连
同理,在你的 dns 规则(指派给 direct_dns)和 route 规则(指派给 🎯 全球直连)中,新建或修改成这样(两边都要加,格式类似):
DNS 规则补充 (加在 dns -> rules 里):
{
"domain_suffix":[
"boc.cn",
"bankcomm.com",
"psbc.com",
"citicbank.com",
"pingan.com",
"pingan.com.cn",
"cib.com.cn",
"cmbc.com.cn",
"hxb.com.cn",
"jdpay.com"
],
"domain_keyword":[
"alipay",
"taobao",
"tenpay",
"icbc",
"cmbchina",
"abchina",
"ccb",
"unionpay",
"95516",
"cebbank",
"spdb",
"cgbchina"
],
"server": "direct_dns",
"strategy": "prefer_ipv4"
}
Route 规则补充 (加在 route -> rules 的前面部分):
{
"domain_suffix":[
"boc.cn",
"bankcomm.com",
"psbc.com",
"citicbank.com",
"pingan.com",
"pingan.com.cn",
"cib.com.cn",
"cmbc.com.cn",
"hxb.com.cn",
"jdpay.com"
],
"domain_keyword":[
"alipay",
"taobao",
"tenpay",
"icbc",
"cmbchina",
"abchina",
"ccb",
"unionpay",
"95516",
"cebbank",
"spdb",
"cgbchina"
],
"action": "route",
"outbound": "🎯 全球直连"
}
💡 总结一下补齐了什么
- 微信支付底层:
tenpay(财付通)。因为在群里发红包、线下扫微信付款时,流量走的其实是tenpay.com相关的域名,这点非常关键。 - 六大国有行补齐:中国银行(改为了更安全的后缀匹配
boc.cn)、交通银行(bankcomm)、邮储银行(psbc)。 - 十二家全国股份制银行:把主流的中信、光大、华夏、民生、广发、平安、浦发、兴业全部加上了。
- 京东体系:加了
jdpay支付接口。