AlmaLinux 10:systemd-resolved 的 foreign 与 stub 两种模式
PVE 上的 AlmaLinux 10.2 虚拟机,最小化安装,systemd-resolved-257-23.el10_2.1.alma.1 从 Alma 10.2 DVD 的 BaseOS 离线安装(实验网无默认路由,公网不可达)。
依次验证:安装前状态 → 只 enable 的状态 → 完成交接的状态 → 回滚。截图:public/evidence/systemd-resolved/alma-foreign-to-stub.png。
安装前的三件事
Section titled “安装前的三件事”$ rpm -q systemd-resolvedpackage systemd-resolved is not installed$ ls -l /etc/resolv.conf-rw-r--r--. 1 root root 51 ... /etc/resolv.conf$ head -2 /etc/resolv.conf# Generated by NetworkManagernameserver 223.5.5.5第三件是不明显的那件:ss -lnup | grep :53 没有任何输出——本机没有 DNS 监听者,解析完全依赖 NM 写出的上游地址。
只启用 ≠ 已接管
Section titled “只启用 ≠ 已接管”# systemctl enable --now systemd-resolved# resolvectl --no-pager status | grep "resolv.conf mode" resolv.conf mode: foreignforeign 是 resolved 对 /etc/resolv.conf 的判断结果:文件不是它写的。此时服务在跑,但系统查询不经过它。所以「装完没效果」是预期行为,不是 bug。
判断自己处在哪个阶段,只看一行即可:
resolv.conf mode | 含义 |
|---|---|
foreign | 文件由别人(NM/手工)维护,resolved 只是旁观 |
stub | 文件指向 /run/systemd/resolve/stub-resolv.conf,查询进 127.0.0.53 |
static | 指向 /etc/resolv.conf 的静态副本(/run/systemd/resolve/resolv.conf) |
让接管发生的两个条件
Section titled “让接管发生的两个条件”# printf '[main]\ndns=none\n' > /etc/NetworkManager/conf.d/90-dns-none.conf# ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf# systemctl restart NetworkManager systemd-resolved- 条件一:NetworkManager 放弃写
/etc/resolv.conf(dns=none);否则它会在下次网络事件里覆盖回来; - 条件二:
/etc/resolv.conf必须是指向 stub 文件的软链,而不是内容相同的普通文件。
生效后:
$ resolvectl --no-pager status | grep -E "mode|Current DNS" resolv.conf mode: stub Current DNS Server: 223.5.5.5$ ss -lnup | grep ":53 "UNCONN ... 127.0.0.54:53 ... ("systemd-resolve")UNCONN ... 127.0.0.53%lo:53 ... ("systemd-resolve")两个监听地址要分清:127.0.0.53 是本机 stub(给普通程序用),127.0.0.54 用于 systemd-resolved 自身对外转发或容器场景。

什么时候不该动它
Section titled “什么时候不该动它”- 目标是「能解析就行」:保持现状,少一层间接;
- 生产上跑着和 DNS 相关的监控或防火墙规则:切到 127.0.0.53 可能让原本直连上游的规则失效;
- 需要 split DNS 但没有 systemd-networkd:NM 的
dns=none是全局开关,做不到按网卡分流。
先删配置、再删软链、最后停服务,顺序反了会出现「resolv.conf 指向不存在的文件」:
# rm -f /etc/NetworkManager/conf.d/90-dns-none.conf# rm -f /etc/resolv.conf# systemctl disable --now systemd-resolved# systemctl restart NetworkManager回滚后再看 ls -l /etc/resolv.conf 应为普通文件,resolvectl status 报服务不可用。
- 拿内容判断是否接管:普通文件里写着
nameserver 127.0.0.53也算 foreign,必须看软链与 mode; - 改完 NM 没重启:
dns=none要重启(或 reload)才生效; - 把
No route to host当 DNS 故障:我们在离线实验网里resolvectl query就报这个,实际是没有默认路由,ip route一看便知; - 回滚只删一半:只删
dns=none不删软链,NM 恢复写文件时行为不确定。
练习:判断自己处于哪种模式
Section titled “练习:判断自己处于哪种模式”ls -l /etc/resolv.confresolvectl --no-pager status | grep "resolv.conf mode"ss -lnup | grep ":53 " || echo "no local resolver"检查:
- 软链指向
stub-resolv.conf且 mode 为stub,才算接管完成; - 普通文件 +
foreign,说明装了但没交接; :53无监听,说明 resolved 未运行或未启用 stub;- 三者要对得上,否则配置只做了一半。
常见问题
为什么最小化安装不带 systemd-resolved?
EL10 默认由 NetworkManager 直接管理 DNS,对服务器场景足够;resolved 作为可选组件放在仓库里。
离线环境怎么装?
包在 DVD 的 BaseOS 目录,可 dnf --disablerepo=* install ./包名.rpm 安装;依赖只有同版本 systemd 组件。
stub 模式会不会影响容器?
会。容器内 /etc/resolv.conf 常指向 127.0.0.53,但容器命名空间里这个地址可能不可达,需要显式配置上游或使用 127.0.0.54。
- 日志与 journald:/journald-logging/
- 网络绑定与 VLAN:bond 与 VLAN
- 安装后的核对:新装系统 7 项核对