修改 Linux 的 DNS 配置完全指南 – wiki基地


修改 Linux 的 DNS 配置完全指南

引言:理解 DNS 在 Linux 中的作用与重要性

在当今的网络世界中,域名系统(DNS,Domain Name System)扮演着至关重要的角色。它就像互联网的电话簿,将人类易于记忆的域名(如 www.google.com)转换成机器可以理解的 IP 地址(如 172.217.160.196)。当我们尝试访问一个网站、连接到一个网络服务或进行任何基于域名的通信时,我们的操作系统首先会向配置的 DNS 服务器查询目标域名的 IP 地址。

对于 Linux 用户而言,正确配置 DNS 不仅关系到能否正常访问互联网资源,还可能影响网络连接的速度、稳定性和安全性。有时,出于以下原因,我们可能需要修改 Linux 系统的 DNS 配置:

  1. 提升速度: 使用距离更近或性能更好的 DNS 服务器可以加快域名解析速度,从而感觉网络更快。
  2. 增强隐私: 默认使用 ISP(互联网服务提供商)的 DNS 服务器,他们的日志可能会记录你的浏览历史。切换到注重隐私的第三方 DNS 提供商(如 Cloudflare 的 1.1.1.1)可以减少这种跟踪。
  3. 绕过限制或过滤: 某些网络环境(如学校、公司)可能通过 DNS 屏蔽特定网站。更换 DNS 服务器有时可以绕过这些限制。
  4. 访问特定内部资源: 在企业或局域网环境中,可能需要配置指向内部 DNS 服务器以解析内部域名。
  5. 故障排除: 当遇到网站无法访问或网络连接问题时,测试不同的 DNS 服务器是常见的故障排除步骤。
  6. 使用特定功能: 一些公共 DNS 提供商提供额外的功能,如恶意网站过滤(如 OpenDNS)、家庭安全保护等。

然而,在 Linux 中修改 DNS 配置有时可能不像在图形界面中简单填写几个数字那样直观。这是因为 Linux 的 DNS 配置可以通过多种方式进行管理,不同的发行版、不同的网络管理工具以及不同的网络连接方式(DHCP 或静态 IP)都会影响最终的配置方式。本指南将详细探讨在 Linux 中修改 DNS 配置的各种方法,帮助你理解背后的原理,并找到适用于你系统的最佳实践。

核心文件:/etc/resolv.conf 的作用与困境

在 Linux 系统中,用于配置域名解析的核心文件是 /etc/resolv.conf。这个文件包含了 DNS 客户端(resolver)用于查询域名的信息。它的基本格式非常简单,主要由以下指令组成:

  • nameserver <IP 地址>:指定一个 DNS 服务器的 IP 地址。可以有多行 nameserver 指令,系统会按照它们出现的顺序依次尝试。通常最多可以指定 3 个或 4 个。
  • search <域名1> [域名2 ...]:指定一个域名搜索列表。当用户输入的域名不是完全限定域名(FQDN,Fully Qualified Domain Name,例如 www.google.com. 最后的点表示根)时,系统会尝试将搜索列表中的每个域名后缀附加到用户输入的域名后面进行解析。例如,如果搜索列表包含 mydomain.com,用户输入 webserver,系统会先尝试解析 webserver.mydomain.com
  • domain <域名>:指定默认的域名。这与 search 指令类似,但通常只指定一个默认域名。如果同时存在 searchdomainsearch 通常会覆盖或扩展 domain
  • options <选项> [...]:指定一些解析器选项,例如 timeout (查询超时时间)、attempts (查询重试次数)、ndots (在尝试搜索列表之前,域名中包含多少个点才认为是 FQDN)。

示例 /etc/resolv.conf 文件:

“`conf

Generated by NetworkManager

search mydomain.com
nameserver 8.8.8.8
nameserver 8.8.4.4
“`

这个文件看起来非常简单,理论上我们只需编辑它就可以修改 DNS。然而,/etc/resolv.conf 的一个常见“困境”是它经常是临时的或由其他服务自动生成和管理的。这意味着你手动修改的内容很可能在系统重启、网络服务重启、网络接口状态变化(如从有线切换到 Wi-Fi,或者 DHCP 租约更新)之后被覆盖掉。

为什么会这样?因为在现代 Linux 发行版中,网络配置通常由后台服务(守护进程)管理,它们负责根据网络连接状态动态生成 /etc/resolv.conf 文件。常见的管理工具有:

  • NetworkManager: 桌面和笔记本电脑上最常见的网络管理工具,尤其是在 GNOME、KDE 等桌面环境中。它根据用户在图形界面或 nmcli 命令中配置的信息生成 /etc/resolv.conf
  • systemd-resolved: systemd 项目提供的一个网络名字解析服务。它作为一个本地的 Stub Resolver(存根解析器)运行,应用程序查询 systemd-resolved,然后由它负责转发请求到实际的上游 DNS 服务器。在这种模式下,/etc/resolv.conf 通常被配置为一个指向本地地址(127.0.0.53)的符号链接或文件,实际的上游 DNS 服务器配置则保存在 systemd-resolved 的内部配置或由其通过其他方式(如 systemd-networkd、DHCP)获取。
  • resolvconf (utility): 一个较旧但仍在一些系统上使用的框架,它收集来自不同来源(如 DHCP 客户端、手动配置)的 DNS 信息,并据此生成 /etc/resolv.conf
  • 传统网络脚本: 在没有 NetworkManager 或 systemd 的较旧系统或某些服务器发行版上,网络可能是通过 /etc/network/interfaces (Debian/Ubuntu) 或 /etc/sysconfig/network-scripts/ (RHEL/CentOS) 等文件配置,并在其中直接指定 DNS 服务器。

因此,仅仅编辑 /etc/resolv.conf 通常只能实现临时性的修改。要实现永久修改,我们需要识别出系统中负责管理 /etc/resolv.conf 的服务,并通过该服务提供的接口进行配置。

识别你的系统如何管理 /etc/resolv.conf

在你开始进行永久性修改之前,了解你的系统是如何管理 /etc/resolv.conf 是非常重要的。以下是一些检查方法:

  1. 查看文件头部的注释: 打开 /etc/resolv.conf 文件,通常文件顶部会有注释说明它是如何生成的,例如 # Generated by NetworkManager# Generated by systemd-resolved
  2. 检查是否是符号链接: 运行 ls -l /etc/resolv.conf。如果它是一个符号链接,它会指向另一个位置,比如 /run/systemd/resolve/stub-resolv.conf (systemd-resolved) 或 /etc/resolvconf/resolv.conf (resolvconf utility)。
  3. 检查运行中的服务: 使用 systemctl status systemd-resolvedsystemctl status NetworkManager 来查看这些服务是否正在运行。
  4. 检查 DHCP 客户端: 如果你的网络配置是通过 DHCP 获取的,那么 DHCP 客户端(如 dhclientdhcpcd)可能会在获取 IP 地址的同时获取 DNS 信息并更新 /etc/resolv.conf。检查你的系统使用了哪个 DHCP 客户端。

了解了是哪个服务在管理 /etc/resolv.conf 后,你就可以选择相应的配置方法来实现永久修改。

方法一:手动修改 /etc/resolv.conf (临时性)

这是最简单、最直接的方法,适用于需要快速测试某个 DNS 服务器或临时修改解析行为的场景。

  1. 打开终端:
    bash
    sudo nano /etc/resolv.conf
    # 或者使用你喜欢的编辑器,如 vi, vim, gedit 等

  2. 编辑文件内容:
    删除或注释掉原有的 nameserver 行,添加你想使用的 DNS 服务器地址。例如,使用 Google Public DNS:
    “`conf
    # Generated by NetworkManager (或者其他注释,保留或删除均可)
    # 原有的 nameserver 行可以注释掉或删除
    # nameserver 192.168.1.1

    添加新的 DNS 服务器

    nameserver 8.8.8.8
    nameserver 8.8.4.4

    可选:添加搜索域名,如果需要

    search mylocaldomain.com

    “`

  3. 保存并关闭文件:
    在 nano 中,按 Ctrl+X,然后按 Y 确认保存,最后按 Enter 键。

效果: 你的系统会立即开始使用新的 DNS 服务器进行域名解析。

局限性: 如前所述,这种修改在大多数现代系统上是临时的,可能会在网络服务重启、系统重启或网络状态变化后被覆盖。不要依赖这种方法进行永久性配置。

方法二:使用 NetworkManager 进行配置 (图形界面 & CLI)

NetworkManager 是许多桌面 Linux 发行版的默认网络管理工具。它提供了图形界面和命令行接口 (nmcli) 来配置网络,包括 DNS。通过 NetworkManager 进行的配置是持久性的。

2.1 使用图形界面配置 (适用于桌面环境)

具体步骤可能因桌面环境(GNOME, KDE, XFCE 等)而异,但基本流程相似:

  1. 打开网络设置: 通常在系统设置或控制面板中找到“网络”或“网络连接”选项。
  2. 选择你的网络连接: 找到你当前使用的连接(例如,有线连接 Ethernet, Wi-F 无线连接名称)。
  3. 编辑连接设置: 点击连接旁边的齿轮图标、属性按钮或“编辑”选项。
  4. 进入 IPv4/IPv6 设置: 在连接设置窗口中,找到 IPv4 或 IPv6 选项卡(根据你的网络类型选择)。
  5. 修改 DNS 设置:
    • 找到 DNS 部分。
    • 默认通常是“自动 (DHCP)”。
    • 切换为“自动 (仅地址)”或者“手动”。
    • 如果选择“手动”,会有一个输入框让你填写 DNS 服务器地址。将你想要使用的 DNS 服务器地址列表输入到框中,多个地址之间用逗号分隔。
    • 如果选择“自动 (仅地址)”,系统会通过 DHCP 获取 IP 地址、网关等信息,但 DNS 将使用你手动输入的地址。
    • 有时也会有“搜索域”的设置,对应 /etc/resolv.conf 中的 search 指令。
  6. 保存设置并应用: 点击“保存”、“应用”或“确定”。可能需要断开并重新连接网络,或者禁用再启用网络适配器,以使更改生效。

通过图形界面配置后,NetworkManager 会自动更新 /etc/resolv.conf 文件,并会在网络状态变化时维护这些设置。

2.2 使用 nmcli 命令配置 (适用于命令行)

nmcli 是 NetworkManager 的命令行工具,非常强大和灵活,适用于服务器或通过 SSH 连接进行远程管理时。

  1. 列出你的网络连接名称:
    首先,你需要知道你想要修改的连接的名称。
    bash
    nmcli connection show

    你会看到一个列表,例如 Wired connection 1, MyWiFi, eth0, wlan0 等。记住你当前正在使用的连接名称。

  2. 修改 DNS 服务器:
    使用 nmcli connection modify 命令来修改指定连接的 IPv4 或 IPv6 DNS 设置。以修改名为 "Wired connection 1" 的连接的 IPv4 DNS 为例,设置为 8.8.8.8 和 8.8.4.4:
    bash
    sudo nmcli connection modify "Wired connection 1" ipv4.dns "8.8.8.8, 8.8.4.4"

    如果你使用的是 IPv6,使用 ipv6.dns:
    bash
    sudo nmcli connection modify "Wired connection 1" ipv6.dns "2001:4860:4860::8888, 2001:4860:4860::8844"

  3. 设置 DNS 方法 (可选,但推荐如果你想完全手动控制 DNS):
    默认情况下,NetworkManager 会结合 DHCP 获取的 DNS 信息和你手动设置的。如果你只想使用手动设置的 DNS,可以强制其使用手动方法:
    bash
    sudo nmcli connection modify "Wired connection 1" ipv4.dns-method manual
    # 如果使用 IPv6
    # sudo nmcli connection modify "Wired connection 1" ipv6.dns-method manual

    如果你想重新允许 NetworkManager 通过 DHCP 获取 DNS(并可能与手动设置的结合),可以设置为 auto
    bash
    sudo nmcli connection modify "Wired connection 1" ipv4.dns-method auto

    如果设置为 dhcp,则完全只使用 DHCP 提供的 DNS。设置为 ignore 则忽略 DHCP 提供的 DNS。设置为 manual 则只使用 ipv4.dns/ipv6.dns 中指定的服务器。通常 manual 是最直接的方式来强制使用你指定的 DNS。

  4. 修改搜索域 (可选):
    bash
    sudo nmcli connection modify "Wired connection 1" ipv4.dns-search "mydomain.com, anotherdomain.net"
    # 如果使用 IPv6
    # sudo nmcli connection modify "Wired connection 1" ipv6.dns-search "mydomain.com, anotherdomain.net"

  5. 应用更改:
    修改连接设置后,你需要重新激活该连接才能使更改生效。
    bash
    sudo nmcli connection down "Wired connection 1"
    sudo nmcli connection up "Wired connection 1"

    或者,你可以简单地重启 NetworkManager 服务(会中断所有网络连接):
    bash
    sudo systemctl restart NetworkManager

    更温和的方法是先关闭网络,再打开:
    bash
    sudo nmcli networking off
    sudo nmcli networking on

通过 nmcli 配置的 DNS 将会持久化到 NetworkManager 的配置文件中(通常在 /etc/NetworkManager/system-connections/ 下),并在每次连接激活时应用。

方法三:使用 systemd-resolved 进行配置

在许多使用 systemd 的现代 Linux 发行版(如 Ubuntu 17.10+,Fedora 33+)中,systemd-resolved 负责处理名字解析。在这种情况下,/etc/resolv.conf 文件通常是一个指向 /run/systemd/resolve/stub-resolv.conf/usr/lib/systemd/resolv.conf 的符号链接,文件内容是 nameserver 127.0.0.53,表示系统将 DNS 请求发送给本地运行的 systemd-resolved 服务。

3.1 使用 resolvectl 命令

resolvectl 是与 systemd-resolved 交互的命令行工具。你可以用它来查看当前 DNS 设置和临时修改设置。

  1. 查看当前 DNS 设置:
    bash
    resolvectl status

    这将显示每个网络接口的 DNS 服务器、全局 DNS 服务器以及当前的 DNS 路由。

  2. 临时修改 DNS 服务器:
    你可以为特定的网络接口(例如 eth0)临时设置 DNS 服务器:
    bash
    sudo resolvectl dns eth0 8.8.8.8 8.8.4.4

    或者设置全局的 fallback DNS 服务器(当接口没有指定 DNS 时使用):
    bash
    sudo resolvectl fallback-dns 8.8.8.8 8.8.4.4

    注意: 使用 resolvectl 命令进行的修改通常不是永久的,可能会在网络服务重启后丢失。

3.2 通过配置文件进行永久配置

要永久配置 systemd-resolved,你需要编辑其配置文件。主要有两种方式:

  1. 全局配置 (/etc/systemd/resolved.conf):
    这个文件用于设置 systemd-resolved 的全局行为,包括全局的 DNS 服务器和 DNS 搜索域。
    bash
    sudo nano /etc/systemd/resolved.conf

    找到 [Resolve] 部分,取消注释或添加 DNSFallbackDNS 行:
    conf
    [Resolve]
    # 设置全局首选 DNS 服务器
    DNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
    # 设置全局备用 DNS 服务器(在首选服务器都失败时使用)
    FallbackDNS=1.1.1.1 1.0.0.1
    # 设置全局搜索域
    # Domains=mydomain.com yourdomain.net
    # 设置 DNS over TLS (DoT) 模式,可选的值有 no, yes, opportunistic
    # DNSOverTLS=no
    # 设置 LLMNR/mDNS/DNSSEC 等选项
    # ...

    保存文件后,需要重启 systemd-resolved 服务:
    bash
    sudo systemctl restart systemd-resolved

  2. 按接口配置 (/etc/systemd/networkd/*.network/etc/NetworkManager/system-connections/*):
    systemd-resolved 通常与 systemd-networkd 或 NetworkManager 集成。如果你的网络是由 systemd-networkd 管理的,你可以在对应的 .network 文件中配置 DNS。例如,为 eth0 配置 DNS:
    bash
    sudo nano /etc/systemd/networkd/20-wired.network # 文件名和内容可能因系统而异

    [Network] 部分添加 DNSDomains 行:
    “`conf
    [Match]
    Name=eth0

    [Network]
    DHCP=ipv4
    DNS=8.8.8.8 8.8.4.4
    Domains=mydomain.com

    …其他配置…

    保存文件后,重启 `systemd-networkd` 服务:bash
    sudo systemctl restart systemd-networkd
    ``
    如果你的系统使用 NetworkManager,如前所述,NetworkManager 会将 DNS 配置信息传递给
    systemd-resolved。通过 NetworkManager 的方式(GUI 或nmcli)配置 DNS 即可,systemd-resolved` 会自动获取这些信息。

使用 systemd-resolved 时,应用程序应该通过其提供的本地接口(通常是 127.0.0.53 或 D-Bus)进行解析,而不是直接读取 /etc/resolv.confsystemd-resolved 会处理缓存、并发查询、DNSSEC 等高级功能。

方法四:使用 resolvconf 实用程序

resolvconf (注意与 /etc/resolv.conf 文件的区别) 是一个用于管理 /etc/resolv.conf 文件的框架或程序。它收集来自系统各个部分的 DNS 配置信息(如 DHCP 客户端、VPN 客户端、手动配置)并将它们合并,然后生成最终的 /etc/resolv.conf 文件。一些 Debian/Ubuntu 系统可能仍在使用它。

如果你发现 /etc/resolv.conf 是一个指向 /run/resolvconf/resolv.conf 或类似路径的符号链接,那么你的系统可能正在使用 resolvconf

要通过 resolvconf 添加永久的 DNS 服务器,你可以编辑 /etc/resolvconf/resolv.conf.d/ 目录下的文件。这个目录下通常有几个文件:

  • head: 这个文件的内容会放在生成的 /etc/resolv.conf 的顶部。适合放你想要总是优先使用的 nameserver
  • base: 这个文件的内容会放在生成的 /etc/resolv.confhead 部分之后,但在动态生成的配置之前。适合放基本的搜索域等。
  • tail: 这个文件的内容会放在生成的 /etc/resolv.conf 的末尾。适合放你想要总是在动态配置之后使用的 nameserver 或其他选项。

最常见的方式是编辑 head 文件来添加你首选的 DNS 服务器:

  1. 编辑 head 文件:
    bash
    sudo nano /etc/resolvconf/resolv.conf.d/head
  2. 添加 DNS 服务器:
    在文件中添加你的 nameserver 行。例如:
    “`conf
    # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
    # DO NOT EDIT THIS FILE BY HAND — YOUR CHANGES WILL BE OVERWRITTEN

    我的自定义 DNS 服务器,放在顶部优先使用

    nameserver 8.8.8.8
    nameserver 8.8.4.4

    下面是动态生成的或 base 文件内容

    “`
    保存并关闭文件。

  3. 更新 resolvconf
    你需要通知 resolvconf 重新生成 /etc/resolv.conf
    bash
    sudo resolvconf -u

resolvconf 会合并来自各个源的信息(包括你手动编辑的 head 文件),并更新 /etc/resolv.conf。这种方式的修改会持久存在,除非 resolvconf 本身被移除或替换。

方法五:通过静态 IP 配置指定 DNS

如果你选择为网络接口配置静态 IP 地址,那么通常可以在配置静态 IP 的文件中直接指定 DNS 服务器。这种方法适用于服务器或不需要 NetworkManager 等高级工具的场景。

5.1 Debian/Ubuntu (使用 /etc/network/interfaces)

在基于 Debian/Ubuntu 的系统上,如果你不使用 NetworkManager 来管理某个接口,通常会在 /etc/network/interfaces 文件中配置它。

  1. 编辑接口配置文件:
    bash
    sudo nano /etc/network/interfaces
  2. 为你的接口添加 dns-nameserversdns-search 行:
    找到对应接口的配置段(例如 iface eth0 inet static),在其中添加以下行:
    conf
    auto eth0
    iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    # 添加 DNS 服务器
    dns-nameservers 8.8.8.8 8.8.4.4
    # 添加搜索域
    dns-search mydomain.com yourdomain.net

    保存并关闭文件。

  3. 重启网络服务或接口:
    bash
    sudo systemctl restart networking
    # 或者只重启特定接口
    # sudo ifdown eth0 && sudo ifup eth0

5.2 RHEL/CentOS/Fedora (使用 Network Scripts – 较旧方法)

在一些较旧的或特定配置的 RHEL/CentOS/Fedora 系统上,网络配置可能存储在 /etc/sysconfig/network-scripts/ifcfg-<interface> 文件中。

  1. 编辑接口配置文件:
    bash
    sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0 # 替换 eth0 为你的接口名称
  2. 添加 DNS1, DNS2, DOMAIN/SEARCH 变量:
    确保 BOOTPROTO 设置为 staticnone。添加或修改以下行:
    conf
    TYPE=Ethernet
    BOOTPROTO=static
    # ... 其他静态 IP 配置 ...
    DNS1=8.8.8.8
    DNS2=8.8.4.4
    # 添加搜索域
    DOMAIN="mydomain.com yourdomain.net"
    # 或者使用 SEARCH 变量,有些系统可能支持
    # SEARCH="mydomain.com yourdomain.net"

    保存并关闭文件。

  3. 重启网络服务或接口:
    bash
    sudo systemctl restart network
    # 或者只重启特定接口
    # sudo ifdown eth0 && sudo ifup eth0

通过这种方式配置的 DNS 信息通常会被对应的网络服务读取,并在接口激活时用来更新 /etc/resolv.conf

方法六:通过 DHCP 客户端配置覆盖 DNS

如果你的系统通过 DHCP 获取网络配置,DNS 服务器通常是由 DHCP 服务器提供的。然而,你可以配置 DHCP 客户端来忽略、替换或添加 DHCP 提供的 DNS 服务器。这取决于你使用的 DHCP 客户端程序(如 dhclient, dhcpcd)。

6.1 使用 dhclient (常见于 Debian/Ubuntu)

dhclient 的配置文件通常是 /etc/dhcp/dhclient.conf。你可以在这里指定 DNS 行为。

  1. 编辑 dhclient.conf
    bash
    sudo nano /etc/dhcp/dhclient.conf
  2. 修改 request 或添加 prepend/supersede 行:

    • 忽略 DHCP 提供的 DNS:request 选项中移除 domain-name-servers
      conf
      # request subnet-mask, broadcast-address, time-offset, routers,
      # domain-name, domain-name-servers, host-name,
      # interface-mtu, expire, root-path, non-local-source-routing;
      # 修改为(移除 domain-name-servers):
      request subnet-mask, broadcast-address, time-offset, routers,
      domain-name, host-name, interface-mtu, expire, root-path,
      non-local-source-routing;
    • 优先使用指定的 DNS (prepend): 在 DHCP 提供的 DNS 服务器列表前面添加你指定的服务器。
      conf
      prepend domain-name-servers 8.8.8.8, 8.8.4.4;
    • 完全使用指定的 DNS (supersede): 忽略 DHCP 提供的所有 DNS 服务器,只使用你指定的。
      conf
      supersede domain-name-servers 8.8.8.8, 8.8.4.4;

      选择其中一种方式进行配置。
  3. 保存并关闭文件。

  4. 续订或重启 DHCP 客户端:
    你需要让 DHCP 客户端重新获取或更新租约。可以通过重启网络接口或重启 DHCP 客户端服务来实现:
    bash
    sudo systemctl restart network # 或者 networking
    # 或者针对特定接口续订
    # sudo dhclient -r -v eth0 # 释放租约
    # sudo dhclient -v eth0 # 获取新租约

6.2 使用 dhcpcd (常见于 Alpine, Slackware, Arch 等)

dhcpcd 的配置文件通常是 /etc/dhcpcd.conf

  1. 编辑 dhcpcd.conf
    bash
    sudo nano /etc/dhcpcd.conf
  2. 添加或修改 nohook, static domain_name_servers, static domain_search 行:

    • 阻止 dhcpcd 更新 /etc/resolv.conf 添加 nohook resolv.conf。这会阻止 dhcpcd 修改 /etc/resolv.conf,然后你可以使用手动编辑或其他方法来管理 /etc/resolv.conf
      conf
      nohook resolv.conf
    • 指定静态 DNS 服务器 (覆盖 DHCP 提供的):
      “`conf
      # 为所有接口指定 DNS
      static domain_name_servers=8.8.8.8 8.8.4.4
      # 或为特定接口指定 DNS
      # interface eth0
      # static domain_name_servers=8.8.8.8 8.8.4.4

      指定搜索域

      static domain_search=mydomain.com yourdomain.net

      “`
      选择合适的方式进行配置。

  3. 保存并关闭文件。

  4. 重启 dhcpcd 服务或接口:
    bash
    sudo systemctl restart dhcpcd
    # 或者针对特定接口
    # sudo ip link set eth0 down
    # sudo ip link set eth0 up
    # sudo dhcpcd eth0

方法七:使用 chattr +i 使 /etc/resolv.conf 文件不可更改 (不推荐用于永久方案)

这是一种简单粗暴的方法,通过文件系统的属性使 /etc/resolv.conf 文件变成不可修改(immutable)。这样做可以防止任何程序(包括 NetworkManager, systemd-resolved, DHCP 客户端等)修改这个文件。

  1. 首先,手动编辑 /etc/resolv.conf 文件,按照你的意愿配置好 DNS 服务器:
    bash
    sudo nano /etc/resolv.conf
    # 添加你的 nameserver 行
    # nameserver 8.8.8.8
    # nameserver 8.8.4.4
    # 保存并关闭

  2. 使用 chattr 命令设置 immutable 属性:
    bash
    sudo chattr +i /etc/resolv.conf

  3. 验证属性是否设置成功:
    bash
    lsattr /etc/resolv.conf

    输出应该包含 i 标志,例如 --i--------e-- /etc/resolv.conf

效果: 现在,即使有服务尝试修改 /etc/resolv.conf,也会因为文件不可修改而失败。你的手动配置将会一直保持。

移除 immutable 属性:
如果你需要再次修改这个文件,必须先移除 immutable 属性:
bash
sudo chattr -i /etc/resolv.conf

然后你就可以像往常一样编辑它了。

警告: 这种方法 不推荐 作为标准的、长期的 DNS 配置方案。它绕过了系统设计的网络管理流程,可能会导致其他依赖于动态更新 /etc/resolv.conf 的服务(如 VPN 连接推送 DNS、某些应用程序的网络配置)出现问题。它主要适用于紧急情况、特定测试场景或你完全清楚你在做什么并且接受其潜在风险的情况。

测试你的 DNS 配置

无论你使用了哪种方法修改了 DNS,都需要验证更改是否生效以及是否能够正确解析域名。

  1. 检查 /etc/resolv.conf 文件内容:
    首先,确认 /etc/resolv.conf 文件中的 nameserver 行是否是你期望的。
    bash
    cat /etc/resolv.conf

    注意: 如果你的系统使用 systemd-resolved 并且 /etc/resolv.conf 指向 127.0.0.53,那么这个文件本身的内容并不能直接显示上游 DNS。你需要使用 resolvectl status 或其他工具来查看。

  2. 使用 ping 命令测试基本连通性:
    尝试 ping 一个域名,看是否能解析成功并与对应的 IP 地址通信。
    bash
    ping google.com

    如果能看到 PING google.com (...) 并且有回复,说明 DNS 解析和网络连通性都没问题。

  3. 使用 nslookupdig 命令测试域名解析:
    nslookupdig 是专门用于查询 DNS 的工具,它们能提供更详细的解析过程信息。dig 通常功能更强大且输出更详细,推荐使用 dig

    • 使用 nslookup
      bash
      nslookup google.com

      输出会显示用于解析的 DNS 服务器地址 (Server 字段) 和解析结果 (Address 字段)。

    • 使用 dig
      bash
      dig google.com

      dig 的输出更详细,其中 SERVER 字段显示了实际进行查询的服务器地址,ANSWER SECTION 显示了查询结果。你可以使用 +short 选项只看结果:
      bash
      dig google.com +short

      你还可以指定使用特定的 DNS 服务器进行查询,以测试某个服务器是否工作正常:
      bash
      dig @8.8.8.8 google.com

      这会强制使用 8.8.8.8 这个 DNS 服务器来解析 google.com

  4. 使用 resolvectl (仅适用于 systemd-resolved):
    bash
    resolvectl status

    查看 Current DNS ServersDNS Servers 字段,确认列出的服务器是你配置的。

    bash
    resolvectl query google.com

    测试使用 systemd-resolved 解析一个域名。

常见问题与故障排除

  • 修改 /etc/resolv.conf 后又被还原了: 这是最常见的问题。说明有其他服务(NetworkManager, systemd-resolved, DHCP 客户端等)在管理这个文件。请回到“识别你的系统如何管理 /etc/resolv.conf”这一节,找出罪魁祸首,并使用对应的方法进行永久配置。
  • 网络连接正常,但域名无法解析:
    • 防火墙: 检查你的防火墙是否阻止了到 DNS 服务器(默认端口 UDP/TCP 53)的出站连接。使用 sudo ufw statussudo firewall-cmd --list-all 查看规则。
    • DNS 服务器本身有问题: 尝试 ping 你配置的 DNS 服务器 IP 地址,确认是否能连接到它。如果能 ping 通 IP 但不能解析域名,可能是 DNS 服务器本身故障或配置错误。
    • 本地 DNS 缓存: 某些系统或应用程序可能有本地 DNS 缓存。尝试重启网络服务,或清除本地缓存(如 sudo systemctl restart systemd-resolved,或对于 dnsmasq 等服务进行相应操作)。浏览器也有自己的 DNS 缓存,可以尝试重启浏览器或清空浏览器缓存。
    • 配置语法错误: 仔细检查你修改的配置文件(如 /etc/resolv.conf, dhclient.conf, resolved.conf 等)是否存在语法错误。
  • 域名解析很慢:
    • DNS 服务器响应慢: 你选择的 DNS 服务器可能延迟较高。尝试切换到其他公共 DNS 服务器,并使用 pingdig 测试它们的响应时间。
    • 网络延迟: 你到 DNS 服务器的网络路径可能存在延迟。
    • DNS 搜索域配置过多或不正确: 如果配置了多个搜索域,系统在解析非 FQDN 时会依次尝试,如果这些域不存在或查询耗时,会导致解析变慢。检查 /etc/resolv.conf 或相关配置中的 searchdomain 行。
    • DNSSEC 验证问题: 如果使用了支持 DNSSEC 的解析器(如 systemd-resolved),验证失败有时可能导致解析延迟。
  • 某些特定域名无法解析:
    • 内网域名: 如果你需要解析内部网络中的域名,确保你配置的 DNS 服务器能够解析这些内部域名(通常是局域网内的路由器或内部 DNS 服务器)。
    • ISP 劫持或过滤: 某些 ISP 可能会劫持 DNS 请求或对特定域名进行过滤。切换到公共 DNS 服务器通常可以解决这类问题。
  • dignslookup 可以解析,但应用程序无法访问网站:
    DNS 解析只是网络连接的第一步。如果解析正确,但应用程序仍然无法连接,问题可能出在:

    • 防火墙: 应用程序使用的端口被防火墙阻止(不仅是 DNS 端口 53,还有 HTTP 的 80,HTTPS 的 443 等)。
    • 代理设置: 应用程序可能配置了错误的代理服务器。
    • 路由问题: 系统无法找到到达目标 IP 地址的正确路由。
    • 服务器端问题: 目标服务器本身故障或阻止了你的连接。

选择合适的 DNS 服务器

选择一个合适的 DNS 服务器很重要。一些流行的公共 DNS 服务包括:

  • Google Public DNS: 8.8.8.88.8.4.4 (IPv4), 2001:4860:4860::88882001:4860:4860::8844 (IPv6)。速度快,全球节点多。
  • Cloudflare: 1.1.1.11.0.0.1 (IPv4), 2606:4700:4700::11112606:4700:4700::1001 (IPv6)。强调隐私和速度。
  • OpenDNS: 208.67.222.222208.67.220.220 (IPv4)。提供可选的过滤功能。
  • Quad9: 9.9.9.9 (IPv4), 2620:fe::fe (IPv6)。注重安全,会阻止恶意域名的解析。
  • 你的 ISP 的 DNS 服务器: 通常会自动通过 DHCP 获取,速度可能较快因为它离你近,但隐私和功能方面可能不如公共 DNS。
  • 你的路由器的 DNS 服务器: 许多家庭路由器充当本地 DNS 转发器,将内网设备的请求转发给 ISP 的 DNS 或路由器本身配置的 DNS。使用路由器地址 (通常是网关地址,如 192.168.1.1) 作为 DNS 可以利用路由器的缓存,但最终取决于路由器的上游 DNS 配置。
  • 本地 DNS 缓存服务器: 你可以在本地运行 DNS 缓存服务(如 dnsmasq),它可以缓存查询结果,加快重复查询的速度,并可以用于简单的内网域名解析或广告过滤。在这种情况下,你的系统会将本地缓存服务器的地址(通常是 127.0.0.1)配置为 DNS 服务器,然后由本地服务负责向上游 DNS 查询。

选择时可以考虑:

  • 速度/延迟: 使用 pingdig 测试延迟,或者使用 namebench 等工具测试多个 DNS 服务器的性能。
  • 隐私政策: 阅读 DNS 提供商的隐私政策,了解他们是否记录查询日志以及如何使用这些日志。
  • 安全性/功能: 是否提供 DNSSEC 验证、恶意网站过滤、内容过滤等功能。

总结

修改 Linux 的 DNS 配置并非只有一种方法。核心在于 /etc/resolv.conf 文件,但它的内容通常由系统中的其他服务动态管理。要实现永久修改,你需要识别出是哪个服务在控制 /etc/resolv.conf,并使用该服务提供的配置接口:

  • 如果使用 NetworkManager (常见于桌面版),通过图形界面或 nmcli 命令配置连接属性。
  • 如果使用 systemd-resolved (常见于较新系统),配置 /etc/systemd/resolved.conf 或使用 resolvectl (临时),或者通过 NetworkManager/systemd-networkd 配置接口的 DNS。
  • 如果使用 resolvconf 实用程序,编辑 /etc/resolvconf/resolv.conf.d/ 下的文件并运行 resolvconf -u
  • 如果配置 静态 IP,在接口的配置文件(如 /etc/network/interfaces/etc/sysconfig/network-scripts/ifcfg-*)中直接指定 DNS。
  • 如果使用 DHCP,配置 DHCP 客户端文件(如 /etc/dhcp/dhclient.conf/etc/dhcpcd.conf)来覆盖或添加 DHCP 提供的 DNS。
  • 手动编辑 /etc/resolv.conf 配合 chattr +i 是强制性的方法,但通常不推荐用于长期方案。

理解你的系统当前的网络管理方式是成功修改 DNS 的关键。通过本指南,你应该能够根据自己的系统环境和需求,选择最合适的方法来配置你的 Linux DNS,从而优化网络体验。在进行任何更改后,务必使用 cat /etc/resolv.confpingnslookupdig 命令来验证配置是否生效。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部