# Domain name resolution (简体中文)

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
翻译状态：本文是 Domain name resolution 的翻译。上次翻译日期：2021-07-25。如果英文版本有所更改，则您可以帮助同步翻译。

通常，一个域名代表了一个 IP 地址，并在域名系统（Domain Name System，DNS）中与其关联。本文将介绍如何配置域名解析和解析域名。

## 名称服务转换（NSS）

名称服务转换（Name Service Switch，NSS）工具是 GNU C 库（glibc）的一部分，支持 getaddrinfo(3) API，用于解析域名。NSS 允许系统数据库由单独的服务提供，其搜索顺序可由管理员在 nsswitch.conf(5) 中配置。负责响应域名解析的数据库是 hosts 数据库，glibc 为此提供了下列服务：

- files（文件）：读取 `/etc/hosts` 文件，参见 hosts(5)
- dns：读取 `/etc/resolv.conf` 的 glibc 解析器，参见 resolv.conf(5)

Systemd 为主机名解析提供了三项 NSS 服务：

- nss-resolve(8) —— 缓存 DNS 存根解析器，systemd-resolved 一文中有描述
- nss-myhostname(8) —— 无需编辑 `/etc/hosts` 即可提供本地主机名解析，Network Configuration#Local hostname resolution 一文中有描述
- nss-mymachines(8) —— 为本地 systemd-machined(8) 容器的名称提供本地主机名解析

### 使用 NSS 解析域名

NSS 数据库可使用 getent(1) 查询。可以使用以下命令通过 NSS 解析域名：

    $ getent hosts domain_name（域名）

注意： 虽然大多数程序使用 NSS 解析域名，但是有些程序可能会直接读取 `/etc/resolv.conf` 和/或 `/etc/hosts`。参见 Network configuration#Local hostname resolution。

## Glibc 解析器

### 覆盖 /etc/resolv.conf

网络管理器们会有意覆盖 `/etc/resolv.conf`，具体细节请参见相应文章章节：

- dhcpcd#/etc/resolv.conf
- netctl#resolv.conf
- NetworkManager#/etc/resolv.conf

要防止程序覆盖 `/etc/resolv.conf`，还可以通过设置不可变文件属性来为其建立写保护：

    # chattr +i /etc/resolv.conf

提示： 如果想要多个进程写入 `/etc/resolv.conf`，可以使用 resolvconf。

### 限制查找时间

如果您遇到了非常长时间查找主机名的情况（可能是在 pacman 里或者在浏览网页时），定义一个小的超时时间通常能对问题有所帮助，在此之后系统会使用备用域名服务器（nameserver）。为此，请在 `/etc/resolv.conf` 中添加以下内容。

    options timeout:1

### IPv6 主机名查找延迟

如果在解析主机名时遇到 5 秒延迟的情况，原因可能是 DNS 服务器/防火墙行为不当，只对并行的 A 和 AAAA 请求给出了一个回应。[1] 可以在 `/etc/resolv.conf` 中设置以下选项来修复问题：

    options single-request

### 本地域名

为了能够使用本地机器名称的主机名，而无需使用格式完全合格的域名，请在 `/etc/resolv.conf` 中添加一行本地域名，如：

    domain example.org

这样当使用 ssh 命令时，可以把 `mainmachine1.example.org` 这样的本地主机简单地称为 `mainmachine1`，不过使用 drill 命令时仍需要格式完全合格的域名以便查找。

## 查找实用工具

要查询特定的 DNS 服务器和 DNS/DNSSEC 记录，可以使用专用 DNS 查询实用工具。这些工具自身实现了 DNS 功能，不使用 NSS。

ldns 软件包提供了 drill(1) 命令，是一个旨在检索 DNS 信息的工具。

例如，要用 drill 查询特定名称服务器（nameserver）获取一个域名的 TXT 记录，可执行：

    $ drill @nameserver TXT domain（域名）

除非指定了一个 DNS 服务器，否则 drill 将使用 `/etc/resolv.conf` 中定义的名称服务器。

提示： 一些 DNS 服务器附带它们自己的 DNS 查找实用工具。例如：

- knot 软件包提供了 khost(1) 和 kdig(1) 命令。
- Unbound 有 unbound-host(1)。
- BIND 有 dig(1)、host(1)、nslookup(1) 和一堆 `dnssec-` 工具。

## 解析器性能

Glibc 不缓存查询结果。要实现本地缓存，请使用 systemd-resolved 或者配置一个本地缓存 DNS 服务器将其用作服务器，方法是在 `/etc/resolv.conf`（如果使用 openresolv，则在 `/etc/resolvconf.conf`）中设置 `127.0.0.1` 和 `::1` 为名称服务器。

提示：

- drill 或 dig 查找实用工具能报告查询时间。
- 路由器通常将自己的缓存解析器设置为网络的 DNS 服务器，从而为整个网络提供 DNS 缓存。
- 如果切换到下一个 DNS 服务器的时间过长，可以尝试减少超时时间。

## 隐私与安全

传统的 DNS 协议是没有加密的，并且不会考虑传输的机密性、完整性和身份验证问题，所以如果您在使用不受信任的网络或者有恶意行为的网络服务供应商（ISP），您的 DNS 查询可能会被窃听并响应他人的操纵。此外，DNS 服务器可进行 DNS 劫持。

您需要相信您的 DNS 服务器处理您的查询时能够保密。网络服务供应商和第三方会提供 DNS 服务器。 另外您也可以运营自己的递归名称服务器，但这需要花费更多精力。 如果您在不受信任的网络中使用 DHCP 客户端，请一定要设置静态名称服务器，以避免使用和受制于任意 DNS 服务器。 为了保证您与远程 DNS 服务器的通信安全，您可以使用加密协议，例如 DNS over TLS（RFC 7858）、DNS over HTTPS（RFC 8484）或 DNSCrypt，前提是上游服务器和您的解析器都支持该协议。 另一种方法是使用专用软件来加密和解密通信，例如 stunnel。 要验证响应是否来自权威的名称服务器，您可以验证 DNSSEC 记录，前提是上游服务器和您的解析器都支持它。

### 应用级 DNS

值得注意的是，一些客户端软件，例如主流的网页浏览器[2][3]，都在开始实现 DNS over HTTPS 功能。虽然一般来说，提供加密查询可以视为一种善举，但这也同时意味着软件可以绕过系统解析器配置，另辟蹊径进行查询。[4]

Firefox 提供了配置选项来启用或禁用 DNS over HTTPS 和选择 DNS 服务器。

Chromium 会检查用户的系统解析器，如果得知系统解析器地址也提供 DNS over HTTPS 支持，则启用 DNS over HTTPS 功能。请参见这篇博文获取更多信息，了解如何禁用 DNS over HTTPS。

Mozilla 提议，如果系统解析器无法解析域名 `use-application-dns.net`，就普遍禁用应用级 DNS。目前，这一功能仅在 Firefox 中实现了。

### 遗忘式 DNS

遗忘式 DNS（Oblivious DNS，ODNS） 是一套解决了若干 DNS 关切隐私问题的系统。参见 Cloudflare 的文章（英文）获取更多信息。

## 第三方 DNS 服务

注意： 在使用第三方 DNS 服务前，请检查其隐私政策，了解其如何处理用户数据。用户数据是有价值的，可以出售给其他各方。

现在有各种第三方 DNS 服务可用，其中有一些还有专用软件：

- cloudflared — Clondflare DNS over HTTPS 的 DNS 客户端

  https://developers.cloudflare.com/1.1.1.1/dns-over-https/cloudflared-proxy || cloudflaredAUR, cloudflared-binAUR

- dingo — Google DNS over HTTPS 的 DNS 客户端

  https://github.com/pforemski/dingo || dingo-gitAUR

- opennic-up — 可以自动更新为反应最迅速的 OpenNIC DNS 服务器

  https://github.com/kewlfft/opennic-up || opennic-upAUR

- nextdns — NextDNS 的 DNS-over-HTTPS 命令行客户端

  https://github.com/nextdns/nextdns || nextdnsAUR

可以使用 dnsperftest 从您所在位置来测试主流 DNS 解析器们的性能。dnsperf.com 提供了全球 DNS 服务供应商的基准。

## DNS 服务器

DNS 服务器有权威式和递归式。如果两个都不是，则称为根解析器，只将所有查询转发到其他的递归名称服务器。根解析器典型用途是在本地主机或网络上引入 DNS 缓存机制。请注意，同样的功能可以通过技术完全成熟的名称服务器来实现。本小节我们比较了可用的 DNS 服务器，如需更详细的比较，请参考维基百科：DNS 服务器软件比较。

名称 | 软件包 | 功能兼容性 | resolvconf | 受支持的协议
--- | --- | --- | --- | ---
权威式 | 递归式 | 缓存式 | 验证 DNSSEC | DNS | DNSCrypt | DNS over TLS | DNS over HTTPS
BIND | bind | 是 | 是 | 是 | 是 | 是 | 是 | 否 | stunnel#DNS over TLS | 否
CoreDNS | corednsAUR 或 coredns-binAUR | ？ | ？ | ？ | ？ | ？ | ？ | ？ | 是 | ？
Deadwood (MaraDNS recursor) | maradnsAUR | 否 | 是 | 是 | 否 | 否 | 是 | 否 | 否 | 否
dnscrypt-proxy | dnscrypt-proxy | 否 | 否 | 是 | 否 | 否 | 服务器 | 解析器 | 否 | 是
dnsmasq | dnsmasq | 部分1 | 否 | 是 | 是 | 是 | 否 | 否 | 否 | 否
Knot Resolver | knot-resolver | 否 | 是 | 是 | 是 | 否 | 是 | 否 | 是 | 服务器
pdnsd | pdnsd | 是 | 是 | 永久 | 否 | 是 | 是 | 否 | 否 | 否
PowerDNS Recursor | powerdns-recursor | 否 | 是 | 是 | 是 | 是 | 是 | 否 | 否 | 否
Rescached | rescached-gitAUR | 否 | 否 | 是 | 否 | 是 | 是 | 否 | 否 | 有限2
SmartDNS | smartdns | 否 | 否 | 是 | 否 | ? | 是 | 否 | 解析器 | 解析器
Stubby | stubby | 否 | 否 | 否 | 是 | 否 | 服务器 | 否 | 解析器 | 否
systemd-resolved | systemd | 否 | 否 | 是 | 是 | 是 | 解析器和有限的服务器 | 否 | 解析器 | 否
Unbound | unbound | 部分 | 是 | 是3 | 是 | 是 | 是 | 服务器 | 是 | 服务器

1. 根据维基百科：dnsmasq 对权威式名称服务器功能支持有限，是旨在为内部网络使用而不是公共互联网使用。
2. 只有当 Rescached 本身使用 DNS over HTTPS 查询时，才会使用 DNS over HTTPS 进行转发。
3. Redis 后端可为 Unbound 提供持久性缓存功能。

### 仅权威式服务器

名称 | 软件包 | DNSSEC | 地理负载均衡
--- | --- | --- | ---
gdnsd | gdnsd | 否 | 是
Knot DNS | knot | 是 | 是
MaraDNS | maradnsAUR | 否 | ？
NSD | nsd | 否 | 否
PowerDNS | powerdns | 是 | 是

### 条件转发

在查询特定域名时，可以使用特定的 DNS 解析器。这在连接到虚拟专用网络（VPN）时特别有用，这样，对 VPN 网络的查询由 VPN 的 DNS 解析，而对普通互联网的查询仍由标准 DNS 解析器解析（分流）。这也可以用于本地网络中。

要实现这个目的，您需要使用本地解析器，因为 glibc 并不支持这样做。

在动态环境中（笔记本和某种程度的台式机），需要根据所连接的网络来配置解析器。最好的方式是使用 openresolv，因为它支持多个订阅器。一些网络管理器会通过 openresolv 或者直接通过配置解析器来支持此功能。NetworkManager 支持条件转发而无需 openresolv。

注意： 虽然您可以使用其他条件进行转发（比如源 IP 地址），但是“条件转发”一名似乎更用于描述“域名查询”这一条件。

## 另请参阅

- Linux 网络管理员指南（英文）
- Debian 手册（英文）
- RFC:7706 - 通过在回环上运行一个根服务器来减少对根服务器的访问时间（Decreasing Access Time to Root Servers by Running One on Loopback，英文）
- 域名系统概览（英文） - DNS 有关图表
- 备用 DNS 服务

Categories:

- Domain Name System (简体中文)
- Network configuration (简体中文)