🌐OpenClash + Mosdns + ADG如何防止DNS泄露?

2024-8-25|2025-3-6
Yawatasensei
Yawatasensei
type
status
date
slug
summary
tags
category
icon
password
📌
OpenWRT的科学上网中,DNS泄露(DNS Leak)是大多数用户并不关心的部分,但也是小部分用户或者强迫症爱好者会纠结的部分。至于DNS泄露之后真正会造成什么样的后果,现在并没有任何确凿的示例,但是秉承着在这个互联网灰色地带尽量安全的准则(黑暗森林法则),以及为了满足自己无穷无尽的动手欲,今天就来尝试通过对自己家里的整体网络链路进行入手分析,寻找可能存在的DNS泄露点,以及进行修复。这是一个从2023年伴随着科学上网就一直在不断讨论的话题,今天我也加入进来。

📝 什么是DNS泄露

首先,我们需要来了解一下到底什么是DNS泄露以及其潜在的风险:
DNS泄露是指在使用VPN(虚拟专用网络)或者科学上网时,用户的DNS请求绕过VPN隧道,直接通过用户的本地网络发送给互联网服务提供商(ISP)的DNS服务器,而不是通过VPN提供的DNS服务器进行解析。这种情况会暴露用户的真实IP地址、位置和浏览活动,从而削弱了使用VPN或科学上网所提供的隐私和匿名性。通常,VPN(科学上网)的一个重要功能是加密和隐藏用户的流量,这其中包括DNS请求。但是,如果VPN或者科学上网程序配置不当或存在漏洞,DNS请求可能不会被加密或路由到正确的DNS服务器,导致信息泄露。这种泄露可能让ISP或其他第三方能够监视用户的上网行为,甚至在某些情况下,影响用户访问内容的安全性。
那么在国内来说,DNS泄露就可能会被ISP(你的宽带运营商,例如电信、联通、移动等等)知晓你要访问什么网站,从而被ISP(宽带运营商)识别,劫持至反诈页面或者被短信提醒。
根据我的个人的实际使用体验,在解决完家里网络DNS泄露的问题之后,目前还没有再被劫持到反诈页面,而在之前,访问Linux.do或者很多独立个人博客都会被劫持到反诈页面,这一点在具有墙中墙的部分省份尤其明显。

📝 OpenWRT DNS泄露排查流程及修复

DNS请求链路

在仅考虑DNS解析请求的链路情况下,目前我所使用的方案基于OpenWRT系统,由AdGuard HomeMosDNS以及Openclash组成,相互共存,以上服务均部署在旁路网关(旁路由)的OpenWRT上。各部分的选择原因如下:
AdGuard Home(ADG):作为监听在53端口的默认DNS服务,我没有选择重定向或者使用其他非标端口,而是直接使用53端口,替代OpenWRT默认的Dnsmasq提供DNS转发服务,这也可以使AdGuard Home与OpenClash共存。同时,由于旁路网关不需要承担DHCP的任务,为局域网内其他客户端分配IPv4地址,所以可以直接替换,将Dnsmasq的监听端口改成其他的就可以了,例如端口5353。AdGuard Home可以提供全局的、并且可视化的DNS请求记录查询功能,以及可以快速添加过滤广告功能,这是我所需要的,且其他DNS服务软件暂时无法提供的。
MosDNS:作为AdGuard Home上游DNS服务器使用,通过配置文件策略进行DNS分流,对国内DNS加速,对污染请求转发至上级OpenClash的DNS服务,通过科学上网进行远端请求。在广告过滤的功能上,MosDNS完全可以替代AdGuard Home,但是由于缺少可用性较好的面板,且AdGuard Home的规则定义模式不如MosDNS多样化,所以在我这里还无法完全替代AdGuard Home的工作。
OpenClash作为整体DNS请求解析链路的最后一环,单纯提供针对需要代理服务和科学上网的域名进行解析并返回查询结果,确保客户端所请求域名地址没有被污染,所以关闭DNS劫持,由AdGuard Home和MosDNS负责DNS工作,使三者共存。其实OpenClash对dnsmasq的依赖主要就在于DNS和实验性:绕过中国大陆IPv4这两部分,而在我们弄明白了OpenClash的绕过中国大陆IPv4实现原理之后,完全是可以替代掉OpenWRT默认使用的Dnsmasq。
notion image

发现问题

1. AdGuard Home的DNS泄露排查

在解决问题之前,我们需要先发现问题,我们需要先确认目前的网络情况是否存在DNS泄露。
首先通过IP/DNS Detect - What is your IP, what is your DNS, what informations you send to websites. (ipleak.net)进行DNS泄露情况检查和泄露结果查看,可以看到在未进行整体DNS请求链路调整之前的DNS泄露情况。
同时,通过在AdGuard Home进行日志查询,可以看到具体进行检测DNS泄露的DNS解析请求的域名,一般来说是一个三级域名,类似于yw9dmycvn53p2zedczygrbjx4v5anjd2as23ly3w-32.ipleak.net 这种。其检测DNS泄露的原理大概是通过生成大量的三级域名让我们请求解析,从而获取我们完整的DNS服务配置,当这里出现五星红旗及大陆IP时候,即证明已经产生的DNS泄露。
同时经过上述测试,在这里我们可以确认:
  1. 由AdGuard Home所提供的DNS转发服务正常,能够正常转发至上级MosDNS进行解析。
  1. 客户端的DNS请求是通过AdGuard Home向上级转发,也就是转发给MosDNS进行处理,并且转发成功,在AdGuard Home中的响应结果正常,没有出现SERVERROR
  1. 由于我的AdGuard Home的DNS设置中,上游DNS只有Mosdns一个地址,那么可以确定问题不是出在AdGuard Home这里,可以继续对整体链路向上进行排查。
  1. 如果你的AdGuard Home里面DNS配置中,添加了后备DNS服务器(Fallback DNS Server),那么这也可能是出现DNS泄露的一个地方。当上游DNS服务器无法正常响应时,AdGuard Home会主动使用后备DNS服务器(Fallback DNS Server)查询,且由于AdGuard Home未进行分流,从而可能导致DNS泄露。

2. MosDNS的DNS泄露排查

我对目前我的MosDNS执行序列执行重新画了流程图。同时我也建议你这么做,这样可以更好的了解MosDNS在你进行域名解析请求的时候都发生了什么,也能更好的了解自己所使用规则的运作原理及解析过程。我的配置文件是使用的Jasper-1024编写的MosDNS配置文件,地址为:mosdns_docker/mosdns_v5 ,并在此基础上我进行了部分修改:增加了污染域名的直接远端请求,同时去掉了并发请求DNS服务器,以及根据自己的需要进行了ECS中请求所使用IP地址的修改。
修改后我的MosDNS解析请求流程如下:
notion image
  1. qtype65判断QTYPE65 是指一种特定的DNS查询类型,正式名称为HTTPS(也称为 SVCB 或 Service Binding)。这种查询类型的数字标识符为 65,是DNS协议中的一部分,用于增强安全性和优化连接。但由于QTYPE65 的相对新颖性和对新技术的依赖,它在实际使用中还不如传统的A、AAAA 等 DNS记录普及,且反而容易产生污染,所以拒绝,也不存在DNS泄露的可能性。
  1. 无效域名和keyword为空域名:垃圾请求,拒绝,不存在DNS泄露可能性。
  1. qtype12:PTR请求,通过序列query_other丢给上级DNS服务查询,本级不存在DNS泄露可能。
  1. qtype255:DNS扩展请求,通过寻猎query_other丢给上级DNS服务查询,本级不存在DNS泄露可能。
  1. 私有IP及geosite_private:本地请求,不涉及外网请求,交由query_lan本地化处理,本级不存在DNS泄露可能。
  1. 广告及geosite_ad_all:广告的DNS请求,直接本级处理,丢弃,不存在DNS泄露可能。
  1. 缓存检查:不存在直接泄露可能,但可能会存在污染被缓存可能。
  1. cn域名判断:通过query_cn进行国内DOH/DOT公共DNS查询,本级不存在DNS泄露可能。
  1. GFW域名判断:通过篇query_gfw直接转发请求至OpenClash远端处理解析并返回结果,本级不存在DNS泄露可能。
  1. 非cn域名判断:通过query_nocn使用cloudflare及nextdns查询,并对结果进行过滤,解析结果为国内IP的请求将继续通过序列向下进行查询,去除被污染的DNS结果。
  1. no_ecs队列:没有什么用的一个执行片段,用于为域名解析请求添加ECS地址,使其响应结果更靠近所设ECS所在IP地址,加快访问速度,其自身不产生DNS请求,同时也不存在DNS泄露可能。
  1. query_fallback序列:将最终未能成功解析的域名执行fallback片段,交由OpenClash进行远端解析请求,本层级不存在DNS泄露可能。
  1. 日志查询:对日志文件进行查询,发现所有关于*.ipleak.net的域名解析全部走的query_fallback,也就是交给OpenClash进行域名解析,那么可以确认在MosDNS这部分,没有产生DNS泄露的情况。
通过对整体MosDNS序列的分析,我认为产生DNS泄露点并不在MosDNS这部分,应该在OpenClash这部分。

3. OpenClash泄露排查

Openclash我所使用的是mihomo内核,也就是原Clash-Meta内核,fake-ip混合模式,同时开启了IPv6的相关功能。fake-ip的机制见仁见智,这不是这篇文章关心的内容,我的目标还是找到泄露的点在哪里,并解决DNS泄露的问题。
通过查看OpenClash的日志发现:
也就是DNS的解析请求最终没有通过OpenClash进行远端解析,而是使用了nameserver或者default nameserver所配置的DNS服务器进行了DNS解析。而我的nameserver组里恰好就阿里云的223.5.5.5
在OpenClash的issue中也有人反应过:OpenClash会同时使用fallback组和nameserver组进行DNS解析请求([Bug] dns泄露 #3843)。也就是说fallback最终back来back去back回了国内,反而污染了已经分流好的域名解析请求,并造成了DNS泄露。

4. 修复OpenClash产生的DNS泄露问题

在OpenClash中,由于DNS的解析请求工作已经由下游的MosDNS完成了一部分,剩下的一部分应该交由上游的代理进行解析,自身并不需要再提供繁杂的DNS分流规则配置工作,那么也就应该简化原有的配置。
  • nameserver:在不配置proxy-server-nameserver 时,nameserver作为默认解析代理节点的dns服务器,同时考虑到DNS污染及泄露可能,我这里配置了一个nextdns的服务器,你也可以配置一个你可以正常访问的且无污染的dns服务,推荐使用DOH或者DOT这种加密DNS。
  • fallback:fallback规则在具有远端DNS请求及MosDNS分流的情况下,不再具有任何意义,因为所有经由OpenClash处理的域名解析请求均是需要使用远端请求的。所以我将所有的OpenClash中的fallback服务器删除。
  • default-nameserver:默认DNS,用于解析DNS服务器的域名(例如部分DOH),由于我们并没有在OpenClash中使用任何域名形式的DNS,所以可以不必填写。但为空时可能会将订阅文件中的值填充至config.yaml中,所以我填了一个nextdns的ip地址。
  • 追加上游DNS:取消勾选,不需要追加。
  • 追加默认DNS:取消勾选,不需要追加。
  • Fallback-Filter:取消勾选,不用fallback。
  • nameserver-policy:取消勾选,DNS分流已经由MosDNS完成,且geoip和geosite文件是同源文件,没必要重复对域名分流两次。
  • 点击应用配置。
这样配置的好处是,不用对GEOIP,CN进行no-resolve处理,不需要OpenClash进行兜底规则配置,简单粗暴,也就不用自己动手去修改配置文件,同时也对Dnsmasq的依赖程度降到了最低。

🤗 总结归纳

执行结果直接上一张DNS泄露检测的成果图吧:
notion image
notion image
国内DNS泄露基本上是解决了。出乎意料的是也没有出现经常看到的IPv6容易造成DNS泄露的问题。
我常用的DNS,国内还是会选择阿里巴巴(Alibaba)或者腾讯(dnspod),因为提供DOH,甚至可以提供H3,不使用运营商的DNS主要就是因为无法提供加密DNS,使我访问的网站可以清晰的被ISP运营商看到,而且很多时候会被劫持到反诈;国外的话主要使用Cloudflare(赛博菩萨)或者NextDNS,最多再从AdGuard或者9.9.9.11中选择一个。IPv6的话没必要单独配置IPv6地址的DNS,一般来说大部分DNS服务器都是IPv4和IPv6双栈模式,同一个服务器也可以解析IPv6的请求。在DNS的选择上,可以参考我的这篇文章《国内外DNS推荐列表
目前这套OpenWRT环境下的配置,在AdGuard Home开启乐观缓存(Optimistic caching)的情况下,DNS请求解析时间也可以接受,处理时间在14ms左右,最低可以达到9ms左右:
notion image
当前以上这些数据也仅供参考,如果有什么问题,可以在评论区回复。

查询DNS泄露的网站

一般来说,以ipleak为例,如果全部300次请求都没有产生泄露,那么就大概率没有DNS泄露。
最后,确保DNS泄露只是在一定程度上避免ISP或者其他组织机构对网络的劫持以及对科学上网的审查,并不能完全避免,因为还存在其他的方法,例如SNI嗅探、WebRTC泄露、浏览器指纹等等。

📎 参考文章

💡
有关DNS的问题,欢迎您在底部评论区留言,一起交流~
在OpenWRT上使用Neovim可以去掉Youtube Music视频的油猴脚本
Loading...