日志
- 2023-03-29:新增测试DNS缓存设置的目标。
前言
本系列教程所配置的网络均为Ipv4网络,所以并不适合使用Ipv6的小伙伴。
在《NAS系列 基于Clash内核的策略分流方案》中,我们描述了一种基于Clash内核的透明代理网络结构,其中DNS服务器这一环需要依赖2个AdGuard Home。根据官方仓库的描述,AdGuard Home是一个免费、开源、功能强大的全网广告和跟踪器屏蔽的DNS服务器;它会将跟踪域重新路由到“黑洞”,从而防止我们的设备连接到跟踪域的源服务器。
如果你已经深刻地理解《NAS系列 基于Clash内核的策略分流方案》所介绍的原理,光从上述简单介绍就可以感受AdGuard Home(或者类似的应用)在该网络结构中的重要地位。不过,对于小白用户而言,AdGuard Home的作用还是比较晦涩难懂的。
本文的主要目的是带大家了解AdGuard Home在透明代理网络中是如何发挥作用的。学习完本文的内容后,你应该会对以下知识点更加了解(尽管之前的文章也有提及):
- DNS是如何工作的
- DNS分流管理和DNS加密与网络安全的关系
- 基于DNS的广告屏蔽原理
我会尽量讲得底层一些,避免单纯地讲解“怎么配置某个项目”而导致大家配置时一知半解。废话不多说,咱们开始喽!
DNS分流
我们用一个虚拟场景来说明DNS分流的特点和优势。比如,现在你有3个ADGuard Home作为DNS服务器,分别记为ADG-1/2/3。你会使用3种不同的网络类型,分别记为网络类型-1/2/3;你希望不同网络类型的流量走不同的DNS服务器。同时,你也希望在联网时总是屏蔽广告。问:应该如何设计DNS分流方案以满足上述需求?
其实,这个问题的答案是显而易见的——对于某个DNS服务器,只允许特定网络类型、阻止其它网络类型和总是阻止广告即可:
总之,我们需要DNS服务器同时具有DNS解析和DNS阻止的功能。这也是我们使用ADGuard Home来搭建DNS服务器的主要前提。
首先,ADGuard Home可以同时自定义多个DNS上游服务器(就是那些真正可以进行DNS解析的服务器):
所以DNS解析不成问题。这里还有一个额外好处——DNS加密。“DNS泄露”的本质是我们不信任某些DNS服务器。基于DNS over TLS(DoT)以及DNS over HTTPS(DoH)这两种方式,使用一些加密DNS服务器可以较好地避免DNS劫持,从而减少DNS污染的概率;具体原理和ssh差不多,运用了不对称性加密的技术手段。
此外,基于基础的adblock规则和Hosts语法,ADGuard Home可以设置拦截名单,阻止匹配DNS拦截清单的域名:
所以DNS阻止不成问题。我们只要在各ADGuard Home中将广告域名和非目标域名的相关规则添加到DNS黑名单,即可完美实现精准的DNS分流。实际上,DNS黑名单结合DNS白名单、自定义规则等功能,可以实现更灵活和精细的DNS管理。
此外,ADGuard Home还有很多比较贴心的设置,比如仪表盘数据可视化:
交互式查询日志:
值得一提的是,这里的amdc.alipay.com
有多个IPv4 IP地址,很可能是因为alipay.com
(支付宝)使用了CDN,所以有很多个泛播IP,不一定是DNS污染。要注意区别喔!
甚至还提供DHCP功能(虽然我不需要用):
感觉棒棒哒 (ฅ´ω`ฅ)
Clash场景分析
回到《NAS系列 基于Clash内核的策略分流方案》所描述的场景,就很容易理解了;其实就是上述举例的简化版本。我们只要设置双ADGuard Home作为DNS服务器——第1个ADGuard Home添加公共DNS上游服务器,拦截公司域名和广告域名;第2个ADGuard Home添加专属DNS上游服务器,拦截非公司域名和广告域名即可。当然,在实际操作中,你应该并不介意非公司域名在公司专属DNS上游服务器进行DNS解析,故你可以忽略对非公司域名的拦截以简化规则(有时候写规则是挺难的)。
根据之前的Clash配置文件,我们可以这样设计双ADGuard Home:
假设我们的路由器IP地址是192.168.1.1
,双ADGuard Home就安装在路由器上。配置不同的管理端口(3001 vs. 3002)。配置不同的DNS请求监听端口(5336 vs. 5335)。这样,就可以完美契合此前Clash配置文件的DNS模块中关于DNS服务器的设置了:
# 之前写的路由器IP地址是192.168.1.254。大家理解这个意思就行。
nameserver:
- 192.168.1.1:5336 # AdGuard Home 01,上游DNS服务器为公众所有。
fallback:
- tcp://192.168.1.1:5335 # AdGuard Home 02,上游DNS服务器为公司专用
值得注意的是,nameserver中的192.168.1.1:5336
其实是udp://192.168.1.1:5336
;而fallback中的却是tcp://192.168.1.1:5335
。关于UDP协议和TCP协议的主要区别可参考视频《一条视频讲清楚TCP协议与UDP协议-什么是三次握手与四次挥手_哔哩哔哩_bilibili》,讲解生动,清晰易懂。简而言之,TCP协议类似于“打电话”,连接和关闭的过程需要通讯双方都确认;优势是连接可靠性和数据完整性高,缺点是资源占用高、速度更慢。而UDP类似于“写情书”,信我只管投出去,对方看不看我管不了;优势是资源占用低、速度更快,缺点是连接可靠性、数据完整性低。
在本实例,nameserver
承载了大部分网络连接的DNS解析,且上游DNS服务器一般在国内,故选择UDP协议可以保证较快的DNS解析速度;这也是一般用户的选择。而fallback
主要承载我们特别关注的域名(caiwu.com
等公司域名),为了保证DNS解析的稳定性和完整性,慢点无所谓,所以选择TCP协议。这其实算是一个小技巧吧!大家也可以尝试一下将nameserver的协议改为TCP或fallback的协议改为UDP,看看对响应速度的影响明不明显。据我测试,fallback的协议改为UDP会很快导致网络连接不通,可能与DNS污染有关。这部分内容我只是推测,欢迎大佬们批评指正!
另外,我们会采用Docker的方式来安装ADGuard Home。当然,你其实可以在OpenWrt里直接安装一个ADGuard Home,不过我不准备那样做。总之,不管你用什么方式安装,最后有2个可用的ADGuard Home就行。
Docker安装双ADGuard Home
请按《NAS系列 在PVE中搭建OpenWrt虚拟机》中“安装Docker”小节的相关教程准备好Docker/Docker Compose环境。
对于学习或使用过我Docker教程的小伙伴,安装Docker应该说是轻车熟路了!本教程的测试环境如下:
uname -a # Linux OpenWrt 5.15.86 #0 SMP Thu Jan 5 23:01:34 2023 x86_64 GNU/Linux
docker --version # Docker version 20.10.22, build 3a2c30b
docker-compose --version # Docker Compose version v2.15.1
根据《NAS系列 在PVE中搭建OpenWrt虚拟机》,我将10G虚拟硬盘挂载到了/mnt/sda1
目录(也是Docker根目录的位置)。我们创建工作目录:
mkdir -p /mnt/sda1/application/{adg1,adg2}
其中,adg1
托管1号ADGuard Home,adg2
托管2号ADGuard Home。由于默认端口号有所冲突,两个ADGuard Home要分别安装。
1号ADGuard Home
进入1号的工作目录:
work=/mnt/sda1/application/adg1; cd $work
创建docker-compose.yml
并添加以下内容:
services:
app:
# 1号ADGuard Home; 面板端口3001,监听端口5336
image: adguard/adguardhome:latest
container_name: adg1 # container name
restart: unless-stopped
# ports:
# - 3000:3000
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
network_mode: "host"
因为ADGuard Home是直接托管路由器的端口的,所以直接侵入宿主机的网络比较保险些。我们使用network_mode: "host"
,该设置表明我们直接使用宿主机的网络,这时宿主/容器不分彼此,不存在“端口映射”,故-p 3000:3000
的命令是不能使用的;也不需要使用,此时宿主/容器共用一套端口。
ADGuard Home的默认管理端口是3000
,咱们直接访问http://<OpenWrt IP>:3000
(之后都以http://192.168.1.1:3000
为例),首先会看到欢迎页面:
步骤2最重要。请将管理界面换为3001
,DNS监听接口改为5336
。你可以选其它未被占用的端口,记得是哪个就行:
用户名和密码,可以使用bitwarden之类的密码工具生成强密码(比如NPHE7^#qbrZdq*JnSaj5
),这没啥好讲的:
一直下一步,直到第5步即可打开仪表盘:
由于这是一个新建的ADGuard Home,从未进行过DNS解析,因此所有的相关记录数均为0
:
到这里,1号AdGuard Home就安装完成配置了!我们暂时先不配置,先将2号ADGuard Home安装完再说。
2号ADGuard Home
和1号差不多。自己调整。
进入2号的工作目录:
work=/mnt/sda1/application/adg2; cd $work
创建docker-compose.yml并添加以下内容:
services:
app:
# 1号ADGuard Home; 面板端口3002,监听端口5335
image: adguard/adguardhome:latest
container_name: adg2 # container name
restart: unless-stopped
# ports:
# - 3000:3000
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
network_mode: "host"
其余步骤和1号基本相同,只是仪表盘监听接口为3002
,DNS监听端口为5335
。你也可以用其它端口,只是未被占用且与1号 ADGuard Home不一样即可:
至于其它Docker管理的常见技巧,可见《Docker系列 配置Docker全局环境》的“常用Docker命令”小节,不再赘述。
配置ADGuard Home
1号ADGuard Home
DNS设置
进入设置——DNS设置
进行配置:
我们先添加上游DNS服务器
。这里是我用的国内速度不错的加密DNS上游服务器:
https://dns.alidns.com/dns-query
tls://dns.alidns.com:853
https://dns.pub/dns-query
tls://dns.pub:853
https://doh.pub/dns-query
tls://dot.360.cn:853
https://doh.360.cn/dns-query
https://223.5.5.5/dns-query
https://223.6.6.6/dns-query
有其它更好用的国内加密DNS服务器,也欢迎大家分享喔!
推荐并行请求
加快DNS解析速度:
Bootstrap DNS 服务器
写些权威的公共DNS服务器即可,不需要加密。我的选择是:
114.114.114.114
223.5.5.5
还可以测试上游DNS
。记得应用
配置:
DNS服务配置中,速度限制选为0
,意味着不限制次数。用软路由还差这点性能?
DNS缓存配置我只用了默认配置。因为咱们选的上游好,其实不用特别在意这边的配置:
最后的访问设置也默认即可:
注意,这里的不允许的域名
并不是过滤(实际上并未发生DNS查询),而是不显示查询(实际上发生了DNS查询)。要特别注意区别,不要随便添加域名在上面喔(除非你清晰地了解自己在做什么)!
DNS黑名单
首先当然是添加一些适合国内网络环境的广告规则了。我用的是这些:
# ADGuard DNS filter
https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
# CHN:anti-AD。非常出名。
https://adguardteam.github.io/HostlistsRegistry/assets/filter_21.txt
# easylistchina
https://easylist-downloads.adblockplus.org/easylistchina.txt
# adgk手机去广告
https://banbendalao.coding.net/p/adgk/d/ADgk/git/raw/master/ADgk.txt
# 大圣净化
https://raw.githubusercontent.com/jdlingyu/ad-wars/master/hosts
# 知乎过滤
https://raw.githubusercontent.com/zsakvo/AdGuard-Custom-Rule/master/rule/zhihu.txt
# 知乎严格版
https://raw.githubusercontent.com/zsakvo/AdGuard-Custom-Rule/master/rule/zhihu-strict.txt
# Google Host
https://raw.githubusercontent.com/googlehosts/hosts/master/hosts-files/hosts
# No Google
https://adguardteam.github.io/HostlistsRegistry/assets/filter_37.txt
有其它更好用的规则也欢迎大家提供喔!添加列表的方法挺简单的:
你也可以手动检查更新
,但没必要。默认的过滤器更新间隔是24h,你可以在设置——常规设置
中自定义:
最后,根据我们的场景,千万不要忘了在DNS黑名单里添加caiwu.com
和xiaoshou.com
这两个单位专属域名!我们可以添加自定义规则:
||caiwu.com^
||xiaoshou.com^
这样代表以caiwu.com
和xiaoshou.com
为后缀的所有域名的DNS请求都会被阻止。具体操作如下:
单位域名小伙伴们按实际情况填写即可,caiwu.com
和xiaoshou.com
只是一个示范。
2号ADGuard Home
DNS设置
和1号大部分是相同的。只有下面一些点不同:
- 上游DNS服务器:要填写单位专属服务器。比如(只是举个例子,请大家按实际情况填写):
https://dns.cloudflare.com/dns-query
https://dns.google/dns-query
tls://dns.google:853
tls://1.1.1.1:853
tls://1.1.1.1/dns-query
https://1.1.1.1/dns-query
tls://dns11.quad9.net
https://dns11.quad9.net/dns-query
https://jp.tiarap.org/dns-query
https://jp.tiar.app/dns-query
tls://8.8.8.8/dns-query
tls://8.8.4.4/dns-query
- Bootstrap DNS 服务器:写些权威的公共DNS服务器即可,不需要加密。我的选择是:
1.1.1.1
9.9.9.10
8.8.8.8
- DNS缓存:最近我正在测试一个DNS缓存的方案,主要是参考了《DNS TTL 值理解及配置 – Jamin Zhang》:
DNS缓存大小我直接设置了100M
(即104857600字节
,默认是4M
)。因为很多著名的国外网站并不会频繁地改动自己的IP,所以最大TTL值
设置得大一些问题应该不大,我使用的是作者推荐的86400s
=24h×3600s,即1天;最小TTL值
我暂时用的也是作者推荐的60s
。理论上该方案可以加快DNS解析速度。以后测试完再来更新体会。不在意的小伙伴选择默认设置即可。
DNS黑名单
简单添加一些针对国外地区的广告列表即可。其实不用太过在意,因为2号DNS服务器是解析公司域名,不太可能会包含广告。另外,如果有需要的话,可以添加国内常见域名;但不添加影响也不大,因为Clash对国内常见域名一般使用的是nameserver(即1号ADGuard Home)的返回结果:
我自己也写了一个chndomains_For_Adblock,大家也可以试用一下。其它设置就不重复描述了,自己尝试一下吧!
更新DNS缓存
有时候,我们修改OpenClash的设置后需要更新DNS缓存,一般按下列操作进行:
- ADGuard Home的
设置——DNS配置——DNS缓存配置
中点击清除缓存
:
- 清理OpenClash的Fake IP模式下的假IP缓存:
小结
本文咱们主要讲了配置双ADGuard Home对网络安全的必要性及相关的原理。大家和《NAS系列 基于Clash内核的策略分流方案》对照着看,理解还挺容易的。值得一提的是,虽然DNS屏蔽可以对付部分广告,但总体效果一般般;对于大多数用户而言,在浏览器里添加Adblock Plus插件的广告屏蔽效果会更好。具体机制以后有机会再介绍吧。
ADGuard Home的功能其实是很强大的,大家多多关注Adblock规则;我没讲到的选项都点开看看,了解一下。慢慢地就知道怎么使用了!
经过这里的设置,其实已经完成了使用OpenClash的基础准备。之后会进一步介绍如何在GUI中设置OpenWrt和OpenClash的选项。敬请期待!
扩展阅读
- Configuration · AdguardTeam/AdGuardHome Wiki:官方文档
- AdGuardHome 自建公共DNS服务器:远程ADGuard Home
---------------
完结,撒花!如果您点一下广告,可以养活苯苯😍😍😍
用过一段时间的ADG.. 后来觉得ADG能做的事情,dnsmasq已经能做了。 但是ADG的DHCP图形化界面还是挺好的。
是的,功能也比较完善些。反正用的是软路由,性能这么好,双ADGuard Home也可以接受