使用 systemd-resolved 自定义你的 DNS 解析

前言

本教程为了解决购买服务器,通过修改 /etc/resolv.conf 配置文件自定义 DNS 时重启服务器被重置的问题。

将指导你如何在 Debian 12 上通过 systemd-resolved 来修改和管理你的 DNS 设置。

自定义 DNS

步骤 1:检查 systemd-resolved 状态

首先,我们需要确认 systemd-resolved 服务是否已安装并正在运行。在 Debian 12 上,它通常是默认启用的。

打开终端,执行以下命令:

1
sudo systemctl status systemd-resolved

你应该会看到类似如下的输出,表明服务是 active (running) 并且 enabled (开机自启):

1
2
3
4
5
6
7
8
9
10
11
12
13
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled; preset: enabled)
Active: active (running) since Mon 2023-10-23 10:00:00 CST; 1h ago
Docs: man:systemd-resolved.service(8)
man:org.freedesktop.resolve1(5)
https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
Main PID: 1234 (systemd-resolve)
Status: "Processing requests..."
Tasks: 1 (limit: 4619)
Memory: 10.5M
CPU: 150ms
CGroup: /system.slice/systemd-resolved.service
└─1234 /lib/systemd/systemd-resolved

如果服务没有运行,你可以尝试安装并启用它:

1
2
3
sudo apt install systemd-resolved -y
sudo systemctl start systemd-resolved
sudo systemctl enable systemd-resolved

步骤 2:理解 /etc/resolv.conf 的角色

在传统的 Linux 系统中,/etc/resolv.conf 文件直接包含了 DNS 服务器的地址。然而,当 systemd-resolved 激活时,它通常会接管这个文件。

检查 /etc/resolv.conf

1
ls -l /etc/resolv.conf

你可能会看到以下几种情况:

  1. 推荐模式 (Stub Resolver): /etc/resolv.conf 是一个指向 /run/systemd/resolve/stub-resolv.conf 的符号链接。

    1
    lrwxrwxrwx 1 root root 39 Aug  1 10:00 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

    这时,/etc/resolv.conf 文件的内容通常会是:

    1
    2
    3
    nameserver 127.0.0.53
    options edns0 trust-ad
    search yourdomain.local

    127.0.0.53systemd-resolved 提供的本地 DNS stub 侦听器。所有 DNS 查询都会先发送到这里,然后由 systemd-resolved 根据其配置转发到上游 DNS 服务器。

  2. 兼容模式 (Static/Foreign): /etc/resolv.conf 是一个指向 /run/systemd/resolve/resolv.conf 的符号链接,或者是一个静态文件(由其他工具如 NetworkManager 或手动配置)。

    1
    lrwxrwxrwx 1 root root 37 Aug  1 10:01 /etc/resolv.conf -> ../run/systemd/resolve/resolv.conf

    这种情况下,文件内容会直接列出 systemd-resolved 正在使用的上游 DNS 服务器。

我们将主要关注如何配置 systemd-resolved 本身,而不是直接编辑 /etc/resolv.conf (除非你知道自己在做什么,并且了解其影响)。

步骤 3:修改 systemd-resolved 的全局 DNS 设置

systemd-resolved 的主配置文件是 /etc/systemd/resolved.conf。我们可以通过编辑这个文件来设置全局的 DNS 服务器。

  1. 打开配置文件进行编辑:

    1
    sudo nano /etc/systemd/resolved.conf
  2. 修改 DNS 设置:
    找到 [Resolve] 部分。你可能需要取消注释 (删除行首的 #) 并修改以下行:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Resolve]
    DNS=1.1.1.1 8.8.8.8 2606:4700:4700::1111 2001:4860:4860::8888
    FallbackDNS=8.8.4.4
    #Domains=~.
    #LLMNR=no
    #MulticastDNS=no
    #DNSSEC=allow-downgrade
    #DNSOverTLS=opportunistic
    #Cache=yes
    #DNSStubListener=yes
    • DNS=: 在这里填入你想要使用的主 DNS 服务器,用空格分隔多个。例如,上面设置了 Google DNS, Cloudflare DNS 和 AliDNS。
    • FallbackDNS=: 设置备用 DNS 服务器,在主 DNS 不可用时使用。
    • Domains=: 可以设置 DNS 搜索域。
    • DNSOverTLS=: 如果你的 DNS 服务器支持,可以设置为 opportunistic (尝试使用,失败则回退) 或 yes (强制使用) 来启用 DNS over TLS 加密。

    示例:仅使用 Cloudflare DNS 和 Google DNS,并尝试启用 DNS-over-TLS

    1
    2
    3
    4
    [Resolve]
    DNS=1.1.1.1 8.8.8.8
    FallbackDNS=1.0.0.1 8.8.4.4
    DNSOverTLS=opportunistic
  3. 保存并关闭文件 (在 nano 中是 Ctrl+X,然后按 Y,再按 Enter)。

  4. 重启 systemd-resolved 服务以应用更改:

    1
    sudo systemctl restart systemd-resolved

步骤 4:验证 DNS 设置

有几种方法可以验证你的新 DNS 设置是否生效:

  1. 使用 resolvectl status
    这是查看 systemd-resolved 当前状态和配置的最佳方式。

    1
    resolvectl status

    你会看到 “Global” 部分列出了你配置的 DNS 服务器。同时,它也会显示每个网络接口(Link)的 DNS 设置,这可能来自 DHCP 或你的全局配置。

    示例输出片段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Global
    Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=allow-downgrade
    resolv.conf mode: stub
    Current DNS Server: 1.1.1.1 <-- 你配置的 DNS
    DNS Servers: 1.1.1.1 8.8.8.8 2606:4700:4700::1111 2001:4860:4860::8888 <-- 你配置的 DNS
    Fallback DNS Servers: 8.8.4.4
    ...

    Link 2 (eth0)
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
    Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=allow-downgrade

Current DNS Server: 1.1.1.1
DNS Servers: 1.1.1.1 8.8.8.8 2606:4700:4700::1111 2001:4860:4860::8888

1

  1. 使用 resolvectl query 进行查询测试:

    1
    resolvectl query debian.org

    这将显示 debian.org 的 IP 地址以及是通过哪个 DNS 服务器解析的。

  2. 检查 /etc/resolv.conf (如果使用 stub 模式):

    1
    cat /etc/resolv.conf

    如果 /etc/resolv.conf 指向 stub-resolv.conf,它仍然应该显示 nameserver 127.0.0.53。这是正常的,因为所有查询都先到本地 stub。