DNS原理

请注意,本文最近一次更新于:2022-06-20,文章内容可能已经不具有时效性,请谨慎参考

本文最后更新于:2022年6月20日星期一晚上10点32分 +08:00

浅浅了解与DNS有关的内容,仅作常识性学习


DNS原理

DNS是什么

域名系统(Domain Name System,DNS)是将域名解析到IP地址的一项互联网基础服务,提供该服务的服务器称为域名服务器(Domain Name Server)

域名系统:
1. 一个由分层的DNS服务器实现的分布式数据库
2. 一个使得主机能够查询分布式数据库的应用层协议


域名(Domain)是一个在互联网上表示主机或主机组的名称,通过域名解析到服务器的IP地址。相比于晦涩难记的IP地址,域名共容易记忆

域名服务系统的结构

域名系统是一个分布式的系统,没有一台域名服务器拥有因特网上所有主机的映射。域名系统在结构上是一个四层树状层次结构,包括本地域名服务器根域名服务器顶级域名服务器权威域名服务器

  • 本地域名服务器(Local DNS):严格来说,本地域名服务器并不属于DNS的层次结构,但它十分重要。每个网络服务提供商(ISP),比如移动、电信,都有一台或多台本地DNS服务器。当主机发出DNS请求时,该请求首先被发往本地DNS服务器,本地 DNS 服务器起着代理的作用,并负责将该请求转发到 DNS 服务器层次结构中
  • 根域名服务器(Root DNS):当本地域名服务器无法查询到解析结果时,就会首先向根域名服务器询问。根域名服务器只负责管理顶级域名服务器的IP地址,因此它只会返回请求中顶级域名服务器的IP地址。不考虑镜像,全球一共有13个根域名服务器
  • 顶级域名服务器(Top level DNS):顶级域名服务器只负责管理在该顶级域名服务器下注册的二级域名,也就是权威域名服务器。请求发送到顶级域名服务器经处理后,返回请求中权威域名服务器的IP地址
  • 权威域名服务器(Authoritative DNS):在特定区域内具有唯一性,负责维护该区域内的域名与IP地址的映射关系。在DNS应答报文中,标志位AA表示本次DNS记录是否来自权威域名服务器,否则可能来自缓存

DNS如何进行解析查询

DNS解析分为递归查询迭代查询两种方式。客户端与本地域名服务器之间一般采用递归查询,而DNS服务器之间一般采用迭代查询

递归查询


递归查询的意思是:如果DNS服务器查找不到该域名,那么它将继续以客户端的身份,向其他DNS服务器发送查询的请求报文,客户端只负责等待查询结果

迭代查询


迭代查询的意思是:如果DNS服务器查找不到该域名,它不会替客户端完成后续的查询工作,而是告诉客户端接下来你该向哪一级别的域名服务器发送请求报文,随后客户端重新向这个新的DNS服务器发送请求报文

下面以查询小U的网站blog.starysky.top为例,说说DNS是如何解析的:

  • 在向域名系统发送请求之前,客户端向本地域名服务器发送请求报文blog.starysky.top,问问它之前是否访问过小U的网站。如果有Cache并且Cache被命中且没有老化,本地域名服务器就会直接把小U网站域名的IP地址扔给客户端,查询就愉快地结束啦;如果没有Cache或者未命中等情况,就不得不开启一场麻烦的请求之旅
  • 首先,本地域名服务器向根域名服务器发送查询请求报文blog.starysky.top,但是根域名服务器只长官顶级域名服务器,所以根域名服务器只能这么回答:“老哥啊,我只能给你.top顶级域名服务器的IP,剩下的事儿你找它去问吧”
  • 本地域名服务器接着就向.top顶域发送请求报文blog.starysky.top,同样,顶级域名服务器只管辖注册在其下的权威域名服务器,因此只返回.starysky.top所在的权威域名服务器的IP
  • 本地域名服务器最后向.starysky.top权威域名服务器请求blog.starysky.top,这样一套下来最后才能得到需要的IP地址,拿到后一边扔进自己的Cache中,一边返回给客户端
  • 折腾完后,你打开了小U的网站

DNS报文

DNS协议定义了三种报文:查询报文应答报文更新报文。这些报文整体上由三部分构成:报文首部请求问题资源记录

报文首部


1. 事务ID:用来关联DNS查询与应答,DNS客户端每次发送查询请求都会使用不同的ID,而服务器在响应中重复这个ID
2. 标志:报文的标志字段
3. 问题数:指定问题部分的个数
4. 回答资源记录数:指定应答部分中回答的资源条目数
5. 权威资源记录数:指定权威资源记录数
6. 附加资源记录数:指定附加资源记录数

问题


问题用于表达具体查询的问题,问题个数与报文首部中的问题数字段一致.按照 DNS 查询的目的,DNS解析可以分为正向解析反向解析正向解析将域名解析为IP地址,而反向解析将IP地址解析域名。问题条目中,查询类型是比较重要的字段,这里列出常用的类型

资源记录

回答资源记录、权威资源记录和附加资源记录的格式相同,其中 TTL(Time to Live, second)表示资源记录的生存时间,也就是允许缓存的时间。0表示该记录只能用于当前响应,不允许被缓存

DNS缓存

一次完整的DNS查询过程需要访问多台DNS服务器才能得到最终的结果,这肯定会带来一定的时延。为了改善时延,DNS 服务并不是每次请求都要去访问DNS服务器,而是访问过一次后将DNS记录缓存在本地。具体来说,DNS服务是一个多级的缓存:

  • 浏览器缓存-》操作系统缓存-》路由器缓存-》local DNS缓存-》DNS查询

缓存并不是永久有效的,DNS应答报文中的TTL决定了DNS记录在缓存中的有效时间,但TTL只是一个参考值,实际使用的缓存有效时间不一定等于该值

DNS的问题

时间延迟

一次完整的DNS查询过程需要访问多台DNS服务器才能得到最终的结果,这会带来一定的时延

缓存一致性

DNS 缓存的存在虽然减少了时延,却是以牺牲一致性(consistency)为代价的

具体来说:Local DNS是分地区、分运营商的,在域名解析缓存的处理上,实现策略就不统一了。有时候Local DNS的解析结果可能不是最近、最优的节点,有的时候并不会遵从 TTL 的限制,而是设置一个固定时间。这就会导致域名指向新的IP地址后,一些客户端依然访问了缓存中旧的IP地址

除了运营商的缓存策略外,缓存投毒也是降低DNS可用性的原因。攻击者可以通过DNS劫持,利用DNS的缓存机制不对应答数据做检查的漏洞,诱骗DNS服务器缓存较大TTL的虚假DNS记录,从而长期欺骗客户端

DNS劫持

由于DNS缺乏加密、认证、完整性保护的安全机制,容易引发网络完全问题。最常见的域名劫持攻击是针对DNS报文首部的事务ID进行欺骗,由于事务ID在查询报文和应答报文中是匹配的,因此伪装DNS服务器可以提前将事务ID相同的伪造报文发送到客户端,以实现域名劫持,把目标网站域名解析到错误的IP地址

UDP & TCP

UDP连接

用户数据包协议(User Datagram Protocol),简称UDP,是基于IP之上开发的能够和应用打交道的协议,通过IP地址信息吧数据包发送给指定的客户端。每个想要访问网络的程序都需要绑定一个端口号,UDP再通过端口号吧数据包分发给对应的应用程序

UDP的问题

  • 数据包在传输过程中容易丢失
  • 对于大文件传输,UDP存在截断的问题(最大数据包不超过512byte),因此不能保证数据的可靠性。但UDP的传输速度非常快,因此常用于小规模数据的传输,或者不严格要求数据完整性的领域,比如在线视频等

TCP连接

传输控制协议(Transmission Control Protocol),间成TCP,是一种面向连接的、可靠的、基于字节流的传输层通讯协议。在一个TCP连接中,会有三个过程:建立连接阶段传输数据阶段断开连接阶段

建立连接阶段

建立连接阶段是通过三次握手来建立客户端与服务器之间的连接。TCP提供面向连接的通讯传输,而面向连接是指数据通讯开始先做好两端之间的准备工作。

三次握手,是指在建立一个TCP连接时,客户端与服务器总共要发送三个数据包来确认连接的建立

三次握手的主要作用是:

  • 确认双方的接收和发送能力
  • 制定自己的初始化序列号,为后面的可靠性做准备
  • 防止已失效的连接请求报文突然传达而产生错误

    三次握手的过程

    术语族:SYN(synchronous,建立联机)、seq(sequence number,顺序号码)、ack(acknowledgement,确认)、ACK(Acknowledgemnt,标识位)

刚开始客户端处于关闭Closed状态,服务器处于监听Listen状态,握手过程如下:

  1. 客户端发送到服务器,客户端发送SYN报文给服务器,并且指明客户端初始化序列号ISN,即以SYN=1,seq=x的形式发送出去,此时客户端处于SYN_SEND状态
  2. 服务器发送给客户端,服务器接收到客户端发送来的SYN包后,对该包进行确认后结束监听Listen状态,并返回一段TCP报文。报文中的标志位为SYN和ACK,表示确认客户端的报文seq序号有效,服务器能正常接受客户端发送的数据,并同意创建新连接,并以ACK=x+1,seq=y,SYN=1的形式发送出去,此时服务器进入SYN-RECV状态
  3. 客户端发送到服务器,客户端接收到服务器发送的SYN+ACK包后,明确了从客户端到服务器的数据传输是正常的,从而结束SYN-SENT阶段,并返回最后一段报文,即以ACK=y+1,seq=x+1的形式发送给服务器。此时客户端处于ESTABLISHED阶段,服务器收到报文后也处于ESTABLISHED阶段

总结就是:

  1. 首先发一个建立连接SYN=1和一个顺序号码seq=x
  2. 服务器接收后,也发送建立连接SYN=1,同时发送确认将客户端顺序号码+1返回ACK=x+1,再带上自己的服务端顺序号码seq=y
  3. 客户端再发送确认将服务端顺序号码+1返回ACK=y+1,再将客户端顺序号码也+1返回seq=x+1

    两次握手会有什么问题

    如果采用两次握手,客户端发送给服务器数据,服务器确认接收后就开始建立连接,会存在以下问题:
  4. 客户端发送一次请求给服务器……指定时间后没响应再发了一个
  5. 服务器先接收到后一个建立连接的请求。(前一个建立连接的请求,因为网络延迟等问题,在第二个之后达到了)
  6. 服务器认为第二个请求是最新发的,于是向客户端发送确认报文段,同意建立连接,于是连接建立了(两次握手)
  7. 这时候客户端还在等待最新的请求连接(第二次请求),自动忽略服务器发送的关于第一个请求连接的响应,也不发送数据
  8. 服务器一直等待客户端发送数据,服务器资源被占用

    三次握手过程的数据携带问题

    第三次握手的时候可以携带数据,第一第二次不可以携带数据。这是因为,如果第一次可以携带数据的话,有可能是恶意攻击服务器。这时候释放大量的数据,不理会服务器的的承受能力,会让服务器花费很多时间、内存空间接收报文

传输数据阶段

此时客户端和服务器都处于ESTABLISHED状态

这个阶段中,接收端需要对每个数据包进行确认操作。即接收端在接收到数据包之后,需要发送确认数据包给发送端

如果发送端在规定时间内没有接收到接收端的反馈确认消息,那么判断丢包(数据包丢失),从而触发自身的重发机制

一个大的文件在传输过程中会被拆分为多个小的数据包,接收端按照TCP头中的序号进行排序,保证组成完整的数据

断开连接阶段

数据传输完毕之后,需要终止连接,通过四次挥手来保证双方都能断开连接

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭

这个原则是当一方完成它的数据发送任务后就能发送一个FIN(finish)来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭

四次挥手的过程

  1. 客户端发送给服务器:客户端以FIN=1,seq=u的形式发送给服务器,表示需要关闭客户端和服务器之间的数据传输,此时客户端处于FIN_WAIT状态
  2. 服务器发送给客户端:服务器收到信息,先返回ACK给客户端,即以ACK=1,seq=v,ack=u+1的形式返回个客户端,表示收到客户端的报文,此时服务器处于CLOSE_WAIT状态
  3. 服务器发送给客户端:服务器等待一会,看客户端是否还有数据没有发送过来。确认没有需要处理的数据后,就准备彻底分手,发送FIN给客户端,即以FIN=1,seq=w,ack=u+1的形式发送给客户端,此时服务器处于LAST_ACK状态
  4. 客户端发送给服务器:客户端接收到FIN后,返回ACK报文作为应答,即以ACK=1,ack=w+1,seq=u+1的形式发送给服务器,此时客户端处于TIME_WAIT状态
  5. 等客户端确保服务器收到自己的ACK报文,则变成CLOSED状态,服务器也变成CLOSED状态

为什么要四次挥手

  1. 可能有一些数据因为网络延迟等问题没有发送到,直接关闭会导致这些数据没有接收到
  2. 可能服务器也有一些数据要发送给客户端,要确保这些数据发送完

TCP与UDP的区别

  • TCP是面向连接的,UDP是无连接的,即发送数据前不需要先建立连接
  • TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复,且按照顺序到达,适合大数据量交换
  • UDP尽最大努力交付数据,但不保证可靠
  • TCP是面像字节流的,UDP是面像报文的,并且即使网络堵塞也不会降低发送速率,因此会出现丢包现象
  • TCP只能是一对一的,而UDP支持一对多
  • TCP的首付较大,为20字节,而UDP只有8字节

您阅读这篇文章共花了:
Invitation
USTC-茶糜花开
FeynmanDirac
created:12/03/2022
Welcome to USTC-茶糜花开

This is an identification card as an honored membership of FeynmanDirac

Happy to see you follow FeynmanDirac, enjoy science together

© 版权声明
验证码启动中...