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


56

我最近安装了dnsmasq充当本地网络的DNS服务器。dnsmasq从systemd-resolved侦听本地DNS存根侦听器已在使用的端口53 。

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

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

但是,一个更有趣的问题是这两种服务通常是如何协同工作的。如果使用dnsmasq,它们甚至打算并肩工作还是被systemd解析?


4
您是否尝试过仅通过禁用sudo systemctl disable systemd-resolved?如果配置正确,则dnsmasq应该可以处理我认为的域解析。
pbhj

1
您还必须发出问题,sudo systemctl stop systemd-resolved如果它正在运行。使用 sudo systemctl status systemd-resolved检查
布鲁斯·巴内特

Answers:


41

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

DNSStubListener=no

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

该选项在resolve.conf联机帮助页中有更详细的描述。

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

systemctl --version

2
进行本次互联网连接
Ravinder

2
@Ravinder:它将禁用系统DNS服务器,是的。如果您的系统配置为使用此服务器,则看起来Internet连接停止工作(因为已将其关闭)。您将需要将系统配置为使用其他DNS服务器。通常,人们会关闭端口53的绑定,因为他们想在那里运行自己的DNS服务器,所以这不是问题。
Malvineous

18

您可以使用禁用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为上游名称服务器创建一个单独的文件,然后使用-r--resolv-file选项将其传递,或者将上游名称服务器添加到dnsmasq配置文件中并使用-R--no-resolv选项。这样,您只有本地主机/etc/resolv.conf,一切都通过dnsmasq进行。


2
我不得不删除之前的评论,因为我无法再确认这已解决了问题。在问这里之前,我确实阅读过Wiki,并且我已经有了一个resolv.conf文件,其顶部是localhost名称服务器。这没有帮助。然后,我按照您的指示将外部名称服务器移至dnsmasq的第二个文件。第一次重新引导后,dnsmasq首先加载,因此不会出现此问题。在第二次重新引导时,首先解决了已加载的解决方案,因此dnsmasq退出并显示了所描述的错误。我和以前一样。
vic

6
在dnsmasq单元中,Before=systemd-resolved[Unit]部分中放置a 。这样,dnsmasq将始终首先启动。
穆尼尔

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

这似乎是一个相当棘手的解决方案,但它可以工作。


2
嘿,实际上这个解决方案很漂亮。即使在软件包更新后,它也是持久的,因为它保留了原始的单位文件。做得很好。DNSStubListener在resolve.conf手册中说明了以下内容:“请注意,当已使用DNS存根侦听器的侦听地址和端口时,它会隐式关闭DNS存根侦听器。” 我认为这就是为什么这种方法行之有效的原因。
乔纳森·

A ++解决方案!!!
sjas

我不得不将/ usr / bin / systemctl更改为/ bin / systemctl
Bruce Barnett

5

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

我能够再次启动dnsmasq:

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

解决了此讨论,我为此解决方案指向了该解决方案:添加一个选项以禁用存根解析器


这是什么是垃圾箱大火的最佳答案。即使环回,也没有理由systemd应该占用该端口。
乔纳森·费舍尔


2

如果您使用默认的Ubuntu 18.04设置,则可能是由于systemd-resolved(默认的DNS服务器)和之间的冲突引起的dnsmasq。如果您dnsmasq是因为明确想要它而故意安装的,那么此问题的其他答案之一(说明如何禁用systemd-resolved)可能会对您有所帮助。如果明确安装dnsmasq,则可能是因为您正在使用而已lxd。这可能是因为您实际上是lxd用来管理容器的,但最有可能是因为lxd在安装应用程序时使用了快照来保护您。从我的角度来看,我想保留dnsmasq(因为lxd想要),但我也想保留systemd-resolved 作为DNS服务器(因为这是Ubuntu团队选择的,我比我更信任他们)。

因此,这似乎是一个lxd内在的问题。如果是这样,那么根据lxd-users邮件列表帖子,我修复它的方式是这样的:

$ lxc network edit lxdbr0

这将在终端编辑器中编辑您的配置。它看起来像这样:

config:
  ipv4.address: 10.216.134.1/24
  ipv4.nat: "true"
  ipv6.address: none
  ipv6.nat: "true"
name: lxdbr0
type: bridge

在其中添加三行:

config:
  ipv4.address: 10.216.134.1/24
  ipv4.nat: "true"
  ipv6.address: none
  ipv6.nat: "true"
  raw.dnsmasq: |
    auth-zone=lxd
    dns-loop-detect
name: lxdbr0
type: bridge

这将导致dnsmasq正在运行的lxd来检测DNS循环。至少对我来说,这可以解决问题并停止systemd-resolveddnsmasq使用100%CPU。


2

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

安装dnsmasq

sudo apt install dnsmasq

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

$ cat /etc/systemd/resolved.conf.d/noresolved.conf 
[Resolve]
DNSStubListener=no

然后重新启动

$ sudo systemctl restart systemd-resolved

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

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

$ sudo rm /etc/resolv.conf
$ sudo touch /etc/resolv.conf

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

$ cat /etc/NetworkManager/conf.d/disableresolv.conf 
[main]
dns=none

并重新启动它:

$ sudo systemctl restart NetworkManager

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

$ cat /etc/dnsmasq.d/nmresolv.conf 
resolv-file=/var/run/NetworkManager/resolv.conf

并重新启动它:

$ sudo systemctl restart dnsmasq

使用dnsmasq解决:

$ cat /etc/resolv.conf 
# Use local dnsmasq for resolving
nameserver 127.0.0.1

1
在尝试了其他一些解决方案之后,您的解决方案在Linux Mint 19.1上解决了我的问题。非常感谢!
Renan Lazarotto

1

我是这样解决的:

/ etc / default / dnsmasq中添加或取消注释以下行:

IGNORE_RESOLVCONF=yes

创建您自己的resolv文件(/etc/resolv.personal)来定义名称服务器。您可以在此处使用任何名称服务器。我从https://www.opennic.org拿了两个

nameserver 5.132.191.104
nameserver 103.236.162.119

/etc/dnsmasq.conf中,添加或取消注释以下行:

resolv-file=/etc/resolv.personal

然后重新启动dnsmasq并禁用默认的解析程序:systemd-resolved。

sudo service dnsmasq restart

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

1

我不确定为什么两个服务都尝试使用相同的地址。也许您可以按照我在Xubuntu 18.04.1上的情况来安排它们,它们的配置如下:

xy@zq:~$ sudo netstat -tulpn | grep 53
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      13549/systemd-resol 
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      9632/dnsmasq 

要使用我的dnsmasq使systemd解析,我只需设置:

#/etc/systemd/resolved.conf 
[Resolve]
DNS=127.0.0.1

在我的dnsmasq配置中,设置我的外部名称服务器:

#/etc/dnsmasq.conf
nameserver x.x.x.x
nameserver y.y.y.y

重新启动所有内容后:

# sudo systemctl restart systemd-resolved.service
# sudo systemctl restart dnsmasq.service

systemd-resolved将在以下位置将默认DNS服务器设置为dnsmasq:

#/etc/resolv.conf
nameserver 127.0.0.1

最后一行使我感到惊讶,所以我抬起头来。听起来像是您的情况,/etc/resolv.conf是的符号链接/run/systemd/resolve/resolv.conf。显然,这是systemd-resolved可能运行的四种(!)可能模式之一。我猜这取决于您的发行版设置方式,即,对于Xubuntu 18.04.1而言是正确的,但在其他方面可能有所不同。系统。
sourcejedi

0

我无法让dnsmasq开始使用在线找到的解决方案,即禁用systemd-resolved,将dnsmasq.conf更改为“动态绑定”而不是“绑定接口”。通过使dnsmasq在network-online.service之后而不是network.service之后启动,我能够使其在启动时启动:

[Unit]
Description=dnsmasq - A lightweight DHCP and caching DNS server
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
After=network-online.target #This line changed

感谢您发布您使用的方法。请注意,通常在订购network-online.target时,还应该将network-online.target添加到的列表中Wants=freedesktop.org/wiki/Software/systemd/NetworkTarget
sourcejedi

0

这是在Ubuntu 18.10 Cosmic Cuttlefish中为我工作的(经过数小时的痛苦)。我这样做是为了利用dnsmasq比较健壮的缓存机制并避免NGINX解析器漏洞。请注意,我正在使用Ubuntu Server版本(no NetworkManager/ nmcli,仅systemd-networkd),并且它在AWS EC2上运行,因此我还需要保持DNS和DHCP与默认EC2搜索域一起使用。我不想systemd-resolved完全禁用它,因为我不知道这可能会影响将来的更新。除非另有说明,否则此处的所有内容均以root / sudo身份运行(默认情况下,作为EC2用户数据传递时会发生这种情况)。

## Configure dnsmasq to work with systemd-resolved
# Set static hostname with hostnamectl
hostnamectl set-hostname mydomainname
# Add an entry for the hostname to /etc/hosts
tee --append /etc/hosts <<EOF
127.0.0.1 mydomainname
EOF
# Disable stub listener for resolvconf and set DNS to loopback
tee --append /etc/systemd/resolved.conf <<EOF
DNSStubListener=no
DNS=127.0.0.1
EOF
# Tell dnsmasq to ignore resolvconf
tee --append /etc/default/dnsmasq <<EOF
IGNORE_RESOLVCONF=yes
EOF
# Create dropin directory
mkdir -p /etc/systemd/system/dnsmasq.service.d
# Create systemd dropin to make sure systemd-resolved stops before dnsmasq starts
tee /etc/systemd/system/dnsmasq.service.d/resolved-fix.conf <<EOF
[Unit]
After=systemd-resolved.service
[Service]
ExecStartPre=bin/systemctl stop systemd-resolved.service
ExecStartPost=bin/systemctl start systemd-resolved.service
EOF
# Create custom resolvconf with name servers (I usec cloudflare)
tee /etc/resolv.mydomainname <<EOF
nameserver 1.1.1.1
nameserver 1.0.0.1 
nameserver [2606:4700:4700::1111] 
nameserver [2606:4700:4700::1001] 
EOF
# Configure dnsmasq
tee /etc/dnsmasq.d/mydomainname.conf <<EOF
# Region comes from:
# EC2_AVAIL_ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
# EC2_REGION=${EC2_AVAIL_ZONE%?}
domain=$EC2_REGION.compute.internal
resolv-file=/etc/resolv.mydomainname
listen-address=127.0.0.1
port=53
interface=lo
bind-dynamic
domain-needed
bogus-priv
dnssec
dns-forward-max=300
cache-size=1000
neg-ttl=3600
EOF
# Reload to pick up dropin
systemctl daemon-reload
# Stop systemd-resolved
systemctl stop systemd-resolved
# Start dnsmasq
systemctl restart dnsmasq

验证127.0.0.1#53是否正在使用解析和DNSSEC正在使用类似dig +trace facebook.com


设置好后,您知道为什么还需要该单元文件插入黑客DNSStubListener=no吗?
sourcejedi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.