
使用 CoreDNS 搭建 DoH (DNS over HTTPS) 服务器
本文介绍如何在 Linux 服务器上搭建自己的 DoH 服务,实现 DNS 查询的加密传输,保护隐私并防止 DNS 劫持。
背景
传统 DNS 查询以明文传输,容易被 ISP 或中间人劫持。DoH (DNS over HTTPS) 将 DNS 查询封装在 HTTPS 协议中,提供更好的隐私保护。
环境说明
本文提供两种系统的安装方法:
| 系统 | 服务管理 | 包管理器 |
|---|---|---|
| Debian / Ubuntu | systemd / supervisor | apt |
| Alpine Linux | OpenRC | apk |
安装 CoreDNS
CoreDNS 是一个灵活的 DNS 服务器,支持插件扩展。
方法一:Debian / Ubuntu
# 安装必要工具
sudo apt install wget jq tar -y
# 下载最新版本
COREDNS_VERSION=$(wget -qO- -t1 -T2 "https://api.github.com/repos/coredns/coredns/releases/latest" | jq -r '.tag_name')
COREDNS_N_VERSION=${COREDNS_VERSION:1}
wget https://github.com/coredns/coredns/releases/download/${COREDNS_VERSION}/coredns_${COREDNS_N_VERSION}_linux_amd64.tgz
# 解压安装
tar zxf coredns_${COREDNS_N_VERSION}_linux_amd64.tgz
sudo mv coredns /usr/local/bin/
sudo chmod +x /usr/local/bin/coredns方法二:Alpine Linux
# 安装必要工具
apk add wget jq tar
# 下载并安装(同上)
COREDNS_VERSION=$(wget -qO- -t1 -T2 "https://api.github.com/repos/coredns/coredns/releases/latest" | jq -r '.tag_name')
COREDNS_N_VERSION=${COREDNS_VERSION:1}
wget https://github.com/coredns/coredns/releases/download/${COREDNS_VERSION}/coredns_${COREDNS_N_VERSION}_linux_amd64.tgz
tar zxf coredns_${COREDNS_N_VERSION}_linux_amd64.tgz
mv coredns /usr/local/bin/
chmod +x /usr/local/bin/coredns配置 CoreDNS
创建配置文件目录和 Corefile:
sudo mkdir -p /etc/CoreDNS
sudo mkdir -p /var/log/coredns创建 /etc/CoreDNS/Corefile:
sudo mkdir -p /etc/CoreDNS && cat << 'EOF' | sudo tee /etc/CoreDNS/Corefile > /dev/null
# 標準 DNS 服務(端口 53)
.:53 {
bind 0.0.0.0
forward . 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4
log
errors
cache
}
# DoH 服務(端口 8053)
https://.:8053 {
bind 0.0.0.0
forward . 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4
log
errors
cache
}
EOF配置说明:
bind 0.0.0.0- 监听所有网卡(容器环境需要让宿主机访问)forward- 上游 DNS 服务器(Cloudflare + Google)cache- 启用 DNS 缓存,减少上游查询log/errors- 记录查询日志和错误
设置开机启动
Debian / Ubuntu(使用 Supervisor)
# 安装 Supervisor
sudo apt install supervisor -y
# 创建服务配置
sudo tee /etc/supervisor/conf.d/coredns.conf << 'EOF'
[program:coredns]
command=/usr/local/bin/coredns -conf /etc/CoreDNS/Corefile
autostart=true
autorestart=true
startretries=3
redirect_stderr=true
stdout_logfile=/var/log/coredns/stdout.log
EOF
# 启动服务
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status corednsAlpine Linux(使用 OpenRC)
Alpine 默认使用 OpenRC,比 Supervisor 更轻量:
# 创建 init 脚本
sudo tee /etc/init.d/coredns << 'EOF'
#!/sbin/openrc-run
name="coredns"
description="CoreDNS DNS Server"
command="/usr/local/bin/coredns"
command_args="-conf /etc/CoreDNS/Corefile"
command_background="yes"
pidfile="/run/coredns.pid"
output_log="/var/log/coredns/stdout.log"
error_log="/var/log/coredns/stderr.log"
depend() {
need net
}
EOF
sudo chmod +x /etc/init.d/coredns
# 注册并启动服务
sudo rc-update add coredns default
sudo rc-service coredns start
# 检查状态
sudo rc-service coredns status验证服务
测试 DNS 查询
# 安装 dig 工具(如需要)
# Debian/Ubuntu: sudo apt install dnsutils
# Alpine: apk add bind-tools
dig @127.0.0.1 google.com +short
# 预期输出:IP 地址,如 142.250.71.174检查端口监听
# Alpine
netstat -tlnp | grep -E '53|8053'
# Debian/Ubuntu
ss -tlnp | grep -E '53|8053'预期输出:
tcp 0 0 :::53 :::* LISTEN <pid>/coredns
tcp 0 0 :::8053 :::* LISTEN <pid>/corednsNginx 反向代理配置
在宿主机上配置 Nginx,将 DoH 流量代理到 CoreDNS 容器:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name dns.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/dns.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dns.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# DoH 端点
location /dns-query {
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 替换为你的 CoreDNS 容器 IP
proxy_pass http://10.10.1.106:8053;
}
}重载 Nginx:
sudo nginx -t
sudo nginx -s reload客户端测试
使用 dig 测试 DoH
dig @dns.yourdomain.com +https google.com浏览器配置
在支持 DoH 的浏览器中添加自定义 DNS:
- Chrome: 设置 → 安全 → 使用安全 DNS → 自定义 →
https://dns.yourdomain.com/dns-query - Firefox: 设置 → 常规 → 网络设置 → 启用基于 HTTPS 的 DNS → 自定义 →
https://dns.yourdomain.com/dns-query
常见问题
1. 容器内服务无法从宿主机访问
确保 CoreDNS 绑定的是 0.0.0.0 而非 127.0.0.1。
2. Alpine 上找不到 supervisorctl
Alpine 推荐使用 OpenRC,但也可以安装 supervisor:
apk add supervisor不过 OpenRC 更轻量且与 Alpine 集成更好。
3. DNS 查询超时
检查防火墙是否放行 53/UDP 和 8053/TCP 端口。
总结
| 对比项 | Debian/Ubuntu | Alpine Linux |
|---|---|---|
| 服务管理 | Supervisor | OpenRC |
| 内存占用 | 较高 | 极低 |
| 启动速度 | 较慢 | 快 |
| 配置复杂度 | 中等 | 简单 |
Alpine Linux 配合 OpenRC 是容器环境的理想选择,资源占用更低。
参考资料: