DNS是上网的第一步,但传统的DNS查询以明文UDP报文传输,同一网络里的任何监听者都能看到你解析了哪些域名。在Debian上启用DNS加密可以解决这个隐私问题,目前主流做法有两种:DoH(DNS over HTTPS)和DoT(DNS over TLS)。本文将详细介绍两者的区别,并给出在Debian系统上的完整配置步骤。

DoH和DoT有什么区别,该选哪个
DoT全称DNS over TLS,由RFC 7858定义,它在专门的853端口上运行TLS加密的DNS会话。DoH全称DNS over HTTPS,由RFC 8484定义,它把DNS报文封装在HTTP/2或HTTP/3里,走普通的443端口,从外面看和普通浏览网页的流量几乎一样。
两者的加密强度没有本质区别,都依赖TLS证书体系,差异主要在使用场景。DoT使用独立端口,网络管理员可以很方便地通过防火墙封禁853端口,一旦封禁DNS就会退回明文查询。DoH由于复用443端口,除非把整个HTTPS都封掉,否则很难被针对性拦截,因此在有审查或严格管控的网络环境下更占优势。
对于Debian桌面用户或者服务器用户,如果只是想在家庭或办公网络里保护DNS隐私,DoT配置更简单直接,推荐优先考虑。如果你经常使用不可信的公共Wi-Fi,或者所在网络对DNS有干涉,那么DoH是更稳妥的选择。两者也可以同时配置互为备份。
方案一:用systemd-resolved快速启用DoT
Debian默认安装了systemd-resolved作为本地DNS存根,它本身就支持DoT,是最轻量的方案。配置文件位于/etc/systemd/resolved.conf,以Cloudflare的DoT服务为例:
sudo mkdir -p /etc/systemd/resolved.conf.d sudo tee /etc/systemd/resolved.conf.d/dns-over-tls.conf <<'EOF' [Resolve] DNS=1.1.1.1#cloudflare-dns.com 9.9.9.9#dns.quad9.net DNSOverTLS=yes DNSSEC=yes EOF sudo systemctl restart systemd-resolved
注意#后面的域名是用来做TLS证书校验的,这一步不能省略,否则无法确认对端身份。配置完成后用resolvectl status检查,如果看到Current DNS Server和DNSOverTLS字段显示为yes,说明DoT已经生效。
systemd-resolved的局限也很明显:它只支持DoT,不支持DoH;而且作为存根解析器,它把上游查询的结果直接转发,本地不做缓存和过滤。如果你需要DoH支持或者更精细的控制,就要考虑下面两种工具。
方案二:用dnscrypt-proxy同时支持DoH和DoT
dnscrypt-proxy是一款专注于加密DNS的代理,支持DoH、DoT以及DNSCrypt协议,内置可自动更新的公共服务器列表,是Debian上最省心的通用方案。安装方式如下:
sudo apt update sudo apt install dnscrypt-proxy systemctl status dnscrypt-proxy
Debian仓库里的dnscrypt-proxy已经预配置好,默认监听在127.0.2.1:53,避免和systemd-resolved的127.0.0.53冲突。主配置文件在/etc/dnscrypt-proxy/dnscrypt-proxy.toml,关键配置项如下:
# 服务器选择,server_names为空表示使用列表中延迟最低的服务器 server_names = ['cloudflare', 'google'] # 只允许DoH和DoT,禁用明文查询 require_dnssec = true dnscrypt_ephemeral_keys = true tls_disable_session_tickets = true # 本地监听地址 listen_addresses = ['127.0.2.1:53']
修改后执行sudo systemctl restart dnscrypt-proxy重启服务。接着把系统的DNS指向这个本地代理,编辑/etc/systemd/resolved.conf.d/下的配置,将DNS设为127.0.2.1并关闭DoT(因为加密由代理负责),或者直接修改/etc/network/interfaces、NetworkManager里的DNS设置。
dnscrypt-proxy的优势在于配置灵活、服务器列表丰富,还能配合cloaking规则实现本地域名映射、配合block列表做广告过滤。缺点是多了一层代理进程,排查DNS问题时链路稍微复杂一些。
方案三:用unbound自建递归解析加DoT转发
如果你想要更强的自主性,可以用unbound这个权威级的递归解析器。它既能自己从根域开始递归解析,也支持把查询通过DoT转发给上游。安装命令:
sudo apt install unbound
编辑/etc/unbound/unbound.conf.d/dot.conf,写入如下配置:
server:
interface: 127.0.0.1
port: 53
do-ip4: yes
do-udp: yes
do-tcp: yes
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
同样,@853指定端口,#后的域名用于证书校验。重启unbound后,注意处理和systemd-resolved的53端口冲突,最简单的办法是让systemd-resolved把unbound当作上游,或者直接禁用systemd-resolved改用unbound作为系统DNS。
unbound方案的好处是功能强大:支持本地缓存、DNSSEC验证、本地覆盖记录,性能也比前两种更好。代价是配置项多、学习曲线陡,对于只需要加密DNS的普通用户来说可能有些杀鸡用牛刀。
如何验证DNS加密已经生效
配置完成后必须验证,不能想当然认为已经加密。第一步用命令行工具直接测试,例如安装kdig并通过DoT发起查询:
sudo apt install knot-dnsutils kdig -d @1.1.1.1 +tls ippipp.com kdig @127.0.0.1 ippipp.com
如果输出中包含TLS session相关信息且查询成功,说明DoT链路正常。第二步做旁路验证:访问Cloudflare提供的检测页面,如果显示使用的是加密DNS且DNSSEC正常,说明系统级配置生效。
还可以用抓包做终极确认。在另一个终端运行sudo tcpdump -i any port 53 or port 853 -nn,然后进行域名解析,观察53端口的明文流量是否只出现在本机回环地址上,而对外流量都走853或443端口。如果发现对外仍有53端口的流量,说明存在配置遗漏,常见原因是DHCP覆盖了DNS设置,或者某些程序绕过系统DNS自己发查询。
常见问题与注意事项
第一个常见坑是端口53被占用。Debian上systemd-resolved默认占用127.0.0.53:53,如果unbound或dnsmasq也要监听53端口就会启动失败。解决思路是让其中一个只监听回环的其他地址,或者干脆禁用systemd-resolved:sudo systemctl disable --now systemd-resolved,然后手动维护/etc/resolv.conf指向新的本地解析器。
第二个问题是/etc/resolv.conf被反复改写。DHCP客户端和NetworkManager都会重写这个文件,导致加密配置失效。建议用sudo chattr +i /etc/resolv.conf加锁,或在NetworkManager连接配置中明确指定DNS为本地代理地址,防止被网络下发的明文DNS覆盖。
最后要提醒的是,加密DNS只保护查询环节的隐私,无法隐藏你随后与服务器建立连接的IP记录。同时选择公共加密DNS服务时,等于把解析数据交给该服务商,尽量选择口碑好、隐私政策明确的服务,或者考虑用unbound自建完整递归,把解析数据留在自己手里。
Debian DNS加密DoH配置DoT设置修改时间:2026-09-07 16:28:49