公网 DoH 服务安全排查与设备识别方案实践

随着家庭和小型团队中私有 DNS 服务(如 AdGuard Home)的普及,越来越多的人开始在公网提供 DoH(DNS-over-HTTPS)服务。然而,公网服务意味着可能会接收到大量未知请求,如果不加控制,很容易出现滥用或者安全问题。本文记录了我们在实际部署过程中遇到的问题、排查思路及最终解决方案,希望对有类似需求的朋友提供参考。

本文域名ip敏感信息已经做了脱敏处理,和实际不一致,但是不影响阅读和核心观点输出

一、问题发现

我们的服务器提供 AdGuard Home 公网 DoH 服务,服务覆盖手机、平板和家庭网络设备。最近在 AdGuard Home 的请求日志中发现大量来自 自身 IP 不在使用范围的请求,且请求均为 DoH 协议:

hub5btmain.v6.shub.sandai.net

siteapi.cloud.huawei.com

wambo.club

tracker1.wasabii.com.tw

tracker.piratepublic.com

...

通过 nginx access log,进一步确认:

tls.mydomain.com - 106.43.40.28 - - "GET /dns-query?dns=AAABAAABAA..." HTTP/1.1" 200

tls.mydomain.com - 106.43.40.28 - - "GET /dns-query?dns=AAABAAABAA... HTTP/1.1" 200

tls.mydomain.com - 106.43.40.28 - - "GET /dns-query?dns=AAABAAABAA... HTTP/1.1" 200

tls.mydomain.com - 106.43.40.28 - - "GET /dns-query?dns=AAABAAABAA... HTTP/1.1" 200

...

可见有外部 IP 正在尝试访问我们的 DoH 接口。

公网 DoH 接口收到大量未知来源的请求,而且很多是重复的,存在潜在滥用或探测风险。

二、排查分析

识别请求来源

检查 AdGuard Home 日志:发现请求来自公网 IP,不是我们控制的设备。

检查 nginx access log:确认请求确实访问了 /dns-query。

分析请求参数:请求使用 DoH GET 方式,传入的 dns= 参数看似正常,但重复频繁,像是扫描或滥用行为。

风险

DoH 是 HTTPS,默认加密,无法通过传统 DNS 层 IP 屏蔽所有请求。

公网暴露意味着任何人都可以尝试使用我们的 DNS 做递归查询或扫描。

如果接口被滥用,会产生带宽压力甚至安全隐患(如 DDoS 放大)。

确认自身设备识别问题

原有配置中,因为nginx没有以下配置:

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

我们从accesslog中无法区分具体设备,只能看到请求 IP。

因此在排查和统计时,难以区分:

正常设备

潜在滥用者

泄露的配置

三、解决思路

首先封禁可疑 IP

临时阻止恶意 IP 访问 DoH 服务:

iptables -A INPUT -s 106.43.40.28 -p tcp –dport 443 -j DROP

iptables -A INPUT -s 106.43.40.28 -p tcp –dport 8043 -j DROP

这可以快速阻止已知滥用者,但不是长期解决方案。

按设备分组访问

给每台设备分配独立子域名?:

iphone.private-ns.mydomain.com

mac.private-dns.mydomain.com

router.private-dns.mydomain.com

wife.private-dns.mydomain.com

Nginx 配置 server_name *.private-dns.mydomain.com,通过访问的子域名进行日志区分。

这样即使公网请求依然可以通过子域名识别合法设备,并排除未知访问。

使用独立的通配符证书用于dns(private-dns)

证书申请 *.private-dns.mydomain.com,确保 HTTPS TLS 校验正常。

注意原有 *.mydomain.com 无法覆盖两层子域名,例如 iphone.private-dns.mydomain.com。

Nginx 配置优化

location = /dns-query 改为 location = /1b2c28 请求专门代理到本地 AdGuard Home 服务。这样即使我们的private-dns子域名暴露,因为不知道location,攻击者也无法拿到我们的doh路径,无法使用我们的dns服务

另外其他路径返回 404,减少无效暴露。

日志按子域名区分设备,便于后续统计和安全审计。

四、实施方案

  1. Nginx 子域名配置示例
server {

listen 443 ssl;

listen [::]:443 ssl;



server_name *.private-dns.mydomain.com;



ssl_certificate /root/.acme.sh/private-dns.mydomain.com/fullchain.cer;

ssl_certificate_key /root/.acme.sh/private-dns.mydomain.com/private-dns.mydomain.com.key;

ssl_ciphers HIGH:!aNULL:!MD5;



access_log /var/log/nginx/doh_access.log;

error_log /var/log/nginx/doh_error.log warn;



location = /1b2c28 {

proxy_http_version 1.1;

proxy_buffering off;

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

proxy_pass http://127.0.0.1:3000/dns-query;

}



location / {

return 404;

}

}
  1. 防护和日志策略

只允许子域名访问 DoH 服务。

非法访问直接返回 404。

通过 access log 可以看到每个设备的请求。

对滥用 IP 可继续使用 iptables 或 fail2ban 封禁。

五、效果与总结

成功区分了不同设备的 DoH 请求。

Nginx 日志清晰显示每台设备的请求来源。

滥用请求可快速封禁。

AdGuard Home 仍然提供正常的 DNS 服务,不受影响。

子域名策略为长期可维护方案,支持未来扩展。

六、经验分享

  1. 公网 DoH 必须考虑安全

  2. 任意 IP 都可以访问递归 DNS。

  3. 滥用和扫描行为不可避免。

  4. 使用子域名区分设备

  5. 每台设备独立子域名,日志可区分。

  6. 子域名可作为“识别 ID”,便于统计和管理。

  7. 证书策略

  • 通配符证书需覆盖实际使用的子域名层级。

  • 两层子域名必须申请对应通配符证书,否则 HTTPS 会报错。

  • iptables 是有效补充

  • 对可疑 IP 临时封禁,快速降低滥用风险。

  • 长期依赖子域名管理,更安全可控。

七、结语

不仅解决了公网 DoH 的滥用问题,还实现了设备可识别管理。对于小型公网 DNS 服务提供者来说,这套方法既安全又易用。希望本文能为有类似需求的朋友提供参考,也欢迎大家根据自身需求调整策略。