如何在Ubuntu中禁用systemd-resolved?

如何在Ubuntu 17.04中禁用systemd-resolved?
使用"systemctl disable"命令禁用它没有起作用,该服务似乎被重新启动(可能是由NetworkManager引起的)。

25systemd-resolved不仅庞大,而且它破坏了DNS解析的工作方式,因为它并不总是按照客户端配置中指定的DNS服务器顺序尝试解析。当一个服务器无法解析一个域名时,列表中的下一个服务器会被移动到顶部(Poettering称之为“内存”)。有关详细信息,请参阅此讨论 - LifeBoy
10它还可以绕过iptables规则,这是一个糟糕的主意。 - Spongman
@LifeBoy 我注意到systemd-resolved缓存配置现在默认为“no”...我正好相反的问题...一些网站有太多嵌套的CDN,导致8.8.8.8限制我们的速度...因此我们需要缓存和本地DNS服务器。第一次手动配置unbound,DNSoverTLS应该是一个不错的加分项。故事的寓意是,不要升级并期望一切都保持不变,我正在重新开始并喜欢这个过程。 - Ray Foss
1我突然想到,_gateway名称是由systemd-resolved提供的...我的整个网络栈依赖它,每次我尝试主机一个完整功能的DNS时都会破坏我的系统。 :facepalm: - Ray Foss
@Spongman,你能否提供一个关于systemd-resolved覆盖或绕过iptables规则的参考文献?我在Google和DuckDuckGo上找不到任何证明这是真实的信息。 - Harold Fischer
2@HaroldFischer 我没有参考资料。你可以自己尝试一下:添加一些iptables规则来重定向DNS流量(在我的情况下,我是按用户进行的),然后启用systemd-resolved并观察它完全忽略了iptables规则。至少在2018年10月左右是这样的。此后我没有再尝试过。 - Spongman
@Spongman 谢谢你的联系。我并不是想无礼,只是希望能有个参考。据你所知,只有 iptables 的 DNS 规则会被 systemd-resolved 覆盖吗?还有一个快速的例子,确保我理解得对:假设我设置了一个 iptables 规则来阻止访问 8.8.8.8;而 systemd-resolved 设置为使用 Google DNS,并且愉快地忽略我的禁止访问 8.8.8.8 的规则——这是你所指的行为吗? - Harold Fischer
2@HaroldFischer 没有冒犯之意。我也遇到过类似的情况,我曾使用iptables根据本地组ID有条件地重定向出站DNS流量到不同的服务器上。我记不清具体的iptables命令了(我想我是用shorewall来实现的)。无论如何...我更新了操作系统,安装了systemd-resolved,然后iptables规则就停止起作用了 - 所有的DNS流量都直接发送到配置的服务器,绕过了iptables规则。 - Spongman
1@Spongman 这个 iptables 的设置可能会“绕过”规则,因为用户发送的查询被 systemd-resolved 接收,并以其 UID 和 GID 发送实际请求(对于所有用户而言,这是相同的)。 - Gert van den Berg
1@GertvandenBerg 我记得我曾试图移除iptables用户过滤器,但DNS流量仍然没有通过iptables路由。禁用了systemd-resolved后,一切都正常工作了。我甚至提交了一个被设计师快速关闭的错误报告。 - Spongman
1@Spongman 我的意思是用户过滤器“有效”,但由于systemd-resolved的工作方式,所有流量都来自同一个用户(这意味着无法按用户进行过滤)(它不会绕过iptables,但会破坏某些类型的规则(通过改变流量发送方式))(我不喜欢systemd-resolved)。 - Gert van den Berg
1@GertvandenBerg 不,你误解了。用户过滤器是无关紧要的。即使不通过用户过滤iptables规则,systemd-resolved仍然没有通过任何iptables规则路由。 - Spongman
5个回答

这种方法适用于Ubuntu的以下版本:17.04(Zesty)、17.10(Artful)、18.04(Bionic)、18.10(Cosmic)、19.04(Disco)和20.04(Focal):
禁用并停止systemd-resolved服务:
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved

然后将以下行放入您的/etc/NetworkManager/NetworkManager.conf文件的[main]部分中:
dns=default

删除符号链接/etc/resolv.conf
rm /etc/resolv.conf

重启 NetworkManager

sudo systemctl restart NetworkManager

请注意,禁用systemd-resolvd可能会导致某些用户的VPN名称解析出现问题。请参阅此launchpad上的错误(感谢Vincent)。

4这在Ubuntu 17.04上似乎不起作用。此外,配置文件位于/etc/NetworkManager/NetworkManager.conf。当我执行上述操作时,名称解析会中断。systemd-resolved真的很糟糕,现在VPN的DNS解析对我来说根本无法正常工作。有关错误进展,请访问此处:https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1624317 - Vincent Gerris
@VincentGerris 谢谢! - Bastian Voigt
5我认为你应该在上面的答案中添加一点内容,即“apt-get install dnsmasq”应该在禁用systemd-resolved之后执行。 - LifeBoy
2刚刚在17.04上进行了测试,一切都可以直接使用(当然,需要安装dnsmasq部分)。 - tribbloid
8@LifeBoy 我不使用dnsmasq。我只是不使用任何本地域名服务器,对此没有看到价值。 - Bastian Voigt
重启后对我有效。 - lurscher
3这个解决方案对我来说是一个绕过Ubuntu 17.10上DNS解析问题的方法。 - vahid-dan
对我来说,在17.10版本上也起作用了。没有尝试使用VPN,但其他一切都按照应有的方式工作(包括pingssh)。 - springloaded
12对于Ubuntu 18.04,只需要运行以下命令:sudo systemctl disable systemd-resolved.service和sudo service systemd-resolved stop。这对我有效。 - Daniel Eagle
禁用这个功能怎么可能比启用它还要破坏更多呢? - Florian Heigl
35谢谢。SystemD正在破坏Linux,使其从可靠且易于理解的东西变成了凭借魔法运行的东西。 - Forbesmyester
2谢谢,在Ubuntu 18.10上,我仍然需要在/etc/NetworkManager/NetworkManager.conf文件的[main]下面添加dns=default - baptx
@baptx 你是否还需要重启网络管理器并删除 resolv.conf 文件? - Bastian Voigt
@BastianVoigt 我记不清确切的细节,但我猜想我可能需要重新启动网络管理器以应用新的设置。我认为我并不需要移除/etc/resolv.conf,因为网络管理器每次重启或建立新连接时都会重写该文件。 - baptx
对于Ubuntu 18.04,您在禁用服务后需要重新启动。 - S.M.Mousavi
我完成了上述所有步骤,但即使在网络管理器重启后,我的/etc/resolv.conf文件也没有重新创建。我发现正确和实际的resolv.conf文件被创建在/var/run/resolvconf/resolv.conf中。所以我只需在/etc/下创建符号链接,一切都开始完美地工作,甚至无需系统重启(我只习惯于重启Windows机器,我不能接受重启Linux系统) PS:我的问题是systemd-resolved在系统启动后的几分钟内无法解析,并且有时在从睡眠中唤醒后也无法解析。我不想花几个小时来调试它。 - Juraj Michalak
1这在最新的Ubuntu mini(18.04.11)上没有起作用,即使是在干净安装之后也是如此。我不知道他们在Ubuntu总部在做什么,但对我来说,无法解析的DNS似乎是一个非常大的失败,/etc/resolv.conf被符号链接到了一个存根文件。哇。在apt安装dnsmasq之后,这个操作系统甚至连dnsmasq都无法启动。而且没有适当地说明为什么会失败。哦,别让我开始谈netplan了。只是试图在其中创建带有DNS解析器的静态NIC就像打开一个充满YAML灾难的潘多拉魔盒。很抱歉我尝试了Ubuntu而不是Debian,那是因为Debian的nginx版本太旧了。 - Julius
如果您仍然遇到问题,请检查您的接口是否命名为eth0。我认为当接口不是eth0时会出现问题,即如果可预测的网络接口名称已配置。或者netplan已经重新命名了一些内容。 - russau
2我们在办公场所也遇到了Ubuntu 18.04的问题,DNS间歇性地停止工作。我们一直使用sudo systemctl restart systemd-resolved来解决。根据您的建议,我们稍作修改(使用sudo systemctl restart NetworkManager代替sudo service network-manager restart),似乎效果不错。 - Amil Waduwawara
在Ubuntu 19.10上的虚拟机中运行Ubuntu 20.04 - 我按照上面的说明进行了操作 - 但是后来我不得不重新添加/etc/resolv.conf文件 - 并在其中加入我的路由条目 - 在我的情况下是"nameserver 192.168.1.1" - 然后DNS就正常工作了。可能因人而异。希望这能帮到你。 - Nick
谢谢,掌握回我resolv.conf的控制真是太棒了。 - MitchellK
太好了,你帮了我很多,谢谢!我只需要将工作电脑重新安装到更新的版本上,但遇到了systemd-resolved的复杂性问题,这可能会阻碍我至少几天的工作。非常感谢你的帮助。 - Martin Mucha
我使用的是Ubuntu 20.04,并按照以下步骤进行操作。一开始一切都很顺利,但在重新启动后出现了问题。我注意到,在重新启动后,systemd-resolved服务仍然处于禁用状态,但名称解析仍然失败。 - dhruvin
你可能想要补充一下,新的 etc/resolv.conf 是由 /etc/netplan/* 的设置生成的。 - FalcoGer
如果我没有/etc/NetworkManager/NetworkManager.conf文件怎么办? - Andrew Savinykh

如果您正在使用Ubuntu 18.04服务器(或Ubuntu 20.04服务器),那么这些答案都不适用。用户user2427436的回答最接近问题。
问题在于systemd-resolved是一个存根解析器,我只需要完全禁用它(根据问题所述)。我需要这样做是因为Zimbra 8.8.15(FOSS)自带了自己集成的解析器(unbound)。
在我的情况下,我从一个原始的服务器18.04安装开始,只选择了最少的选项,并且是在裸机上(实际上是虚拟机)。
所以这里是解决方法:
   vi /etc/systemd/resolved.conf
     edit line #DNSStubListener=yes
         to be DNSStubListener=no
   systemctl stop systemd-resolved
   systemctl status systemd-resolved
   rm /etc/resolv.conf
   reboot to test...

这是现在/etc/systemd/resolved.conf的样子:
# See resolved.conf(5) for details
[Resolve]
#DNS=
#FallbackDNS=
#Domains=
#LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#Cache=yes
#DNSStubListener=yes
DNSStubListener=no

那就是所需的全部。
在此之后,随意安装任何其他解析器。

3终于有一个好答案了...我只是希望Debian Buster/Ubuntu 20.04 LTS能够与真正的DNSServer相容...没有简单的方法可以更新systemd-resolved到一个允许将其转发、DNSoverTLS和缓存暴露给局域网的版本。这已经成为一个严重的问题,10年前错误的答案在SO上仍然比正确的最新答案更受重视。 - Ray Foss
1对于systemd我完全同意。StackExchange赢了!我来修改答案——它也适用于服务器 20.04(相同的初始条件)。 - BISI
在你按照我的建议进行操作后,随意安装任何其他解析器都是可以的。但要注意,这样做会禁用系统自带的system-resolved功能,而像CentOS这样的其他Linux发行版中并没有这个功能。我的问题是,例如CentOS是否默认具备另外一种解析器?我想知道在Ubuntu中禁用system-resolved是否会使其与CentOS类似,还是需要进行其他操作? - Steve Moretz
这个也适用于Ubuntu 22吗?为什么你说服务器版,不适用非服务器版吗? - Steve Moretz
一如既往,问题比答案容易 :-/ 不,移除systemd-resolved对将Ubuntu变成Red Hat没有任何影响。你的CentOS问题最好在CentOS论坛上提问。至于相同的方法是否适用于桌面版本 - 试一下吧!正如我在第一行所说的,之前的答案在Ubuntu服务器版本上并没有起作用。我还没有需要将任何人升级到22.04服务器版本,也没有进行全新安装,所以除了打赌一杯啤酒说这个步骤会在Ubuntu服务器22.04上起作用之外,我无法发表评论。关于桌面实验,请告诉我们。 - BISI
适用于Ubuntu服务器22.04版本。 - undefined

我最近升级到了(k)Ubuntu 17.04,也遇到了systemd的变化。
我觉得我的设置相当典型,因为我在宽带HUB中有一个DNS提供商,这是我网络上所有设备的主要信息来源(我有几个设备)。
systemd确实有一些优点,不全都是坏的,但真正糟糕的是文档、Ubuntu团队缺乏沟通以及“让我们改变它,尽管它会对每个人造成问题”的冲动心态。
对我来说,解决办法是编辑/etc/systemd/resolved.conf文件。
[Resolve]
DNS=192.168.1.254   # <-- change to your router address
#FallbackDNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
Domains=lan         # <-- change to your localdomain name (maybe .local)
#LLMNR=yes  <-- I dabbled with this for a while but it doesn't matter
#DNSSEC=no
#Cache=yes
#DNSStubListener=udp

在不理解为什么这样不起作用之后,我发现还需要切换到systemd提供的/etc/resolv.conf。在开箱即用的安装中,这并不是默认情况(原因我不清楚)。
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

本地DNS服务器将不再使用,所有DNS请求都将发送到我的HUB。
我认为这比剪切和插入其他解决方案要好得多,因为systemd-resolv现在是默认的。
顺便说一下,一个相关的问题是/etc/nsswitch.conf被禁用了。
它应该这样写:
hosts:          files mdns4_minimal dns [NOTFOUND=return] resolve [!UNAVAIL=return] dns

这是一个令人困惑的配置,因为[NOTFOUND=return]意味着处理在此结束。之后的条目将永远不会被使用。

1然后每次连接到新的WIFI,我都要在配置中更改路由器地址?你是认真的吗?-1 - Bastian Voigt
我没意识到你正在漫游。如果是的话,请将配置项注释掉。然后你应该得到一个 /etc/resolv.conf 文件,内容如下:nameserver 8.8.8.8 nameserver 8.8.4.4 - user2427436
2我认为如果你正确设置了netplan,就不需要编辑resolved.conf。也就是说,netplan会将正确的值写入符号链接文件中...顺便说一句,systemd真糟糕! - user70382
2我更喜欢将所有的解析器瓶颈排除掉。在成千上万台服务器的5年寿命中,通常只有2-3次合法的解析器更新,但是他们仍然在为笔记本电脑进行优化。对于他们来说,公司因为这些问题导致数百万损失并持续停机所带来的影响,并不重要,对于安全关键系统的影响也被“那些人会测试/优化它”的说辞轻描淡写地带过。是的,通过移除它,从而确保没有人会死于此。 - Florian Heigl
1这不是对“如何在Ubuntu 17.04中禁用systemd-resolved?”的回答。 - Robert Riedl

如果您的VPN存在泄漏问题,并且无法弄清楚如何设置systemd(就像我一样),您可以按照第一个答案中描述的方法进行删除,但不要添加dns=default行,因为它会激活nameserver 127.0.0.1。 要将路由器设置为DNS,请在/etc/resolvconf/resolv.conf.d/文件夹中创建名为"tail"的文件,并添加nameserver 192.168.1.1行。
如果您对此文件弄乱了,请执行ln -sf /var/run/resolved/resolv.conf /etc/resolv.conf

1真的吗?对我来说,它完全按照我的回答所描述的方式运作。绝对没有使用127.0.0.1命名服务器。我也认为在配置文件中硬编码你的命名服务器的IP地址并不是很方便。至少我经常切换无线网络,每个无线网络都有不同的命名服务器。 - Bastian Voigt
1是的,“默认”选项将127.0.0.1设置为DNS。 - Yvain
我觉得我在这里是错的。 - Yvain
请链接到“第一个”答案 - 答案的顺序可能会改变... - Gert van den Berg

我感到有必要添加这个出现在重复问题上的优秀答案,它涵盖了当您想要最小化设置 ifupdown + dhclient + resolvconf(是的,在2021年的Ubuntu Focal中仍然可能)的情况。
其他答案没有涵盖这种用例。也许我们应该努力为我们网络堆栈中大多数不同组合提供非systemd-resolved的设置(基于netplan、基于networkmanager、wicd等等)。

https://askubuntu.com/a/1336755/32178


那绝对不是systemd的方式!;-) 也许你在想这是Devuan吗?https://www.devuan.org/ - BISI
@BISI 嘿,尽管我很欣赏Devuan的努力,但每当我能验证主流发行版仍然非常容易被黑客攻击时,我仍然感到深深的满足。 - ata