如何避免 dnsmasq 和 systemd-resolved 之间的冲突?

vic*_*vic 97 systemd dnsmasq

我最近安装了dnsmasq作为本地网络的 DNS 服务器。dnsmasq 侦听端口 53,该端口已被systemd-resolved的本地 DNS 存根侦听器使用。

只需停止 systemd-resolved,然后在 dnsmasq 运行后重新启动它即可解决此问题。但它在重新启动后返回:systemd-resolved 优先启动,dnsmasq 将不会启动,因为端口 53 已在使用中。

我想,第一个明显的问题是我如何最好地让 systemd-resolved 理解它不应该启动本地 DNS 存根侦听器,从而保留端口 53 以供 dnsmasq 使用?

然而,一个更有趣的问题是这两种服务通常如何协同工作。他们甚至打算并排工作还是只是在使用 dnsmasq 的情况下被 systemd 解决?

Mal*_*ous 76

systemd 232(2017 年发布)开始,您可以编辑/etc/systemd/resolved.conf并添加以下行:

DNSStubListener=no
Run Code Online (Sandbox Code Playgroud)

这将关闭与端口 53 的绑定。

这个选项在resolved.conf manpage中有更详细的描述。

您可以找到系统正在运行的 systemd 版本:

systemctl --version
Run Code Online (Sandbox Code Playgroud)

  • @Ravinder:它会禁用 systemd DNS 服务器,是的。如果您的系统被配置为使用该服务器,那么看起来 Internet 连接停止工作(因为您将其关闭)。您需要将系统配置为使用另一个 DNS 服务器。通常人们会关闭端口 53 上的绑定,因为他们想在那里运行自己的 DNS 服务器,所以这不是问题。 (5认同)
  • 进行互联网连接的这一轮 (3认同)

Mun*_*nir 27

您可以systemd-resolved使用sudo systemctl disable systemd-resolved.

如果您想同时运行两者,您可以重定向systemd-resolved以使用 localhost 作为主名称服务器。这将确保在访问外部 DNS 服务器之前,所有查询都被定向到 dnsmasq 进行解析。这可以通过nameserver 127.0.0.1/etc/resolv.conf文件顶部添加行来完成。这也将禁用 systemd 的本地缓存。

您可以在Arch Linux wiki上阅读更多内容。我从那里复制了这个,它很好地涵盖了它。

然而,这并不能可靠地避免启动时的错误,即如果 systemd-resolved 恰好首先启动,则 dnsmasq 仍然会失败。如果您的版本systemd足够新,请使用Malvineous的答案。如果您的版本systemd太旧,您可以通过修改 dnsmasq 单元来解决此问题:在[Unit]部分中,添加Before=systemd-resolved.

在此之后,如果您愿意,您可以/etc/dnsmasq-resolv.conf为上游名称服务器创建一个单独的文件并使用-ror--resolv-file选项传递它,或者将上游名称服务器添加到 dnsmasq 配置文件并使用-Ror--no-resolv选项。这样你就只有本地主机/etc/resolv.conf,一切都通过 dnsmasq。

  • 在 dnsmasq 单元中,在 `[Unit]` 部分放置一个 `Before=systemd-resolved`。这样, dnsmasq 将始终首先启动。 (7认同)
  • 我不得不删除我之前的评论,因为我无法再确认这是否解决了问题。在问这里之前,我确实阅读了 wiki,并且我已经有一个 resolv.conf 文件,其中 localhost 名称服务器位于顶部。这没有帮助。然后我按照您的指示将外部名称服务器移到 dnsmasq 的第二个文件中。第一次重新启动后,首先加载 dnsmasq 所以没有出现问题。在第二次重新启动时,首先解析加载,因此 dnsmasq 退出并出现所描述的错误。我和以前一样。 (2认同)

小智 20

我刚刚通过删除 /etc/dnsmasq.conf 中行开头的“#”来启用选项“bind-interfaces”。

我能够再次启动 dnsmasq:

  • dnsmasq 在所有接口(包括 127.0.0.1)端口 53 上绑定 DNS 端口,
  • systemd-resolv 继续监听 127.0.0。53 :53

我通过这个讨论解决了这个解决方案:添加一个选项来禁用存根解析器

  • 这是什么是垃圾箱火灾的最佳答案。即使在环回时,systemd 也没有理由占用该端口。 (2认同)

sen*_*ena 12

这是 (X)Ubuntu 18.04 Bionic 的解决方案。

安装 dnsmasq

sudo apt install dnsmasq
Run Code Online (Sandbox Code Playgroud)

在端口 53 上禁用 systemd-resolved 侦听器(不要触摸 /etc/systemd/resolved.conf,因为它可能会在升级时被覆盖):

$ cat /etc/systemd/resolved.conf.d/noresolved.conf 
[Resolve]
DNSStubListener=no
Run Code Online (Sandbox Code Playgroud)

并重新启动它

$ sudo systemctl restart systemd-resolved
Run Code Online (Sandbox Code Playgroud)

(或者完全禁用它$ sudo systemctl disable systemd-resolved.service

删除 /etc/resolv.conf 并重新创建。这很重要,因为默认情况下 resolv.conf 是指向 /run/systemd/resolve/stub-resolv.conf 的符号链接。如果您不删除符号链接,该文件将在重新启动时被 systemd 覆盖(即使我们禁用了 systemd-resolved!)。NetworkManager (NM) 还会检查它是否是一个符号链接来检测 systemd 解析的配置。

$ sudo rm /etc/resolv.conf
$ sudo touch /etc/resolv.conf
Run Code Online (Sandbox Code Playgroud)

禁用 NM 覆盖 /etc/resolv.conf(还有一个选项 rc-manager,但它不起作用,尽管它在 NM 手册中有描述):

$ cat /etc/NetworkManager/conf.d/disableresolv.conf 
[main]
dns=none
Run Code Online (Sandbox Code Playgroud)

并重新启动它:

$ sudo systemctl restart NetworkManager
Run Code Online (Sandbox Code Playgroud)

告诉 dnsmasq 使用来自 NM 的 resolv.conf:

$ cat /etc/dnsmasq.d/nmresolv.conf 
resolv-file=/var/run/NetworkManager/resolv.conf
Run Code Online (Sandbox Code Playgroud)

并重新启动它:

$ sudo systemctl restart dnsmasq
Run Code Online (Sandbox Code Playgroud)

使用 dnsmasq 解决:

$ cat /etc/resolv.conf 
# Use local dnsmasq for resolving
nameserver 127.0.0.1
Run Code Online (Sandbox Code Playgroud)

  • 在尝试了其他一些解决方案后,您的解决方案在 Linux Mint 19.1 上解决了我的问题。非常感谢! (2认同)

小智 7

从 systemd 联机帮助页来看,它不打算手动禁用存根 DNS 服务器。有趣的是,我只是在将 systemd 从 230 升级到 231 后才注意到所描述的问题。

禁用 systemd-resolved 对我来说没有选择,因为我需要它通过 DHCP 处理接收到的上游 DNS 服务器。

我的解决方案是让 dnsmasq 在启动之前停止 systemd-resolved 并在之后再次启动它。

我在以下位置创建了一个嵌入式配置/etc/systemd/system/dnsmasq.service.d/resolved-fix.conf

[Unit]
After=systemd-resolved.service

[Service]
ExecStartPre=/usr/bin/systemctl stop systemd-resolved.service
ExecStartPost=/usr/bin/systemctl start systemd-resolved.service
Run Code Online (Sandbox Code Playgroud)

这似乎是一个相当黑客的解决方案,但它有效。

  • 嘿,实际上这个解决方案非常巧妙。即使在包更新后它也是持久的,因为它保留了原始单元文件。做得很好。在resolved.conf 手册中的`DNSStubListener` 下说明了以下内容:“请注意,当DNS 存根侦听器的侦听地址和端口已被使用时,它会隐式关闭。” 这就是我认为这种方法工作正常的原因。 (2认同)