自建 DNS over HTTPS(DoH)并在 macOS 配置使用
2025-06-26 tech doh mac dns linux 11 mins 4 图 3894 字
这篇文章简单记录自建DNS over HTTPS(DoH)服务的步骤。
架构说明
- 上游DNS:
100.100.100.100:53
- DoH服务:
satishweb/doh-server
Docker容器(监听100.100.100.100:1053
) - 前端代理:Nginx提供HTTPS并反向代理到DoH服务
- 客户端:macOS通过配置文件接入
一、部署DoH服务器(Docker容器)
# 停止并删除旧容器
docker stop doh && docker rm doh
# 启动DoH容器
docker run -d --restart unless-stopped \
--network host \
--name doh \
-e UPSTREAM_DNS_SERVER="udp:100.100.100.100:53" \
-e DOH_HTTP_PREFIX="/dns-query" \
-e DOH_SERVER_LISTEN="100.100.100.100:1053" \
-e DOH_SERVER_TIMEOUT="10" \
-e DOH_SERVER_TRIES="3" \
-e DOH_SERVER_VERBOSE="true" \
satishweb/doh-server
关键参数说明:
UPSTREAM_DNS_SERVER
:上游DNS地址(需可被容器访问)DOH_SERVER_LISTEN
:容器监听的本地地址和端口DOH_HTTP_PREFIX
:DoH请求路径(必须与Nginx配置一致)
二、配置Nginx反向代理
在Nginx站点配置中(如/etc/nginx/sites-available/default
)添加:
server {
listen 443 ssl;
server_name blog.kelu.org; # 替换为您的域名
# SSL证书配置(必需)
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# DoH代理配置
location = /dns-query {
allow 100.100.100.5; # 允许访问的客户端IP
deny all; # 禁止其他IP
proxy_pass http://100.100.100.100:1053; # 指向DoH容器
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 其他配置...
}
操作命令:
sudo nginx -t && sudo systemctl reload nginx # 测试并重载配置
直接访问地址,验证是否成功:
https://aa.bb.com/dns-query?name=baidu.com&type=A
三、客户端配置(macOS)
-
手工生成配置文件
doh.mobileconfig
:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <array> <dict> <key>DNSSettings</key> <dict> <key>DNSProtocol</key> <string>HTTPS</string> <key>ServerURL</key> <string>https://blog.kelu.org/dns-query</string> <!-- 改为您的域名 --> </dict> <key>PayloadDescription</key> <string>Configures DNS over HTTPS</string> <key>PayloadDisplayName</key> <string>DoH DNS Server</string> <key>PayloadIdentifier</key> <string>com.yourdomain.dns</string> <key>PayloadType</key> <string>com.apple.dnsSettings.managed</string> <key>PayloadUUID</key> <string>065AB183-5E34-4794-9BEB-B5327CF61F27</string> <!-- 用uuidgen生成 --> <key>PayloadVersion</key> <integer>1</integer> </dict> </array> <key>PayloadDescription</key> <string>Install to enable DNS over HTTPS</string> <key>PayloadDisplayName</key> <string>Custom DoH Configuration</string> <key>PayloadIdentifier</key> <string>com.yourdomain.dohprofile</string> <key>PayloadUUID</key> <string>030E6D6F-69A2-4515-9D77-99342CB9AE76</string> <!-- 用uuidgen生成 --> <key>PayloadVersion</key> <integer>1</integer> </dict> </plist>
- 替换
ServerURL
为您的HTTPS地址 - 使用uuidgen
命令生成新的PayloadUUID
- 替换
-
安装配置:
-
双击
.mobileconfig
文件导入macOS提醒打开系统设定,在设备管理里可以看到:
双击后安装即可。
-
四、验证服务
-
测试DoH服务:
curl -H 'content-type: application/dns-message' \ "https://blog.kelu.org/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
正常应返回加密的DNS响应。
-
客户端检查:
- 在macOS终端执行
scutil --dns | grep 'nameserver\[0\]'
- 查看日志:
docker logs doh
日志大概长这个样:
- 在macOS终端执行