域名解析 - Arch Linux 中文维基

跳转到内容

# 域名解析

来自 Arch Linux 中文维基
翻译状态：

- 本文（或部分内容）译自 Domain name resolution，最近一次同步于 2024-11-22，若英文版本有所更改，则您可以帮助同步与翻译更改的内容。
- 您可以在 ArchWiki 的对应页面找到本文翻译的原始修订历史。
- 本文可能与英文原文存在出入。

通常，一个域名代表了一个 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` 即可提供本地主机名解析，网络配置#Local hostname resolution 一文中有描述
- nss-mymachines(8)——为本地 systemd-machined(8) 容器的名称提供本地主机名解析

### 使用 NSS 解析域名

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

    $ getent ahosts domain_name（域名）

注意：虽然大多数程序使用 NSS 解析域名，但是有些程序可能会直接读取 `/etc/resolv.conf` 和/或 `/etc/hosts`。参见 网络配置#局域网主机名解析。

## Glibc 解析器

### 覆盖 /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#/etc/resolv.conf。

附注： NetworkManager 有专门的章节来介绍这一主题。（在 Talk:域名解析 中讨论）

如果使用 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)。

### 限制查找时间

如果您遇到了非常长时间查找主机名的情况（可能是在 pacman 里或者在浏览网页时），定义一个小的超时时间通常能对问题有所帮助，在此之后系统会使用备用域名服务器（nameserver）。为此，请在 `/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 功能，不使用 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-` 工具。
- systemd-resolved 有 resolvectl(1)，它提供了用于DNS 查找的`query`子命令。

## 解析器性能

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 解析器，但浏览器在请求网站证书时仍会泄漏服务器名称指示（Server Name Indication, SNI）中的域名。可以使用 Wireshark 过滤器 `tls.handshake.extensions_server_name_len > 0` 或者下面的命令检查这种泄漏。建议的解决方案是使用ECH (Encrypted Client Hello)，这是 TLS 1.3 协议的扩展。

    # tshark -p -Tfields -e tls.handshake.extensions_server_name -Y 'tls.handshake.extensions_server_name_len>0'

### 应用级 DNS

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

Firefox 提供了配置选项来启用或禁用 DNS over HTTPS 和选择 DNS 服务器。Mozilla 设立了可信递归解析器 (TRR) 计划，并提供了默认提供商的透明度信息。这里要注意，Firefox 支持并自动为 TRR 提供商启用 ECH，请参阅 Firefox/隐私#加密客户端问候。

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

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

### 遗忘式 DNS

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

## 第三方 DNS 服务

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

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

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

  https://developers.cloudflare.com/1.1.1.1/dns-over-https/cloudflared-proxy || cloudflared包

- 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 服务器软件比较。

这篇文章的某些内容需要扩充。

原因：Fill in the unknowns. (在 Talk:域名解析 中讨论)

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

1. BIND 可以为 DNS over TLS 和 DNS over HTTPS 提供服务（请参阅 tls{} 和listen-on)），但尚无法将查询转发到 DNS over TLS/DNS over HTTPS 上游。 dig 工具可以通过 DNS over TLS 和 DNS over HTTPS（使用 `+tls` 和 `+https` 选项）进行查询，但没有任何证书检查。
2. 根据维基百科：对权威式名称服务器功能支持有限，是旨在为内部网络使用而不是公共互联网使用。
3. 支持使用 Redis 后端进行持久缓存。

### 仅权威式服务器

名称 | 软件包 | 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 服务
- What does DNS stand for

分类：​

- DNS
- 网络配置

隐藏分类：​

- 使用“模板:合并”标记的页面或章节

域名解析
添加话题