域名解析
通常,域名代表一个IP地址,并在域名系统 (DNS) 中与之关联。本文将介绍如何配置域名解析以及解析域名。
名称服务切换
名称服务切换 (Name Service Switch) (NSS) 是 GNU C 库 (glibc) 的一部分,并支持用于解析域名 的 getaddrinfo(3) API。NSS 允许通过独立的服务的系统数据库,其搜索顺序可以由管理员在 nsswitch.conf(5) 中配置。负责域名解析的数据库是 hosts 数据库,为此 glibc 提供了以下服务:
- files: 读取
/etc/hosts文件,参见 hosts(5) - dns: glibc 解析器,它读取
/etc/resolv.conf,参见 resolv.conf(5)
systemd 为主机名解析提供了三个 NSS 服务:
- nss-resolve(8) — 一个缓存 DNS 存根解析器,在 systemd-resolved 中描述。
- nss-myhostname(8) — 提供本地主机名解析,无需编辑
/etc/hosts。 - nss-mymachines(8) — 为本地 systemd-machined(8) 容器提供主机名解析。
使用 NSS 解析域名
可以使用 getent(1) 查询 NSS 数据库。可以通过以下方式使用 NSS 解析域名:
$ getent ahosts domain_name
/etc/resolv.conf 和/或 /etc/hosts。参见 Network configuration#local hostname is resolved over the network。Glibc 解析器
glibc 解析器每次解析时都会读取 /etc/resolv.conf 来确定要使用的名称服务器和选项。
resolv.conf(5) 列出了名称服务器以及一些配置选项。列在前面的名称服务器会优先被尝试,最多可以列出三个名称服务器。以井号 (#) 开头的行将被忽略。
/etc/resolv.conf 的覆盖
网络管理器倾向于覆盖 /etc/resolv.conf,具体请参见相应部分:
- dhcpcd#/etc/resolv.conf
- Netctl#/etc/resolv.conf
- NetworkManager#/etc/resolv.conf
- ConnMan#/etc/resolv.conf
要阻止程序覆盖 /etc/resolv.conf,也可以通过设置不可变的 文件属性来写保护它。
# chattr +i /etc/resolv.conf
/etc/resolv.conf,可以使用 resolvconf。使用 nmcli 的替代方案
如果您使用 NetworkManager,可以使用 nmcli(1) 来设置 /etc/resolv.conf 的持久化选项。将 "Wired" 替换为您的连接名称。例如:
# nmcli con mod Wired +ipv4.dns-options 'rotate,single-request,timeout:1'
有关更多选项,请参阅 nmcli(1)、nm-settings-nmcli(5) 和 resolv.conf(5) 的 man 页。
限制查找时间
如果您遇到非常长的域名查找时间(无论是在 pacman 中还是在浏览时),通常可以定义一个较短的超时时间,之后使用备用名称服务器。为此,请在 /etc/resolv.conf 中添加以下内容:
/etc/resolv.conf
options timeout:1
IPv6 延迟主机名查找
如果您在解析主机名时遇到 5 秒延迟,这可能是由于 DNS 服务器/防火墙行为不当,只对 A 和 AAAA 请求并行发送的请求回复一次。[1] 您可以通过在 /etc/resolv.conf 中设置以下选项来解决此问题:
/etc/resolv.conf
options single-request
本地域名
为了能够使用本地机器名称的主机名而不使用完全限定域名,请在 /etc/resolv.conf 中添加一行,包含本地域,例如:
/etc/resolv.conf
search example.org
这样,在使用 ssh 命令时,您可以将本地主机(如 mainmachine1.example.org)简单地称为 mainmachine1,但 drill 命令在执行查找时仍需要完全限定域名。
查找工具
要查询特定的 DNS 服务器和 DNS/DNSSEC 记录,您可以使用专门的 DNS 查找工具或 DNS 服务器附带的工具。这些工具自行实现 DNS,不使用 NSS。
- drill(1) — 一个旨在从 DNS 获取信息的工具。它只支持未加密的 DNS。
- https://nlnetlabs.nl/projects/ldns/ || ldns
- 例如,使用 drill 为域的 TXT 记录查询特定名称服务器:
$ drill domain @nameserver TXT
- 除非指定了 DNS 服务器,否则 drill 将使用
/etc/resolv.conf中定义的名称服务器。
- adig(1) — 向 DNS 服务器发送关于名称的查询并打印收到的信息。
- dnsi — 一个用于检查 DNS 各方面的命令行工具。
- dnslookup — 一个简单的命令行工具,用于执行 DNS 查询。支持所有已知的 DNS 协议。
- dog(1) — 类似 dig 的命令行 DNS 客户端。
- doggo — 面向人类的命令行 DNS 客户端。
- q — 一个小巧的命令行 DNS 客户端。
一些 DNS 服务器软件包附带的 DNS 查找工具可以在不运行 DNS 服务器的情况下使用。
- knot 提供了 khost(1) 和 kdig(1)。
- unbound 提供了 unbound-host(1)。
- bind 提供了 dig(1)、host(1) 和 nslookup(1)。
- powerdns 提供了 sdig(1)。
解析器性能
Glibc 解析器不缓存查询。要实现本地缓存,请使用 systemd-resolved 或设置一个本地缓存的 DNS 服务器,并通过将 127.0.0.1 和 ::1 设置为 /etc/resolv.conf 或 /etc/resolvconf.conf(如果使用 openresolv)中的名称服务器来使用它。
隐私和安全
DNS 协议 (Do53) 是未加密的,不考虑保密性、完整性或身份验证,因此如果您使用不受信任的网络或恶意的 ISP,您的 DNS 查询可能会被窃听,响应也可能被篡改。此外,DNS 服务器可能进行DNS 劫持。
您需要信任您的 DNS 服务器能够保密处理您的查询。DNS 服务器由 ISP 和第三方提供。或者,您可以运行自己的递归名称服务器(也称为递归解析器、DNS 递归器),但这需要更多的工作。如果您在不受信任的网络中使用DHCP客户端,请务必设置静态名称服务器以避免使用和受到任意 DNS 服务器的影响,或者,连接到安全网络并使用其 DNS 服务器来使用VPN。为了保护您与远程 DNS 服务器的通信,您可以使用加密协议,前提是上游服务器和您的本地解析器都支持该协议。常见的加密 DNS 协议包括:
- DNS over TLS (DoT)—RFC 7858;
- DNS over HTTPS (DoH)—RFC 8484;
- DNS over QUIC (DoQ)—RFC 9250;
- DNSCrypt.
为了验证响应是否确实来自权威名称服务器,您可以验证DNSSEC,前提是上游服务器和您的本地解析器都支持它。
TLS 服务器名称指示
即使您使用加密的 DNS 解析器,在请求域名证书时,TLS 连接仍然会在服务器名称指示 (SNI) 中泄露域名。此泄露可以使用 Wireshark 过滤器 tls.handshake.extensions_server_name_len > 0 或使用以下 tshark 命令检查:
# tshark -p -Tfields -e tls.handshake.extensions_server_name -Y 'tls.handshake.extensions_server_name_len>0'
一个提出的解决方案是使用 Encrypted Client Hello (ECH),一个 TLS 1.3 协议扩展。
应用层 DNS
请注意,一些客户端软件,如主要的网页浏览器[2][3],已经开始实现 DNS over HTTPS。虽然查询加密通常被视为一个优点,但它也意味着软件绕过了系统解析器配置。[4]
Firefox 提供了配置选项来启用或禁用 DNS over HTTPS 并选择 DNS 服务器。Mozilla 已经建立了一个可信递归解析器 (TRR) 项目,并提供了关于其默认提供商的透明度信息。值得注意的是,Firefox 支持并自动为 TRR 提供商启用 Encrypted Client Hello (ECH),请参见 Firefox/Privacy#Encrypted Client Hello。
Chromium 将检查用户系统的解析器,并在系统解析器地址已知提供 DNS over HTTPS 时启用 DNS over HTTPS。有关更多信息以及如何禁用 DNS over HTTPS,请参见这篇博文。
Mozilla已提议,如果系统解析器无法解析域名 use-application-dns.net,则全局禁用应用层 DNS。目前,这仅在 Firefox 中实现。
隐匿 DNS over HTTPS
隐匿 DNS over HTTPS (ODoH)—RFC 9230—是一个解决许多 DNS 隐私问题的系统。有关更多信息,请参阅Cloudflare 的文章。它将 DNS over HTTPS 添加到学术性的隐匿 DNS设计中。请参阅Improving the privacy of DNS and DoH with oblivion一文,了解其差异的讨论。
递归解析器
递归解析器和根服务器之间的通信未加密,根服务器运营商反对实现它。对于与权威服务器的加密通信,有实验性的 RFC 9539,它允许机会性地使用 DNS over TLS 和 DNS over QUIC。
第三方 DNS 服务
- 在使用第三方 DNS 服务之前,请检查其隐私政策,了解用户数据如何处理。用户数据是有价值的,可以出售给其他方。
- 强烈建议在使用第三方 DNS 服务时使用加密协议。
有各种第三方 DNS 服务。维基百科有一个“知名”公共 DNS 服务运营商列表,而 curl 项目的维基有一个更全面的公共 DNS over HTTPS 服务器列表(其中很多也支持 DNS over TLS)。systemd 软件包为systemd-resolved配置了回退 DNS,当没有配置 DNS 服务器时(手动或通过 DHCP/RA)。
您可以使用 dnsperftest 从您的位置测试最流行的 DNS 解析器的性能。dnsperf.com 提供了提供商之间的全球基准测试。
第三方 DNS 客户端软件
一些 DNS 服务也提供专用软件:
- cloudflared — Cloudflare DNS over HTTPS 的 DNS 客户端
- opennic-up — 自动续订响应最快的 OpenNIC 服务器的 DNS 服务器
- nextdns — NextDNS 的 DNS-over-HTTPS CLI 客户端
DNS 服务器
DNS 服务器可以是权威的和递归的。如果它们都不是,它们被称为存根解析器,并且只将所有查询转发给另一个递归名称服务器。存根解析器通常用于在本地主机或网络上引入 DNS 缓存。请注意,这也可以通过功能齐全的名称服务器来实现。本节比较了可用的 DNS 服务器,有关更详细的比较,请参阅维基百科:DNS 服务器软件比较。
| 名称 | 软件包 (Package) | 功能 | resolvconf | 支持的协议 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 权威 | 递归 | 缓存 | 验证 DNSSEC |
DNS | DNSCrypt | DNS TLS 传输 |
DNS HTTPS 传输 |
DNS QUIC 传输 | |||
| BIND | bind | 是 | 是 | 是 | 是 | 是 | 是 | 否 | 是 | 服务器 | 否 |
| CoreDNS | corednsAUR | 是 | 否 | 是 | 否 | 否 | 是 | 否 | 是 | 服务器 | 否 |
| DNS-over-HTTPS | dns-over-https | 否 | 否 | 否 | 否 | 否 | 服务器 | 否 | 否 | 是 | 否 |
| Deadwood (MaraDNS 递归器) | maradnsAUR | 否 | 是 | 是 | 否 | 否 | 是 | 否 | 否 | 否 | 否 |
| dnscrypt-proxy | dnscrypt-proxy | 否 | 否 | 是 | 否 | 否 | 服务器 | 解析器 | 否 | 是 | 否 |
| dnsmasq | dnsmasq | 部分1 | 否 | 是 | 是2 | 是 | 是 | 否 | 否 | 否 | 否 |
| dnsproxy | dnsproxy | 否 | 否 | 是 | 否 | 否 | 是 | 是 | 是 | 是 | 是 |
| Knot Resolver | knot-resolver | 否 | 是 | 是 | 是 | 否 | 是 | 否 | 是 | 服务器 | 否 |
| pdnsd | pdnsd | 部分1 | 是 | 永久 | 否 | 是 | 是 | 否 | 否 | 否 | 否 |
| PowerDNS Recursor | powerdns-recursor | 否 | 是 | 是 | 是2 | 是 | 是 | 否 | 部分 | 否 | 否 |
| Rescached | rescached-gitAUR | 否 | 否 | 是 | 否 | 是 | 是 | 否 | 是 | 是 | 否 |
| RouteDNS | routedns-gitAUR | 否 | 否 | 是3 | 否 | 否 | 是 | 否 | 是 | 是 | 是 |
| SmartDNS | smartdns | 否 | 否 | 是 | 否 | 否 | 是 | 否 | 解析器 | 解析器 | 否 |
| Stubby | stubby | 否 | 否 | 否 | 是2 | 否 | 服务器 | 否 | 解析器 | 否 | 否 |
| systemd-resolved | systemd | 否 | 否 | 是 | 实验性2 | 是 | 解析器和有限的服务器 | 否 | 解析器 | 否 | 否 |
| Unbound | unbound | 部分 | 是 | 是3 | 是 | 是 | 是 | 服务器 | 是 | 服务器 | 服务器 |
仅权威服务器
| 名称 | 软件包 (Package) | DNSSEC 签名 |
地理 平衡 |
|---|---|---|---|
| gdnsd | gdnsd | 否 | 是 |
| Knot DNS | knot | 是 | 是 |
| MaraDNS | maradnsAUR | 否 | 否 |
| NSD | nsd | 是 | 否 |
| PowerDNS | powerdns | 是 | 是 |
条件转发
在查询特定域名时,可以使用特定的 DNS 解析器。这在连接到 VPN 时尤其有用,这样 VPN 网络中的查询就可以由 VPN 的 DNS 解析,而对互联网的查询仍由您的标准 DNS 解析器解析。它也可以在本地网络中使用。
要实现它,您需要使用一个本地解析器,因为 glibc 不支持它。
在动态环境中(笔记本电脑,有时也包括台式机),您需要根据您连接的网络来配置解析器。最好的方法是使用 openresolv,因为它支持多个订阅者。一些 网络管理器支持它,无论是通过 openresolv 还是直接配置解析器。NetworkManager 支持在没有 openresolv 的情况下进行条件转发。
参见
- Linux 网络管理员指南
- Debian Handbok
- RFC:7706 - 通过在本地运行根服务器来减少访问根服务器的时间
- 域名系统概述 - DNS 图解
- DNS 代表什么