应修改 /etc/systemd/resolved.conf 中的 nameservers= 行并重启 systemd-resolved,而非手动编辑 /etc/resolv.conf;同时确保 networkmanager 配置为 dns=systemd-resolved 或正确设置 ipv4.ignore-auto-dns=true 以避免 dhcp 覆盖。

resolv.conf 被 systemd-resolved 覆盖怎么办
Linux 发行版(尤其是 Ubuntu 20.04+、Fedora、Debian 12+)默认启用 systemd-resolved,它会接管 DNS 解析,并通过符号链接把 /etc/resolv.conf 指向自己的动态文件。你手动改了 /etc/resolv.conf,重启或网络重连后又变回 nameserver 127.0.0.53 —— 这不是权限问题,是服务在“守规矩”。
真正该改的是 systemd-resolved 的配置,而不是硬写死 /etc/resolv.conf:
- 编辑
/etc/systemd/resolved.conf,取消注释并修改Nameservers=行,比如:Nameservers=8.8.8.8 1.1.1.1 - 运行
sudo systemctl restart systemd-resolved - 验证:执行
resolvectl status,确认 Global 部分显示你配的 DNS;cat /etc/resolv.conf应仍指向/run/systemd/resolve/stub-resolv.conf,但解析已生效
硬删符号链接再建静态文件,会导致 systemd-resolved 功能异常(如 LLMNR/mDNS 失效),且 NetworkManager 可能再次覆盖。
NetworkManager 写死 DNS 后不生效的典型原因
你在 GUI 网络设置里填了 DNS,或者用 nmtui 配了 ipv4.dns,但 dig google.com 还是走错服务器 —— 很可能因为 DNS 模式没设对。
NetworkManager 默认使用 dns=systemd-resolved(转发给 systemd-resolved),但如果你手动改过 /etc/resolv.conf 或停用了 systemd-resolved,它就退回到 dns=default,此时实际由 DHCP 提供的 DNS 覆盖你的手动配置。
解决方法(二选一):
- 保持
systemd-resolved启用:确保/etc/NetworkManager/conf.d/99-dns.conf中有dns=systemd-resolved,然后重启NetworkManager - 彻底绕过它:在连接配置中加
ipv4.ignore-auto-dns=true和ipv4.dns-priority=-100,再设ipv4.dns,最后nmcli connection reload && nmcli connection up <conn-name></conn-name>
注意:仅设 ipv4.dns 不够,必须配合 ignore-auto-dns,否则 DHCP 的 DNS 优先级更高。
容器或 curl/wget 访问失败,但 host/nslookup 正常
host 和 nslookup 直接走系统 DNS 配置,而 curl、wget、Docker 容器默认用 libc 的 getaddrinfo(),受 /etc/nsswitch.conf 和 glibc 缓存影响;容器更可能继承宿主机的 /etc/resolv.conf,但被 --dns 或 CNI 插件覆盖。
排查重点:
- 查
getent hosts google.com:如果失败,说明 glibc 层解析卡住,检查/etc/nsswitch.conf中hosts:行是否含dns,且顺序合理(比如别写成files [!UNAVAIL=return] dns) - 查
curl -v http://google.com输出里的* Trying行:看它连的是哪个 IP,确认是不是解析错了,还是连通性问题 - Docker 容器内执行
cat /etc/resolv.conf:若内容是127.0.0.11(dockerd 内置 DNS),需确认dockerd是否配置了--dns,或容器启动时加了--dns参数
常见陷阱:在容器里改 /etc/resolv.conf 是临时的,下次启动就丢;应通过 docker run --dns 或 /etc/docker/daemon.json 全局配置。
systemd-resolved 日志里反复出现 “Failed to send packet: Operation not permitted”
这个错误通常出现在启用了 systemd-resolved 但同时又运行了另一个本地 DNS 服务(比如 dnsmasq、unbound 或 bind9)监听 127.0.0.1:53。systemd-resolved 尝试向自己配置的上游发包时,被本地服务拦截并拒绝。
本质是端口冲突和职责重叠:
- 检查谁占着 53 端口:
sudo ss -tulpn | grep ':53' - 如果看到
dnsmasq或unbound,停掉它:sudo systemctl stop dnsmasq,再禁用:sudo systemctl disable dnsmasq - 不要让多个本地 DNS 服务共存;如果真需要自建 DNS,请关闭
systemd-resolved并确保/etc/resolv.conf指向你的服务(如127.0.0.1),同时 NetworkManager 设为dns=none
这个错误不会直接导致解析失败,但会让日志刷屏、掩盖真实问题,而且上游查询可能静默超时。
DNS 配置真正的复杂点不在“怎么写”,而在“谁在管”——systemd-resolved、NetworkManager、dhcpcd、dockerd、甚至云平台的 metadata 服务,都可能悄悄改写同一个文件或覆盖同一层解析逻辑。盯住 resolvectl status 和 nmcli device show,比反复改 /etc/resolv.conf 有用得多。










