在内网的树莓派上部署了 AdGuardHome,做 DNS 服务器的同时,也可以为内网所有设备过滤广告。本来嘛拦截了广告理应网络加载会更快,然而实际体验却很糟糕。网页加载要比之前慢得多。AdGuardHome 的面板显示的平均反应时间一度达到了 1000ms。1s 的延时还是会非常影响网络体验的。用 dig 命令看了下 DNS 查询的情况。不看不知道一看吓一跳,随便查询一个域名竟然废了四秒多!这怎么能忍受!

[图片已丢失]

看网上其他人的评价,并没有我这种龟速的情况。况且我的上游 DNS 已经更换为了国内几个大厂的 DNS 比如阿里的腾讯的,测试查询一般反应时间也才 50ms。本地这个结果肯定是不能接受的。最开始还想过要根据常用域名手动制作 hosts 直接重定向。但是 dnspython 这个库不好直接指定 dns 查询,adguardhome 的 query 日志又经过特殊加密,这条路困难重重。决定将其作为备用方案。接下来进入漫长的排雷环节。

首先考虑上游 DNS 中设置了谷歌等国外的 DNS,某些情况下会比国内的 DNS 慢。但是即便只留了一个阿里的 DNS,反应速度还是在秒级。

接下来定位过滤器,开了五六个过滤器,按理说查询 DNS 前会先读取本地的过滤器以寻找匹配项,过滤规则一多自然会反应迟钝。禁用了一个默认的 30k 条规则的配置,速度有那么一点提升,但还是在 1s 以上,完全不能接收。这跟平时用阿里 DNS 差了几个数量级啊。

后来发现了这货:

[图片已丢失]

原来,他会把每次查询的域名先交给他服务器做安全性检查,这在国内的互联网环境中完全是鸡肋,而且因为每次都要连接境外服务器,其延迟可想而知。果然禁用了这一项,速度嗖嗖的就起来了:

[图片已丢失]

即便是冷门的实验室官网的域名,也在 100ms 内解决了,对于常见的热门网站由于多设备频繁访问,会直接查询本地缓存。虽然基本只有可怜的差不多 60s 的缓存时间,但是一旦命中,就可以在 < 10ms 的时间响应。如果是过滤器中的域名,更是可以达到 < 5ms。终于,这个 AdGuard Home DNS 可以正式投入使用了。