systemd-resolved: Linux DNS 解析服务介绍

发布时间: 更新时间: 总字数:2449 阅读时间:5m 作者: IP上海 分享 网址

systemd-resolved 是 Linux 系统中 systemd 套件的一部分,主要负责 网络名称解析(DNS 解析) 服务。

介绍

systemd-resolved 不仅是一个简单的 DNS 客户端,还提供了本地 DNS 缓存、DNSSEC 验证、DNS over TLS (DoT) 支持、LLMNRMulticastDNS解析(resolver)应答(responder)以及对多网络接口的分割 DNS(Split DNS)管理。

核心功能

  • 本地 DNS 缓存 (Caching): 它会在本地缓存 DNS 请求的结果。当应用程序再次请求相同的域名时,它可以直接从内存中返回结果,从而减少延迟并减轻上游 DNS 服务器的负载。
  • 本地 Stub 监听器 (Stub Listener): 默认情况下,它会监听本地回环地址 127.0.0.53 的 53 端口。/etc/resolv.conf 通常被配置为指向这个地址,从而将系统所有的 DNS 请求转发给 systemd-resolved 处理。
  • 分割 DNS (Split DNS): 这是 systemd-resolved 的杀手级功能。它允许为不同的网络接口配置不同的 DNS 服务器。
    • 场景: 当你连接 VPN 时,公司内部域名的请求会发送到 VPN 接口的 DNS,而普通互联网请求则走原本的 Wi-Fi/以太网 DNS。
  • 支持多种解析协议:
    • 传统的单播 DNS。
    • LLMNR (Link-Local Multicast Name Resolution) 和 mDNS (Multicast DNS):用于在没有 DNS 服务器的局域网内解析主机名(类似于 Windows 的网络发现或 Apple 的 Bonjour)。
    • DNS over TLS (DoT): 支持加密 DNS 查询,防止隐私泄露和中间人篡改。

配置文件与工作模式

主配置文件

主要配置文件位于 /etc/systemd/resolved.conf。 常见的配置项包括:

[Resolve]
# 全局 DNS 服务器,配置 DNS,多个使用空格分隔
DNS=8.8.8.8 1.1.1.1
# 备用 DNS
FallbackDNS=114.114.114.114
# 是否开启多播 DNS 支持 (yes/no/resolve)
MulticastDNS=yes
# 是否开启 DNS over TLS (yes/no/opportunistic)
DNSOverTLS=no
# 是否开启缓存
Cache=yes
特性   DNS FallbackDNS
作用 主要的 DNS 服务器列表 在主要服务器失败时使用的备用 DNS 服务器列表
使用场景 始终使用,根据配置的顺序尝试解析 在主要 DNS 服务器不可达或解析失败时才使用
配置方式 可以设置一个或多个地址 同样可以设置一个或多个地址

启动服务

# 启动服务,通过解析配置文件,实时更新 /run/systemd/resolve/resolv.conf、 /run/systemd/resolve/stub-resolv.conf
systemctl start systemd-resolved.service
systemctl restart systemd-resolved.service

/etc/resolv.conf 的关系

这是用户最容易困惑的地方。systemd-resolved 提供了几种管理 /etc/resolv.conf 的模式,通过软链接(Symbolic Link)来控制:

  1. Stub 模式 (推荐/默认): /etc/resolv.conf 指向 /run/systemd/resolve/stub-resolv.conf

    • 文件内容里 nameserver127.0.0.53
    • 这是使用 systemd-resolved 缓存和高级功能的唯一方式。
  2. Uplink 模式: /etc/resolv.conf 指向 /run/systemd/resolve/resolv.conf

    • 文件内容列出了真实的全局 DNS 服务器(如 8.8.8.8)。
    • 应用程序直接查询上游 DNS,绕过 systemd-resolved 的缓存,但 systemd-resolved 仍在后台更新这个文件。
  3. 非托管模式: /etc/resolv.conf 是一个普通文件,不是软链接。

    • systemd-resolved 不会修改它,你需要手动管理或用其他工具(如 NetworkManager)管理。
  4. 系统的情况

$ ls -lhart /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Jan 13  2022 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

# 文件内容兼容 /etc/resolv.conf 的格式
$ cat /run/systemd/resolve/stub-resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search localdomain

# 本地监听 53 端口,代理到 DNS 配置的地址
$ ss -lpn | grep 53
udp   UNCONN 0      0                                           127.0.0.54:53               0.0.0.0:*    users:(("systemd-resolve",pid=668,fd=16))
udp   UNCONN 0      0                                        127.0.0.53%lo:53               0.0.0.0:*    users:(("systemd-resolve",pid=668,fd=14))
tcp   LISTEN 0      4096                                        127.0.0.54:53               0.0.0.0:*    users:(("systemd-resolve",pid=668,fd=17))
tcp   LISTEN 0      4096                                     127.0.0.53%lo:53               0.0.0.0:*    users:(("systemd-resolve",pid=668,fd=15))

Linux 应用程序获取名称解析

  • systemd-resolved 服务
  • glibc 的 getaddrinfogethostbyname API
    • 此方法通过 glibc Name Service Switch 实现
    • glibc NSS 通过 nss-resolve 模块才能让 glibc NSS 使用 systemd-resolved 提供的名字解析功能
  • systemd-resolved 在本地 127.0.0.53 上提供的本地DNS服务器

常用管理命令 (resolvectl)

在较新的 systemd 版本中,管理工具是 resolvectl(旧版本为 systemd-resolve)。

  • resolvectl 用来解析主机名、IP 地址、域名、DNS 记录等
  • resolvectl 通过 systemd-resolved.service 实现相关功能
resolvectl --help ...
$ resolvectl --help
resolvectl [OPTIONS...] COMMAND ...

Send control commands to the network name resolution manager, or
resolve domain names, IPv4 and IPv6 addresses, DNS records, and services.

Commands:
  query HOSTNAME|ADDRESS...    Resolve domain names, IPv4 and IPv6 addresses
  service [[NAME] TYPE] DOMAIN Resolve service (SRV)
  openpgp EMAIL@DOMAIN...      Query OpenPGP public key
  tlsa DOMAIN[:PORT]...        Query TLS public key
  status [LINK...]             Show link and server status
  statistics                   Show resolver statistics
  reset-statistics             Reset resolver statistics
  flush-caches                 Flush all local DNS caches
  reset-server-features        Forget learnt DNS server feature levels
  dns [LINK [SERVER...]]       Get/set per-interface DNS server address
  domain [LINK [DOMAIN...]]    Get/set per-interface search domain
  default-route [LINK [BOOL]]  Get/set per-interface default route flag
  llmnr [LINK [MODE]]          Get/set per-interface LLMNR mode
  mdns [LINK [MODE]]           Get/set per-interface MulticastDNS mode
  dnsovertls [LINK [MODE]]     Get/set per-interface DNS-over-TLS mode
  dnssec [LINK [MODE]]         Get/set per-interface DNSSEC mode
  nta [LINK [DOMAIN...]]       Get/set per-interface DNSSEC NTA
  revert LINK                  Revert per-interface configuration

Options:
  -h --help                    Show this help
     --version                 Show package version
     --no-pager                Do not pipe output into a pager
  -4                           Resolve IPv4 addresses
  -6                           Resolve IPv6 addresses
  -i --interface=INTERFACE     Look on interface
  -p --protocol=PROTO|help     Look via protocol
  -t --type=TYPE|help          Query RR with DNS type
  -c --class=CLASS|help        Query RR with DNS class
     --service-address=BOOL    Resolve address for services (default: yes)
     --service-txt=BOOL        Resolve TXT records for services (default: yes)
     --cname=BOOL              Follow CNAME redirects (default: yes)
     --search=BOOL             Use search domains for single-label names
                                                              (default: yes)
     --raw[=payload|packet]    Dump the answer as binary data
     --legend=BOOL             Print headers and additional info (default: yes)

See the resolvectl(1) man page for details.
  • 查看 DNS 状态: 显示所有接口的 DNS 服务器配置、当前的 DNS 协议支持情况等。

    resolvectl status
    
  • 查询域名 (测试解析): 类似于 dignslookup

    resolvectl query google.com
    
  • 清空 DNS 缓存: 如果你修改了 DNS 记录但本地仍然解析到旧 IP,可以执行此命令。

    resolvectl flush-caches
    
  • 查看缓存统计: 查看缓存命中率、缓存大小等。

    resolvectl statistics
    
  • 重置服务器状态: 如果 DNS 解析卡住或状态异常。

    resolvectl reset-server-features
    
  • 查找 SRV 服务

resolvectl service
  • 查看 openpgp 公钥
resolvectl openpgp me@xiexianbin.cn
  • 实操
# 查域名解析
$ resolvectl query www.xiexianbin.cn
www.xiexianbin.cn: 60.200.32.109               -- link: ens33
                   60.200.32.108               -- link: ens33
                   60.200.32.115               -- link: ens33
                   60.200.32.114               -- link: ens33
                   60.200.32.113               -- link: ens33
                   60.200.32.112               -- link: ens33
                   60.200.32.111               -- link: ens33
                   60.200.32.110               -- link: ens33
                   (www.xiexianbin.cn.w.cdngslb.com)

# 查 IP
$ resolvectl query 223.5.5.5
223.5.5.5: public1.alidns.com                  -- link: ens33

# 查 MX 记录
$ resolvectl --legend=no -t MX query xiexianbin.cn
xiexianbin.cn IN MX 10 mxw.mxhichina.com                    -- link: ens33
xiexianbin.cn IN MX 5 mxn.mxhichina.com                     -- link: ens33

# tlsa
$ resolvectl tlsa tcp fedoraproject.org:443
_443._tcp.fedoraproject.org IN TLSA 3 1 1 5441af1dc3c6df9a6bd408daea995bd1a5e328404a271a575f11b4feebd93b09
        -- Cert. usage: Domain-issued certificate
        -- Selector: SubjectPublicKeyInfo
        -- Matching type: SHA-256 -- link: ens33

为什么有人想要禁用它?

尽管 systemd-resolved 功能强大,但在某些场景下可能带来麻烦:

  1. 端口冲突: 它占用 53 端口。如果你想自己运行 dnsmasqbind9AdGuard Home,会发生冲突。
  2. VPN 泄漏或兼容性问题: 某些老旧的 VPN 客户端可能无法正确处理 Split DNS,导致 DNS 泄漏。
  3. 习惯问题: 许多管理员习惯直接编辑 /etc/resolv.conf,发现修改被 systemd 覆盖后会感到困扰。

如何禁用?

如果你决定不使用它,可以按照以下步骤操作(以 Ubuntu 为例):

# 1. 停止并禁用服务
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

# 2. 删除指向 systemd 的软链接
sudo rm /etc/resolv.conf

# 3. 创建一个新的 resolv.conf 并填入 DNS
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

扩展

  • localhost 不会路由到网络上
  • 不包含 . 的名称,使用 LLMNR 协议路由到所有支持 IP 多播的本地接口
  • .local 后缀的名称,使用多播 DNS(MulticastDNS)协议路由到所有支持 IP 多播的本地接口
  • _gateway 路由到默认网关(多网关到字典序第一个)

F&Q

systemd-resolved[]: Failed to add DNS server address

  • journalctl -u systemd-resolved 出现如上错误日志
  • 原因:/etc/systemd/resolved.confDNS 字段配置异常导致,注意多个 DNS 使用空格分隔

总结

systemd-resolved 是现代 Linux 发行版(如 Ubuntu 18.04+, Fedora 等)网络栈的重要组成部分。它通过统一管理 DNS 请求,提供了更好的性能(缓存)和灵活性(针对不同接口的 DNS 配置)。对于大多数普通用户和服务器管理员,保留其默认设置是最佳选择;但对于需要精细控制 DNS 流量的高级用户,理解其工作原理(尤其是与 /etc/resolv.conf 的关系)至关重要。

本文总阅读量 次 本站总访问量 次 本站总访客数
Home Archives Categories Tags Statistics