linux需用cloudflared等第三方工具实现doh;它监听127.0.0.1:5053,系统dns指向该地址即可,systemd-resolved仅作转发不解析doh,须抓包或查日志验证https加密流量。

Linux 系统本身不内置 DoH 客户端,必须依赖第三方工具实现加密 DNS 解析;直接改 /etc/resolv.conf 或 systemd-resolved 的默认配置无法启用 DoH,硬写 nameserver 1.1.1.1 仍是明文 UDP 查询。
用 cloudflared 做本地 DoH 代理最稳
cloudflared 是 Cloudflare 官方维护的 Go 工具,轻量、无依赖、支持自动证书验证和连接复用,比 dnsproxy 或 stubby 更适合服务器场景。它不修改系统 DNS 配置,而是监听本地 127.0.0.1:5053(默认),你只需把系统 DNS 指向它即可。
- 安装后运行
cloudflared proxy-dns --address 127.0.0.1 --port 5053 --upstream https://cloudflare-dns.com/dns-query - 若要用国内节点,把 upstream 换成
https://dns.alidns.com/dns-query或https://doh.pub/dns-query - 加
--bootstrap-dns 223.5.5.5可指定引导 DNS(防 DoH 地址本身解析失败) - 建议加
--loglevel 1和--pidfile /var/run/cloudflared.pid方便管理
systemd-resolved 怎么对接 DoH 代理
systemd-resolved 默认只支持 DoT(DNS-over-TLS),不原生支持 DoH。强行在 /etc/systemd/resolved.conf 里写 DNS=127.0.0.1 是可以的,但要注意:
- 必须关闭
ResolveUnicastSingleLabel=yes(否则单标签域名查不到) - 要设
Domains=~.显式启用全局解析,否则可能 fallback 到其他 DNS -
resolvectl status中看到Current DNS Server: 127.0.0.1且Server Resolution Capabilities显示UDP和TCP即可,DoH 能力由 cloudflared 提供,resolved 不需要理解 DoH
验证 DoH 是否真生效
别只看 dig example.com @127.0.0.1 -p 5053 能返回结果——那只是证明代理通了,不等于用了加密通道。
- 抓包确认:
sudo tcpdump -i lo port 5053 or port 443 and host cloudflare-dns.com,应看到本地到127.0.0.1:5053的 UDP 请求,以及从127.0.0.1发往 DoH 服务器 443 端口的 HTTPS 流量 - 查日志:
journalctl -u cloudflared -n 20应有类似query=example.com type=A proto=https的记录 - 避免误判:
systemd-resolve --status显示的 “DNS Servers” 是 resolved 自己的上游,不是 DoH 终端;真正走 DoH 的是 cloudflared 进程发出去的请求
最容易被忽略的是:cloudflared 启动后没加 --no-autoupdate,它可能在后台静默升级并重启,导致 PID 变化、服务中断;生产环境务必加上这个参数并用 systemd 管理生命周期。











