一文搞明白DNS与域名解析

文章正文
发布时间:2024-07-13 00:39

DNS,Domain Name System,域名系统
它是一个层次树状结构的联机分布式数据库系统
可以理解为电话簿或翻译器,将域名转化为IP地址

本文尽可能全面的归纳总结DNS的整个工作和一些细节

1、域名

域名服务主要是基于UDP实现的,端口号为53
域名具有唯一性

(1)域名的层次结构

域名采用了层次结构的命名方法:

每一个域名(本文只讨论英文域名)都是一个label序列,用字母(A-Z,a-z,大小写等价)、数字(0-9)和连接符(-)组成

label序列总长度不能超过255个字符,它由点号分割成一个个的标号(label)

每个label应该在63个字符之内,每个label都可以看成一个层次的域名

级别最低的域名写在左边,级别最高的域名写在右边

在这里插入图片描述


例子:

com: 顶级域名. 表示这是一个企业域名

baidu: 二级域名,指公司名

www: 三级域名

(2)顶级域名

顶级域名有三种:国家顶级域名(nTLD)、通用顶级域名(gTLD)、基础结构域名(infrastructure domain)

在这里插入图片描述

2、资源记录

资源记录(resourse record)就是域名服务器保存的记录,也是解析器请求的内容,资源记录会被存在zone文件中

(1)SOA资源记录

每个区在区的开始处都包含了一个起始授权记录( Start of Authority Record) ,简称SOA记录
SOA定义了域的全局参数,进行整个域的管理设置,存储有关域的重要信息,如管理员的电子邮件地址、上次更新域的时间,以及服务器在刷新之间应等待的时间
每个区域文件只允许存在唯一的SOA记录

(2)NS记录(Name Server)

NS(Name Server)记录是域名服务器记录,也称为授权服务器,用来指定该域名由哪个DNS服务器来进行解析,每个区在区根处至少包含一个NS记录
将网站的NS记录指向到目标地址,在设置NS记录的同时还需要设置目标网站的指向,否则NS记录将无法正常解析
NS记录优先于A记录。即,如果一个主机地址同时存在NS记录和A记录,则A记录不生效。(CDN缓存会用到此记录)


在这里插入图片描述

(3)A记录(Address)正向解析

A记录是将一个主机名(全称域名FQDN)和一个IP地址关联起来,如果是IPv6,就用AAAA记录
地址( A )资源记录把FQDN(Fully Qualified Domain Name)映射到IP地址,因为有此记录 ,所以DNS服务器能解析FQDN域名对应的IP地址
这也是大多数客户端程序默认的查询类型

例子

在这里插入图片描述


此处的“@”表示这是根域的记录,“14400”这个值是 TTL(生存时间),以秒为单位。A 记录的默认 TTL 是 14400 秒。这意味着,如果更新 A 记录,则需要 240 分钟(14400秒)后才会生效

(4)PTR记录(Pointer)反向解析

PTR记录将一个IP地址对应到主机名(全称域名FQDN)
这些记录保存在in-addr.arpa域中
相对于A资源记录,指针( PTR )记录把IP地址映射到FQDN,用于反向查询 ,通过IP地址,找到域名

(5)CNAME记录(Canonical Name)别名

别名记录( CNAME )资源记录创建特定FQDN的别名,也称为规范名字(Canonical Name)
这种记录允许您将多个名字映射到同一台计算机,用户可以使用CNAME记录来隐藏用户网络的实现细节,使连接的客户机无法知道真正的域名

例: ping百度时,解析到了百度的别名服务器。百度有个cname=的别名

(6)MX记录(Mail eXchange)

MX记录是邮件交换记录,它指向一个邮件服务器,用于电子邮件系统发邮件时根据收信人的地址后缀来定位邮件服务器
MX记录也叫做邮件路由记录,用户可以将该域名下的邮件服务器指向到自己的mail server上,然后即可自行操控所有的邮箱设置
当有多个MX记录(即有多个邮件服务器)时,则需要设置数值来确定其优先级。通过设置优先级数字来指明首选服务器,数字越小表示优先级越高

(7)SRV 记录

“服务”记录指定特定服务的主机和端口,例如 IP 语音 (VOIP)、即时消息等

在这里插入图片描述


在上面的示例中,“_sip”指示服务类型,“_tcp”指示协议,“8080”指示端口,而“example.com”是主机

3、域名服务器

域名需要由遍及全世界的域名服务器去解析
域名服务器实际上就是装有域名系统的主机

一个域名服务器所负责的范围,或者说有管理权限的范围,就称为“区”(zone),区<=域,一个例子如下:

在这里插入图片描述

域名是分层结构,域名服务器也是对应的层级结构:

每个层的域名上都有自己的域名服务器,最顶层的是根域名服务器

每一级域名服务器都知道下级域名服务器的IP地址

为了容灾, 每一级至少设置两个或以上的域名服务器

在这里插入图片描述

(1)根域名服务器(root nameserver)

最高层次的域名服务器,也是最重要的域名服务器
IPv4时代,全球共设有 13 个根域名服务器
所有的根域名服务器都知道所有的顶级域名服务器的域名和 IP 地址

当其他的域名服务器无法解析域名时,会首先求助于根域名服务器,可将其视为指向不同书架的图书馆中的索引,一般其作为对其他更具体位置的引用

(2)顶级域名服务器(TLD nameserver)

顶级域名服务器(top-level-domain) 负责管理在该顶级域名服务器上注册的所有二级域名,可被视为图书馆中的特定书架
当收到 DNS 查询请求时,就给出相应的回答

(3)权限域名服务器(authoritative nameserver)

负责一个区的域名服务器,可视为书架上的字典,其中特定名称可被转换成其定义

权威性域名服务器是域名服务器查询中的最后一站,如果权威性域名服务器能够访问请求的记录,则其会将已请求主机名的 IP 地址返回到发出初始请求的 DNS 解析器(图书管理员)。当一个权限域名服务器没有给出最后的查询结果时,就会告诉发出查询请求的 DNS 客户,下一步应当查询哪一个权限域名服务器

(4)本地域名服务器

本地域名服务器(local name server)并不属于上面的服务器层次结构,但是它在域名服务系统却发挥着至关重要的作用
当一台主机发出 DNS 查询请求时,这个查询请求报文就会发送给本地域名服务器。每一个互联网提供者,或者一个大学,甚至小到一个学院,都可以拥有一台本地域名服务器,这种域名服务器也被称为默认域名服务器。我们本地网络服务连接的域名服务器指的就是本地域名服务器。

(5)DNS解析器(DNS resolver)

DNS解析器(DNS resolver)是域名服务器的客户端,是DNS 查找的第一站,其负责与发出初始请求的客户端打交道。解析器启动查询序列,它负责向域名服务器发起一系列请求,然后成功解析域名

在这里插入图片描述


按我理解,这玩意儿有时候也被认为是本地域名服务器

4、域名解析

域名解析过程如图所示:

当用户在浏览器中输入域名访问该网站时,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析

如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析

如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,即本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性

如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性

如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就会开始迭代查询:把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到主机

如果用的是转发模式,本地DNS服务器就会开始递归查询:把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

在这里插入图片描述

典型 DNS 查找中会出现三种类型的查询。通过组合使用这些查询,优化的 DNS 解析过程可缩短传输距离。在理想情况下,可以使用缓存的记录数据,从而使 DNS 域名服务器能够返回非递归查询

(1)迭代查询(iterative query)

本地域名服务器向根域名服务器的查询方式通常采取迭代查询(iterative query)

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

通俗讲,迭代是我交给你一件事,你能办多少就告诉我你办了多少,然后剩下的事情就由我来办

在这里插入图片描述

(2)递归查询(recursive query)

主机向本地域名服务器的查询一般都采用递归查询(recursive query)

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

通俗讲,递归是把一件事情交给别人,如果事情没有办完,哪怕已经办了很多,都不要把结果告诉我,我要的是你的最终结果,而不是中间结果;如果你没办完,请你找别人办完。

在这里插入图片描述

(3)非递归查询(non-recursive query)

当 DNS 解析器客户端查询 DNS 服务器以获取其有权访问的记录时通常会进行此查询,因为其对该记录具有权威性,或者该记录存在于其缓存内

DNS 服务器通常会缓存 DNS 记录,以防止更多带宽消耗和上游服务器上的负载

通俗讲,就是你查的我有缓存或你查的就是我管的

5、DNS记录缓存

针对上面两种方式,我们可以知道不管是递归查询还是迭代查询,都会发送 8 个 UDP 用户数据报的报文。为了提高 DNS 的查询效率,减轻根域名服务器的负荷和 DNS 数据报的查询数量,在域名服务器中广泛地使用了高速缓存。高速缓存用来存放最近查询过的域名以及从何处获得域名映射信息的记录。

假设我们要查询域名对应的 IP 地址,如果本地域名服务器上有该域名对应的 IP 地址,那么可以直接从本地域名服务器上获得对应的 IP 地址,而不需要到根域名服务器上进行查询。当本地域名服务器查询不到 IP 地址时,本地域名服务器也可以不向根域名服务器发送请求报文,而是直接向顶级域名服务器发送查询请求报文。

不仅在本地域名服务器中有高速缓存,在主机中也有。很多主机在启动的时候从本地域名服务器下载名字和地址的全部数据库,维护存放自己使用的域名的高速缓存,只有在缓存中找不到名字时才使用域名服务器。每个位置均将存储 DNS 记录并保存由生存时间(TTL)决定的一段时间。

(1)浏览器 DNS 缓存

现代 Web 浏览器设计为默认将 DNS 记录缓存一段时间。目的很明显;越靠近 Web 浏览器进行 DNS 缓存,为检查缓存并向 IP 地址发出正确请求而必须采取的处理步骤就越少。发出对 DNS 记录的请求时,浏览器缓存是针对所请求的记录而检查的第一个位置。

例:在 Chrome 浏览器中,您可以转到 chrome://net-internals/#dns 查看 DNS 缓存的状态。

(2)操作系统(OS)级 DNS 缓存

操作系统级 DNS 解析器是 DNS 查询离开您计算机前的第二站,也是本地最后一站。操作系统内旨在处理此查询的过程通常称为“存根解析器”或 DNS 客户端。当存根解析器获取来自某个应用程序的请求时,其首先检查自己的缓存,以便查看是否有此记录。如果没有,则将本地网络外部的 DNS 查询(设置了递归标记)发送到 Internet 服务提供商(ISP)内部的 DNS 递归解析器。

与先前所有步骤一样,当 ISP 内的递归解析器收到 DNS 查询时,其还将查看所请求的主机到 IP 地址转换是否已经存储在其本地持久性层中。

根据其缓存中具有的记录类型,递归解析器还具有其他功能:

如果解析器没有 A 记录,但确实有针对权威性域名服务器的 NS 记录,则其将直接查询这些域名服务器,从而绕过 DNS 查询中的几个步骤。此快捷方式可防止从根和 .com 域名服务器(在我们对 example.com 的搜索中)进行查找,并且有助于更快地解析 DNS 查询。

如果解析器没有 NS 记录,它会向 TLD 服务器(本例中为 .com)发送查询,从而跳过根服务器。

万一解析器没有指向 TLD 服务器的记录,其将查询根服务器。这种情况通常在清除了 DNS 高速缓存后发生。

6、DNS报文格式

DNS 分为查询请求和查询响应,请求和响应的报文结构基本相同,如下:

在这里插入图片描述

(1)首部

首部共12字节:

事务 ID:DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。

标志:DNS 报文中的标志字段。

问题计数:DNS 查询请求的数目。

回答资源记录数:DNS 响应的数目。

权威名称服务器计数:权威名称服务器的数目。

附加资源记录数:额外的记录数目(权威名称服务器对应 IP 地址的数目)

其中,标志段如下:

QR(Response):查询请求/响应的标志信息。查询请求时,值为 0;响应时,值为 1。

Opcode:操作码。其中,0 表示标准查询;1 表示反向查询;2 表示服务器状态请求。

AA(Authoritative):授权应答,该字段在响应报文中有效。值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器。

TC(Truncated):表示是否被截断。值为 1 时,表示响应已超过 512 字节并已被截断,只返回前 512 个字节。

RD(Recursion Desired):期望递归。该字段能在一个查询中设置,并在响应中返回。该标志告诉名称服务器必须处理这个查询,这种方式被称为一个递归查询。如果该位为 0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表。这种方式被称为迭代查询。

RA(Recursion Available):可用递归。该字段只出现在响应报文中。当值为 1 时,表示服务器支持递归查询。

Z:保留字段,在所有的请求和应答报文中,它的值必须为 0。

rcode(Reply code):返回码字段,表示响应的差错状态。当值为 0 时,表示没有错误;当值为 1 时,表示报文格式错误(Format error),服务器不能理解请求的报文;当值为 2 时,表示域名服务器失败(Server failure),因为服务器的原因导致没办法处理这个请求;当值为 3 时,表示名字错误(Name Error),只有对授权域名解析服务器有意义,指出解析的域名不存在;当值为 4 时,表示查询类型不支持(Not Implemented),即域名服务器不支持查询类型;当值为 5 时,表示拒绝(Refused),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。

在这里插入图片描述


例子
一个请求包如下

Domain Name System (query) Transaction ID: 0x9ad0 #事务ID Flags: 0x0000 Standard query #报文中的标志字段 0... .... .... .... = Response: Message is a query #QR字段, 值为0, 因为是一个请求包 .000 0... .... .... = Opcode: Standard query (0) #Opcode字段, 值为0, 因为是标准查询 .... ..0. .... .... = Truncated: Message is not truncated #TC字段 .... ...0 .... .... = Recursion desired: Don't do query recursively #RD字段 .... .... .0.. .... = Z: reserved (0) #保留字段, 值为0 .... .... ...0 .... = Non-authenticated data: Unacceptable #保留字段, 值为0 Questions: 1 #问题计数, 这里有1个问题 Answer RRs: 0 #回答资源记录数 Authority RRs: 0 #权威名称服务器计数 Additional RRs: 0 #附加资源记录数 (2)查询

该部分是用来显示 DNS 查询请求的问题,通常只有一个问题
该部分包含正在进行的查询信息,包含查询名(被查询主机名字)、查询类型、查询类:

在这里插入图片描述

查询名:一般为要查询的域名,有时也会是 IP 地址,用于反向查询。

查询类型:DNS 查询请求的资源类型。通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。

查询类:地址类型,通常为互联网地址,值为 1。

例子
一个请求包

Domain Name System (query) #查询请求 Queries #问题部分 baidu.com: type A, class IN Name: baidu.com #查询名字段, 这里请求域名baidu.com [Name Length: 9] [Label Count: 2] Type: A (Host Address) (1) #查询类型字段, 这里为A类型 Class: IN (0x0001) #查询类字段, 这里为互联网地址 (3)资源记录

资源记录部分只有在 DNS 响应包中才会出现

在这里插入图片描述

域名:DNS 请求的域名。

类型:资源记录的类型,与问题部分中的查询类型值是一样的。

类:地址类型,与问题部分中的查询类值是一样的。

生存时间:以秒为单位,表示资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间。它同时也可以表明该资源记录的稳定程度,稳定的信息会被分配一个很大的值。

资源数据长度:资源数据的长度。

资源数据:表示按查询段要求返回的相关资源记录的数据。

例子
一个响应包

# 回答区域 Answers #“回答问题区域”字段 baidu.com: type A, class IN, addr 220.181.57.216 #资源记录部分 Name: baidu.com #域名字段, 这里请求的域名为baidu.com Type: A (Host Address) (1) #类型字段, 这里为A类型 Class: IN (0x0001) #类字段 Time to live: 5 #生存时间 Data length: 4 #数据长度 Address: 220.181.57.216 #资源数据, 这里为IP地址 baidu.com: type A, class IN, addr 123.125.115.110 #资源记录部分 Name: baidu.com Type: A (Host Address) (1) Class: IN (0x0001) Time to live: 5 Data length: 4 Address: 123.125.115.110 # 权威名称服务器区域 Authoritative nameservers #“权威名称服务器区域”字段 baidu.com: type NS, class IN, ns ns7.baidu.com #资源记录部分 Name: baidu.com Type: NS (authoritative Name Server) (2) #类型字段, 这里为NS类型 Class: IN (0x0001) Time to live: 5 Data length: 6 Name Server: ns7.baidu.com #权威名称服务器 baidu.com: type NS, class IN, ns dns.baidu.com #资源记录部分 Name: baidu.com Type: NS (authoritative Name Server) (2) #类型字段, 这里为NS类型 Class: IN (0x0001) Time to live: 5 Data length: 6 Name Server: dns.baidu.com #权威名称服务器 baidu.com: type NS, class IN, ns ns3.baidu.com #资源记录部分 Name: baidu.com Type: NS (authoritative Name Server) (2) Class: IN (0x0001) Time to live: 5 Data length: 6 Name Server: ns3.baidu.com #权威名称服务器 baidu.com: type NS, class IN, ns ns4.baidu.com #资源记录部分 Name: baidu.com Type: NS (authoritative Name Server) (2) Class: IN (0x0001) Time to live: 5 Data length: 6 Name Server: ns4.baidu.com #权威名称服务器 baidu.com: type NS, class IN, ns ns2.baidu.com #资源记录部分 Name: baidu.com Type: NS (authoritative Name Server) (2) Class: IN (0x0001) Time to live: 5 Data length: 6 Name Server: ns2.baidu.com #权威名称服务器 # 附加信息区域字段的资源记录部分信息如下: Additional records #“附加信息区域”字段 dns.baidu.com: type A, class IN, addr 202.108.22.220 #资源记录部分 Name: dns.baidu.com #“权威名称服务器”名称 Type: A (Host Address) (1) #类型字段, 这里为A类型 Class: IN (0x0001) Time to live: 5 Data length: 4 Address: 202.108.22.220 #“权威名称服务器”的IP地址 ns2.baidu.com: type A, class IN, addr 61.135.165.235 #资源记录部分 Name: ns2.baidu.com #“权威名称服务器”名称 Type: A (Host Address) (1) #类型字段, 这里为A类型 Class: IN (0x0001) Time to live: 5 Data length: 4 Address: 61.135.165.235 #“权威名称服务器”的IP地址 ns3.baidu.com: type A, class IN, addr 220.181.37.10 #资源记录部分 Name: ns3.baidu.com #“权威名称服务器”名称 Type: A (Host Address) (1) #类型字段, 这里为A类型 Class: IN (0x0001) Time to live: 5 Data length: 4 Address: 220.181.37.10 #“权威名称服务器”的IP地址 ns4.baidu.com: type A, class IN, addr 220.181.38.10 #资源记录部分 Name: ns4.baidu.com #“权威名称服务器”名称 Type: A (Host Address) (1) #类型字段, 这里为A类型 Class: IN (0x0001) Time to live: 5 Data length: 4 Address: 220.181.38.10 #“权威名称服务器”的IP地址 ns7.baidu.com: type A, class IN, addr 180.76.76.92 #资源记录部分 Name: ns7.baidu.com #“权威名称服务器”名称 Type: A (Host Address) (1) #类型字段, 这里为A类型 Class: IN (0x0001) Time to live: 5 Data length: 4 Address: 180.76.76.92 #“权威名称服务器”的IP地址 7、其他 (1)查询命令

dig可以显示整个查询过程

dig math.stackexchange.com dig +trace math.stackexchange.com # 显示整个分机查询过程 dig ns stackexchange.com # 查询NS记录

host命令可以看作dig命令的简化版本,返回当前请求域名的各种记录。

host github.com host facebook.github.com host 192.30.252.153 # 逆向

nslookup命令用于互动式地查询域名记录。

$ nslookup > facebook.github.io Server: 192.168.1.253 Address: 192.168.1.253#53 Non-authoritative answer: facebook.github.io canonical name = github.map.fastly.net. Name: github.map.fastly.net Address: 103.245.222.133

whois命令用来查看域名的注册情况。

whois github.com (2)关于1.1.1.1

1.1.1.1 是浏览 Internet 的一种快速且私密的方式
它是一种公共 DNS 解析器,但与大多数 DNS 解析器不同,1.1.1.1 不会向广告商出售用户数据
1.1.1.1 的实现使其成为目前最快的解析器

(3)为什么 DNS 使用 UDP 协议

关键在于数据包大小带来的开销

如果数据包小到一定程度,UDP 协议绝对最佳的选择

当数据包逐渐增大直到突破 512 字节以及 MTU 1500 字节的限制时,我们也只能选择使用更可靠的 TCP 协议来传输 DNS 查询和相应。

参考:为什么 DNS 使用 UDP 协议

结语

归纳总结了DNS整个工作和细节