smartdns
smartdns copied to clipboard
如果上游只有doh时,dnsperf测试出现大量SERVFAIL(85%以上)
问题现象
简要描述问题出现的现象
如果上游只有doh时,dnsperf测试出现大量SERVFAIL(85%以上),感觉只有前面若干域名查询正常
运行环境
-
固件型号
ubuntu 24.04 -
运营商
-
smartdns来源以及版本 46.1
-
涉及的配置(注意去除个人相关信息)
重现步骤
- 上游DNS配置。
server-https https://dns.google/dns-query -host-ip 8.8.8.8 -no-check-certificate -group cf -proxy xray - 访问的域名。
信息收集
- 将/var/log/smrtdns.log日志作为附件上传(注意去除个人相关信息)。
- 如进程异常,请将coredump功能开启,上传coredump信息文件,同时上传配套的smartdns进程文件。
在自定义界面,开启设置->自定义设置->生成coredump配置,重现问题后提交coredump文件 coredump文件在/tmp目录下
smartdns连接doh上游时,有没有连接重用,超时之类的参数可以设置? [Status] Command line: dnsperf -d ./data/processed/domain-A-10000.txt -s 127.0.0.1 -p 1056 -m udp -c 100 -t 5 [Status] Sending queries (to 127.0.0.1:1056) [Status] Started at: Sat May 17 12:14:00 2025 [Status] Stopping after 1 run through file [Status] Testing complete (end of file)
Statistics:
Queries sent: 10000 Queries completed: 10000 (100.00%) Queries lost: 0 (0.00%)
Response codes: NOERROR 138 (1.38%), SERVFAIL 9844 (98.44%), NXDOMAIN 18 (0.18%) Average packet size: request 30, response 31 Run time (s): 228.156083 Queries per second: 43.829644
Average Latency (s): 2.266110 (min 0.000046, max 2.406129) Latency StdDev (s): 0.243429 大约从30个域名查询之后,全部为fail
如果你的查询每秒超过100次,google将拒绝服务
如果你的查询每秒超过100次,google将拒绝服务
但是为何udp正常?如果上游只设置为:server 8.8.8.8 错误率低于2%
运营商劫持udp
同样的配置,只更换了上游的测试结果: Statistics:
Queries sent: 10000 Queries completed: 10000 (100.00%) Queries lost: 0 (0.00%)
Response codes: NOERROR 8785 (87.85%), SERVFAIL 175 (1.75%), NXDOMAIN 1040 (10.40%) Average packet size: request 30, response 72 Run time (s): 17.943180 Queries per second: 557.314813
Average Latency (s): 0.161082 (min 0.000054, max 2.289929) Latency StdDev (s): 0.260508
运营商劫持udp
通过透明代理翻的,不存在被劫持吧?
在mosdns内测试了同样的doh上游,mosdns的测试结果正常。 Statistics:
Queries sent: 10000 Queries completed: 9994 (99.94%) Queries lost: 6 (0.06%)
Response codes: NOERROR 8785 (87.90%), SERVFAIL 162 (1.62%), NXDOMAIN 1047 (10.48%) Average packet size: request 30, response 98 Run time (s): 22.755007 Queries per second: 439.200041
Average Latency (s): 0.195032 (min 0.036653, max 4.697946) Latency StdDev (s): 0.352383
能否分享一下 domain-A-10000.txt,我也测一测
localhost:~/smartdns# smartdns -c $(pwd)/smartdns.conf
localhost:~/smartdns# dnsperf -d $(pwd)/domain-A-10000.txt -s 127.0.0.1 -p 5353 -m udp -c 100 -t 5
DNS Performance Testing Tool
Version 2.14.0
[Status] Command line: dnsperf -d /root/smartdns/domain-A-10000.txt -s 127.0.0.1 -p 5353 -m udp -c 100 -t 5
[Status] Sending queries (to 127.0.0.1:5353)
[Status] Started at: Sat May 17 18:55:45 2025
[Status] Stopping after 1 run through file
[Status] Testing complete (end of file)
Statistics:
Queries sent: 10000
Queries completed: 10000 (100.00%)
Queries lost: 0 (0.00%)
Response codes: NOERROR 51 (0.51%), SERVFAIL 9943 (99.43%), NXDOMAIN 6 (0.06%)
Average packet size: request 30, response 30
Run time (s): 27.725040
Queries per second: 360.684782
Average Latency (s): 0.269307 (min 0.000138, max 2.449236)
Latency StdDev (s): 0.684117
localhost:~/smartdns# kdig +https www.baidu.com @8.8.8.8
;; TLS session (TLS1.3)-(ECDHE-X25519)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
;; HTTP session (HTTP/2-POST)-(8.8.8.8/dns-query)-(status: 200)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
;; Flags: qr rd ra; QUERY: 1; ANSWER: 4; AUTHORITY: 0; ADDITIONAL: 1
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 512 B; ext-rcode: NOERROR
;; PADDING: 337 B
;; QUESTION SECTION:
;; www.baidu.com. IN A
;; ANSWER SECTION:
www.baidu.com. 46 IN CNAME www.a.shifen.com.
www.a.shifen.com. 3 IN CNAME www.wshifen.com.
www.wshifen.com. 261 IN A 119.63.197.139
www.wshifen.com. 261 IN A 119.63.197.151
;; Received 468 B
;; Time 2025-05-17 18:56:24 JST
;; From 8.8.8.8@443(HTTPS) in 47.1 ms
localhost:~/smartdns# kdig www.baidu.com @127.0.0.1:5353
;; ->>HEADER<<- opcode: QUERY; status: SERVFAIL; id: 42891
;; Flags: qr rd ra; QUERY: 1; ANSWER: 0; AUTHORITY: 0; ADDITIONAL: 0
;; QUESTION SECTION:
;; www.baidu.com. IN A
;; Received 31 B
;; Time 2025-05-17 18:56:37 JST
;; From 127.0.0.1@5353(UDP) in 2195.5 ms
至此证实是smartdns的问题。等会儿我看看日志
问了一deepseak:
高并发瓶颈 单线程同步 SSL 发送可能成为性能瓶颈。参考 SmartDNS 文档,建议启用多线程模式(threads 2)。 缓冲区未限制大小,极端情况下可能导致内存耗尽(需结合 cache-size 参数控制)。 TLS 握手开销 未实现 TLS 会话复用(Session Resumption),每次连接需完整握手。可通过配置 tls-handshake-timeout 优化超时。 HTTP/2 支持缺失 当前代码基于 HTTP/1.1,而主流 DoH 服务已支持 HTTP/2。升级后可利用多路复用降低延迟。
http3.c **1. 流控与拥塞控制:**当前代码未显式实现 QUIC 的流级别流量控制(如 WINDOW_UPDATE 帧),可能在高并发场景下引发性能问题。 2. 会话复用优化:未使用 QUIC 的会话票据(Session Ticket)机制,每次连接需完整 TLS 握手,增加延迟。 3. 缓冲区管理:inpacket_data 固定大小为 DNS_IN_PACKSIZE,若上游响应过大(如 ECS 扩展数据),可能触发报文截断。
测试了一下,223.5.5.5的情况下确实有这个问题。 但smartdns自己套自己的DOH查询测试是没有问题,性能也正常。 所以应该不是smartdns http处理出错的问题, 根本原因是应该是smartdns目前用了http1.1的协议,只要上游出现流控,就会导致后面的请求被上游服务器全部丢弃不响应。 后面看看增加http2的支持。 但C没有现成好用的http2库支持,这部分要手写,可能要很久。
目前的情况,家用应该是没有问题,并发300QPS的情况下,不会有问题。 所有建议是,如果有大量请求,改用DOT.
nghttp2 这个库可以用吗?
如果缓存中的域名比较多,在预取的时候会触发这个问题吗
只要你的上游不全是doh类型的话应该没问题
测试了一下,223.5.5.5的情况下确实有这个问题。 但smartdns自己套自己的DOH查询测试是没有问题,性能也正常。 所以应该不是smartdns http处理出错的问题, 根本原因是应该是smartdns目前用了http1.1的协议,只要上游出现流控,就会导致后面的请求被上游服务器全部丢弃不响应。 后面看看增加http2的支持。 但C没有现成好用的http2库支持,这部分要手写,可能要很久。
目前的情况,家用应该是没有问题,并发300QPS的情况下,不会有问题。 所有建议是,如果有大量请求,改用DOT.
正确的,短时间大量请求触发了google的封锁。但是此时使用kdig测试https服务器又是通的。我猜是封了端口,改端口重连应该能缓解?
如果缓存中的域名比较多,在预取的时候会触发这个问题吗
我的经验是预读也不会导致每秒100次以上
如果你的查询每秒超过100次,google将拒绝服务
但是为何udp正常?如果上游只设置为:server 8.8.8.8 错误率低于2%
建议你不要用 Google 公共 DNS 来发送大量查询,除非你真的仔细阅读了他们的文档。
他们(在文档里)说得很清楚,Google 会强制执行 1500 QPS(每秒查询次数)的速率限制。这个限制适用于所有 IP,除非你是 ISP,并且明确向他们申请提高你 IP 的限制——但如果你没有一个“无论发生什么都不会改变/轮换的”静态专用公网 IP,(申请)获批的几率很低。
参考资料,这是他们的官方文档: https://developers.google.com/speed/public-dns/docs/isp
如果你想每秒推送超过 20000 个请求(当然,前提是你的硬件允许),可以试试 v.recipes DNS。vrcp 清楚地说明了他们实现了一种“单请求调速逻辑”(per-request pacing logic),所以从数学上讲,你不可能触发任何上游 DoH 提供商的速率限制(假设他们至少提供 1000 QPS 的限制)。
否则(如果你不用 vrcp),你就必须在应用层面自己实现这个(调速)逻辑,而这就需要你修改 App 的代码了。
这和你是用 DoH 还是 DoT 没关系。如果谷歌说了只允许 1500 QPS,那么用 DoH 还是 DoT 都无所谓,你不可能绕过这个限制。因为谷歌(很可能)是按 IP 地址来跟踪请求的,而不是按协议。
这并不是什么新鲜事,大多数公共 DNS 提供商都用同样的逻辑:就是追踪某个 IP 是否发送了过多请求,然后就(暂时)封掉它,直到那个 IP“冷静”下来。
这跟用 DoH 还是 DoT 毫无关系。除非 DNS 提供商明确表示“我们是按协议来限制请求的”,那时候你才能说“哦那我换成 DoT 就行了”(反之亦然)。😐