1. 什么是 DNS

DNSDomain Name System,域名系统),因特网上作为域名和ip地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的ip数串。通过主机名,最终得到该主机名对应的**ip**地址的过程叫做域名解析(或主机名解析)

可以把DNS理解为电话本

2. 什么时候会发起 DNS 请求

当你在浏览器输入**url**地址时,先检查强缓存,如果命中直接使用,否则浏览器开始查找域名的**ip**地址

  1. 浏览器自身搜索DNS缓存。
  2. 浏览器搜操作系统的DNS缓存。
  3. 读取本地的hosts文件。
  4. 上述几步都会去本地文件中查找和这个域名对应的规则,如果有的话就直接使用本地文件里面的ip地址。没有找到的话,浏览器就会向本地DNS服务器发出一个DNS请求。(本地DNS服务器一般都是你的网络接入服务器商提供,比如电信,移动)

3. 因特网的域名

3.1 域名结构

由于因特网的用户数量较多,所以因特网在命名时采用的是层次树状结构的命名方法。任何一个连接在因特网上的主机或路由器,都有一个唯一的层次结构的名字,即域名(domain name)。这里,“域”(domain)是名字空间中一个可被管理的划分。

如下例子所示:

image.png

这是中央电视台用于手法电子邮件的计算机的域名,它由三个标号组成,其中:

  • com是顶级域名,代表国家或者组织形式。
  • cctv是二级域名,代表组织或者公司名称。
  • mail是三级域名,代表组织或者公司内部的主机名称。

DNS规定,域名中的标号都有英文和数字组成,每一个标号不超过63个字符(为了记忆方便,一般不会超过12个字符),也不区分大小写字母。标号中除连字符(-)外不能使用其他的标点符号。级别最低的域名写在最左边,而级别最高的字符写在最右边。由多个标号组成的完整域名总共不超过255个字符。DNS既不规定一个域名需要包含多少个下级域名,也不规定每一级域名代表什么意思。各级域名由其上一级的域名管理机构管理,而最高的顶级域名则由**ICANN**进行管理。用这种方法可使每一个域名在整个互联网范围内是唯一的,并且也容易设计出一种查找域名的机制。

image.png

3.2 域名服务器

如果采用上述的树状结构,每一个节点都采用一个域名服务器,这样会使得域名服务器的数量太多,使域名服务器系统的运行效率降低。所以在DNS中,采用划分区的方法来解决。

一个服务器所负责管辖(或有权限)的范围叫做区(zone)。各单位根据具体情况来划分自己管辖范围的区。但在一个区中的所有节点必须是能够连通的。每一个区设置相应的权限域名服务器,用来保存该区中的所有主机到域名ip地址的映射。总之,DNS服务器的管辖范围不是以“域”为单位,而是以“区”为单位。区是**DNS**服务器实际管辖的范围。(区 <= 域)

因特网上的DNS服务器也是按照层次安排的。每一个域名服务器只对域名体系中的一部分进行管辖。根据域名服务器所起的作用,可以把域名服务器划分为下面四种不同的类型。

image.png

  • 根域名服务器:最高层次的域名服务器(.),也是最重要的域名服务器。所有的根域名服务器都知道所有的顶级域名服务器的域名和ip地址。不管是哪一个本地域名服务器,若要对因特网上任何一个域名进行解析,只要自己无法解析,就首先求助根域名服务器。所以根域名服务器是最重要的域名服务器。假定所有的根域名服务器都瘫痪了,那么整个DNS系统就无法工作。需要注意的是,在很多情况下,根域名服务器并不直接把待查询的域名直接解析出**ip**地址,而是告诉本地域名服务器下一步应当找哪一个顶级域名服务器进行查询
  • 顶级域名服务器:负责管理在该顶级域名服务器注册的二级域名。
  • 权限域名服务器:负责管理一个“区”的域名服务器。
  • 本地域名服务器:本地服务器不属于下图的域名服务器的层次结构,但是它对域名系统非常重要。当一个主机发出DNS查询请求时,这个查询请求报文就发送给本地域名服务器。

4. DNS 解析过程

DNS解析的过程就是寻找哪台机器上有你需要资源的过程。当你在浏览器中输入一个地址时,例如www.baidu.com,其实不是百度网站真正意义上的地址。互联网上每一台计算机的唯一标识是它的ip地址,但是ip地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其它计算机,也就是上面提到的百度的网址。所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到ip地址的转换,这个过程就是DNS解析。它实际上充当了一个翻译的角色,实现了网址到ip地址的转换。那网址到ip地址转换的过程是如何进行的?

DNS解析过程分为两类:

4.1 递归查询

如果主机所询问的本地域名服务器不知道被查询的域名的**ip**地址,那么本地域名服务器就以**DNS**客户的身份,向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。因此,递归查询返回的查询结果要么是所要查询的ip地址,要么是报错(表示无法查询到所需的ip地址)。

image.png

4.2 迭代查询

当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的**ip**地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”,然后让本地服务器进行后续的查询。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地域名服务器再向顶级域名服务器查询。顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个权限域名服务器进行查询。最后,知道了所要解析的ip地址或报错,然后把这个结果返回给发起查询的主机。

image.png

4.3 最佳性能的查询方式

  • 主机向本地域名服务器的查询一般都是采用递归查询。
  • 本地域名服务器向根域名服务器的查询的迭代查询。

如图:

image.png

从上述过程中,可以看出网址的解析是一个从右向左的过程: com -> google.com -> www.google.com。但是你是否发现少了点什么,根域名服务器的解析过程呢?事实上,真正的网址是www.google.com.,并不是多打了一个.这个**.**对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.。既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上,所有网址真正的解析过程为:. -> .com -> google.com. -> www.google.com.

5. DNS 优化

了解了DNS的过程,如果每次都经过这么多步骤,是否太耗时间?如何减少该过程的步骤呢?那就需要DNS优化了——DNS缓存。

  • DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种:
    • 浏览器缓存
    • 系统缓存
    • 路由器缓存
    • IPS服务器缓存
    • 根域名服务器缓存
    • 顶级域名服务器缓存
    • 主域名服务器缓存
  • Chrome浏览器中输入:chrome://dns/,可以看到Chrome浏览器的DNS缓存。系统缓存主要存在/etc/hostsLinux系统)中。

6. DNS 负载均衡

互联网用户巨大的今天,假如亿万请求请求的资源都位于同一台机器上面,那么这台机器随时可能会蹦掉。

处理办法就是用DNS负载均衡技术,它的原理是在**DNS**服务器中为同一个主机名配置多个**ip**地址,在应答**DNS**查询时,**DNS**服务器对每个查询将以**DNS**文件中主机记录的**ip**地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。

大家耳熟能详的CDNContent Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的ip地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。

7. DNS 劫持

DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能访问或访问的是假网址。其实本质就是对DNS解析服务器做手脚,或者是使用伪造的DNS解析服务器可以通过下图来展示:

image.png

解决办法:DNS的劫持过程是通过攻击运营商的解析服务器来达到目的。我们可以不用运营商的DNS解析而使用自己的解析服务器或者是提前在自己的App中将解析好的域名以IP的形式发出去就可以绕过运营商DNS解析,这样一来也避免了DNS劫持的问题。