TL;DR: Ubuntu/Debian 默认用systemd-resolved做本地 DNS 解析(监听在127.0.0.53:53),它从 systemd 239 版本开始原生支持 DNS over TLS(DoT)。配置方法:编辑/etc/systemd/resolved.conf或在/etc/systemd/resolved.conf.d/下新建一个.conf文件,写入DNS=1.1.1.1和DNSOverTLS=yes,然后sudo systemctl restart systemd-resolved,最后用resolvectl status验证即可。不需要装任何第三方软件。
Ubuntu/Debian 的 DNS 架构:先搞清楚 systemd-resolved
很多人刚上手 Linux 时会困惑:我明明改了 /etc/resolv.conf,为什么重启又变回去了?这是因为从 Ubuntu 16.04(以及 Debian 10)开始,系统默认使用 systemd-resolved 作为本地 DNS 存根解析器。
它的工作方式是这样的:
systemd-resolved作为一个系统服务在后台运行。- 它在本地
127.0.0.53的 53 端口上监听,扮演一个「DNS 中转站」的角色。 /etc/resolv.conf是一个软链接,指向/run/systemd/resolve/stub-resolv.conf,里面只写了一行nameserver 127.0.0.53。- 所有程序的 DNS 请求都先发给本地的
127.0.0.53,再由systemd-resolved转发到真正的上游 DNS 服务器。
所以你要配置加密 DNS,正确的做法不是改 /etc/resolv.conf,而是改 systemd-resolved 的配置文件——因为加密是在 systemd-resolved 转发给上游那一段做的。
先确认你的系统确实在用 systemd-resolved:
systemctl status systemd-resolved如果显示 active (running) 就对了。再确认一下 /etc/resolv.conf 是不是软链接:
ls -l /etc/resolv.conf正常应该显示指向 /run/systemd/resolve/stub-resolv.conf 或 /run/systemd/resolve/resolv.conf。
配置 DoT:编辑 resolved.conf
systemd-resolved 的主配置文件是 /etc/systemd/resolved.conf。官方文档推荐的做法是不要直接改主文件,而是在 /etc/systemd/resolved.conf.d/ 目录下新建一个 drop-in 配置文件,这样升级系统时不会被覆盖。
第一步:创建 drop-in 配置文件
sudo mkdir -p /etc/systemd/resolved.conf.d/
sudo nano /etc/systemd/resolved.conf.d/99-opendns.conf第二步:写入配置内容
在文件里填入以下内容:
[Resolve]
DNS=1.1.1.1#one.one.one.one 1.0.0.1#one.one.one.one
FallbackDNS=9.9.9.9#dns.quad9.net
DNSOverTLS=yes逐行解释:
| 配置项 | 含义 |
|---|---|
DNS=1.1.1.1#one.one.one.one | 指定上游 DNS 服务器。# 后面是服务器的主机名,用于 TLS 证书校验和 SNI。格式是 IP地址#主机名 |
FallbackDNS=9.9.9.9#dns.quad9.net | 备用 DNS,当主 DNS 连不上时自动切换 |
DNSOverTLS=yes | 开启 DoT 加密。yes = 强制加密,不支持 TLS 的服务器会直接失败;opportunistic = 优先加密,不支持就降级明文;no = 关闭 |
注意:DNSOverTLS=yes模式下,如果服务器证书验证失败,所有 DNS 请求都会失败。所以一定要写对#后面的主机名,让 systemd-resolved 能正确校验证书。如果你只是想试试水,可以先设成opportunistic,不会因为证书问题断网。
第三步:重启服务使配置生效
sudo systemctl restart systemd-resolved第四步:验证配置
运行:
resolvectl status输出里你应该能看到类似这样的内容:
Link 2 (eth0)
Current Scopes: DNS
Current DNS Server: 1.1.1.1
DNS Servers: 1.1.1.1
1.0.0.1
DNS OverTLS: yes关键看最后一行 DNS OverTLS: yes——这就说明 DoT 已经开启了。
再用 resolvectl query 测一下解析是否正常:
resolvectl query google.com如果能返回 IP 地址,说明 DoT 通道工作正常。
不想用 drop-in?直接改主文件也行
如果你觉得多建一个文件麻烦,也可以直接编辑 /etc/systemd/resolved.conf:
sudo nano /etc/systemd/resolved.conf找到 [Resolve] 段,把下面几行前面的注释(#)去掉并改成:
[Resolve]
DNS=1.1.1.1#one.one.one.one
FallbackDNS=9.9.9.9#dns.quad9.net
DNSOverTLS=yes保存后同样 sudo systemctl restart systemd-resolved。两种方法效果完全一样,drop-in 的好处是更干净、不污染系统自带的主配置文件。
常见坑与排查
坑一:NetworkManager 接管了 DNS
如果你用的是带桌面环境的 Ubuntu(GNOME),NetworkManager 可能会通过 DHCP 自动下发 DNS 服务器,把你手动配的 DNS= 覆盖掉。
排查方法:运行 resolvectl status,看「Current DNS Server」是不是你自己设的 1.1.1.1。如果不是,说明 NetworkManager 给你的网卡分配了别的 DNS。
解决办法:在 NetworkManager 里手动设置该连接的 DNS:
- 打开「设置 → 网络 → 你的连接 → 详细信息 → IPv4」。
- 把「DNS」改成手动,填入
1.1.1.1。 - 关掉「自动 DNS」开关。
坑二:改了 resolv.conf 不生效
记住:在 Ubuntu/Debian 上,直接编辑 /etc/resolv.conf 是没用的——它是软链接,重启或重新联网后会被 systemd-resolved 重新生成。你所有的配置都应该写在 resolved.conf 或 drop-in 文件里。
坑三:开了 DoT 之后上不了网
大概率是 # 后面的主机名写错了,导致 TLS 证书校验失败。排查方式:
- 先把
DNSOverTLS临时改成opportunistic,重启服务。 - 如果能上网了,说明就是证书校验的问题,检查主机名拼写。
- 确认主机名正确后,再改回
yes。
另外注意:DNSOverTLS=yes 需要服务器真的支持 DoT(监听 853 端口)。不是所有公共 DNS 都支持 DoT,Cloudflare(1.1.1.1)、Quad9(9.9.9.9)、Google(8.8.8.8)都支持。可以参考本站整理的 免费加密 DNS 地址列表。
其他发行版的差异
- Fedora:默认也是
systemd-resolved,配置方法完全一样。 - Arch Linux:默认不一定启用
systemd-resolved,需要手动sudo systemctl enable --now systemd-resolved并把/etc/resolv.conf软链接到/run/systemd/resolve/stub-resolv.conf。 - 没有 systemd 的发行版(如 Alpine、部分嵌入式系统):用不了
systemd-resolved,需要换stubby、dnscrypt-proxy等独立 DoT/DoH 客户端。
常见问题 FAQ
Q:systemd-resolved 支持 DoH 吗?
A:不支持。systemd-resolved 只支持 DoT(DNS over TLS),不支持 DoH。如果你在 Linux 上需要 DoH,得用 dnscrypt-proxy 或 cloudflared 这类第三方工具。DoT 和 DoH 都是 TLS 加密,安全性相当,DoT 配置更简单(systemd 原生支持)。
Q:配置完需要重启电脑吗?
A:不需要。sudo systemctl restart systemd-resolved 就够了。本地 DNS 缓存会清空,第一次查询会稍慢一点,之后就正常了。
Q:DoT 会影响网速吗?
A:DNS 查询本身只占极少量流量,DoT 多了一次 TLS 握手,但 systemd-resolved 有本地缓存,日常浏览几乎感觉不到延迟。如果你对速度有疑虑,可以看看本站的 私人 DNS 测速方法。
Q:怎么恢复默认 DNS 设置?
A:删掉你建的 drop-in 文件:sudo rm /etc/systemd/resolved.conf.d/99-opendns.conf,然后重启 systemd-resolved。如果你是直接改的主文件,把 DNS= 和 DNSOverTLS= 行前面重新加上 # 注释掉就行。
参考来源
- freedesktop.org — resolved.conf.d 官方文档:支撑
DNS=、FallbackDNS=、DNSOverTLS=(yes/opportunistic/no)的参数定义,以及IP地址#主机名格式用于证书校验和 SNI 的官方说明。URL:https://www.freedesktop.org/software/systemd/man/latest/resolved.conf.d.html - freedesktop.org — systemd-resolved.service 官方文档:支撑 systemd-resolved 作为本地 DNS 存根解析器、监听 127.0.0.53、从 resolved.conf 读取全局 DNS 配置的架构说明。URL:https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html
- Debian Manpages — systemd-resolved.service:支撑 systemd-resolved 作为本地存根解析器、维护
/run/systemd/resolve/stub-resolv.conf、监听 127.0.0.53:53 的官方手册页。URL:https://manpages.debian.org/testing/systemd-resolved/systemd-resolved.service.8.en.html - Debian Manpages — resolved.conf:支撑 DNSStubListener、
/etc/systemd/resolved.conf.d/drop-in 配置目录及优先级说明的官方手册页。URL:https://manpages.debian.org/testing/systemd/resolved.conf.5.en.html