dnsmasq & systemd-resolve



Ubuntu 20.04。试图继续搭建一个 WireGuard Hub,但是这次考虑到 DNS 转发的性能问题,决定在Hub上搭一个 dnsmasq ,这样 DNS 解析结果可以被缓存下来,能够提升访问性能。

不记得从哪个版本起,Ubuntu 不再默认安装 dnsmasq ,而靠 systemd-resolve 协调管理本机的 DNS 解析。我只用 Ubuntu 当 Server,所以一般直接读 VPS 或者云服务商的 DNS 列表,干掉 systemd-resolve,安装 dnsmasq 接管解析。

但是这次我不想管系统的设置,只希望 dnsmasq 纯转发 WireGuard 接口的 DNS 请求。于是遇到了一个奇怪的问题,当我启动 dnsmasq 时,本机 DNS 解析挂了。dnsmasq 配置如下

仔细观察,结果发现,默认的时候 resolve.conf 里 nameserver=127.0.0.53,而dnsmasq启动后变成了 127.0.0.1。但是我 dnsmasq 根本没有接管 127.0.0.1。

排查了 systemd-resolve 的设置,没有相关的选项。

回过头来看resolvconf,结果在 /etc/resolvconf/update.d/dnsmasq 里看到了更新 resolv.conf 的代码。但是出于系统完整性和可维护性考虑,这个脚本肯定是不能动的,而这个脚本里也没有提供任何方法终止执行,只能再去别的地方找。

dnsmasq 是我在 WireGuard PostUp / PreDown 里调用启动和停止的。所以看启动脚本 /etc/init.d/dnsmasq 。里边有 start_resolvconf 方法。

显然,只有让第一个 for 的块能退出,才能解决问题。后边两个 if 都不能碰。

解决方案是,在 /etc/default/dnsmasq 里加入 DNSMASQ_EXCEPT=no 。

此外,这个脚本里还有一个 IGNORE_RESOLVCONF,单加没用,我是两个都加了。

有点简单粗暴,因为我 dnsmasq 本身default里没有加任何设置,所以不怕被覆盖。



dnsmasq & systemd-resolve by @sskaje: https://sskaje.me/2021/07/dnsmasq-systemd-resolve/