为了测量一个 DNS 服务器的放大性能,使用dig命令向能够放大的 DNS 服务器请求某个具有大量回复的域名的 ANY 资源,并利用 tcpdump 进行捕包。
dig @x.x.x.x xxx.gov ANY
tcpdump -i interface -n -vv '(udp) and (port 53) and (host x.x.x.x)'
问题1:
- 问题描述:收到了一个 IP 包长度为1500的分片包,但没有收到后续的 IP 分片包。
- 解释:这是因为除了第一个分片包,其他分片包本身并不包含 UDP 或 TCP 头部,所以也无从得知这些 IP 包的端口号,后续的IP分片包也就被过滤掉了。
- 解决办法:把
port 53
这一过滤条件删除。
问题2:
- 问题描述:根据RFC 1035,使用UDP的 DNS 回复包大小被限制在512字节,但是这次回复显然超过了512字节,这是为什么?
- 解释:x.x.x.x DNS 服务器应该实现了 DNS 扩展机制——EDNS0,EDNS0允许大于512字节的UDP回复包。DNS 响应因为引入了一些大型数据项,如 AAAA 记录,DNSSEC 信息(例如RRSIG或DNSKEY),或大型 TXT 记录,导致其大小增加。EDNS 提供更大的 UDP 载荷能力可以避免 DNS 广泛使用 TCP 进行通信,提高 DNS 的可伸缩性。关于 EDNS 详情参考RFC 6891。
问题3
问题描述:dig提示
;; Truncated, retrying in TCP mode.
,也就是说回复太大,被DNS服务器截断了,并没有返回完整的资源记录,重新使用了TCP进行查询。对比了一下 TCP 回复的资源记录和 UDP 回复的资源记录,TCP 回复的资源记录更多,也就是说即使启用了 EDNS0,仍然会有最大长度的限制,超过这个限制仍然会转去使用 TCP。那这个限制是多少呢?是在客户端设置的还是服务器端设置的呢?-
解释:在RFC 6891的 Payload Size Selection 章节中讨论了这一问题:
Due to transaction overhead, it is not recommended to advertise an architectural limit as a maximum UDP payload size. Even on system stacks capable of reassembling 64 KB datagrams, memory usage at low levels in the system will be a concern. A good compromise may be the use of an EDNS maximum payload size of 4096 octets as a starting point. A good compromise may be the use of an EDNS maximum payload size of 4096 octets as a starting point.
大致意思是考虑到传输的开销,不建议把可接收的UDP负载设的太大,所以把'EDNS的最大有效载荷大小为4096字节'作为一个折衷方案。
实验表明,UDP负载大小限制是在服务器端设置的,和客户端发送的请求包中 OPT 记录设置没有关系(请求包中有OPT 记录表明客户端支持 EDNS,如果没有,DNS 服务器最多回复512字节,如下图所示)。关于服务器是如何设置的以及为什么不需要看请求包的 OPT 记录还需要查看RFC 6891进行确认。
实验过程如下:
dig @x.x.x.x xxx.gov ANY +bufsize=1024
dig @x.x.x.x xxx.gov ANY +bufsize=8192
"+bufsize=xxxx"是把请求包的 OPT 资源 UDP payload size 修改成xxxx,DNS 请求包证实可以修改,如下图所示:
但是从收到的回复包来看不管设置成1024还是8196,服务器仍然按照4096进行截断。也就是说这个UDP负载大小限制是在服务器端设置的,和客户端发送的请求包中 OPT 记录设置没有关系。
参考资料:
- 使用 DNS 的扩展名机制 (EDNS0),oschina.
- DNS系统与DDOS攻击的关联,51web.