我使用 Lubuntu 17.04,当我连接到新网络时,NetworkManager 服务(子系统?)会执行一些配置操作。其中之一是将/etc/resolv.conf
文件(重新)设置为:
# Generated by NetworkManager
search some-local-domain-here
nameserver 127.0.1.1
至少这是我使用 DHCP 时得到的结果。有一个dnsmasq
实例在本地主机上侦听(下面提供了有关它的更多信息。)
现在,在某些网络上,并且非常一致地,在这种情况下无法解析名称;但如果我nameserver
用从 DHCP 租约 ( /var/lib/NetworkManager/dhclient-blah-blah.wlan0.lease
) 获得的实际名称服务器地址替换该行 - 解析工作正常。
问题:
- 造成这个问题的原因可能是什么?
- 如何强制 NetworkManager 配置的 dnsmasq 将名称解析请求实际转发到 DHCP 提供的 DNS 服务器? (请注意,它有时已经这样做了 - 当这个问题没有出现时)
附加信息:
本地DNS服务器是一个dnsmasq
实例,命令行如下:
/usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --clear-on-reload --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d
配置目录/etc/NetworkManager/dnsmasq.d
有一个文件,其内容是:
# Tell any system-wide dnsmasq instance to make sure to bind to interfaces
# instead of listening on 0.0.0.0
# WARNING: changes to this file will get lost if network-manager is removed.
bind-interfaces
答案1
大多数现代 Debian 相关发行版现在倾向于使用该/sbin/resolvconf
工具进行配置,/etc/resolv.conf
而不是直接编辑它。该工具将跟踪每个接口收到的 DNS 服务器信息,并根据文件中指定的顺序优先考虑 DNS 服务器设置/etc/resolvconf/interface-order
。
这样,您可以在打开 Wi-Fi 时获取一组 DNS 服务器设置,在插入网线时获取另一组 DNS 服务器设置,在启动 VPN 连接时获取第三组 DNS 服务器设置……而不会出现混乱的配置当您以非严格相反的顺序关闭它们时。另外,在这种情况下,您可以得到两种不同的机制(例如 NetworkManager 和dnsmasq
)来争夺真实的控制权/etc/resolv.conf
,这可能是
不过,resolvconf
是一个可选包。如果/sbin/resolvconf
您的系统上不存在,则您/etc/resolv.conf
可能处于 NetworkManager 的直接控制之下。但看起来dnsmasq
包中的大部分脚本都是假设/sbin/resolvconf
存在的情况下编写的 - 因此,如果没有它,您将依赖于可能无法充分涵盖所有情况的后备。您可能想尝试使用apt-get install resolvconf
或类似的东西安装它,并查看安装后 DNS 设置的行为方式。
如果您没有resolvconf
安装该软件包,恐怕 NetworkManager 会自行完成所有操作 - 在这种情况下,故障排除需要阅读 NetworkManager 的源代码,以了解它实际上如何决定要使用哪些 DNS 设置。resolvconf
不那么不透明。
在 (L)Ubuntu Zesty (17.04) 上启动后dnsmasq
,其启动脚本将运行此命令(假设resolvconf
已安装该软件包):
echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.dnsmasq
这表明/sbin/resolvconf
新的 DNS 名称服务器已在界面上可用lo
,并且它将更新真实的/etc/resolv.conf
.
/etc/resolv.conf
当发生此(或任何)更新时,/sbin/resolvconf
将运行位于/etc/resolvconf/update.d
.其中之一是/etc/resolvconf/update.d/dnsmasq
应该获取resolvconf
当时已知的所有非本地 DNS 服务器的列表,并将它们推送到,这显然是应该使用的/run/dnsmasq/resolv.conf
DNS 服务器列表。dnsmasq
每秒一次,dnsmasq
应该检查修改时间/run/dnsmasq/resolv.conf
并更新其配置。
但是,您的 dnsmasq 命令行表明您可能对默认设置进行了一些更改:您可能希望将 dnsmasq 选项替换--no-resolv
为--resolv-file=/run/dnsmasq/resolv.conf
... 或仅删除任何 NetworkManager 或 resolv.conf 相关的自定义设置,因为它看起来像默认设置的设置dnsmasq
已设计为resolvconf
以适当的方式与 NetworkManager 集成。
如果resolvconf
正在使用该工具,您将在 目录 中找到由所有各种可能的源提供的 DNS 服务器设置/run/resolvconf/interface/
。每个文件的内容将与真实的类似/etc/resolv.conf
。文件的名称将引用 DNS 服务器信息的来源,无论是特定网络接口的静态或 DHCP 配置,还是一般的 NetworkManager,或者本地 DNS 服务器的启动脚本。
之前,我提到过如果安装了命令行,该命令行将在dnsmasq
启动时执行。/sbin/resolvconf
如果您想暂时撤消该操作(以测试 DNS 在dnsmasq
绕过本地时是否正常工作),您可以使用以下命令来执行此操作:
resolvconf -d lo.dnsmasq
当您这样做时,最高优先级活动网络接口的 DNS 设置应该在实际的/etc/resolv.conf
.
如果您想让dnsmasq
启动脚本停止用“nameserver 127.0.0.1”行替换活动的 DNS 设置(无论是出于故障排除还是出于其他原因),显然添加DNSMASQ_EXCEPT=lo
即可/etc/default/dnsmasq
实现此目的。
但由于您的名称服务器行的值为 127.0.1.1,因此它可能是由 NetworkManager 直接编写的,并且我不知道如何修复该问题(如果resolvconf
超出了范围)。