关于DNS TCP和UDP那些事

759 阅读4分钟

关于DNS你需要了解的不只是搭建权威DNS、域名层次级别、递归查询,你还需要了解报文格式和TCP/UDP协议。

背景资料两台云服务器配合内网负载均衡搭建了一套高可用的权威DNS架构(其实如果是DNS的话本来可以使用主备模式,不需要再使用负载均衡进行高可用)。

  • 权威DNS使用的是bind来构建,只解析自己的域名,其他的域名还是通过云厂商的DNS服务器进行递归查询。
  • 使用的是四层轮询负载模式,开启了健康检查,监听了UDP53号端口。
经过的排查:
  • 直接绕过负载均衡直接使用权威DNS进行解析。 可以通

  • 解析其他外网域名例如baidu.com。 可以通

  • 查看后端监听是否有UDP53,健康检查状态是否正常 正常

  • 解析 **单独唯一一个报错(某第三方公司提供的服务) ** 不能通

解决问题最好的办法就是抓包:

  • 其实看到这个问题的时候**很奇怪DNS使用UDP报文为什么会出现S 标志位?**这不是TCP协议的吗?

现在进行大胆猜想

数据到达了传输层,而且目测是正常的。得到了包但是还是报错。我猜测是应用层的问题(DNS配置或者DNS BUG)。

现在进行小心求证

我们根据它的架构模式来搭建简单的DNS,涉及产品CLB,CVM,VPC

  • 网络通讯架构模式

    • 内网Client(无hosts指定)访问CLB,CLB四层转发到DNS2,DNS2去DNS1,DNS经过NAT网关访问指定的腾讯云提供的DNS服务。

  • 购买机器、基本配置CLB、NAT、安装配置DNS就不再进行赘述了。

  • 通过搭建DNS、添加域名A记录 dns2.lqhtest.com,来看一下DNS报文不超过512个字节的响应情况

  • 通过上图我们可以对DNS协议分析得到以下结论:
    • 正常的响应包使用的UDP进行传输。
    • Flags标签位中的Truncated截断位表示并未被截断。
    • 相应包返回的解析IP地址只有一个为10.2.1.13
  • 我们再来看看DNS报文大小超过512字节时的特殊响应情况。

  • 根据上图我们可以得到的信息有:

    • DNS块报文大小超过了512字节。
    • Flags标志位中信息截断位为1被截断。
    • 在应用层DNS收到这个被截断的报文后,主动与DNS服务器重新使用TCP建立会话,进行通讯。
    • 来看看这个由TCP和UDP维护的DNS请求报文内容。

  • 对比下响应报文。

分析和总结

当名字解释器发出一个查询请求,并且返回响应中的TC(删减标志)比特被设置为1时,它就意味着响应的长度超过了512个字节,而仅返回前512个字节。在遇到这种情况时,名字解释器通常使用TCP重发原来的查询请求,它将允许返回的响应超过512个字节。-------引用自TCP/IP协议一卷 翻译版14章DNS域名系统。

  • 那么可以得出响应的总结了:
    • 如果DNS报文内容大于512个字节,那么DNS在收到这个报文内容时,发现Flags标志位中的信息截断被标识为1,那么客户端会再次会主动的向DNS服务器发起TCP连接会话请求,在成功建立起TCP会话请求后并再次向服务器发送域名解析请求,DNS服务器在接收到后并同样返回使用TCP封装的DNS报文。
自问自答
  • UDP数据包理论能够承载多少数据报?
    • 理论上支持的公式为:IP数据报最大长度 - IP首部 - UDP首部 = UDP数据报数据最大长度推算则为:65535-20-8=65507(字节),UDP理论支持的数据最大为:65507字节。
  • 为什么DNS只能承载512个字节的数据块报文,加上IP首部UDP首部540字节的报文?
    • 因为这是DNS自己来进行限制的。与此需要注意的还有TFTP、BOOTP、SNMP。都是在应用端进行了限制。
解决方法
  • 知道原理后就知道如何进行解决了,居然是客户端在解析报文得到被截断标志位后会重新改为TCP进行传输,那么只需要在负载均衡上面设置转发后端TCP53端口即可。