检测DNS服务器状态的问题

时间:2022-10-17 18:09:02

产品的一个功能要求和DNS服务器对接,并通过心跳机制实时探测DNS服务器的状态。


测试发现,当DNS服务器正常运行时,产品总是报错:“DNS服务器状态异常”。


代码是使用dnsjava库实现的,每隔X秒钟向DNS服务器发出一个只带header的server status request请求(opcode=2),若能收到响应(只要不抛异常),则认为DNS服务器状态正常。


在DNS服务器上抓包发现,当使用TCP协议时,对收到的请求,DNS服务器不回响应;而使用UDP协议时,DNS服务器每隔大约1分钟,才对某个请求返回Not Implemented错误响应(Response code=4),而在这1分钟之内的其他请求都不回响应。


这个DNS服务器使用的是一台win2008 R2上的“DNS管理器”,对于产品发出的server status request请求,在其日志中也有记录,说是不合法的请求,但没有更具体的说明。(如果将其调试日志打开,也许能有。)


虽然怀疑是windows的bug,但是在网上搜索不到别人反馈win2008有类似问题,于是找协议来分析。rfc1034(https://www.rfc-editor.org/std/std13.txt)中,Status queries 是Experimental并且To be defined。另外能搜到一篇2001/2002年左右的draft试图定义这个opcode,但最终还是没有被标准化。所以没有标准支撑,虽然感觉windows处理不正确(“至少给回个错误,而不是直接丢消息啊”),也无可奈何。


这部分是老代码,为什么之前没有暴露问题?原来之前的开发测试都使用Linux上的bind来做DNS服务器,而抓包可以看到,bind对每个server status request请求都会返回Not Implemented,而代码只要能收到响应就行,不判断错误码,因此没有这个问题。


最终的解决方法是改用一个A查询(example.com)来代替server status request。另外在网上也能找到,好像MS也是这么干的,
DNS_STATUS DnsValidateServerStatus(
  _In_  PSOCKADDR server,
  _In_  PCWSTR    queryName,
  _Out_ PDWORD    serverStatus
);
具体参见https://msdn.microsoft.com/en-us/library/windows/desktop/ee837436(v=vs.85).aspx