Linux 上配置 DNS 踩坑记
最近看到了一篇谁动了我的 DNS 解析?(重制版),突然想起自己上次在高铁上因为没有把 dns 改成路由器提供的 dns,导致无法找到上网认证的经历,于是决定好好配置一下 dns。
由于众所周知的原因,ISP 提供的 DNS 服务器通常不是很靠谱,因此我用 dnsmasq 和 dnscrypt-proxy 在本地跑了个 dns 服务器。然而,一些内网地址却只能通过网络接口的 dns 服务器提供解析(比如上网认证的页面)。因此,我们希望当查询 dns 时,可以先询问本地的 dns 服务器,如果返回错误再询问接口提供的 dns。
我目前的方法是在 NetworkManager.conf
中设置
dns=none
,关闭 systemd-resolved
,手动在
resolv.conf
中设置 dns 服务器为 dnsmasq
的监听地址。显然如果遇到的上网认证或者需要通过 VPN
访问内网设备之类的情况就会挂。
于是,配(zhe)置(teng) DNS 之旅就开始了。
NetworkManager
注意到
NetworkManager 可以配合 dnsmasq 使用,只需要将 dns
设置为
dnsmasq
即可。 编辑
/etc/NetworkManager/NetworkManager.conf
: 1
2
3
4# Configuration file for NetworkManager.
# See "man 5 NetworkManager.conf" for details.
[main]
dns=dnsmasqdnsmasq.service
,将 /etc/dnsmasq.conf
软链接到
/etc/NetworkManager/dnsmasq.d/dnsmasq.conf
,然后重启
NetworkManager.service
。大功告成!本文就写到这里,感谢阅读。
还没结束!别忘了标题是什么!
dnsmasq 的分流和 hosts
的功能一切正常。然而,当我查询了几个我经常访问的域名时,dnsmasq 的返回和
dnscrypt-proxy 的返回值并不一样。 1
2
3
4
5
6
7
8
9
10$ dig github.com @127.0.0.1
...
;; ANSWER SECTION:
github.com. 600 IN A 20.205.243.166
...
$ dig github.com @127.0.0.1 -p 5533 #dnscrypt 的端口
...
;; ANSWER SECTION:
github.com. 21 IN A 140.82.121.3
...,翻过一大堆
,找到: cached github.com is xxx
1
2
3May 9 22:24:38 dnsmasq[14956]: forwarded github.com to 127.0.0.1#5533
May 9 22:24:38 dnsmasq[14956]: forwarded github.com to 192.168.1.1
May 9 22:24:38 dnsmasq[14956]: forwarded github.com to fe80::1127.0.0.1#5533
确实是唯一的服务器。网上有人说 dnsmasq
会把网络链接提供的 dns 通过 dbus 发送给 dnsmasq,dnsmasq 将这两个 dns
服务器与我指定的本地 dns 合并,同时向 \(3\) 个 dns 服务器询问。dnsmasq
会直接返回了较快返回的那个而因为本地 dns 最后用的是 cloudflare 的
doh,因此速度较慢,没有被 dnsmasq 使用。
查阅了互联网发现并没有设置优先级之类的选项。因此我抛弃了在 NetworkManager 中使用 dnsmasq 的想法。(还有一个原因是听说 NetworkManager 拉起来的 dnsmasq 会忽略部分配置文件,但不知道是真是假,我也懒得验证了)
systemd-resolved
有请下一位候选人!
systemd-resolved!
虽然之前配置 dnsmasq
时因为端口冲突直接关掉了,但其实让这两位共存也不难。 将 dnsmasq
改个端口: 1
2
3
4$ vim /etc/dnsmasq.conf
...
port=5353
.../etc/systemd/resolved.conf
中设置 dns 服务器: 1
2[Resolve]
DNS=127.0.0.1:5353 [::1]:5353
DNS requests are sent to one of the listed DNS servers in parallel to suitable per-link DNS servers acquired from systemd-networkd.service(8) or set at runtime by external applications.
看来这个也没办法满足我们的要求。看来这个问题目前没有解决方案,本文到此结束。
然而测试一下,神奇的事情发生了: 1
2
3
4
5
6
7
8
9
10
11$ dig github.com
...
;; ANSWER SECTION:
github.com. 600 IN A 20.205.243.166
...
$ dig github.com
...
;; ANSWER SECTION:
github.com. 22 IN A 140.82.121.4
...1
May 10 14:58:52 dnsmasq[1316]: reply github.com is 140.82.121.4
总之就是这么神奇的解决了。那么本文就这样结束了。