![如何使用 systemd-resolved 排除 DNS 故障?](https://linux22.com/image/100226/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20systemd-resolved%20%E6%8E%92%E9%99%A4%20DNS%20%E6%95%85%E9%9A%9C%EF%BC%9F.png)
您将如何查找 所使用的 DNS 服务器systemd-resolved
以进行故障排除?
一般来说,我可以使用dig
和测试 中所示的 DNS 服务器/etc/resolv.conf
。 (或 Windows - ipconfig /all
+ nslookup
)。但是,当 resolv.conf 仅指向环回地址上的本地解析器守护程序时,该方法不起作用。 systemd-resolved下使用什么方法来显示它使用的DNS服务器?
(unbound
有我可以查看的配置文件。 dnsmasq
也有,但我不确定是否可以在没有配置文件的情况下动态添加服务器。即使是 NetworkManager,现在也有nmcli
,而且我看到您可以查询nmcli d show wlan0
以显示接口的 DNS 配置。 )
答案1
对于故障排除也非常有帮助:
journalctl -u systemd-resolved -f
在那里你可以看到systemd-resolved
真正在做什么。就我而言,它systemd-resolve --status
根本没有联系所报告的 DNS 服务器。如果它做了类似的奇怪的事情,那么有时重新启动sudo systemctl restart systemd-resolved
是一个好主意。
编辑:
为了获得更多信息,resolved
你需要
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
进入override.conf
通过systemd-resolved
sudo systemctl edit systemd-resolved
重启生效:
sudo systemctl restart systemd-resolved
编辑2:
不要忘记随后恢复此操作,正如@bmaupin 和@Aminovic 在评论中指出的那样。
sudo systemctl revert systemd-resolved
sudo systemctl restart systemd-resolved
答案2
使用resolvectl status
(systemd-resolve --status
当使用早于239)来展示你的全局和每个链接的 DNS 设置。
答案3
文件resolv.conf
手册说:
解析器是 C 库中的一组例程,提供对 Internet 域名系统 (DNS) 的访问。解析器配置文件包含解析器例程第一次被进程调用时读取的信息。
如果该文件不存在,则仅查询本地机器上的名称服务器,并且搜索列表包含根据主机名确定的本地域名。
systemd-resolved
在 Ubuntu 20.04 上,systemd-resolved
是包含在内的本地 DNS 服务器systemd
它充当存根解析器,它应该自动/etc/resolv.conf
使用正确的配置进行编辑。
在旧版本上,您可能需要使用以下内容手动对其进行符号链接:
$ sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
默认情况下,systemd-resolved
配置本地 DNS 服务器侦听127.0.0.53
端口53
,您可以运行lsof -i @127.0.0.53:53
来验证。确保您没有任何其他服务,例如dnsmasq
监听相同的地址和端口。
请注意,这127.0.0.53
是环回接口,但您可以让另一个 DNS 服务器在环回接口上另一个 IP 地址的端口 53 上侦听,例如127.0.0.1
或127.0.0.2
。
如果不起作用,请尝试以下操作:
$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
此文件包含来自 DHCP 租约的 DNS 服务器,但请注意,您不会从存根解析器缓存功能中受益。
dnsmasq
和NetworkManager
这dnsmasq
轻量级缓存 DNS 服务器接受 DNS 查询,并从小型本地缓存中回答它们,或者将它们转发到真实的递归 DNS 服务器。
对于 Web 开发机器来说,拥有一个小小的 DNS 服务来测试本地网站是非常好的。
首先,验证NetworkManager
管理您当前的界面(wlp0s20f3
在我的例子中):
$ nmcli dev
$ nmcli dev set wlp0s20f3 managed yes
现在您可以启用NetworkManager
内置dnsmasq
解析器:
$ cat /etc/NetworkManager/NetworkManager.conf
[main]
dns=dnsmasq
NetworkManager
您现在可以受益于沿的灵活性dnsmasq
,其配置位于/etc/NetworkManager/dnsmasq.d
:
$ cat /etc/NetworkManager/dnsmasq.d/custom.conf
# Resolve all domains ending in .dev to 127.0.0.1
address=/.dev/127.0.0.1
不要忘记禁用系统范围的dnsmasq
服务(如果存在)并应用您的更改:
$ sudo systemctl stop dnsmasq.service && sudo systemctl disable dnsmasq.service
$ sudo systemctl restart NetworkManager.service
如果由于某些原因您希望dnsmasq
单独运行,则必须首先防止NetworkManager
覆盖/etc/resolv.conf
:
$ cat /etc/NetworkManager/NetworkManager.conf
[main]
dns=none
现在您必须告诉dnsmasq
从其他地方获取其上游服务器/etc/resolv.conf
:
$ cat /etc/dnsmasq.conf
listen-address=127.0.0.53
resolv-file=/run/NetworkManager/resolv.conf
该文件由 DHCP 租约生成NetworkManager
,也包含 DNS 服务器。现在配置dnsmasq
解决:
$ cat /etc/resolv.conf
# Use local dnsmasq resolver
nameserver 127.0.0.53
配置您自己的本地 DNS 设置:
$ cat /etc/dnsmasq.d/custom.conf
# Resolve all domains ending in .dev to 127.0.0.1
address=/.dev/127.0.0.1
应用您的新配置:
$ sudo systemctl stop systemd-resolved.service && sudo systemctl disable systemd-resolved.service
$ sudo systemctl restart dnsmasq.service
dnsmasq
和systemd-networkd
不幸的是,它并不像使用 那样容易NetworkManager
,这是因为它systemd-networkd
没有公开从 DHCP 服务器获得的 DNS 名称服务器的文件,因为它是由 DHCP 服务器管理的systemd-resolved
。
如果您使用完全不推荐使用的软件包,情况也会如此ifupdown
。
打开man
:dhclient-script
$ man 8 dhclient-script
这挂钩部分说:
当它启动时,客户端脚本首先定义一个 shell 函数 ,
make_resolv_conf
该函数稍后用于创建/etc/resolv.conf
文件。要覆盖默认行为,请在 Enter 挂钩脚本中重新定义此函数。
dnsmasq
因此,如果您仍然想一起使用,systemd-networkd
则需要重新定义make_resolv_conf
以创建resolv-file
for ,dnsmasq
以便它可以从您的 DHCP 设置获取其上游服务器。
这resolvconf
package 围绕填充中涉及的不同守护进程提供了一个包装器接口/etc/resolv.conf
,您可以使用它来配置make_resolv_conf
行为。
如果您需要从路由器通告消息中的 RDNSS 获取 IPv6 上游服务器,也会发生同样的问题(请参阅邻居发现协议),因为这也是由 管理的systemd-resolved
。
尝试从以下命令ndisc6
包裹:
$ rdisc6 wlp0s20f3
您应该会看到来自路由器的各种信息,包括 IPv6 地址前缀和 DNS 服务器。如果您没有看到任何内容,则您的路由器可能不支持它。
该rdisc6
程序在用户空间中实现了 ICMPv6 路由器发现,使用NETLINK_ROUTE
Linux 内核 2.6.24 中添加了 RDNSS 支持的套接字。如果你想支持旧版本,你别无选择,只能与 OSI 第 2 层的设备驱动程序交互,使用SOCK_RAW
插座。
答案4
这里的答案都没有让我更接近工作systemd-resolved
。解决所有问题的一种方法systemd-resolved
是将其从方程中删除。
首先禁用它(以 root 身份):
service systemd-resolved stop
systemctl disable systemd-resolved
但这还不够。 Systemd 将重新启用它并在几分钟后重新启动它。因此,您必须通过systemd-resolved
从服务器中完全删除来防止这种情况:
rm -f /lib/systemd/systemd-resolved
我从来没有因为这样做而遇到 systemd 其他部分的问题,但是 YMMV。您可以重命名它,而不是删除它。
最后,编辑/etc/resolv.conf
并放入一些名称服务器:
nameserver 8.8.8.8
nameserver 8.8.4.4