Linux 下 DNS 配置详解:从原理到实践

DNS(域名系统)是互联网的基础设施之一,它负责将人类可读的域名(如 www.example.com)转换为计算机可识别的 IP 地址(如 93.184.216.34)。在 Linux 系统中,正确配置 DNS 不仅关系到网络连接的稳定性,还可能影响隐私(如通过加密 DNS)和访问速度。

本文将从 DNS 在 Linux 中的工作原理讲起,详细介绍多种修改 DNS 配置的方法(包括传统方式和现代工具),并总结最佳实践与常见问题排查技巧。无论你是桌面用户还是服务器管理员,都能从中找到适合自己的配置方案。

目录#

  1. DNS 在 Linux 中的工作原理
  2. 修改 DNS 的常用方法
  3. DNS 配置最佳实践
  4. 常见问题与故障排查
  5. 总结
  6. 参考资料

1. DNS 在 Linux 中的工作原理#

在 Linux 中,DNS 解析流程主要依赖 解析器(Resolver) 和 配置文件/服务 的协同工作。核心组件包括:

  • 解析器库:如 glibc 的 libresolv,应用程序通过它发起 DNS 查询。
  • /etc/resolv.conf:解析器的主要配置文件,记录 DNS 服务器地址和解析规则。
  • 本地缓存服务:如 systemd-resolved、dnsmasq 或 unbound,用于缓存 DNS 结果以加速解析。
  • 网络管理工具:如 NetworkManager(桌面)、Netplan(Ubuntu Server),负责动态管理 DNS 配置(如从 DHCP 获取 DNS)。

工作流程简化:
当你在终端执行 ping www.google.com 时:

  1. 应用程序(如 ping)调用解析器库,请求解析 www.google.com。
  2. 解析器检查本地缓存(如 systemd-resolved 的缓存),若命中则直接返回结果。
  3. 若未命中,解析器读取 /etc/resolv.conf 中的 DNS 服务器地址,向其发送查询请求。
  4. DNS 服务器返回 IP 地址,解析器将结果缓存并返回给应用程序。

2. 修改 DNS 的常用方法#

2.1 直接编辑 /etc/resolv.conf(传统方式)#

/etc/resolv.conf 是 Linux 中最古老的 DNS 配置文件,早期系统直接通过它指定 DNS 服务器。但现代 Linux 系统(如使用 systemd 的发行版)中,该文件可能由其他服务(如 systemd-resolved)自动生成,手动修改可能被覆盖。

适用场景:#

  • 无网络管理工具(如极简服务器)。
  • 临时测试 DNS 配置(重启后可能失效)。

配置步骤:#

  1. 查看当前配置:

    cat /etc/resolv.conf

    若输出中包含 # Generated by ...(如 systemd-resolved 或 NetworkManager),则该文件由工具自动管理,手动修改可能无效。

  2. 临时修改(仅当前会话有效):
    用文本编辑器(如 vim 或 nano)打开文件,添加或修改 nameserver 字段(最多 3 个,按优先级排序):

    sudo vim /etc/resolv.conf

    示例配置(使用 Cloudflare DNS 和 Google DNS):

    nameserver 1.1.1.1       # Cloudflare DNS
    nameserver 8.8.8.8       # Google DNS
    options timeout:2 attempts:3  # 超时时间 2 秒,重试 3 次
  3. 使配置生效:
    无需重启服务,修改后立即生效(但部分程序可能需要重启以读取新配置)。

注意事项:#

  • 自动覆盖问题:若系统使用 systemd-resolved 或 NetworkManager,重启后 /etc/resolv.conf 会被重置。需通过对应工具修改(见下文)。
  • 权限:修改需 root 权限(使用 sudo)。

2.2 使用 systemd-resolved(现代系统推荐)#

systemd-resolved 是 systemd 生态中的 DNS 解析服务,负责管理 DNS 缓存、解析规则和 /etc/resolv.conf。它是大多数现代 Linux 发行版(如 Ubuntu 20.04+、Fedora、Arch Linux)的默认服务。

核心优势:#

  • 自动管理 /etc/resolv.conf(通过符号链接指向 /run/systemd/resolve/stub-resolv.conf)。
  • 支持按网络接口(如 Wi-Fi、以太网)配置不同 DNS。
  • 内置 DNS 缓存和 DNSSEC(域名系统安全扩展)支持。

配置步骤:#

2.2.1 查看当前 DNS 状态#
resolvectl status  # 查看所有接口的 DNS 配置
resolvectl query www.baidu.com  # 测试 DNS 解析
2.2.2 全局 DNS 配置(所有接口生效)#

修改 /etc/systemd/resolved.conf,这是 systemd-resolved 的主配置文件:

sudo vim /etc/systemd/resolved.conf

添加以下内容(以 Cloudflare 和 Quad9 DNS 为例):

[Resolve]
DNS=1.1.1.1 9.9.9.9  # DNS 服务器列表(空格分隔)
FallbackDNS=8.8.8.8 8.8.4.4  # 备选 DNS(当主 DNS 不可用时)
Domains=~.  # 对所有域名使用上述 DNS(`~.` 表示全局)
DNSSEC=yes  # 启用 DNSSEC(可选,增强安全性)

重启服务使配置生效:

sudo systemctl restart systemd-resolved
sudo systemctl enable systemd-resolved  # 确保开机自启
2.2.3 按接口配置 DNS(特定网络生效)#

若需为某个接口(如 eth0 或 wlan0)单独配置 DNS,可创建 每接口配置文件:

sudo mkdir -p /etc/systemd/resolved.conf.d/
sudo vim /etc/systemd/resolved.conf.d/eth0.conf  # 文件名格式:<接口名>.conf

添加接口专属配置:

[Resolve]
DNS=223.5.5.5 223.6.6.6  # 阿里 DNS
Domains=example.com  # 仅对 example.com 域名使用该 DNS

重启服务后,通过 resolvectl status eth0 验证:

resolvectl status eth0
# 输出应包含:DNS Servers: 223.5.5.5 223.6.6.6

2.3 通过 NetworkManager 配置(桌面环境常用)#

NetworkManager 是 Linux 桌面环境(如 GNOME、KDE)的默认网络管理工具,它会自动管理 DNS 配置(通常从 DHCP 获取)。若需手动修改,可通过命令行或图形界面操作。

适用场景:#

  • 桌面用户(如 Ubuntu Desktop、Fedora Workstation)。
  • 需要为特定网络连接(如家庭 Wi-Fi、公司以太网)配置不同 DNS。

配置步骤(命令行方式):#

2.3.1 查看网络连接名称#
nmcli connection show  # 列出所有网络连接(NAME 列即连接名称)
# 示例输出:NAME                UUID                                  TYPE      DEVICE
#          Wired connection 1  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  ethernet  eth0
2.3.2 修改指定连接的 DNS#

以连接名称 Wired connection 1 为例,设置 DNS 为 Google DNS:

sudo nmcli connection modify "Wired connection 1" ipv4.dns "8.8.8.8,8.8.4.4"
# 设置 IPv6 DNS(可选):
sudo nmcli connection modify "Wired connection 1" ipv6.dns "2001:4860:4860::8888,2001:4860:4860::8844"

设置 DNS 优先级(避免被 DHCP 覆盖):

sudo nmcli connection modify "Wired connection 1" ipv4.ignore-auto-dns yes  # 忽略 DHCP 提供的 DNS
sudo nmcli connection modify "Wired connection 1" ipv6.ignore-auto-dns yes

应用配置并重启连接:

sudo nmcli connection up "Wired connection 1"  # 重新激活连接
2.3.3 图形界面配置(适合桌面用户)#

以 GNOME 为例:

  1. 打开 设置 → 网络,选择当前连接(如有线或 Wi-Fi)。
  2. 点击齿轮图标进入详情页,切换到 IPv4 或 IPv6 选项卡。
  3. 将 方法 设为 手动(或保留 自动 但关闭“自动获取 DNS”),在 DNS 栏输入 8.8.8.8,8.8.4.4。
  4. 点击 应用 保存设置。

2.4 使用 Netplan(Ubuntu Server 专用)#

Netplan 是 Ubuntu 18.04+ 服务器版默认的网络配置工具,通过 YAML 文件定义网络规则,包括 DNS。

适用场景:#

  • Ubuntu Server(18.04+)或基于 Netplan 的服务器(如 Kubernetes 节点)。
  • 需要配置静态 IP 和 DNS 的服务器环境。

配置步骤:#

2.4.1 找到 Netplan 配置文件#

Netplan 配置文件位于 /etc/netplan/,文件名通常为 00-installer-config.yaml 或 50-cloud-init.yaml(由 cloud-init 生成):

ls /etc/netplan/
2.4.2 编辑配置文件#

以 00-installer-config.yaml 为例,添加 DNS 配置:

sudo vim /etc/netplan/00-installer-config.yaml

示例配置(静态 IP + DNS):

network:
  version: 2
  renderer: networkd  # 使用 systemd-networkd 作为后端(服务器推荐)
  ethernets:
    eth0:  # 网卡名称(通过 `ip link` 查看)
      addresses: [192.168.1.100/24]  # 静态 IP 和子网掩码
      gateway4: 192.168.1.1  # 网关(IPv4)
      nameservers:
        addresses: [114.114.114.114, 119.29.29.29]  # DNS 服务器(国内常用 114DNS)
        search: [example.com]  # 搜索域(可选,解析短域名时自动补全)

注意:YAML 语法严格缩进(使用空格,不能用 Tab),冒号后需加空格。

2.4.3 应用配置#
sudo netplan apply  # 应用配置(立即生效)
# 若需调试,可执行:sudo netplan try  # 测试配置,按 Enter 确认

3. DNS 配置最佳实践#

无论使用哪种方法,以下原则可确保 DNS 配置的稳定性和安全性:

3.1 选择可靠的 DNS 服务器#

优先使用知名公共 DNS 或企业内部 DNS,避免随机第三方服务:

  • 国内常用:114DNS(114.114.114.114)、阿里 DNS(223.5.5.5)、腾讯 DNS(119.29.29.29)。
  • 国际常用:Cloudflare(1.1.1.1,隐私优先)、Google(8.8.8.8,速度快)、Quad9(9.9.9.9,安全过滤恶意域名)。

3.2 避免配置冲突#

  • 若使用 systemd-resolved,不要手动修改 /etc/resolv.conf(它通常是指向 /run/systemd/resolve/stub-resolv.conf 的符号链接)。
  • NetworkManager 和 Netplan 不要同时管理同一网卡(服务器建议禁用 NetworkManager,仅保留 Netplan)。

3.3 启用 DNS 加密(增强隐私)#

  • DNS over TLS (DoT):通过 TLS 加密 DNS 查询(端口 853),systemd-resolved 支持配置(需在 /etc/systemd/resolved.conf 中添加 DNSOverTLS=yes)。
  • DNS over HTTPS (DoH):通过 HTTPS 加密 DNS(如 Cloudflare 的 https://cloudflare-dns.com/dns-query),可配合 unbound 或浏览器插件实现。

3.4 配置多个 DNS 服务器#

至少设置 2 个 DNS 服务器(主备分离),避免单点故障。例如:

nameserver 1.1.1.1  # 主 DNS
nameserver 8.8.8.8  # 备用 DNS

3.5 测试 DNS 解析效率#

使用 dig 或 nslookup 测试解析速度和可用性:

dig www.baidu.com  # 查看解析耗时(`Query time` 字段)
dig @1.1.1.1 www.google.com  # 指定 DNS 服务器测试

4. 常见问题与故障排查#

4.1 /etc/resolv.conf 被自动覆盖#

原因:现代系统中,systemd-resolved、NetworkManager 或 Netplan 会自动管理 /etc/resolv.conf。
解决:

  • 若使用 systemd-resolved:通过 /etc/systemd/resolved.conf 或接口配置文件修改。
  • 若使用 NetworkManager:通过 nmcli 修改连接的 DNS 设置。

4.2 DNS 配置不生效#

排查步骤:

  1. 检查服务状态:
    # systemd-resolved 用户:
    sudo systemctl status systemd-resolved  # 确保服务运行正常
    # NetworkManager 用户:
    sudo systemctl status NetworkManager
  2. 验证 DNS 是否被正确应用:
    resolvectl status  # 查看当前 DNS 服务器
    cat /etc/resolv.conf  # 确认 nameserver 字段是否正确
  3. 检查防火墙是否阻止 DNS 端口(UDP 53,DoT 为 TCP 853):
    sudo ufw status  # 若启用 UFW,确保允许 DNS 流量

4.3 DNS 解析缓慢或失败#

可能原因:

  • DNS 服务器响应慢:尝试更换公共 DNS(如从 Google 切换到 Cloudflare)。
  • 本地缓存污染:清除 systemd-resolved 缓存:
    sudo resolvectl flush-caches
  • IPv6 配置问题:若 IPv6 DNS 不可用,可禁用 IPv6 或仅使用 IPv4 DNS。

5. 总结#

Linux 下修改 DNS 的方法因系统环境而异:

  • 桌面用户:优先使用 NetworkManager(图形界面或 nmcli)。
  • 现代服务器(systemd 系统):推荐 systemd-resolved,支持灵活的全局/接口配置。
  • Ubuntu Server:通过 Netplan 的 YAML 文件定义静态 DNS。

核心原则是:避免配置冲突,选择可靠 DNS 服务器,并通过 dig 或 resolvectl 验证配置。遵循最佳实践(如启用 DNSSEC、加密 DNS)可进一步提升网络安全性和隐私性。

6. 参考资料#