DNS 解析协议完整对比
| 协议 |
端口 |
传输层 |
加密 |
可被 ISP 识别 |
防篡改 |
延迟 |
RFC |
| Plain DNS | 53 | UDP/TCP | 无 | 完全可见 | 否 | 最低 | 1035 |
| DNSSEC | 53 | UDP/TCP | 无(仅签名) | 可见 | 是 | 低 | 4033 |
| DoT (DNS-over-TLS) | 853 | TLS/TCP | TLS 1.3 | 可识别端口 | 是 | 中 | 7858 |
| DoH (DNS-over-HTTPS) | 443 | HTTPS/TCP | TLS 1.3 | 与 HTTPS 不可区分 | 是 | 中 | 8484 |
| DoH3 (DNS-over-HTTP/3) | 443 | QUIC/UDP | TLS 1.3 | 同 HTTPS | 是 | 低 | 9250 |
| DoQ (DNS-over-QUIC) | 853/8853 | QUIC/UDP | TLS 1.3 | 可识别 | 是 | 最低(加密中) | 9250 |
| DNSCrypt | 443/5443 | UDP/TCP | X25519+XSalsa20 | 可识别 | 是 | 低 | — |
推荐选择
大多数场景推荐 DoH:走 443 端口与正常 HTTPS 流量混合,ISP 无法通过端口识别你在用加密 DNS。如果追求极低延迟,可用 DoQ(QUIC 无需 TCP 握手)。企业内网推荐 DoT,端口独立便于防火墙策略管理。
加密 DNS 提供商对比
| 提供商 |
DoH URL |
DoT 主机名 |
IP |
日志策略 |
广告过滤 |
DNSSEC |
| Cloudflare | https://cloudflare-dns.com/dns-query | one.one.one.one | 1.1.1.1 / 1.0.0.1 | 24h 删除 | 否(1.1.1.2 有) | ✅ |
| Google | https://dns.google/dns-query | dns.google | 8.8.8.8 / 8.8.4.4 | 48h 匿名化 | 否 | ✅ |
| Quad9 | https://dns.quad9.net/dns-query | dns.quad9.net | 9.9.9.9 / 149.112.112.112 | 无日志 | 恶意域名 | ✅ |
| NextDNS | https://dns.nextdns.io/YOUR_ID | YOUR_ID.dns.nextdns.io | 动态分配 | 可配置 | 高度自定义 | ✅ |
| AdGuard | https://dns.adguard-dns.com/dns-query | dns.adguard-dns.com | 94.140.14.14 | 无日志 | 广告+追踪 | ✅ |
| Mullvad | https://dns.mullvad.net/dns-query | dns.mullvad.net | 194.242.2.2 | 无日志 | 可选 | ✅ |
| Ali DNS | https://dns.alidns.com/dns-query | dns.alidns.com | 223.5.5.5 / 223.6.6.6 | 未公开 | 否 | ✅ |
| Tencent DNSPod | https://doh.pub/dns-query | dot.pub | 119.29.29.29 | 未公开 | 否 | ✅ |
操作系统配置
Windows 11 / 10 (DoH)
# Windows 11: Settings → Network → DNS → Manual
# Set Preferred DNS: 1.1.1.1
# DNS over HTTPS: On (automatic template)
# Or via PowerShell (Win 11):
Set-DnsClientDohServerAddress -ServerAddress "1.1.1.1" `
-DohTemplate "https://cloudflare-dns.com/dns-query" `
-AllowFallbackToUdp $False -AutoUpgrade $True
# Verify:
Resolve-DnsName example.com -DnsOnly | Select-Object Name,IPAddress
macOS (DoH / DoT)
# Create a .mobileconfig profile (XML plist)
# Or use a tool like dns-profile-creator
# Manual: System Settings → Network → DNS → add 1.1.1.1
# For DoH via mobileconfig:
# PayloadType: com.apple.dnsSettings.managed
# DNSSettings:
# DNSProtocol: HTTPS
# ServerURL: https://cloudflare-dns.com/dns-query
# ServerAddresses: [1.1.1.1, 1.0.0.1]
# Install: double-click .mobileconfig → System Settings → Profiles
Linux (systemd-resolved DoT)
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#one.one.one.one 1.0.0.1#one.one.one.one
DNSOverTLS=yes
DNSSEC=yes
Domains=~.
FallbackDNS=9.9.9.9#dns.quad9.net
# Restart:
sudo systemctl restart systemd-resolved
# Verify:
resolvectl status
resolvectl query example.com
Android (DoT 原生支持)
# Settings → Network → Private DNS
# Select "Private DNS provider hostname"
# Enter: one.one.one.one (Cloudflare)
# or: dns.google (Google)
# or: dns.adguard-dns.com (AdGuard)
iOS / iPadOS (DoH)
# Install a DoH/DoT profile (.mobileconfig)
# Cloudflare: https://1.1.1.1/dns-over-https.mobileconfig
# Or install "1.1.1.1: Faster Internet" app from App Store
# Settings → General → VPN & Device Management → DNS
浏览器 DoH 配置
| 浏览器 | 设置路径 | 默认 DoH |
| Chrome | chrome://settings/security → 使用安全 DNS | 跟随系统 / Cloudflare / Google 可选 |
| Firefox | about:preferences#privacy → DNS over HTTPS | Cloudflare (美国默认开启) |
| Edge | edge://settings/privacy → 安全 DNS | 同 Chrome |
| Brave | brave://settings/security → 安全 DNS | Quad9 |
| Safari | 不支持浏览器级 DoH(需系统级配置) | — |
注意
浏览器级 DoH 只保护浏览器内的 DNS 查询。其他应用(终端、邮件客户端等)的 DNS 仍走系统 DNS。要全面保护需在系统级或路由器级配置。
代理工具 DNS 配置
Clash / Clash Meta (mihomo)
# config.yaml
dns:
enable: true
listen: 0.0.0.0:53
enhanced-mode: fake-ip # redir-host | fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '*.lan'
- '*.local'
- 'time.*.com'
default-nameserver: # bootstrap DNS (plain, for resolving DoH domain)
- 223.5.5.5
- 119.29.29.29
nameserver: # main encrypted DNS
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
- tls://dot.pub:853
fallback: # fallback for non-CN domains
- https://dns.cloudflare.com/dns-query
- https://dns.google/dns-query
- tls://dns.google:853
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
tun:
enable: true
stack: system # system | gvisor | mixed
dns-hijack:
- any:53
auto-route: true
auto-detect-interface: true
V2Ray / Xray
// config.json → dns 部分
{
"dns": {
"servers": [
{
"address": "https://cloudflare-dns.com/dns-query",
"domains": ["geosite:geolocation-!cn"],
"skipFallback": true
},
{
"address": "https://doh.pub/dns-query",
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
"223.5.5.5" // fallback plain DNS
],
"queryStrategy": "UseIPv4"
}
}
sing-box
// config.json
{
"dns": {
"servers": [
{
"tag": "remote",
"address": "https://dns.cloudflare.com/dns-query",
"detour": "proxy"
},
{
"tag": "local",
"address": "https://doh.pub/dns-query",
"detour": "direct"
},
{
"tag": "block",
"address": "rcode://success"
}
],
"rules": [
{"geosite": "cn", "server": "local"},
{"geosite": "category-ads-all", "server": "block"}
],
"strategy": "prefer_ipv4"
}
}
WireGuard
# wg0.conf
[Interface]
PrivateKey = YOUR_PRIVATE_KEY
Address = 10.0.0.2/32
DNS = 1.1.1.1, 1.0.0.1 # WireGuard sets system DNS when connected
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0 # route all traffic (full tunnel)
PersistentKeepalive = 25
# DNS leak prevention: AllowedIPs = 0.0.0.0/0 forces all traffic through tunnel
# For split tunnel, also add: AllowedIPs = 1.1.1.1/32 to route DNS specifically
OpenVPN
# client.ovpn — server pushes DNS:
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"
push "block-outside-dns" # Windows: prevents DNS leak
# Client-side override (add to .ovpn):
dhcp-option DNS 1.1.1.1
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
Shadowsocks + dns2socks
# Use dns2socks to forward DNS through SOCKS5 proxy
dns2socks 127.0.0.1:1080 8.8.8.8:53 127.0.0.1:5353
# Then point system DNS to 127.0.0.1:5353
# Or use ss-tunnel for DNS forwarding:
ss-tunnel -s server -p 8388 -l 5353 -L 8.8.8.8:53 -k password -m aes-256-gcm
TUN 模式详解
TUN(网络隧道)模式在操作系统中创建一个虚拟网络接口,接管所有网络流量(包括 DNS),将其转发到代理客户端处理。相比手动配置系统代理,TUN 模式的优势是无需应用单独配置代理,所有流量自动走代理隧道。
TUN 工作流程
应用 → 系统路由 → TUN 虚拟网卡 → 代理客户端(Clash/sing-box)→ 规则匹配 → 直连或代理 → 远端服务器
DNS 处理
TUN 模式下 DNS 查询被 dns-hijack 拦截,由代理客户端的 DNS 模块处理。fake-ip 模式返回假 IP,建立连接后用真实域名请求。
fake-ip vs redir-host
fake-ip:快速(无 DNS 延迟),但某些应用不兼容(需要 fake-ip-filter 排除)。redir-host:先做真 DNS 解析再路由,兼容性好但慢。
协议栈选择
system:用系统协议栈,稳定但需 root/admin。gvisor:用户态协议栈,无需 root 但 CPU 稍高。mixed:TCP 走 system,UDP 走 gvisor(推荐)。
Clash TUN 完整配置
tun:
enable: true
stack: mixed
dns-hijack:
- any:53
- tcp://any:53
auto-route: true
auto-detect-interface: true
# macOS/Linux: auto-route adds route rules
# Windows: sets TUN as default gateway
sing-box TUN
{
"inbounds": [{
"type": "tun",
"interface_name": "tun0",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"strict_route": true,
"stack": "mixed",
"sniff": true,
"sniff_override_destination": true
}]
}
iptables 透明代理 DNS 转发
在 Linux 网关/路由器上,用 iptables 将所有 DNS 流量强制转发到本地加密 DNS 代理(如 clash、sing-box 或 dnscrypt-proxy),防止任何设备绕过加密 DNS。
DNS 劫持(重定向 53 端口)
# Redirect all outbound DNS (port 53) to local proxy on port 5353
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5353
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5353
# Also catch local traffic (from the gateway itself)
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 5353
iptables -t nat -A OUTPUT -p tcp --dport 53 -j REDIRECT --to-ports 5353
# Exclude the proxy itself from being redirected (prevent loop)
iptables -t nat -A OUTPUT -m owner --uid-owner clash -p udp --dport 53 -j RETURN
TPROXY 透明代理(全流量)
# TPROXY mode: proxy all TCP+UDP (including DNS) through clash/sing-box
# Step 1: Create routing rule
ip rule add fwmark 0x1 table 100
ip route add local default dev lo table 100
# Step 2: Mark packets for TPROXY
iptables -t mangle -N CLASH
iptables -t mangle -A CLASH -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A CLASH -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A CLASH -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A CLASH -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A CLASH -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A CLASH -p tcp -j TPROXY --on-port 7893 --tproxy-mark 0x1
iptables -t mangle -A CLASH -p udp -j TPROXY --on-port 7893 --tproxy-mark 0x1
iptables -t mangle -A PREROUTING -j CLASH
# Step 3: Exclude proxy process
iptables -t mangle -A OUTPUT -m owner --uid-owner clash -j RETURN
iptables -t mangle -A OUTPUT -p tcp -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT -p udp -j MARK --set-mark 0x1
nftables (现代替代)
# nftables DNS redirect
nft add table ip nat
nft add chain ip nat prerouting { type nat hook prerouting priority -100\; }
nft add rule ip nat prerouting udp dport 53 redirect to :5353
nft add rule ip nat prerouting tcp dport 53 redirect to :5353
路由器级 DNS 加密
OpenWrt
安装 https-dns-proxy 包 → LuCI → Services → HTTPS DNS Proxy → 添加 Cloudflare/Google → 禁用 dnsmasq 转发。或安装 OpenClash/PassWall 集成代理+DNS。
Asus Merlin
固件 386+ 原生支持 DoT:Administration → System → DNS Privacy Protocol → DNS-over-TLS → 添加服务器。或通过 Entware 安装 stubby。
pfSense / OPNsense
Services → DNS Resolver (Unbound) → Custom Options → 添加 forward-tls-upstream: yes 和 DoT 服务器。OPNsense 的 Unbound DNS 原生支持 DoT。
MikroTik
RouterOS v6.47+ 支持 DoH:/ip dns set use-doh-server=https://cloudflare-dns.com/dns-query verify-doh-cert=yes。注意先导入 CA 证书。
DNS 分流策略
在代理环境中,DNS 分流是关键优化:国内域名用国内 DNS 解析(避免解析到海外 CDN),海外域名用海外 DNS 解析(避免被污染)。
# Clash DNS 分流逻辑示意
# ┌─────────────────────────────────────────────────────────┐
# │ DNS Query: example.com │
# ├─────────────────────────────────────────────────────────┤
# │ 1. Check geosite rules: │
# │ - geosite:cn → nameserver (Ali/Tencent DoH) │
# │ - geosite:geolocation-!cn → fallback (CF/Google) │
# │ 2. If no rule match → both nameserver + fallback │
# │ 3. Apply fallback-filter: │
# │ - If nameserver returns CN IP → use it (direct) │
# │ - If nameserver returns non-CN IP → use fallback │
# └─────────────────────────────────────────────────────────┘
最佳实践
① bootstrap DNS 用纯 IP(如 223.5.5.5),避免"用 DNS 解析 DNS 服务器域名"的循环依赖;② fake-ip 模式下无需关心 DNS 污染,因为实际域名通过代理隧道在远端解析;③ fallback-filter 开启 geoip,根据解析结果的 IP 地理位置决定是否使用 fallback。
安全性与隐私分析
| 威胁 |
Plain DNS | DNSSEC | DoT | DoH | DoQ |
| ISP 监听查询内容 | ✗ | ✗ | ✓ | ✓ | ✓ |
| ISP 识别协议类型 | — | — | 端口 853 | 混入 HTTPS | QUIC |
| DNS 缓存投毒 | ✗ | ✓ | ✓ | ✓ | ✓ |
| 中间人篡改 | ✗ | ✓ | ✓ | ✓ | ✓ |
| ISP 封锁 | — | — | 易封 | 难封 | 可封 |
| 元数据泄露(SNI/IP) | 全部 | 全部 | 服务器 IP | SNI+IP | 服务器 IP |
QUIC 泄露风险
QUIC (HTTP/3) 使用 UDP 443 端口。大量仅处理 TCP 的代理工具(HTTP 代理、部分 SOCKS5)无法隧道 QUIC 流量,导致浏览器绕过代理直连,同时泄露 IP 和 DNS。防护方案:① 代理中启用 TUN 模式捕获所有 UDP;② 禁用浏览器 QUIC(chrome://flags/#enable-quic → Disabled);③ 使用支持 UDP 的协议(Shadowsocks/Trojan/VLESS+XUDP)。可用本站 IP 泄露检测的 QUIC 通道验证。
ECH (Encrypted Client Hello)
DoH 的 HTTPS 连接仍会在 TLS 握手时通过 SNI 暴露 DoH 服务器域名。ECH(原 ESNI)加密了 SNI 字段,与 DoH 结合可实现完全不可见的 DNS 查询。Chrome 和 Firefox 已实验性支持 ECH。
FAQ
DoH 和 DoT 应该选哪个?DoH 走 443 端口,与普通 HTTPS 不可区分,更难被 ISP/防火墙识别和封锁。DoT 用专用 853 端口,防火墙可以针对性封锁。一般个人用户推荐 DoH,企业内网推荐 DoT(便于管控)。
加密 DNS 会变慢吗?首次查询可能多 5-20ms(TLS 握手开销),但后续查询因 HTTP/2 多路复用和连接复用,延迟与 Plain DNS 接近。DoQ 基于 QUIC,0-RTT 握手让延迟更低。实际使用中感知差异极小。
fake-ip 模式有什么缺点?① 部分应用(如 Telegram)直接用 IP 连接时不走 DNS,fake-ip 无法代理;② 本地 ping 返回假 IP,不能用于网络调试;③ 需要维护 fake-ip-filter 排除列表(如 NTP 服务器、局域网发现协议)。
如何验证 DoH/DoT 是否生效?① 使用本站的 DNS 泄露检测工具;② 在 Cloudflare 的 https://1.1.1.1/help 页面检查"Using DNS over HTTPS"是否为 Yes;③ 用 dig 指定服务器测试:dig @1.1.1.1 example.com +https(需 dig 9.18+)。
为什么用了 DoH 还是被 DNS 污染?可能原因:① bootstrap DNS 使用了被污染的 Plain DNS 来解析 DoH 服务器域名——改用 IP 地址作为 bootstrap;② 系统有其他应用绕过代理直接发 DNS 查询——开启 TUN 模式拦截所有流量;③ IPv6 DNS 未被代理覆盖——禁用 IPv6 或在代理中配置 IPv6 DNS。
iptables 和 TUN 模式哪个更好?TUN 模式更简单、跨平台(Windows/macOS/Linux),代理客户端自动处理路由。iptables/TPROXY 更灵活、性能更高,但仅限 Linux 且配置复杂。路由器/网关场景推荐 iptables,个人设备推荐 TUN。
企业环境应该怎么做?① 在网关部署 Unbound + DoT 作为递归解析器;② 用 iptables 强制所有 53 端口流量走网关 DNS;③ 内网域名走内部 DNS,外部域名走加密 DNS(split-horizon);④ 启用 DNSSEC 验证;⑤ 日志留存满足合规要求。