为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 DNS 使用 UDP 协议

标签:
Java

为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。

今天要分析的具体问题是『为什么 DNS 使用 UDP 协议』,DNS 作为整个互联网的电话簿,它能够将可以被人理解的域名翻译成可以被机器理解的 IP 地址,使得互联网的使用者不再需要直接接触很难阅读和理解的 IP 地址。作者曾经在 详解 DNS 与 CoreDNS 的实现原理 一文中介绍过 DNS 的实现原理,这篇文章中就不会介绍 DNS 的实现原理了,感兴趣的读者可以看一下。

相信 DNS 使用 UDP 协议已经成为了软件工程师的常识,对计算机网络稍有了解的人都知道 DNS 会使用 UDP 协议传输数据,但是这一观点其实不是完全正确的,我们在这里就会详细分析『为什么 DNS 会使用 UDP 传输数据』以及『为什么 DNS 不止会使用 UDP 传输数据』两个问题,希望能够帮助各位读者理解 DNS 协议的全貌。

概述

我们将要讨论的两个问题其实并不冲突,在绝大多数情况下,DNS 都是使用 UDP 协议进行通信的,DNS 协议在设计之初也推荐我们在进行域名解析时首先使用 UDP,这确实能解决很多需求,但是不能解决全部的问题。

实际上,DNS 不仅使用了 UDP 协议,也使用了 TCP 协议,不过在具体介绍今天的问题之前,我们还是要对 DNS 协议进行简单的介绍:DNS 查询的类型不止包含 A 记录、CNAME 记录等常见查询,还包含 AXFR 类型的特殊查询,这种特殊查询主要用于 DNS 区域传输,它的作用就是在多个命名服务器之间快速迁移记录,由于查询返回的响应比较大,所以会使用 TCP 协议来传输数据包。

作为被广泛使用的协议,我们能够找到非常多 DNS 相关的 RFC 文档,DNS Camel Viewer 中列出了将近 300 个与 DNS 协议相关的 RFC 文档,其中有 6 个是目前的互联网标准,有 102 个是 DNS 相关的提案,这些文档共同构成了我们目前对于 DNS 协议的设计理解,作者也没有办法去一一阅读其中的内容,只选择了其中一些重要的文档帮我们理解 DNS 的发展史以及它与 UDP/TCP 协议的关系,这里只会摘抄文档中与 UDP/TCP 协议相关的内容:

  1. RFC1034 · Domain Names - Concepts and Facilities Internet Standard, 1987-11
    1. DNS 查询可以通过 UDP 数据包或者 TCP 连接进行传输;
    2. 由于 DNS 区域传输的功能对于数据的准确有着较强的需求,所以我们必须使用 TCP 或者其他的可靠协议来处理 AXFR 类型的请求;
  2. RFC1035 · Domain Names - Implementation and Specification
    1. 互联网支持命名服务器通过 TCP 或者 UDP 协议进行访问;
    2. UDP 协议携带的消息不应该超过 512 字节,超过的消息会被截断并设置 DNS 协议的 TC 位,UDP 协议对于区域传输功能是不可接受的,不过是互联网上标准查询的推荐协议。通过 UDP 协议发送的查询可能会丢失,所以需要重传策略解决这个问题;
  3. RFC1123 · Requirements for Internet Hosts – Application and Support Internet Standard, 1989-10
    1. 未来定义的新 DNS 记录类型可能会包含超过 512 字节的信息,所以我们应该使用 TCP 协议来传输 DNS 记录;因此解析器和命名服务需要使用 TCP 协议作为 UDP 无法满足需求时的备份;
    2. DNS 解析器和递归服务器必须支持 UDP 协议,并且应该支持使用 TCP 协议发送非区域传输的查询;也就是说,DNS 解析器或者服务器在发送非区域传输查询时,必须先发送一个 UDP 查询,如果该查询的响应被截断,它应该尝试使用 TCP 协议重新请求;
  4. RFC3596 · DNS Extensions to Support IP Version 6 Internet Standard, 2003-10
    1. 通过 DNS 扩展支持 IPv6 协议,每个 IPv6 占 16 个字节是 IPv4 的四倍;
  5. RFC5011 · Automated Updates of DNS Security (DNSSEC) Trust Anchors Independent, 2007-10
    1. 新增多种资源记录为 DNS 客户端的 DNS 数据来源进行认证,记录包含的数据往往较大;
  6. RFC6376 · DomainKeys Identified Mail (DKIM) Signatures Internet Standard, 2011-09
    1. 选择合适的键大小进行加密是需要在成本、性能和风险之间的权衡,然而大的键(4096-bit)可能没有办法直接放到 DNS UDP 响应包中直接返回;
  7. RFC6891 · Extension Mechanisms for DNS (EDNS(0)) Internet Standard, 2013-04
    1. 使用 UDP 进行传输的 DNS 查询和响应最大不能超过 512 字节,不能支持大量 IPv6 地址或者 DNS 安全签名等记录的传输;
    2. EDNS 为 DNS 提供了扩展功能,让 DNS 通过 UDP 协议携带最多 4096 字节的数据;
  8. RFC7766 · DNS Transport over TCP - Implementation Requirements Proposed Standard, 2016-03
    1. 当客户端接收到一个被截断的 DNS 响应时,应该通过 TC 字段判断是否需要通过 TCP 协议重复发出 DNS 查询请求;
    2. DNSSEC 的引入使得截断的 UDP 数据包变得非常常见;
    3. 使用 UDP 传输 DNS 的数据包大小超过最大传输单元(MTU)时可能会导致 IP 数据包的分片,RFC1123 文档中预测的未来已经到来了,唯一一个用于增加 UDP 能够携带数据包大小的 EDNS 机制被认为不够可靠;
    4. 所有通用 DNS 实现必须要同时支持 UDP 和 TCP 传输协议,其中包括权威服务器、递归服务器以及桩解析器;
    5. 桩解析器和递归解析器可以根据情况选择使用 TCP 或者 UDP 查询直接请求目标服务器,以 UDP 协议来开始发起 DNS 请求不再是强制性的,TCP 协议与 UDP 协议在 DNS 查询中可以互相替代,而不是作为重试机制;
  9. Specification for DNS over Transport Layer Security (TLS) Proposed Standard, 2016-05
    1. 在 DNS 协议中引入 TLS 来为用户提供隐私,减少对 DNS 查询的窃听和篡改,但是 TLS 协议的引入会带来一些性能方面的额外开销;
  10. RFC8484 · DNS Queries over HTTPS (DoH) Proposed Standard, 2018-10
  11. 定义了一种通过 HTTPS 发送 DNS 查询和获取 DNS 响应的协议;

我们可以简单总结一下 DNS 的发展史,1987 年的 RFC1034RFC1035 定义了最初版本的 DNS 协议,刚被设计出来的 DNS 就会同时使用 UDP 和 TCP 协议,对于绝大多数的 DNS 查询来说都会使用 UDP 数据报进行传输,TCP 协议只会在区域传输的场景中使用,其中 UDP 数据包只会传输最大 512 字节的数据,多余的会被截断;两年后发布的 RFC1123 预测了 DNS 记录中存储的数据会越来越多,同时也第一次显式的指出了发现 UDP 包被截断时应该通过 TCP 协议重试。

过了将近 20 年的时间,由于互联网的发展,人们发现 IPv4 已经不够分配了,所以引入了更长的 IPv6,DNS 也在 2003 年发布的 RFC3596 中进行了协议上的支持;随后发布的 RFC5011RFC6376 增加了在鉴权和安全方面的支持,但是也带来了巨大的 DNS 记录,UDP 数据包被截断变得非常常见。

RFC6891 提供的 DNS 扩展机制能够帮助我们在一定程度上解决大数据包被截断的问题,减少了使用 TCP 协议进行重试的需要,但是由于最大传输单元的限制,这并不能解决所有问题。

DNS 出现之后的 30 多年,RFC7766 才终于提出了使用 TCP 协议作为主要协议来解决 UDP 无法解决的问题,TCP 协议也不再只是一种重试时使用的机制,随后出现的 DNS over TLS 和 DNS over HTTP 也都是对 DNS 协议的一种补充。

从这段发展时来看,DNS 并不只是使用 UDP 数据包进行通信,在 DNS 的标准中就一直能看到 TCP 协议的身影,我们在今天也是想要站在历史的角度上分析 ——『为什么 DNS 查询选择使用 UDP/TCP 协议』。

原文链接:https://draveness.me/whys-the-design-dns-udp-tcp/
作者公众号:一起写程序

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
33
获赞与收藏
206

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消