对DNS 泄漏的一点讨论

来源: https://blog.skk.moe/post/lets-talk-about-dns-cdn-fake-ip/

为什么说 DNS 泄漏毫无风险?

在众多国际上一些运行在 OSI 模型三层的 VPN 提供商(例如 ExprsVPN、SfShark、N**dVPN)的洗脑宣传、在一些 KOL 的炒作下,「DNS 泄漏」被渲染成洪水猛兽、令人谈虎色变;然而事实真的是如此吗?

在谈论「DNS 泄漏」之前,首先要能理解 DNS 解析的参与者。Cloudflare 这篇 What is DNS? | How DNS works 文章详细介绍了 DNS 的工作原理,本文不再赘述,简而言之,DNS 解析书是由 发起 DNS 查询的用户、作为中间人的递归 DNS(即 Local DNS。运营商 DNS 和 公共 DNS 都属于递归 DNS)、真正决定一个域名应该指向何处的权威 DNS(即 Authoritative DNS)共同完成的。假如我要访问 ip.skk.moe、需要知道 ip.skk.moe 的 IP 地址,浏览器和操作系统并不会亲自完成整个 DNS 递归流程,它们只需要问递归 DNS 就好了,而 Cloudflare 公共 DNS 需要完成的递归就很多了(沟槽的鸣式还在追我)。「DNS 泄漏」实际上发生在递归 DNS 和权威 DNS 之间;查询「DNS 泄漏」,本质上查询的就是 递归 DNS 请求权威 DNS 时所使用的出口 IP。


上图为 ip.skk.moe 提供的「DNS 出口查询」工具的截图,可以看到,图中出现了数个属于 Cloudflare 的 IP,这些就是 Cloudflare 公共 DNS 在日本东京的「DNS 出口 IP」。

然而,由于递归 DNS 都有自己的缓存,并不会每次都去请求权威 DNS,如果需要将「DNS 出口 IP」与某个具体的用户关联起来,就需要让用户请求一些完全随机的域名(例如 evtg8mxu1s-big-tail-fox.edns.skk.moe)、绕开 DNS 缓存、迫使递归 DNS 请求权威 DNS,权威 DNS 就可以通过随机域名将递归 DNS 的请求 IP 和当前用户关联起来,这就是「DNS 泄漏查询」的原理。

知道了「DNS 泄漏查询」的原理,就能理解「DNS 泄漏」的局限性、以及为什么完全不可能将「DNS 出口 IP」用于风控措施了。首先,「DNS 出口 IP」的地理位置和用户的地理位置很难关联起来。以 Cloudflare 公共 DNS 为例,截至本文写就,Cloudflare 在全世界 125 个国家和地区 部署了 330 个 PoP(其中 35 个位于中国大陆境内、和京东云合作的 PoP 不被用于 Cloudflare 公共 DNS),因此 Cloudflare 公共 DNS 的用户的「DNS 出口 IP」只可能是位于这 124 个国家和地区,甚至不能一对一覆盖全球 208 个国家和地区;而规模和体量更小的公共 DNS,例如只在 110 个国家和地区部署了 230 个节点的 Quad9 DNS,只在 22 个国家和地区部署了 48 个节点的 Cisco OpenDNS,只在 15 个国家和地区部署了节点的 AdGuard Public DNS, 通过它们的出口 IP 甚至无法判断用户在具体某个国家,难道要把所有使用公共 DNS 的用户全部标记为「可疑用户」吗? 其次,为了查询递归 DNS 出口 IP,需要走完整个 DNS 递归流程,需要等待很长时间;而且每次查询都无法被递归 DNS 缓存、会有相对较高的失败率。这些都导致「DNS 出口 IP」很难被作为风控监测的因子。

虽然「DNS 泄漏」毫无危害、不过是一些 VPN 服务商和一些 KOL 贩卖焦虑罢了;但是「DNS 出口 IP」依然值得我们关注,并不是为了化解什么风险,而是为了验证我们的配置是否正确,因为…
域名的 DNS 查询,一定要通过实际使用的网络出口发送
:writing_hand::writing_hand::writing_hand::writing_hand::writing_hand:

CDN(Content Delivery Network,内容传输网络)是互联网基础设施中不可或缺的一环。在 Cloudflare 的 What is a content delivery network (CDN)? | How do CDNs work? 中详细介绍了 CDN 的工作原理,本文亦不再赘述,简而言之,CDN 通过在全球各地部署大量的服务器(PoP、CDN 节点)、从字面意义上将网站带到用户附近。而 CDN 在为用户分配距离他们最近的服务器时,CDN 的权威 DNS 会通过递归 DNS 的出口 IP 来返回最适合用户的 CDN 节点 IP,即 GeoDNS。

几乎所有 CDN 都在使用 GeoDNS。即使是像 Fastly、Cloudflare 这样大量使用 Anycast 的 CDN,他们依然在部分场景下使用 GeoDNS 技术(Fastly CDN 会为不同的大洲返回 不同 BGP Routing Profile 的 Anycast IP,Cloudflare 也曾针对欧洲地区分配专属 Anycast IP);而像 Akamai、AWS CloudFront、Azure Front Door、CDN77、BunnyCDN、CacheFly、KeyCDN 等不使用 Anycast 的 CDN,更是完全依赖于 GeoDNS 为用户调度、分配 CDN 节点;即使在视频推流、直播、文件下载等大流量场景下,CDN 可能使用基于 HTTP API(常见于在线视频网站)或 HTTP 302(例如腾讯云的实时音视频 CDN)的调度,这些调度方式的前序请求 依然依赖 GeoDNS。因此,递归 DNS 的出口 IP 对我们的网络体验有着直接的影响。

如果使用新加坡出口访问 Netflix,我们自然不希望 Netflix 分配位于美国的 CDN 节点;如果通过日本出口访问 YouTube,我们自然不希望 YouTube 分配位于香港的 CDN 节点。为了保证 CDN 能够分配合适的 CDN 节点,不论使用的是 Fake IP 模式还是 Real IP 模式,都需要确保对域名的 DNS 解析查询,一定要通过实际使用的网络出口发送。

可能一些读者此时会提问,如果使用 EDNS Client Subnet(ECS)是否就不需要通过实际使用的网络出口发起 DNS 解析了?不要着急,下一个章节我会专门聊一聊 EDNS Client Subnet。

对于 Fake IP 模式来说,由于 DNS 解析的责任从代理客户端转移到了代理服务器、尽可能避免在本地进行 DNS 解析,因此 Fake IP 无需额外的 DNS 转发配置、天生就具备「无视 DNS 污染」和「CDN 体验优化」两大优势。我在 浅谈在代理环境中的 DNS 解析行为 中详细介绍过,Surge 在 Surge 官方中文指引:理解 Surge 原理 一文中的「接管」章节也有所介绍,但是简单来说,在 Fake IP 模式下,浏览器和其他软件在访问需要被代理的域名时,只会看到被代理客户端接管 DNS 后返回的 Fake IP;而代理客户端通过接管浏览器与 Fake IP 建立的连接,通过域名和 Fake IP 一对一的关系反推出目标域名后、将目标域名和目标端口发送给代理服务器,只有代理服务器进行真正的 DNS 解析,获取目标网站的「Real IP」(即目标网站使用的互联网可达的公网 IP 地址),无视本地网络的 DNS 污染。

如果代理客户端使用的并不是 Fake IP 模式而是 Real IP 模式,那么此时不论浏览器和其他软件访问什么网站、不论是否需要代理,代理客户端都必须向递归 DNS 查询「Real IP」。为了避免 DNS 污染和改善网络体验,这些 DNS 查询必须通过访问网站所使用的网络出口发出(如果需要使用美国出口解锁 ChatGPT、此时代理客户端查询 chatgpt.com 的 DNS Question 就必须从美国出口发出;如果需要使用英国出口解锁 BBC iPlayer、此时代理客户端查询 www.bbc.co.uk 的 DNS Question 就必须从英国出口发出;其他网络出口同理)。由于 Real IP 不能像 Fake IP 一样建立和目标域名一对一的对应关系(因为多个网站可能解析到相同的 IP 地址),因此代理客户端不得不使用 嗅探 HTTP 明文请求中的 Host 请求头、嗅探 HTTPS/QUIC 中明文 TLS Client Hello 的 SNI 等手段,才能获取目标域名按照域名规则进行分流;一旦遇到并非使用 HTTP 与 TLS 的连接,或者 TLS 启用了 Encrypted Client Hello(ECH)时,嗅探便束手无策了。因此 Real IP 模式下,域名规则分流的准确性不如 Fake IP 模式。

另外需要注意的是,大部分支持 Real IP 模式的主流代理客户端,并不能自动将 DNS 查询通过指定网络出口发出,因此 Real IP 模式下需要用户在域名分流的基础上、额外手动配置对应的 DNS 转发规则。

....................

个人观点:

sukka 写的这篇文章有点问题

8.9.6.4             19.53.06.15                         
client   ---->      dns server      --->      权威dns 
     xxjjpp.gov.cn             xxjjpp.gov.cn     

因为三级域名是随机生成的 xxjjpp.gov.cn ,所以可以确定 xxjjpp.gov.cn-- 19.53.06.15 ---- client 唯一

此文对 DNS 泄漏 定义是: 权威 DNS 知道client 正在使用哪个dns server查询域名,从而可以根据 dns server 的 ip 的地理位置来大致推测 client 的地理位置


client --- www.google.com--->运营商dns

                                     GFW
client --- 明文查询 www.google.com --      --> 1.1.1.1
   <----------------------------------
   |time|<--------------------------------------

但还有一个对 DNS 泄漏的定义是: 不希望泄露的DNS查询发出去了。

这个定义会出现的情况就相当宽泛了,包括加密/不加密的对外网域名的dns查询发到国内的dns服务器,不加密的对外网域名的dns查询发到国外的dns服务器

举例良子做过的一个视频 https://www.youtube.com/watch?v=fqREM6b25SY 对www.google.com发起dns请求后,根据 ip来判断走代理还是走直连,如果配置里用不加密的DNS,把dns查询发到ISP那去了, 那就是DNS泄露。

                                     GFW
client --- 明文dns查询 www.google.com     ----> 1.1.1.1
   <----------------------www.google.com 8.9.6.4
   |time|<-----------------------------www.google.com  142.251.157.119

    ----- ss  加密|https://www.google.com| ---> ss server

如果说暴露了在加密隧道中访问的网站一次或若干次的dns查询无关紧要,那么再加上一次加密隧道连接呢?这种特征就非常明显了

不过到最后良子也没明确说明哪个才是DNS泄露,但不论如何最后一种情况的是客观存在的,也是存在风险的。即便前一种情况最终会成为DNS泄露的主要阐述,后一种情况也需要给与一个新的命名,对吗

别搬 :poop:
看多了降低认知

DNS递归泄露 和 DNS查询泄露

也行