在VPS上使用AdGuardHome自建DNS服务器
今天趁着黑五打折,入手了Adguard永久版,感觉效果还是相当不错,网页清爽了很多(其实免费的Adblock等浏览器插件也有这个功能),主要是在手机上也能过滤掉浏览器以及一些APP中的广告,不过软件配置起来还是有一点点麻烦,也不方便分享给同学朋友使用,今天还了解到他家有一个Adguard home的软件,可以部署在路由器上,建立一个DNS服务器,也能起到过滤广告的作用。
除了在路由器上部署,我们还能在VPS上使用AdGuardHome建立一个公共DNS服务器,这样不需要安装应用,也不需要在特定的网络下,只需要设置好了DNS就能去除烦人的广告了,正好有一台香港的机器,1M带宽做不了太多事情,但是作为DNS服务器使用就绰绰有余了。
不过要注意 在中国大陆使用53端口建立DNS服务器是需要资质的 而且貌似不备案也不会开放UDP53端口…(曾看有人发帖说因为自建公共DNS被请喝茶了)。
还有一点,国内很多地方对于境外的DNS请求一视同仁的劫持了,表现就是DNS服务器修改成自己的服务器后,本地nslookup,远程服务器却收不到请求。所以建议有条件的话,还是尽量使用DoH。
因为可能被利用来进行攻击,很多运营商封锁了53端口,建议先测试一下53端口是否开放,如果发现打不开可以向服务提供商申请解封。或者不使用传统的53端口的DNS而仅使用DoT/DoH(DNS over TLS/DNS over HTTPS),正好一步到位,既屏蔽广告,也防止了DNS污染。
AdGuardHome是什么
工作方式
AdGuard Home 作为 DNS 服务器以重新路由跟踪域到 “黑洞”,从而防止您的设备连接这些服务器。其是基于我们的公共 AdGuard DNS 服务器之上— 这两者共用大量的常用代码。
和公共AdGuard DNS的区别
运行您自己的 AdGuard Home 服务器比使用公共 DNS 能做得更多: 决定某些服务器是否应该被拦截; 监控您的网络活动; 添加您自己的过滤器规则 。 未来,AdGuard Home 将不止是一个 DNS 服务器。
安装Adguard home
可以访问AdGuardHome的项目主页查看详情。
这里我直接使用官方的脚本来安装了 curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh,官方还提供了手动一步步安装,docker部署,编译安装等方式,感兴趣的可以自己去看看。
脚本一键下载了压缩包,解压到指定的目录中并创建了守护进程然后开启了AdGuardHome,可以看到此时程序已经开始运行了,我们可以直接前往访问3000端口,配置页面还是相当友好的,完成基础配置后我们便可以登录仪表盘了。
配置AdGuardHome
DNS配置
因为我们建立的dns服务器只是递归dns服务器
我把上游DNS服务器设置成了1.1.1.1和8.8.8.8,并开启了并行请求,这里其实没必要使用DoH,因为服务器在墙外,不过要是服务器在大陆地区,建议这里使用Cloudflare的DoH查询,可以避免污染。
1.权威DNS:
权威DNS是经过上一级授权对域名进行解析的服务器,同时它可以把解析授权转授给其他人,如COM顶级服务器可以授权dns.com这个域名的的权威服务器为NS.ABC.COM,同时NS.ABC.COM还可以把授权转授给NS.DDD.COM,这样NS.DDD.COM就成了ABC.COM实际上的权威服务器了。平时我们解析域名的结果都源自权威DNS。比如dns.com的权威DNS服务器就是帝恩思的ns1.dns.com ns2.dns.com
2.递归DNS:
负责接受用户对任意域名查询,并返回结果给用户。递归DNS可以缓存结果以避免重复向上查询。我们平时使用最多的就是这类DNS,他对公众开放服务,一般由网络运营商提供,大家都自己可以架递归DNS提供服务。递归DNS一定要有可靠的互联网连接方可使用。比如谷歌的8.8.8.8和8.8.4.4以及114的114.114.114.114和114.114.115.115都属于这一类DNS。你本地电脑上设置的DNS就是这类DNS。
拦截模式使用了默认模式。
基础配置
我们可以先简单的设置一下过滤规则,方便之后的测试,过滤规则可以参考 https://wsgzao.github.io/post/adguard/ 里面分享的。
测试
将电脑的DNS服务器地址修改成我们自己的服务器的ip并进行请求,然后可以去AdGuardHome的面板看看查询日志。
这里我尝试进行了一下dns查询,发现结果还是受到了污染。返回的结果是个德国的ip,而且也ping不通。 (也算是直观的体会到了dns污染)
使用境外DNS存在的问题(网站访问缓慢)
虽然使用8.8.8.8或者是1.1.1.1速度并配合DoH可以避免DNS污染,但是实际使用后发现访问网站的速度慢了很多,尤其是一些大网站,查看解析记录发现,由于这些网站使用了CDN,递归DNS服务器使用境外的上游DNS服务器请求得到的IP也是递归服务器当地的CDN IP,这样访问自然缓慢了,如下图,使用8.8.8.8解析的时候可以看见解析出来的ip都是阿里云亚洲地区的服务器,而不是大陆境内的服务器。
另外,我发现,如果使用了EDNS,并使用8.8.8.8等支持EDNS的服务器,部分域名可以正常的解析到大陆的ip,但是并非所有的网站都通用,如果想要让大陆的网站都能正常的访问,建议还是使用下面的方法.
解决方法有两种:
- 直接使用大陆的DNS服务器
- 按黑白名单对解析进行分流
如果不介意DNS被污染,可以直接使用大陆的DNS服务器如223.5.5.5,119.29.29.29等。
如果想去广告的同时避免污染,又希望访问能够快一些,可以参考v2ex里面的一篇文章中提到的分流的做法,对于部分域名走大陆的DNS,而另外一部分走境外DNS。
我使用了ChinaWhiteList,即除大陆白名单以外全部走境外DNS。
第一次尝试设置dns列表,由于列表过长,复制进去的时候网页卡了好几秒,上传的时候还出现了413错误——请求太大。因为nginx默认限制上传大小为1MB,所以我们需要先修改nginx的配置文件。 nano /etc/nginx/nginx.conf,在http{}里面加上 client_max_body_size 20m; ,然后 systemctl restart nginx 即可。
另外,查看AdGuardHome的配置文件,我还看到了一个 upstream_dns_file 的配置项,也就是说手动修改的话,也可以直接在这里填写文件的绝对路径,手动修改完毕之后需要使用systemctl restart AdGuardHome.service重启一下服务,使用文件的方式要麻烦一些,但是看上去要整洁一些。
关于使用EDNS
第二天我注意到,AdGuardHome还提供传递EDNS的选项,可以在向权威DNS服务器请求的时候传递客户端的IP,于是我想着这个功能能否实现DNS智能解析,实现更友好的CDN体验,经过搜索资料发现确实是可以的,DNSPOD的119.29.29.29与阿里的223.5.5.5都已经支持EDNS了(自然,他们的DoH服务器也已经支持了)。
传统DNS解析,不判断访问者来源,会随机选择其中一个IP地址返回给访问者。而智能DNS解析,会判断访问者的来源,为不同的访问者智能返回不同的IP地址,可使访问者在访问网站时可获取用户指定的IP地址,能够减少解析时延,并提升网站访问速度的功效。
更多内容可以查看阿里的文档介绍了EDNS的原理。
关于EDNS的效果可以使用命令dig +subnet=220.249.50.1 12306.cn @119.29.29.29来看看,可以发现传递不同的子网地址返回的结果也是不同的(前提是网站支持)。
我们只需要前往AdGuardHome的设置页面,DNS设置->勾选 **使用客户端的子网地址(EDNS)**即可。
关于代理服务器去广告
之前我发现配置好AdGuardHome后,如果 使用代理服务器上网,广告依旧会出现,查看解析记录发现通过代理访问时,压根就没有向DNS服务器请求。原因是一些代理软件为了避免污染,会将解析交给代理服务器进行。解决的方法也很简单,只需要前往代理服务器上修改DNS服务器地址为你搭建AdGuardHome的服务器的ip即可。(不过由于这个依旧会出现CDN的问题,所以建议服务器之间不要离得太远,我的两台服务器都在香港,所以表现非常优秀。
配置DoH
为了能够避免解析结果被污染以及不使用53端口,我们可以尝试对DNS请求加密,这里用了DoH。
关于DNS污染的介绍这篇文章写的很好,可以学习学习。
另外,有人提到现在支持DoH的设备不多,所以我们还可以使用DoT——安卓上被称为私人DNS,来实现全局使用加密DNS。
DoT
全称是 DNS over TLS,是基于 tcp 传输层协议的,默认端口是 853。因此在具体使用中也很容易被 GFW 干扰,只要重点监控和屏蔽掉 853 端口的流量即可达到目的。
DoH
全称是 DNS over HTTPS,是基于 https 应用层协议的,从而让 GFW 无法区别于正常的 https 流量,但是目前提供该服务的站点还是比较少,最出名的就是 Cloudflare 的 1.1.1.1。
申请证书
我们首先需要tls证书,这里还是使用certbot直接签发let’s encrypt的证书。
1 2 |
apt-get install nginx certbot python3-certbot-nginx certbot --nginx |
#之后填入你的邮箱以及要签发证书的域名就可以了 (记得把域名解析到服务器上)```
证书的路径在 /etc/letsencrypt/live/dns.example.com/ 中。
配置加密
前往adguardhome的面板设置->加密设置 配置加密
之后我们还要对这个https端口(444)进行反代,编辑nginx站点配置文件 /etc/nginx/site-enable/xxx
增加下面的规则 记得写在443端口的配置括号内
location /dns-query { # 这里的 Path 可以是任意 proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_buffering off; proxy_redirect off; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记得修改端口 proxy_pass https://127.0.0.1:444/dns-query; # 这里的 Path 必须为 dns-query }
之后 systemctl restart nginx重启一下nginx,在访问 dns.example.com/dns-query看看
Chrome使用DoH
当前Chrome版本(86)可以直接在设置页面里面找到安全DNS设置,使用如图格式填写即可。
Firefox Edge等浏览器的设置都几乎相同,另外为了测试,我把网络适配器选项里面的DNS改回了223.5.5.5.
可以看到,我们虽然在适配器选项里面设置了DNS服务器为223.5.5.5,但是实际Chrome里面访问网站使用的是DoH服务,依旧使用了我们自己的dns服务器。
之后我们就对过滤规则进行配置,然后享受干净的浏览体验了。
对比一下
-
使用Chrome 并使用DoH 打开新浪网
-
edge 使用默认dns打开的新浪网
-
edge 修改dns为我们的AdGuardHome服务器(53端口)之后打开新浪网
可以看到,无论是使用DoH还是直接使用传统的DNS,当我们把DNS服务器换成AdGuardHome服务器后,效果都相当的明显。另外,使用了DoH之后,像是http://raw.githubusercontent.com/这种仅被DNS污染的网站也可以正常打开了。
-
关于DoT(安卓上的“私人DNS”)
现在很多设备都不支持DoH,浏览器,尤其是手机上的浏览器也只有少数几款支持(我只看见Chrome可以设置DoH),不过我在手机(安卓系统)上看到了私人DNS这个设置,经过搜索,在知乎的一篇文章中了解到这个“私人DNS”就是DoT(DNS over TLS),设置之后如果DNS服务器支持,那么手机默认会使用DoT来进行解析。而在我们设置AdGuardHome启用加密的时候,DoT也会打开,使用853端口。我们只需要将私人DNS改成DNS服务器的域名即可,必须是你之前配置DoH的时候使用的域名。
“私人DNS”——DOT在设备没办法设置全局使用DoH的时候也不失为一个不错的选择,虽然我个人更加喜欢DoH(因为运营商都不知道你在进行DNS查询,DoT需要访问特定端口)。
过滤规则
可以使用下面这些过滤规则
- https://github.com/233Bazinga/AdGuardHome
- https://wsgzao.github.io/post/adguard/