Closed hapood closed 4 months ago
能提供下当时的日志吗?我需要从日志分析,是什么情况导致你说的这个错误。
能提供下当时的日志吗?我需要从日志分析,是什么情况导致你说的这个错误。
chinadns.log 这是完整的日志,可以看到很多too many pending requests
456 [server.zig:129 QueryCtx.List.add] too many pending requests: 65536
1126 [server.zig:391 on_query] dns.check_query(fd:6) failed: invalid query msg
6646 [Upstream.zig:396 TCP.push_qmsg] too many pending queries: 1000
4 [Upstream.zig:551 TCP.on_error] recv(tcp://8.8.8.8) failed: (104) Connection reset by peer
简单统计了一下日志,我感觉这个与 #180 是类似的问题,也许可以一并讨论。
如果可以复现,建议开 verbose log,这样就能看到 too many pending requests 之前的日志,得知查询者的 ip:port,查询的域名。
这个看起来确实很像 DDoS 攻击(我猜是某个程序的 Bug,一直在死循环解析某些域名,毕竟内网应该不应该存在 DDoS 攻击),短时间内 chinadns-ng 收到了巨量的 dns query,因为 qctx_list 容量是有限的(65535),所以可能导致正常请求无法得到处理。
invalid query msg 这个错误我估计也是上述 Bug程序 触发的,具体见 #180。
能否对同一域名的DNS请求做一个单独LIST,而不是把所有的DNS请求放入同一个LIST。
问题没有这么简单,这种类似“DDoS”的攻击实际上很难防御,且听我道来。
首先需要介绍一些 DNS 知识:
chinadns-ng 与每个 upstream 都是单个“持久的” TCP/UDP 会话,因此 qctx_list 最多可容纳 65536 个未完成的查询,如果 qctx_list 满了,那么新来的 query 就无法得到处理,因为没有 msg-id 可用了。无论你怎么“优化”qctx_list的结构,都受到这个 msg-id 的限制,所以你提议的方法没什么效果。
有人会问,是否可以换个思路:让 chinadns-ng 对于收到的每个 “DNS查询” 都使用一个 “单独的TCP/UDP会话” 与 upstream 进行通信,这样就可以绕过 dns msg-id 的限制了。
这样确实绕过了 msg-id 的限制,但陷入了另一个限制:“五元组”的限制,或者说可同时打开的 socket 数的限制。
所以我的想法是,找出这个有问题的程序/主机,看看查询的是什么域名,为什么它会疯狂发DNS查询。从这个方向入手。
当网络状况突然变差时,可能会出现某些APP或者机器疯狂请求DDNS的情况。导致chinadns-ng持续报错too many pending requests,干扰了其他应用的DNS请求。
能否对同一域名的DNS请求做一个单独LIST,而不是把所有的DNS请求放入同一个LIST。