本文转载自微信公众号「 乱敲代码」,作者 乱敲代码 。转载本文请联系 乱敲代码公众号。
今天晚上我正在床上躺着刷手机,然后我女朋友突然说她的电脑坏了。说连着WIFi上不了网,让我给她看一下。(这就是有个程序员男朋友的好处??)
图片然后我拿到电脑看了一下发现访问网页会出现DNS解析错误,就立马定位到问题了。解决起来很简单就直接修改了一下DNS解析地址然后在CMD输入ipconfig /flushdns就解决了。但是她突然问我DNS是什么。于是乎我就给她讲......
正文
就比如我们打电话一样如果你想要给你的朋友打电话,那么你肯定要知道他的手机号你们才可以建立通信,而这里的手机号就指的是IP地址,因为在计算机网络中是使用的TCP/IP进行通信的而TCP/IP是通过IP地址来确定通信对象,而IP地址都是由数字加点号所组成的12.11.12.11。如果没有IP地址就相当于你不知道你朋友的手机号但是想给他打电话,这合理吗?
图片但是在你访问某个网站的时候你并不是输入的IP地址,而是输入一个名字就可以访问这个网站。这个名字用来把便于人们使用的机器名字转换成为IP地址,而DNS全称就是Domain Name System域名系统。而为什么使用域名而不使用IP呢?其实就因为IP很难记??。不信你给我记十个IP试试。
域名系统其实就是名字系统,为什么不叫"名字"而叫"域名"呢?这是因为在这种因特网的命名系统中使用了许多的"域 (domain)",因此就出现了"域名"这个名词。"域名系统"明确地指明这种系统是应用在因特网中。
举例来说你如果要访问www.baidu.com这个域名。那么你就需要委托操作系统帮你查询目标网站的IP地址,这是对用户来说是不可见的。按照上面的例子来如果让你记你朋友的手机号那么肯定很困难。这个时候如果你有个电话本你只需要对每个手机号添加一个备注,想要联系某人只需要在电话本中查看到他的手机号即可。而DNS你就可以把它想象成一本巨大的电话本。而这种DNS不仅适用于IPV4还适用于IPv6。同时DNS是属于应用层并为应用层软件提供帮助。
交互流程:
域名结构
域名命名是采用的是层次树状结构的命名方法,那百度的域名举例子,百度的真实域名应该是www.baidu.com.root一般简写为www.baidu.com.而这个.表示的就是域名的根平时根域名。而后面的结构又区分为顶级域名、二级域名、三级域名等等。而二级以后的域名一般都会称之为子域名。如图:
从上图可以看出域名是由多部分组成每部分通过.分割然后在连接在一起最右边就是根域名,根域名都是对用户不可见的。一般我们见到的域名都是这样的:
域名的每个等级不超过不超过63个字符(主要为了方便记忆)。还有就是在域名中是不区分大小写的但是一般都是使用小写。而且DNS也不规定每一层级域名的意思也不限制域名的层级,各个级别的域名都是由上一级的域名机构进行管理,而最高的顶级域名则由ICANN进行管理。这样做的好处就是每个域名在互联网中都是唯一的而且也容易设计出一种查询域名的机制。
在之前域名分为三大类:
- 国家顶级域名nTLD:比如.cn代表的是中国、.us代表的是美国、.uk代表的是英国等等
- 通用顶级域名gTLD:最早的顶级域名有
- com 代表了公司和企业
- net 代表了网络服务机构
- org 非盈利性组织
- edu 教育机构
- gov 政府部门
- int 美国军事组织
- 基础结构域名:基础结构域名只有一个就是arpa用于反向解析,一般都称之为反向域名。
结合着域名系统是层次树状结构那么在因特网中域名系统的结构是这样的:
那么现在就又有一个问题了。上面说到了域名有很多那么是怎么查询的?如果是com的域名就去com的域名查询吗?如果是net域名就去net服务器查询吗?
DNS服务器
如果按照上面的域名结构,那么每一个域名都需要一台服务器。现在在因特网中有很多域名那对应起来就要很多个域名服务器。并且服务器太多的话也会影响域名查询的速度。而且也不可能把所有的域名都保存在一个服务器中。所以在DNS中服务器采用分区的方法来解决上述问题。
在DNS中一个服务器所管辖的范围叫做区,每个单位根据自己的情况划分自己所管辖的区。在自己所管辖的区中每个节点都是可以连通的。然后每个区都有自己的权限域名服务器,用来保存所有域名和IP的映射。
所以在DNS中并不是用域作单位而是使用区作单位。理解了区的概念就比较简单了。
其实可以把根域名看做是一个国家而顶级域名就是一个省份以此类推那么二级域名就是市级单位,三级域名就是县级单位和镇单位。
那么从上图可以看出a.com就是一个市然后下面的节点都属于a.com这个市管辖那它们就只需要一台权限域名服务器就可以完成对a.com下面所有子域名的解析工作。所以在DNS服务器中类别并不是以域作为单位而是用区作为单位,区就是DNS服务器实际管辖的范围。在上图中其实一个区和域的关系是等于的。那么在看下面的这张图。
这时候c.a.com也划分了一个区但是它又属于a.com这个域下面这个时候他们的关系就是域大于区。因为它们同属于a.com这个域下面,在a.com这个域下面又分了一个c.a.com的区。一个区需要一台服务器那现在划分了两个区也就是需要两台权限域名服务器。那现在又有一个问题什么是权限域名服务器?
其实在DNS中服务器也是有区分的
分为三个类别分别为根域名服务器、顶级域名服务器、权限域名服务器。
- 根域名服务器也就是最高等级的域名服务器,根域名服务器知道所有顶级域名服务器的地址。在解析过程中只要本地DNS服务器无法解析都会去根服务器去查询。所以只要根服务器瘫痪了那么所有的DNS服务器都没法工作了。而根服务器并不做解析工作它只负责告诉你下次应该去哪个顶级服务器去查询。
- 顶级域名服务器负责管理在该顶级域名服务器注册的二级域名
- 权限域名服务器主要就是管理一个区的服务器
DNS是怎么查询的
浏览器拿到输入的域名后会先去浏览器的DNS缓存中查询一下是否有记录,如果存在就直接返回,不存在的话就去查询操作系统的缓存,如果操作系统也没有缓存那么就会去查看本地的HOST文件。如果HOST文件也没有记录就会去本地DNS服务如果本地DNS服务器也没有就只能去根服务器去查询了。而这些DNS服务器一般都是由网络运营商提供,或者你自己手动设置。其中根服务器世界上一共存在13台,域名服务器名字分别为“A”至“M”。一台主根服务器在美国其余12台都是辅根服务器,其中9个在美国,欧洲2个,位于英国和瑞典,亚洲1个位于日本。而所有服务器都是由ICANN统一管理。
下面完善一下查询的步骤:
1.客户端浏览器缓存,没有缓存就查询操作系统缓存,如果没有就查询HOST文件,如果还没有就查询本地DNS服务器
2.本地DNS服务器查询本地是否有缓存,如果没有就去查询根服务器
3.根服务器返回给本地DNS服务器查询域,然后本地DNS服务器再次去查询
4.本地DNS服务器把查询的结果返回给客户端,并且把结果缓存。
下图是查询a.com的流程图:
DNS查询域名的IP地址有两种方式一种是递归查询一种是迭代查询。
迭代查询
迭代查询就是本地服务器向根服务器查询一般都是使用迭代查询。迭代查询的特点就是当根域名服务器收到本地DNS服务器查询的请求后会告诉本都服务器去那个顶级服务器去查询,然后本地DNS服务器在去顶级服务器。如果顶级服务器会把自己知道的权限服务器地址告诉本地服务器,然后本地服务器在去查询权限服务器。查询到以后本地DNS服务器就会把结果返回给客户端。
递归查询
递归查询就比较简单,客户端祥本地DNS服务器查询就是采用的递归查询,如果客户端查询的域名本地DNS服务器不知道的话就会以DNS客户的身份向其他域名服务器查询。
手动查询
接下来我们在操作系统中手动查询一下某个域名的DNS。Linux中有dig,dig命令主要用来从 DNS域名服务器查询主机地址信息。
dig 命令默认的输出信息比较丰富,大概可以分为 5 个部分。
- 第一部分显示 dig 命令的版本和输入的参数。
- 第二部分显示服务返回的一些技术详情,比较重要的是 status。如果 status 的值为 NOERROR 则说明本次查询成功结束。
- 第三部分中的 "QUESTION SECTION" 显示我们要查询的域名。
- 第四部分的 "ANSWER SECTION" 是查询到的结果。
- 第五部分则是本次查询的一些统计信息,比如用了多长时间,查询了哪个 DNS 服务器,在什么时间进行的查询等等。
dig默认查询的是A记录上面第四部分返回的结果中的A就代表了查询到的是A记录。dig命令解释网上有很多资料这里就不过多解释。想要了解更多dig命令这里推荐阮大的文章。
https://www.ruanyifeng.com/blog/2016/06/dns.html
DNS 记录的类型
类型 | 解释 |
---|---|
A | 地址记录,用来指定域名的 IPv4 地址,如果需要将域名指向一个 IP 地址,就需要添加 A 记录。 |
AAAA | 用来指定主机名(或域名)对应的 IPv6 地址记录。 |
CNAME | 如果需要将域名指向另一个域名,再由另一个域名提供 ip 地址,就需要添加 CNAME 记录。 |
MX | 如果需要设置邮箱,让邮箱能够收到邮件,需要添加 MX 记录。 |
NS | 域名服务器记录,如果需要把子域名交给其他 DNS 服务器解析,就需要添加 NS 记录。 |
SOA | SOA 这种记录是所有区域性文件中的强制性记录。它必须是一个文件中的第一个记录。 |
TXT | 可以写任何东西,长度限制为 255。绝大多数的 TXT记录是用来做 SPF 记录(反垃圾邮件)。 |
最后
同时需要注意DNS是有缓存机制的,缓存的目的就是为了提高查询的效率。所以在修改完DNS服务器后一定要记得刷新DNS缓存。就像我文章开头的ipconfig /flushdns命令目的就是为了清除本地DNS缓存。
巨人的肩膀
图解TCP/IP
https://www.ruanyifeng.com/blog/2016/06/dns.html
https://tojohnonly.github.io/68-DNS%E5%8E%9F%E7%90%86%E5%8F%8A%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B.html
网络是怎么连接的
https://zhuanlan.zhihu.com/p/61394192
https://blog.csdn.net/m0_37263637/article/details/85157611
https://baike.baidu.com/item/%E5%9F%9F%E5%90%8D%E7%BA%A7%E5%88%AB/15536218?fr=aladdin
https://www.cnblogs.com/sparkdev/p/7777871.html