这几天有人问我dns使用协议的问题,之前只知道大概的一个情况,为了详细了解下,google并进行了测试,做下总结:
首先dns是使用tcp + udp的。
使用tcp的场景:
1.区域复制
2.解析返回结果比较大的时候(udp报文内容超过512字节时)
3.rndc 管理dns
4.udp端口不能返回解析,重新使用tcp请求解析(这个和dns的版本有关,bind9是不行的)
使用udp的场景:
用户解析访问。
为什么区域复制时使用tcp而用户访问时使用udp呢?
1.tcp是面向链接的,而且会对数据进行验证,这样区域复制的数据就不会出错,另外由于报文大小的限制也导致区域传送时使用tcp报文
2.正因为tcp是面向连接的,而且建立连接时需要3次握手,用户在使用dns解析时,如果使用tcp报文响应速度会受影响,服务器也会因为维护
大量的tcp连接而产生比较大的压力
3.udp相对来说比较安全些?不多dns的安全还是使用dnssec比较好(dnssec返回的内容会比较大,在超过限制时使用tcp报文,不超过限制时还是使用udp)
那么再思考下:区域复制是否可以使用udp?查询是否可以在不超过限制时使用tcp?
在dig中有几个参数可以方便做下相关的测试:
几个测试结果:
1.区域复制和普通的udp解析就不用说了。
2.dnssec默认使用udp的也比较好测试。
3.普通dns请求也可以使用tcp
dig @servera.vimage2.com +tcp
标准的tcp解析流程:
4.区域复制是否可以使用udp?
5.512限制的测试,主要测试3点,512是指整个报文大小还是去除ip头和udp头之后的大小?超过512时请求是什么样的?超过512时可以使用udp么?
1)构造一个大的返回测试
整个消息报文是533bytes(消息大小为533-20(ip报文头)-8(udp报文头)=505),仍然使用的是udp报文。
结论,只是消息大小,不包括header
rfc1035也明确说明了这一点:
Messages carried by UDP are restricted to 512 bytes (not counting the IPor UDP headers). Longer messages are truncated and the TC bit is set in
the header.
2)超过512时的请求流程?
tcpdump抓包测试:
可以看到用户首先使用udp进行访问,返回的数据被truncate后,用户在使用标准的tcp请求流程进行请求。
根据RFC 1123的解释:
用户在发起dns请求时,默认是以udp开始的(指定+tcp时,使用tcp),在返回udptruncate的包后,再使用tcp进行请求
Specifically,a DNS resolver or server that is sending a
non-zone-transferquery MUST send a UDP queryfirst. Ifthe
Answer section of the response is truncatedandif the
requestersupports TCP, it SHOULD try the query again using
TCP.
3)超过512时可以使用udp么?
网上看到下面的一句话:
说是通过在dnsserver端进行设置,可以改变这种行为,不过我的dns版本没有测试成功,后面有环境的话再进行测试。。。
One ofthe key issues mentioned is that DNSSEC can cause DNS replies to belarger than 512 bytes. DNSSEC(Defined in RFC 4033, RFC 4034, and RFC 4035) requires the abilityto transmit larger DNS messagesbecause of the extra key information contained in the queryresponses. TCP port 53 can be used in the cases where the DNSresponses greater than 512bytes. However,using UDP messages are preferable to using TCP for large DNSmessages is due to the factthat TCP connections can consume computing resources for eachconnection. DNS servers get numerous connections per second andusing TCP can add too much overhead.Toaddress this issue, the IETF RFC2671"ExtensionMechanisms for DNS (EDNS0)" defines a method to extend the UDPbuffer size to 4096 bytes to allow for DNSSEC and larger queryresponses. To enable EDNS0 on your BIND 9 configuration you can usethe following BIND operations statement
edns-udp-size 4096 ;
6.另外看到一句话,说是在udp不能正常响应时,会使用tcp重试。
使用iptables墙掉udp 53测试。
dig @server a.vimage2.com +time=1 +tries=2
结果:
两次重试后,没有数据返回。
看到别人说了一句话。这个行为应该和dns的不同版本有关:
DifferentDNS resolvers may handle it differently. It is well known thatMicrosoft DNS resolvers will query with TCP if the UDP responsedidn't come back in time. However, some other resolvers may notrequery with TCP if the UDP queries don't come back and this is perfectly within the standard aswell.
没了。。。额,说了这么多还是要告诉大家,有些细节方面的东西还是需要自己动手做测试的。
参考文档:
http://www.ietf.org/rfc/rfc2671.txt