systemd-resolved

来自 ArchWiki
(重定向自 Systemd-resolvconf

systemd-resolved 是一个 systemd 服务,它通过 D-Bus 接口、resolve NSS 服务(nss-resolve(8))以及 127.0.0.53 上的本地 DNS 存根监听器为本地应用程序提供网络名称解析。有关用法,请参阅 systemd-resolved(8)

安装

systemd-resolvedsystemd 软件包的一部分,默认情况下已安装。

配置

systemd-resolved域名系统 (DNS)(包括 DNSSECDNS over TLS)、多播 DNS (mDNS)链路本地多播名称解析 (LLMNR) 提供解析器服务。

可以通过编辑 /etc/systemd/resolved.conf 和/或 /etc/systemd/resolved.conf.d/ 中的 drop-in .conf 文件来配置解析器。请参阅 resolved.conf(5)

要使用 systemd-resolved,请启动启用 systemd-resolved.service

提示: 要理解围绕选择和开关的上下文,可以按照systemd#诊断服务中所述,为 systemd-resolved 开启详细的调试信息。

DNS

依赖于 glibc 的 getaddrinfo(3)(或类似)的软件将开箱即用,因为默认情况下,如果 /etc/nsswitch.conf 可用,则配置为使用 nss-resolve(8)

为了为直接读取 /etc/resolv.conf 的软件(例如 Web 浏览器GoGnuPG)提供域名解析systemd-resolved 具有四种不同的文件处理模式——stub、static、uplink 和 foreign。它们在 systemd-resolved(8) § /ETC/RESOLV.CONF 中描述。我们在此仅关注推荐模式,即使用 /run/systemd/resolve/stub-resolv.conf 的 stub 模式。

/run/systemd/resolve/stub-resolv.conf 包含本地存根 127.0.0.53 作为唯一的 DNS 服务器和搜索域列表。这是推荐的操作模式,它将 systemd-resolved 管理的配置传播到所有客户端。要使用它,请将 /etc/resolv.conf 替换为指向它的符号链接

# ln -sf ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
注意
  • ../ 开头的目标路径相对于链接位置,而不是相对于当前目录。
  • 未能正确配置 /etc/resolv.conf 将导致 DNS 解析中断。
  • arch-chroot 内部时,无法创建 /etc/resolv.conf 符号链接,因为该文件是从外部系统绑定挂载的。相反,请从 chroot 外部创建符号链接。例如
    # ln -sf ../run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf

设置 DNS 服务器

提示: 要检查 systemd-resolved 当前使用的 DNS,请运行 resolvectl status
自动

systemd-resolved 将与使用 /etc/resolv.conf网络管理器开箱即用。由于 systemd-resolved 将通过跟踪 /etc/resolv.conf 符号链接来检测到,因此不需要特定的配置。 systemd-networkdNetworkManageriwd 都是这种情况。

但是,如果 DHCPVPN 客户端使用 resolvconf 程序来设置名称服务器和搜索域(有关使用 resolvconf 的软件列表,请参阅 openresolv#用户),则需要额外的软件包 systemd-resolvconf 来提供 /usr/bin/resolvconf 符号链接。

注意
手动

在 stub 和 static 模式下,可以在 resolved.conf(5) 文件中设置自定义 DNS 服务器。

/etc/systemd/resolved.conf.d/dns_servers.conf
[Resolve]
DNS=192.168.35.1 fd7b:d0bd:7a6e::1
Domains=~.
注意
  • 如果没有 resolved.conf(5) 中的 Domains=~. 选项,如果任何每个链接的 DNS 服务器在每个链接的配置中设置了 Domains=~.systemd-resolved 可能会使用它们。
  • 此选项不会影响与每个链接配置中指定的更具体的搜索域匹配的域名查询,它们仍将使用各自的每个链接 DNS 服务器进行解析。

有关每个链接配置的更多信息,请参阅 systemd-networkd#网络文件

备用

如果 systemd-resolved 没有从网络管理器接收到 DNS 服务器地址,并且没有手动配置 DNS 服务器,则 systemd-resolved 会回退到备用 DNS 地址,以确保 DNS 解析始终有效。

注意: 备用 DNS 的顺序为:Cloudflare、Quad9 和 Google。请参阅 systemd PKGBUILD,其中定义了服务器。

可以通过在 resolved.conf(5) 中设置 FallbackDNS 来更改地址。例如

/etc/systemd/resolved.conf.d/fallback_dns.conf
[Resolve]
FallbackDNS=127.0.0.1 ::1

要禁用备用 DNS 功能,请设置 FallbackDNS 选项,但不指定任何地址

/etc/systemd/resolved.conf.d/fallback_dns.conf
[Resolve]
FallbackDNS=

DNSSEC

警告: 截至 2023 年 6 月,systemd-resolved 中的 DNSSEC 支持被认为是实验性的和不完整的。[1] 因此,systemd 构建时默认禁用 DNSSEC 验证。

可以通过更改 resolved.conf(5) 中的 DNSSEC 设置来启用 DNSSEC 验证。

  • 设置 DNSSEC=allow-downgrade 以仅在上游 DNS 服务器支持 DNSSEC 时才验证 DNSSEC。
  • 设置 DNSSEC=true 以始终验证 DNSSEC,从而破坏不支持 DNSSEC 的名称服务器的 DNS 解析。例如
/etc/systemd/resolved.conf.d/dnssec.conf
[Resolve]
DNSSEC=true

通过查询具有无效签名的域来测试 DNSSEC 验证

$ resolvectl query badsig.go.dnscheck.tools
badsig.go.dnscheck.tools: resolve call failed: DNSSEC validation failed: invalid

现在测试具有有效签名的域

$ resolvectl query go.dnscheck.tools
go.dnscheck.tools: 2604:a880:400:d0::256e:b001 -- link: enp2s0
                   142.93.10.179               -- link: enp2s0

-- Information acquired via protocol DNS in 122.2ms.
-- Data is authenticated: yes; Data was acquired via local or encrypted transport: no
-- Data from: network

DNS over TLS

DNS over TLS 默认禁用。要启用它,请更改 resolved.conf(5)[Resolve] 部分的 DNSOverTLS 设置。要启用 DNS 提供商的服务器证书验证,请在其主机名中包含 DNS 设置,格式为 ip_address#hostname。例如

/etc/systemd/resolved.conf.d/dns_over_tls.conf
[Resolve]
DNS=9.9.9.9#dns.quad9.net
DNSOverTLS=yes
注意
  • 使用 DNSOverTLS=yes,使用的 DNS 服务器必须支持 DNS over TLS。否则所有 DNS 请求都将失败。
  • 或者,可以使用 DNSOverTLS=opportunistic 仅在服务器支持 DNS over TLS 时才使用 DNS over TLS。如果使用的 DNS 服务器不支持 DNS over TLS,systemd-resolved 将回退到常规的未加密 DNS。

ngrep 可用于测试 DNS over TLS 是否正常工作,因为 DNS over TLS 始终使用端口 853,而从不使用端口 53。当使用 DNS over TLS 解析主机名时,命令 ngrep port 53 应不产生输出,而 ngrep port 853 应产生加密输出。

Wireshark 可用于对 DNS over TLS 查询进行更详细的数据包检查。

附加监听接口

默认情况下,systemd-resolved 通过环回接口应答本地应用程序的 DNS 请求。要使 systemd-resolved 在默认接口或地址之外的其他接口或地址上应答 DNS 请求,请在 resolved.conf(5) 中为每个附加接口设置选项 DNSStubListenerExtra。例如

/etc/systemd/resolved.conf.d/additional-listening-interfaces.conf
[Resolve]
DNSStubListenerExtra=192.168.10.10
DNSStubListenerExtra=2001:db8:0:f102::10
DNSStubListenerExtra=192.168.10.11:9953
提示: 当在充当 DNS 服务器的路由器上使用 systemd-resolved 时,这很有用。

mDNS

systemd-resolved 能够充当 多播 DNS 解析器和响应器。

解析器使用“hostname.local”命名方案提供主机名解析。

仅当 systemd-resolved 的 mDNS 支持已启用,并且当前活动的网络管理器的配置为连接启用 mDNS 时,mDNS 才会为连接激活。

默认情况下,systemd-resolved's mDNS 支持已启用。可以通过其 MulticastDNS 设置禁用它(请参阅 resolved.conf(5) § 选项)。

启用每个连接的 mDNS 支持取决于网络管理器

  • 对于 systemd-networkd,在每个连接设置文件的 [Network] 部分中设置 MulticastDNS 设置。您可能还需要在 [Link] 部分中设置 Multicast=yes。请参阅 systemd.network(5)
  • 对于 NetworkManager,在连接的设置文件的 [connection] 部分中设置 mdns。运行 nmcli connection modify interface_name connection.mdns {yes|no|resolve} 将为您执行此操作。请参阅 nm-settings(5)
注意
  • 如果已安装 Avahi,请考虑禁用屏蔽 avahi-daemon.serviceavahi-daemon.socket 以防止与 systemd-resolved 冲突。
  • 如果您计划使用 mDNS 和防火墙,请确保打开 UDP 端口 5353
提示: 所有 NetworkManager 连接的默认值可以通过在 /etc/NetworkManager/conf.d/ 中创建配置文件并在 [connection] 部分中设置 connection.mdns=2 来设置。请参阅 NetworkManager.conf(5) § 连接部分[2]

LLMNR

链路本地多播名称解析是由 Microsoft 创建的主机名解析协议。

仅当 systemd-resolved 的全局设置(resolved.conf(5) § 选项中的 LLMNR)和网络管理器的每个连接设置都启用时,LLMNR 才会为连接激活。默认情况下,systemd-resolved 启用 LLMNR 响应器;systemd-networkdNetworkManager[3] 为连接启用它。

提示: 所有 NetworkManager 连接的默认值可以通过在 /etc/NetworkManager/conf.d/ 中创建配置文件并在 [connection] 部分中设置 connection.llmnr 来设置。请参阅 NetworkManager.conf(5) § 连接部分

如果您计划使用 LLMNR 并使用防火墙,请确保打开 UDP 和 TCP 端口 5355

查找

要查询 DNS 记录、mDNS 或 LLMNR 主机,您可以使用 resolvectl 实用程序。

例如,要查询 DNS 记录

$ resolvectl query archlinux.org
archlinux.org: 2a01:4f8:172:1d86::1
               138.201.81.199

-- Information acquired via protocol DNS in 48.4ms.
-- Data is authenticated: no

故障排除

systemd-resolved 未搜索本地域

当仅给出主机名时,即使在相应的 systemd-networkd.network 文件中存在 UseDomains=yesDomains=[domain-list],并且该文件在 resolv.conf 中产生预期的 search [domain-list]systemd-resolved 也可能不搜索本地域。您可以运行 networkctl statusresolvectl status 来检查是否实际拾取了搜索域。

可能的解决方法

  • 禁用 LLMNR 以使 systemd-resolved 立即继续附加 DNS 后缀
  • 修剪 /etc/nsswitch.confhosts 数据库(例如,通过删除 resolve 服务后的 [!UNAVAIL=return] 选项)
  • 切换到使用完全限定域名
  • 使用 /etc/hosts 解析主机名
  • 回退到使用 glibc 的 dns 而不是使用 systemd 的 resolve

systemd-resolved 不解析无后缀的主机名

要使 systemd-resolved 解析不是完全限定域名的主机名,请将 ResolveUnicastSingleLabel=yes 添加到 /etc/systemd/resolved.conf

警告: 这会将单标签名称转发到您可能无法控制的全局 DNS 服务器。此行为不符合标准,可能会造成隐私和安全风险。有关详细信息,请参阅 resolved.conf(5)

这似乎仅在禁用 LLMNR(LLMNR=no)时有效。

如果您正在使用 systemd-networkd,您可能希望将 DHCP 服务器或 IPv6 路由器通告提供的域用作搜索域。默认情况下禁用此功能,要启用它,请添加到接口的 .network 文件

[Network]
UseDomains=true

您可以使用以下命令检查 systemd-resolved 为每个接口拥有的内容

$ resolvectl domain

参见