最后更新于:2026年07月

当你使用公共 DNS(如 8.8.8.8 或 1.1.1.1)时,你的每一次域名查询都可能被记录和分析。自建 DNS over HTTPS(DoH)服务不仅能保护你的 DNS 查询隐私,还能实现自定义的域名过滤、智能分流和访问控制。
本文将带你从零搭建一个生产级的 DoH 公共解析服务,包括 doh-server 部署、AdGuard Home 集成、访问控制、证书管理以及完整的隐私审计方案。
🧭 DoH 是什么?为什么需要自建?
DNS over HTTPS 原理
传统 DNS 查询使用明文 UDP/TCP 传输,容易被窃听和篡改:
┌──────────────────────────────────────────────────────────┐
│ 传统 DNS 查询 │
│ │
│ 客户端 ──明文──► 本地 DNS ──明文──► 根服务器 │
│ │ │ │
│ │ ISP 可见所有查询 │ │
│ │ 可能被篡改返回结果 │ │
│ └──────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘DoH 通过 HTTPS 加密传输 DNS 查询:
┌──────────────────────────────────────────────────────────┐
│ DNS over HTTPS 查询 │
│ │
│ 客户端 ──HTTPS加密──► DoH 服务器 ──DNS──► 根服务器 │
│ │ │ │
│ │ ISP 只看到加密流量 │ │
│ │ 查询内容不可见 │ │
│ │ 响应完整性受 TLS 保护 │ │
│ └──────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘自建 DoH 的优势
| 对比项 | 公共 DoH(1.1.1.1/8.8.8.8) | 自建 DoH |
|---|---|---|
| 隐私保护 | 服务商可见所有查询 | 完全自主控制 |
| 自定义规则 | 无法自定义 | 可配置任意过滤规则 |
| 分流解析 | 固定解析策略 | 可实现国内/国外智能分流 |
| 访问控制 | 无限制 | 可限制访问来源 |
| 日志保留 | 可能保留日志 | 可配置不保留或定期清理 |
| 可用性 | 依赖服务商 | 完全自主可控 |
📦 方案选择:doh-server vs AdGuard Home
方案对比
| 方案 | 功能 | 性能 | 部署复杂度 | 推荐场景 |
|---|---|---|---|---|
| doh-server | 纯 DoH 服务 | ⭐⭐⭐⭐⭐ | ⭐⭐ | 需要高性能纯 DoH 服务 |
| AdGuard Home | DoH + 广告过滤 + 管理界面 | ⭐⭐⭐ | ⭐⭐⭐⭐ | 需要完整 DNS 管理功能 |
| CoreDNS + DoH 插件 | 高度可定制 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 复杂场景需要自定义插件 |
推荐组合
生产环境推荐架构:
┌──────────────────────────────────────────────────────────┐
│ 客户端 ──► DoH 入口 ──► AdGuard Home │
│ │ │ │
│ │ ├── 广告过滤 │
│ │ ├── 自定义规则│
│ │ └── 智能分流 │
│ │ │
│ ▼ ▼
│ doh-server 上游 DNS │
│ (高性能入口) (国内/国外) │
└──────────────────────────────────────────────────────────┘🚀 实战一:doh-server 部署
环境准备
# 系统要求:Linux(推荐 Debian 12 或 Ubuntu 22.04)
# 需要域名(如 doh.example.com)
# 需要 SSL 证书(Let's Encrypt)
# 更新系统
apt update && apt upgrade -y安装 doh-server
# 使用 go 安装
go install github.com/m13253/dns-over-https/doh-server@latest
# 或下载预编译二进制
VERSION=$(curl -s https://api.github.com/repos/m13253/dns-over-https/releases/latest | grep tag_name | cut -d '"' -f 4)
wget https://github.com/m13253/dns-over-https/releases/download/$VERSION/doh-server_${VERSION}_linux_amd64.tar.gz
tar -xzvf doh-server_${VERSION}_linux_amd64.tar.gz
cp doh-server /usr/local/bin/
# 验证安装
doh-server --help创建配置文件
# 创建配置目录
mkdir -p /etc/doh-server
mkdir -p /var/log/doh-server创建 /etc/doh-server/doh-server.conf:
{
"listen_address": ":443",
"listen_address_tls": ":443",
"upstream": [
"119.29.29.29:53",
"223.5.5.5:53"
],
"upstream_timeout": 5,
"tls_cert": "/etc/letsencrypt/live/doh.example.com/fullchain.pem",
"tls_key": "/etc/letsencrypt/live/doh.example.com/privkey.pem",
"http3": true,
"logfile": "/var/log/doh-server/doh-server.log",
"loglevel": "info",
"cors": true,
"metrics": ":9153",
"health": ":9154"
}配置说明
{
"listen_address": ":443",
// DoH HTTP 监听地址,用于反向代理或测试
"listen_address_tls": ":443",
// DoH HTTPS 监听地址
"upstream": [
"119.29.29.29:53",
"223.5.5.5:53"
],
// 上游 DNS 服务器,可以配置多个实现负载均衡
"upstream_timeout": 5,
// 上游查询超时时间(秒)
"tls_cert": "/etc/letsencrypt/live/doh.example.com/fullchain.pem",
"tls_key": "/etc/letsencrypt/live/doh.example.com/privkey.pem",
// TLS 证书和私钥
"http3": true,
// 是否启用 HTTP/3(QUIC)支持
"logfile": "/var/log/doh-server/doh-server.log",
"loglevel": "info",
// 日志配置
"cors": true,
// 是否允许跨域请求(浏览器 DoH 需要)
"metrics": ":9153",
// Prometheus 指标监听地址
"health": ":9154"
// 健康检查接口
}获取 SSL 证书
# 安装 Certbot
apt install -y certbot python3-certbot-nginx
# 获取证书
certbot certonly --nginx -d doh.example.com
# 或使用 DNS 验证(推荐,支持泛域名)
certbot certonly --dns-cloudflare -d doh.example.com
# 验证证书
openssl x509 -in /etc/letsencrypt/live/doh.example.com/fullchain.pem -text -noout创建 systemd 服务
cat > /etc/systemd/system/doh-server.service << 'EOF'
[Unit]
Description=DNS over HTTPS Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/doh-server --conf /etc/doh-server/doh-server.conf
Restart=on-failure
RestartSec=10
User=doh-server
Group=doh-server
[Install]
WantedBy=multi-user.target
EOF
# 创建专用用户
useradd -r -s /usr/sbin/nologin doh-server
# 设置文件权限
chown -R doh-server:doh-server /etc/doh-server
chown -R doh-server:doh-server /var/log/doh-server
# 启动服务
systemctl daemon-reload
systemctl enable --now doh-server
systemctl status doh-server测试 DoH 服务
# 使用 curl 测试
curl -H "Accept: application/dns-json" \
"https://doh.example.com/dns-query?name=google.com&type=A"
# 预期输出(JSON 格式):
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": false,
"CD": false,
"Question": [{
"name": "google.com.",
"type": 1
}],
"Answer": [{
"name": "google.com.",
"type": 1,
"TTL": 300,
"data": "142.250.185.14"
}]
}
# 使用 dig 测试(需要安装 dnsutils)
dig @127.0.0.1 -p 443 +https google.com🛡️ 实战二:AdGuard Home 集成
安装 AdGuard Home
# 官方脚本安装
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh
# 或使用 Docker(推荐)
docker run -d \
--name adguardhome \
--restart unless-stopped \
-v /opt/adguardhome/work:/opt/adguardhome/work \
-v /opt/adguardhome/conf:/opt/adguardhome/conf \
-p 53:53/tcp \
-p 53:53/udp \
-p 80:80/tcp \
-p 3000:3000/tcp \
-p 853:853/tcp \
adguard/adguardhome:latest配置 AdGuard Home
1. 初始化设置
访问 http://your-server-ip:3000,按照向导完成初始化:
设置步骤:
1. 设置用户名和密码
2. 配置 DNS 监听端口(默认 53)
3. 配置上游 DNS 服务器
4. 启用加密 DNS(DoH/DoT/DoQ)2. 配置上游 DNS
AdGuard Home → 设置 → DNS 设置 → 上游 DNS 服务器
添加上游服务器:
- 国内:223.5.5.5、119.29.29.29、101.226.4.6
- 国外:8.8.8.8、1.1.1.1、9.9.9.9
配置自定义规则:
- 国内域名走国内 DNS
- 国外域名走国外 DNS3. 启用加密 DNS
设置 → DNS 设置 → 加密 DNS
启用 DoH:
- 启用 DoH 服务器
- 端口:853(标准 DoH 端口)或 443
- TLS 证书:使用 Let's Encrypt
启用 DoT:
- 启用 DoT 服务器
- 端口:853
启用 DoQ(可选):
- 启用 DoQ 服务器
- 端口:88534. 配置自定义过滤规则
过滤器 → 添加过滤规则列表
常用规则列表:
- https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
- https://v.firebog.net/hosts/AdguardDNS.txt
- https://v.firebog.net/hosts/Easylist.txt
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
自定义规则:
||example.com^ # 阻止 example.com
@@||example.com^ # 允许 example.com5. 配置访问控制
设置 → 访问控制
允许列表模式:
- 只允许指定 IP 访问
- 其他 IP 被拒绝
拒绝列表模式:
- 拒绝指定 IP 访问
- 其他 IP 允许
推荐:允许列表模式,只允许自己的网络访问🔗 实战三:doh-server + AdGuard Home 组合
架构设计
┌──────────────────────────────────────────────────────────┐
│ 组合架构 │
│ │
│ 客户端 ──HTTPS──► doh-server(443端口) │
│ │ │
│ ▼ │
│ AdGuard Home(53端口) │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ 国内 DNS 国外 DNS │
│ 223.5.5.5 8.8.8.8 │
│ 119.29.29.29 1.1.1.1 │
└──────────────────────────────────────────────────────────┘配置 doh-server 转发到 AdGuard Home
修改 /etc/doh-server/doh-server.conf:
{
"listen_address": ":443",
"listen_address_tls": ":443",
"upstream": [
"127.0.0.1:53"
],
"upstream_timeout": 10,
"tls_cert": "/etc/letsencrypt/live/doh.example.com/fullchain.pem",
"tls_key": "/etc/letsencrypt/live/doh.example.com/privkey.pem",
"http3": true,
"logfile": "/var/log/doh-server/doh-server.log",
"loglevel": "info",
"cors": true,
"metrics": ":9153",
"health": ":9154"
}配置 AdGuard Home 智能分流
在 AdGuard Home 的"自定义过滤规则"中添加:
# 国内域名走国内 DNS
@@||cn^$dnsrewrite=NOERROR;A;223.5.5.5
@@||china^$dnsrewrite=NOERROR;A;119.29.29.29
# 使用上游服务器组
# 在 AdGuard Home 中配置上游服务器组📊 监控与日志
Prometheus 监控
doh-server 内置了 Prometheus 指标:
# 查看指标
curl http://localhost:9153/metrics
# Prometheus 配置
# /etc/prometheus/prometheus.yml
scrape_configs:
- job_name: 'doh-server'
static_configs:
- targets: ['localhost:9153']
- job_name: 'adguardhome'
static_configs:
- targets: ['localhost:3000']日志管理
# doh-server 日志
tail -f /var/log/doh-server/doh-server.log
# AdGuard Home 日志
tail -f /opt/adguardhome/work/logs/AdGuardHome.log
# 日志轮换配置
# /etc/logrotate.d/doh-server
/var/log/doh-server/doh-server.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 640 doh-server doh-server
}
# 应用日志轮换
logrotate -f /etc/logrotate.d/doh-server🔒 安全加固
1. 限制访问来源
# 使用 iptables 限制只允许特定 IP 访问 DoH 服务
iptables -A INPUT -p tcp --dport 443 -s 192.168.0.0/16 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j DROP
# 或使用 UFW
ufw allow from 192.168.0.0/16 to any port 443
ufw deny 4432. 禁用日志保留
// doh-server 配置
{
"logfile": "",
"loglevel": "warn"
}
// AdGuard Home 配置
// 设置 → DNS 设置 → 日志设置
// 日志级别:警告或关闭
// 日志保留时间:不保留3. 定期更新
# 更新 doh-server
VERSION=$(curl -s https://api.github.com/repos/m13253/dns-over-https/releases/latest | grep tag_name | cut -d '"' -f 4)
wget https://github.com/m13253/dns-over-https/releases/download/$VERSION/doh-server_${VERSION}_linux_amd64.tar.gz
tar -xzvf doh-server_${VERSION}_linux_amd64.tar.gz
cp doh-server /usr/local/bin/
systemctl restart doh-server
# 更新 AdGuard Home(Docker)
docker pull adguard/adguardhome:latest
docker stop adguardhome
docker rm adguardhome
docker run -d --name adguardhome ... adguard/adguardhome:latest4. 使用 HTTP/3
// doh-server 配置
{
"http3": true
}
// 客户端配置(支持 HTTP/3 的浏览器)
// Chrome: 访问 chrome://flags 启用 HTTP/3
// Firefox: about:config → network.http.http3.enabled = true📱 客户端配置
浏览器配置
Chrome / Edge:
设置 → 隐私和安全性 → 安全 → 高级 → 使用安全 DNS
选择:自定义
输入:https://doh.example.com/dns-query
或在 chrome://flags 中:
- Secure DNS lookups: Enabled
- DNS over HTTPS: EnabledFirefox:
设置 → 常规 → 网络设置 → 设置 → DNS over HTTPS
选择:自定义
输入:https://doh.example.com/dns-query系统级配置
Windows 11:
设置 → 网络和 Internet → Wi-Fi / 以太网 → 编辑 → IPv4 DNS
选择:手动
输入首选 DNS:1.1.1.1(或你的服务器 IP)
然后启用:使用 DNS over HTTPSmacOS:
系统设置 → 网络 → Wi-Fi / 以太网 → 详细信息 → DNS
点击 + 添加你的服务器 IP
点击 DNS over HTTPS 下拉菜单,选择:加密Linux(systemd-resolved):
# 编辑配置文件
cat > /etc/systemd/resolved.conf << 'EOF'
[Resolve]
DNS=127.0.0.1
DNSOverHTTPS=yes
DNSOverHTTPSFallback=no
EOF
# 重启服务
systemctl restart systemd-resolved代理客户端配置
Clash Meta:
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- https://doh.example.com/dns-query
fallback:
- https://doh.example.com/dns-query
fallback-filter:
geoip: cn
ipcidr:
- 240.0.0.0/4sing-box:
{
"dns": {
"servers": [
{
"tag": "doh",
"type": "https",
"server": "doh.example.com",
"server_port": 443,
"path": "/dns-query"
}
],
"rules": [
{
"outbound": "any",
"server": "doh"
}
]
}
}🔍 故障排查
问题 1:DoH 服务无法访问
# 检查服务状态
systemctl status doh-server
# 检查端口监听
ss -tlnp | grep 443
# 检查防火墙
ufw status
iptables -L -n | grep 443
# 测试本地访问
curl -v https://localhost/dns-query?name=google.com
# 测试远程访问
curl -v https://doh.example.com/dns-query?name=google.com
# 常见原因:
# 1. 防火墙未开放 443 端口
# 2. SSL 证书过期或配置错误
# 3. 域名解析错误
# 4. doh-server 配置错误问题 2:DNS 查询返回错误
# 检查上游 DNS 是否可用
dig @119.29.29.29 google.com
# 检查 AdGuard Home 状态
curl http://localhost:3000/control/status
# 检查日志
tail -f /var/log/doh-server/doh-server.log
# 常见原因:
# 1. 上游 DNS 不可用
# 2. 查询超时
# 3. 域名被过滤问题 3:浏览器无法使用 DoH
# 测试浏览器是否支持
curl -H "Accept: application/dns-json" \
"https://doh.example.com/dns-query?name=google.com&type=A"
# 检查 CORS 设置
curl -v -H "Origin: https://example.com" \
"https://doh.example.com/dns-query?name=google.com"
# 检查 SSL 证书
openssl s_client -connect doh.example.com:443
# 常见原因:
# 1. SSL 证书不被浏览器信任
# 2. CORS 未配置
# 3. 浏览器版本不支持 DoH问题 4:性能问题
# 测试 DNS 查询延迟
dig @doh.example.com google.com +stats
# 检查服务器资源
top
free -h
# 检查连接数
ss -tlnp | grep 443 | wc -l
# 优化建议:
# 1. 增加上游 DNS 数量
# 2. 启用 HTTP/3
# 3. 使用 CDN 加速
# 4. 增加服务器资源📊 性能优化
1. 启用 HTTP/3
{
"http3": true
}HTTP/3 使用 QUIC 协议,减少握手延迟,提高连接稳定性。
2. 配置多个上游服务器
{
"upstream": [
"119.29.29.29:53",
"223.5.5.5:53",
"101.226.4.6:53",
"101.226.4.6:53"
]
}多个上游服务器实现负载均衡和故障转移。
3. 启用缓存
在 AdGuard Home 中配置缓存:
设置 → DNS 设置 → 缓存设置
缓存大小:10000 条
缓存时间:默认(根据 TTL)4. 使用 CDN
将 DoH 服务部署在 Cloudflare CDN 后面:
Cloudflare → 添加域名 → 配置 SSL/TLS → 启用 HTTPS
Cloudflare → 网络 → HTTP/3:启用
Cloudflare → 缓存 → 配置:优化 DNS 查询📋 完整部署检查清单
部署前准备:
□ 注册域名(如 doh.example.com)
□ 服务器配置(至少 1 核 512MB)
□ SSL 证书(Let's Encrypt)
部署步骤:
□ 安装 doh-server
□ 配置 doh-server.conf
□ 获取 SSL 证书
□ 创建 systemd 服务
□ 安装 AdGuard Home(可选)
□ 配置上游 DNS
□ 配置过滤规则
□ 配置访问控制
安全配置:
□ 限制访问来源(防火墙)
□ 禁用日志保留
□ 定期更新
□ 启用 HTTP/3
客户端配置:
□ 浏览器 DoH 配置
□ 系统级 DoH 配置
□ 代理客户端 DNS 配置
测试验证:
□ DoH 服务访问测试
□ DNS 查询测试
□ 过滤规则测试
□ 加密验证测试
□ 性能测试结语
自建 DNS over HTTPS 服务不仅能保护你的 DNS 查询隐私,还能实现高度自定义的域名过滤和智能分流。通过 doh-server + AdGuard Home 的组合,你可以构建一个功能完整、性能卓越的私有 DNS 服务。
总结要点:
- ✅ doh-server:高性能 DoH 入口,支持 HTTP/3
- ✅ AdGuard Home:完整的 DNS 管理功能,广告过滤
- ✅ 智能分流:国内/国外域名自动选择上游 DNS
- ✅ 隐私保护:加密传输,可配置不保留日志
- ✅ 访问控制:限制访问来源,提高安全性
- ✅ 监控告警:Prometheus 指标,健康检查
推荐架构:
生产环境:
doh-server(443端口)→ AdGuard Home(53端口)→ 上游 DNS
家庭使用:
AdGuard Home(53端口 + 853端口)→ 直接供家庭设备使用
高性能需求:
doh-server(HTTP/3)→ 多个上游 DNS → 负载均衡记住:DNS 是互联网的入口,保护 DNS 隐私是保护网络隐私的第一步。 掌握了自建 DoH 服务,你就拥有了对网络入口的完全控制权。
愿你的 DNS 查询永远安全、快速、私密!🔒
