说明

Ubuntu 18.04 开始,系统会自动启动 systemd-resolved 服务,它在本地开启了一个小型的 DNS 解析器(监听地址是 127.0.0.53,这也是为什么 resolv.conf 中会有一个 127.0.0.53),并把 /etc/resolv.conf 指向一个由它维护的文件 /run/systemd/resolve/stub-resolv.conf。这样一来,所有 DNS 请求都会先发到本地这个stub,再由stub去联系真正的上游服务器。

所以如果你直接修改 /etc/resolv.conf 在重启后会被重置,因为该文件是通过 NetworkManager 动态生成的。
(本篇文章仅记录,因为我已经好几次忘记怎么改了,几年改不了一次🤣)

解决方案

这里提供 netplan 方案,修改起来简单快捷,并且可以在保留 DHCP 的前提下仅修改 DNS 服务器。

Netplan 本质上是给底层网络服务下“指令”,而 systemd‑resolved 又会动态读取这些指令:

  • Netplan → networkd/NM:你在 YAML 里写 DNS,netplan apply 就把它转换给 systemd‑networkd 或 NetworkManager。
  • networkd/NM → systemd‑resolved:这两个守护进程会把各自的 DNS 设置,通过内部接口(D‑Bus/API)上报给 systemd‑resolved。
  • 动态生效:systemd‑resolved 一直在监控这些变化,收到新配置后马上切换它转发查询的上游服务器,并更新缓存。

修改过程如下:

  1. 找到本机的配置文件
    ls /etc/netplan/
    
  2. 编辑该文件
    # This is the network config written by 'subiquity'
    network:
      ethernets:
        ens18:
          dhcp4: true
          dhcp4-overrides: 
            use-dns: false # 不让 dns 动态获取
          nameservers:
            addresses: # 设置如下 dns 服务器
              - 1.1.1.1
              - 8.8.8.8
      version: 2
    
  3. 应用配置
    sudo netplan apply
    

主要在所属网卡下加入以下内容:

dhcp4-overrides: 
  use-dns: false # 不让 dns 动态获取
nameservers:
  addresses: # 设置如下 dns 服务器
    - 1.1.1.1
    - 8.8.8.8