【Server Geek】AdGuard Home 部署的一些坑点记录
很多玩机的都会自己部署 AdGuard Home 来做内网的 DNS 解析服务。一方面是提升 DNS 解析速度,另一方面也可以做局域网内机器的免广告或者是家长控制等。这篇文章说说我在部署 AdGuard Home 踩的一些坑点,以及 Docker 部署 AdGuard Home 的注意事项。
OpenWrt 开启 AdGuard Home
大多数人部署 AdGuard Home(下称 adh) 基本都是在 OpenWrt 中,现在主流的 OpenWrt 镜像基本都已经集成了,在 OpenWrt 中开启很方便,但是如果你的 OpenWrt 中还有别的服务要跑,那可能都跑在 OpenWrt 就没有那么方便了。
这里有两个东西值得关注:Dnsmasq、酸酸乳(不多解释,用的人都知道,不知道的不用也无需关注)。AdGuard Home 跟这两个跑在一起,会有一点麻烦。
先说第一个,在 OpenWrt 中一般都是用 Dnsmasq 来作为自己的 DNS 解析处理服务,如果你想开启 AdGuard Home,面临的问题就是端口冲突,两个服务都依赖对 53 端口的监听,当然在 OpenWrt 中的 AdGuard Home 插件的作者也对此做了处理,允许配置端口重定向,其中有三个设置项。
这三个设置项以及分别的效果是:
- 作为dnsmasq的上游服务器 - dns 请求先到 dnsmasq 处理完之后,再到 adh 处理
- 使用53端口替换dnsmasq - dns 请求不走 dnsmasq 直接到 adh 处理
- 重定向53端口到adguardhome - dns 请求的流量直接通过防火墙规则导入到 adh 处理
关于这三个设置项的一些解释,感觉这篇文章是比较浅显易懂的,对Adguardhome的重定向配置研究的一些心得-OPENWRT专版-恩山无线论坛,值得一看。
其中 1、3 都是要有数据转发,一个是 dnsmasq -> adh,一个是防火墙直接进行流量转发,理论上说性能肯定是不如 2。但是抛开剂量谈毒性,那都是耍流氓。1、3 的转发,如果你是 x86 的软路由,性能上的损失基本也可以忽略不计,如果是那种盒子或者是路由器芯片就要谨慎了。说完了性能上的问题,说说别的坑。如果选 3,不做其它设置,这个时候你会发现 adh 中是无法区分客户端流量的,看到的地址都是 127.0.0.1,因为防火墙规则导过去的流量,源 ip 都会变成本地回环地址,就要额外改 iptable 规则,而对于 iptable 这种东西来说,专业的网维工程师都不想改这东西,太恶心,所以 3 这个选项是最不推荐的。
所以考虑上述因素,这三个选项的选择排序应该是 2 > 1 > 3 的。这里我选了 2,真男人就要极致性能,虽然我是 x86 上的虚拟机,其实 1 应该也没啥性能损耗。然后我又顺利地掉入下一坑。
开启 adh 之后,需要设置 adh 的监听 ip。当然如果你选择所有 ip,就不会掉到我的这个坑里,但是会有公网暴露的风险,所以我直接选了局域网 ip 监听,防止公网暴露。美滋滋的配置完 adh 之后,发现我的 OpenWrt 上的其它服务 HTTP 请求不正常,比如酸酸乳,帕斯沃的百度测速,直接一个失败,排查过程就不讲了,其实就是因为选了 2,53 端口替换了 dnsmasq,导致 OpenWrt 系统的 DNS 解析被 adh 接管,但是 adh 上我选了局域网 ip 监听,没有监听本地回环地址(127.0.0.1),所以导致本机 DNS 请求没人处理,所以 HTTP 这些请求都会有问题。
于是在 adh 的配置文件里,bind_hosts
下边加上 - 127.0.0.1
,这回正常了。以上是跟 Dnsmasq 的羁绊,还不算很多,但是如果不是很了解,只是通过现象瞎找方法,那估计要忙活一阵子了。
下面说说酸酸乳,酸酸乳主要是关于模式选择的问题,这玩意跟 adh 放在一个地方,你会惊奇地发现,gfw列表
和 绕开大陆ip
这两个模式,会跟 adh 产生羁绊,导致你的流量不能有正确的走向,比如本来应该是国内的,但是走了你的科学,或者本来应该走科学的走了你的国内,或者应该走 adh 的,在 adh 看不到请求,等等。具体可以查看插件仓库简介,作者其实在这里有说,具体在 关于ssr配合
这一段。
无论选择那个选项,其实会发现都是耦合在一起的,互相有依赖,这并不合理,而且也并不满足我们自己根据需求调整各个工具使用的需求。
所以综上所述,其实 AdGuard Home 的最佳实践就是不要跟酸酸乳放在一起部署。原因就是酸酸乳在 OpenWrt 上使用的场景一般都是透明代理,接管所有端口流量,这样方便科学,而其它设备的 dns 请求也会被它接管,这是不合理的,所以这两个在一起,正常 dns 请求的流量会被酸酸乳接管,而造成麻烦。
所以搞了一圈,最终选择不在 OpenWrt 中开启 adh,而是自部署。
Docker 部署 AdGuard Home
Docker 部署的话自然涉及网络模式选择,直接说答案,最佳实践:Host 模式。adh 是支持端口映射部署的,但是跟防火墙重定向流量一样,端口映射之后,会发现在 adh 中无法区分客户端来源,都是显示 Docker 子网的网关 ip,类似 172.20.0.1 这种。所以就老老实实 Host 模式部署就行了。
这里如果查看其它教程,会发现他们说因为本机 systemd-resolve 服务占用了 53 端口,所以部署 adh 的时候,会导致端口冲突,adh 服务异常。这些基本也都是半吊子,操作系统不知道比这些人高到哪里去了,因为当你 netstat -antp | grep 53
查看 53 端口占用的时候,会发现 systemd-resolve 监听的是 127.0.0.53:53,不是监听的 127.0.0.1,所以只需在 conf/AdGuardHome.yaml
配置文件中,在 bind_host 那里不要监听 0.0.0.0 而是监听 127.0.0.1 和本地局域网 ip 就可以了,这样完全不用停用 systemd-resolve 服务。
配置文件的局部示例(包含 v6 这样 v6 dns 也可以被 adh 处理,其中局域网 ip 查看 adh 所在设备的局域网 ip 就好):
bind_hosts:
- 127.0.0.1
- 192.168.12.8
- ::1
- fd87:1111:63b8:0:be24:1111:1111:1111
注意防火墙
这些我都配置好之后,发现在 adh 上看不到我的 dns 请求,后来想起来,我机器上有防火墙,然后把防火墙规则加一下,对局域网内 ip 放通 53 端口,adh 就正常了。 完整的放通需要,放通如下端口:
Ports mappings you may need:
- -p 53:53/tcp -p 53:53/udp: plain DNS.
- -p 67:67/udp -p 68:68/tcp -p 68:68/udp: add if you intend to use AdGuard Home as a DHCP server.
- -p 80:80/tcp -p 443:443/tcp -p 443:443/udp -p 3000:3000/tcp: add if you are going to use AdGuard Home's admin panel as well as run AdGuard Home as an HTTPS/DNS-over-HTTPS server.
- -p 853:853/tcp: add if you are going to run AdGuard Home as a DNS-over-TLS server.
- -p 784:784/udp -p 853:853/udp -p 8853:8853/udp: add if you are going to run AdGuard Home as a DNS-over-QUIC server. You may only leave one or two of these.
- -p 5443:5443/tcp -p 5443:5443/udp: add if you are going to run AdGuard Home as a DNSCrypt server.
具体端口含义也在上边了,也可以查看 Docker Hub 上的介绍,根据自己需求放通就行。
总结
- 如果有酸酸乳需求的,不要把 adh 和酸酸乳放同一个设备上,要分开部署;
- Docker 部署的时候要用 Host 模式,不要监听 0.0.0.0,写 127.0.0.1 、::1 和 局域网 v4 v6 的 ip 就好,可以避免跟系统服务端口冲突,也可以避免公网暴露风险
- 注意自己的防火墙设置,要保证 53 端口畅通,当然如果你还使用其他服务,要把其它需要的端口也要放通