试想一个问题,我们人类可以有多少种识别自己的方式?可以通过身份证来识别,可以通过社保卡号来识别,也可以通过驾驶证来识别,尽管有多种识别方式,但在特定的环境下,某种识别方法会比其他方法更为适合。因特网上的主机和人类一样,可以使用多种方式进行标识。互联网上主机的一种标识方法是使用它的主机名,比如 www.baidu.com、www.google.com 等。这是我们人类习惯的记忆方式,因特网中的主机却不会这么记忆,它们喜欢定长的、有层次结构的 IP 地址。
那么路由器如何把 IP 地址解析为我们熟悉的网址呢?这时候就需要 DNS 出现了。
图 7-1
DNS 的全称是 Domain Name Systems,它是一个由分层的DNS 服务器(DNS server)实现的分布式数据库;它还是一个使得主机能够查询分布式数据库的应用层协议。DNS 协议运行在 UDP 协议上,使用 53 端口。
DNS 基本概述
与 HTTP、FTP 和 SMTP 一样,DNS 协议也是一种应用层的协议,DNS 使用客户-服务器模式运行在通信的端系统之间,在通信的端系统之间通过 UDP 运输层协议来传送 DNS 报文。
DNS 通常不是一门独立的协议,它通常为其他应用层协议所使用,这些协议包括 HTTP、SMTP 和 FTP,将用户提供的主机名解析为 IP 地址。
下面根据一个示例来描述一下 DNS 解析过程:
你在浏览器键入 www.someschool.edu/index.html 时会发生什么?为了使用户主机能够将一个 HTTP 请求报文发送到 Web 服务器 www.someschool.edu ,会经历如下操作:
除了提供 IP 地址到主机名的转换,DNS 还提供了下面几种重要的服务:
假设运行在用户主机上的某些应用程序(如 Web 浏览器或邮件阅读器) 需要将主机名转换为 IP 地址。这些应用程序将调用 DNS 的客户端,并指明需要被转换的主机名。DSN 客户端收到 DNS 后,会使用 UDP 通过 53 端口向网络上发送一个 DNS 查询报文,经过一段时间后,DNS 客户端会收到一个主机名对应的 DNS 应答报文。因此,从用户主机的角度来看,DNS 就像是一个黑盒子,其内部的操作你无法看到。但是实际上,实现 DNS 这个服务的黑盒子非常复杂,它由分布于全球的大量 DNS 服务器以及定义了 DNS 服务器与查询主机通信方式的应用层协议组成。
DNS 最早的设计是只有一台 DNS 服务器。这台服务器会包含所有的 DNS 映射。这是一种集中式单点设计,这种设计并不适用于当今的互联网,因为互联网有着数量巨大并且持续增长的主机,这种集中式的设计会存在以下几个问题
所以 DNS 不可能集中式设计,因为集中式设计完全没有可扩展能力,因此采用分布式设计,这种设计的特点如下。
分布式、层次数据库
分布式设计首先解决的问题就是 DNS 服务器的扩展性问题。因此 DNS 使用了大量的 DNS 服务器,它们的组织模式一般是层次方式,并且分布在全世界范围内。没有一台 DNS 服务器能够拥有因特网上所有主机的映射。相反,这些映射分布在所有的 DNS 服务器上。
大致来说有三种 DNS 服务器:根 DNS 服务器、 顶级域(Top-Level Domain, TLD) DNS 服务器和权威 DNS 服务器。这些服务器的层次模型如下图所示。
图 7-2
假设现在一个 DNS 客户端想要知道 www.amazon.com 的 IP 地址,那么上面的域名服务器是如何解析的呢?
首先,客户端会先根服务器之一进行关联,它将返回顶级域名 com 的 TLD 服务器的 IP 地址。然后客户端与这些 TLD 服务器之一联系,它将为 amazon.com 返回权威服务器的 IP 地址。最后,该客户与 amazom.com 权威服务器之一联系,它为 www.amazom.com 返回其 IP 地址。
DNS 层次结构
我们现在来讨论一下上面域名服务器的层次系统。
下面我们来描述一下 DNS 的查询步骤,从 DNS 解析 IP 再到 DNS 报文返回的一系列流程。
注意:通常情况下 DNS 会将查找的信息缓存在浏览器或者计算机本地中,如果有相同的请求到来时,就不再会进行 DNS 查找,而会直接返回结果。
通常情况下,DNS 的查找会经历下面这些步骤
一旦 DNS 查找的步骤返回了 example.com 的 IP 地址,浏览器就可以请求网页了。
整个流程如下图所示
图 7-3
DNS 解析器
进行 DNS 查询的主机和软件叫做 DNS 解析器,用户所使用的工作站和个人电脑都属于解析器。一个解析器要至少注册一个以上域名服务器的 IP 地址。DNS 解析器是 DNS 查找的第一站,其负责与发出初始请求的客户端打交道。解析器启动查询序列,最终使 URL 转换为必要的 IP 地址。
图 7-4
DNS 递归查询和 DNS 递归解析器不同,该查询是指向需要解析该查询的 DNS 解析器发出请求。DNS 递归解析器是一种计算机,其接受递归查询并通过发出必要的请求来处理响应。
DNS 查询类型
DNS 查找中会出现三种类型的查询。通过组合使用这些查询,优化的 DNS 解析过程可缩短传输距离。在理想情况下,可以使用缓存的记录数据,从而使 DNS 域名服务器能够直接使用非递归查询。
DNS 缓存(DNS caching) 有时也叫做DNS 解析器缓存,它是由操作系统维护的临时数据库,它包含有最近的网站和其他 Internet 域的访问记录。也就是说, DNS 缓存只是计算机为了满足快速的响应速度而把已加载过的资源缓存起来,再次访问时可以直接快速引用的一项技术和手段。那么 DNS 的缓存是如何工作的呢?
DNS 缓存的工作流程
在浏览器向外部发出请求之前,计算机会拦截每个请求并在 DNS 缓存数据库中查找域名,该数据库包含有最近的域名列表,以及 DNS 首次发出请求时 DNS 为它们计算的地址。
DNS 缓存方式
DNS 数据可缓存到各种不同的位置上,每个位置均将存储 DNS 记录,它的生存时间由 TTL(DNS 字段) 来决定。
浏览器缓存
现如今的 Web 浏览器设计默认将 DNS 记录缓存一段时间。因为越靠近 Web 浏览器进行 DNS 缓存,为检查缓存并向 IP 地址发出请求的次数就越少。发出对 DNS 记录的请求时,浏览器缓存是针对所请求的记录而检查的第一个位置。
在 chrome 浏览器中,你可以使用 chrome://net-internals/#dns 查看 DNS 缓存的记录。
图 7-7
操作系统内核缓存
在浏览器缓存查询后,会进行操作系统级 DNS 解析器的查询,操作系统级 DNS 解析器是 DNS 查询离开你的计算机前的第二站,也是本地查询的最后一个步骤。
DNS 报文
共同实现 DNS 分布式数据库的所有 DNS 服务器存储了*资源记录(Resource Record, RR)*,RR 提供了主机名到 IP 地址的映射。每个 DNS 回答报文中会包含一条或多条资源记录。RR 记录用于回复客户端查询。
资源记录是一个包含了下列字段的 4 元组。
(Name, Value, Type, TTL)
RR 会有不同的类型,下面是不同类型的 RR 汇总表。
DNS RR 类型解释A 记录IPv4 主机记录,用于将域名映射到 IPv4 地址AAAA 记录IPv6 主机记录,用于将域名映射到 IPv6 地址CNAME 记录别名记录,用于映射 DNS 域名的别名MX 记录邮件交换器,用于将 DNS 域名映射到邮件服务器PTR 记录指针,用于反向查找(IP地址到域名解析)SRV 记录SRV记录,用于映射可用服务。
表 7-1
DNS 有两种报文,一种是查询报文,一种是响应报文,并且这两种报文有着相同的格式,下面是 DNS 的报文格式。
图 7-8
下面我们就来看一下详细的报文字段。
报文段首部
报文段首部是 DNS 报文的基础结构部分,下面我们对报文段首部中的每个字节进行描述。
图 7-9
每个字段的含义如下
相信读者跟我一样,只看这些字段没什么意思,下面我们就通过抓包的方式,看一下具体的 DNS 报文。
图 7-10
现在我们可以看一下具体的 DNS 报文,通过 Query 可知这是一个请求报文,这个报文的标识符是 0xcd28,它的标志如下。
然后我们看一下响应报文。
图 7-11
可以看到,标志位也是 0xcd28,可以说明这就是上面查询请求的响应。
查询请求已经解释过的报文我们这里就不再说明了,现在只解释一下请求报文中没有的内容。
查询区通常指报文格式中查询的部分。这部分用来显示 DNS 查询请求的问题,包括查询类型和查询类。
图 7-12
这部分中每个字段的含义如下:
同样的,我们再使用 wireshark 查看一下查询区域。
图 7-13
可以看到,这是对 mobile-gtalk.l.google.com 发起的 DNS 查询请求,查询类型是 A(0x0001),那么得到的响应类型应该也是 A ,A 表示的是 IPv4 类型,如果 Type 是 AAAA,那么就表示的是 IPv6 类型。
图 7-14
如上图所示,响应类型也是 A。
资源记录部分
资源记录部分是 DNS 报文的最后三个字段,包括回答问题区域、权威名称服务器记录、附加信息区域,这三个字段均采用一种称为资源记录的格式,如下图所示。
图 7-15
资源记录部分的字段含义如下
资源记录部分只有在 DNS 响应包中才会出现。下面我们就来通过响应报文看一下具体的字段示例。
图 7-16
其中,域名的值是 mobile-gtalk.l.google.com ,类型是 A,类是 1,生存时间是 5 秒,数据长度是 4 字节,资源数据表示的地址是 63.233.189.188。
CNAME 记录
CNAME 是 DNS 的一种记录类型,它的全称是 Canonical Name Record,这个类型能够将某些 DNS 别名映射到 DNS 命名系统中。
一个很简单的例子,如下所示
www.cxuanblog.edu IN CNAME www.cxuanblog.com
这是啥意思呢?
这表示的是如果用户在浏览器中输入的是 www.cxuanblog.edu 这个域名,其实输入的是 www.cxuanblog.com 这个域名,如果你打算把博客搬家后,你输入的旧域名其实会直接跳转到新域名的网页下。
CNAME 还有一种普遍的做法就是把它作为公共域名进行访问。
反向 DNS 查询
我们上面一直讨论的是 DNS -> IP 的这种转换方式,这种方式也是 DNS 的精髓所在。但是如果你认真看了图 7 - 1 的话,你会发现还存在一种 IP -> DNS 的转换方式,这种反向的转换也被叫做反向 DNS 查询。他们之间的关系很像 ARP 和 RARP 。
反向 DNS 查询向 DNS 服务器查询 PTR(Pointer Record)记录,如果服务器没有 PTR 记录,则无法解析反向查找这个过程。PTR 也是一种 RR 资源记录,见表 7 - 1。
PTR 记录会存储 IP 地址,反向查询时,PTR 中存储的 IP 地址会颠倒过来,并附上 .in-addr.arpa 字段,比如如果域的 IP 地址为 192.137.8.22,那么反向查询时,PTR 记录就是 22.8.137.192.in-addr.arpa 。
反向 DNS 查询通常用于电子邮件协议中,电子邮件服务器会检查电子邮箱中的电子邮件消息是否来自真实有效的服务器,垃圾邮件发送者经常使用被劫持机器的,这些邮件过来后就不会有 PTR 记录。电子邮件服务器会拒绝不支持反向查找的服务器或者不太合法的服务器邮件。
SOA 记录
如果是权威 DNS 服务器的响应的话,会显示记录存储有关区域的重要信息,这种信息就是 SOA 记录。所有的 DNS 区域都需要一个 SOA 记录才能符合 IETF 标准。SOA 记录对于区域传输也很重要。
SOA 记录除具有 DNS 解析器响应的字段外,还具有一些额外的字段,如下
图 7-17
具体字段含义
上面提到了主要名称服务器和辅助名称服务器,他们之间的关系如下。
图 7-18
这块我们主要解释了 RR 类型为 A(IPv4) 和 SOA 的记录,除此之外还有很多类型,这篇文章就不再详细介绍了,读者朋友们可以阅读 《TCP/IP 卷一 协议》和 cloudflare 的官网 https://www.cloudflare.com/learning/dns/dns-records/ 查阅,值得一提的是,cloudflare 是一个学习网络协议非常好的网站。
区域传输和 DNS NOTIFY
区域传输通常指一块区域内 DNS 服务器中的 RR 资源更新,这样做的目的是为了保证多台服务器保证内容同步。如果区域中一台服务器失效了,那么其他服务器可以临时顶上,充当临时 DNS 服务器的角色。区域传输通常在轮询(polling)后开启,在轮询中,从服务器会周期性的检查主服务器,查看区域是否已经更新,区域传输需要开启。
一旦启动区域传输,就会存在两种传输方式:
但是使用轮询这种方式有一些弊端,因为从服务器会定期检查主服务器上内容是否更新,这是一种资源浪费,因为绝大多数情况下都是一次无效检查,所以为了改善这种情况,DNS 设计了 DNS NOTIFY 机制,DNS NOTIFY 允许修改区域内容后主服务器通知从服务器内容需要更新,应该启动区域传输。
DNS 网络排查工具
DNS 常用的排查工具有两种,一种是 nslookup,这是一般书籍中推荐使用的排查工具,下面我们先来介绍一下这个工具的使用,一会儿我们再来介绍另外一种工具。
nslookup
nslookup 是一款用来解决 DNS 相关问题排查的工具。
它主要分为两种模式,一种是交互模式,一种是非交互模式。交互模式就是一问一答式的,而非交互模式就是一次执行的。
比如你要使用交互式,就直接在命令行中输入 nslookup。
图 7-19
这样就会开始一个 nslookup 的命令提示符,然后你再输入想要查询的域名即可,如下所示:
图 7-20
非交互式就是直接输入 nslookup 你想要查询的内容即可,比如我们还以 baidu 为例子。
图 7-21
其实查询出来的内容是一样的,使用方式其实也大相径庭。
nslookup 一般用于查询下面这些常见的场景:
可以通过 nslookup -querytype 查询域名的邮件服务器,如下
图 7-22
会分为两种查询结果,一种是 Non-authoritative answer,这表明我们想查询的这个网址是从本地 DNS cache 也就是 DNS 缓存中查询出来的,而不是从本地 DNS 经过 DNS 查询后得到的真实域名。
还有一种就是 Authoritative answers,这种就是本地 DNS 经过 DNS 查询后得到的真实域名。
上图还显示了 netease.com 邮件服务器的一些参数,origin 表示源地址,mail addr 表示邮件服务器的地址,serial 表示序列号,refresh 表示刷新间隔,retry 表示重试间隔,expire 表示过期时间, minumum 表示最大长度。
dig
我们的电脑上有多个网络连接,每个网络连接会有不同的 DNS ,而且 DNS 也分为主 DNS 和备用 DNS,nslookup 会默认使用主 DNS 连接,如果你的主 DNS 没有配置,使用可能会存在下面这种情况。
图 7-23
与 nslookup 不同的是,dig 也是一款 DNS 网络排查工具,它会从你的网络连接中选取一块可用的连接进行解析和使用,不过 windows 10 下默认不支持 dig 命令工具的使用,mac 倒是支持。
下面是 mac 下的 dig 命令。
图 7-24
不过,贴心的我给你整理出来了 windows10 下 dig 的安装和配置使用 (https://www.csdn.net/tags/Mtjacg0sMjU1ODQtYmxvZwO0O0OO0O0O.html)
安装完成后,就可以在 windows 10 下使用 dig 了。
图 7-25
下面我们就来介绍一下 dig 这款工具都用哪些用法以及各个参数的含义,我们以 dig baidu.com 来进行说明
图 7-26
如上图所示,最上面的
; <<>> DiG 9.16.23 <<>> www.baidu.com 表示 dig 版本和要查询的域信息。
;; global options: +cmd 表示全局选项,dig 可以查询多个域信息,这里显示应用于所有查询的选项,默认是 +cmd。
;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63799 这行表示头信息,其中操作码 QUERY 表示查询,IQUERY 表示反查询,STATUS 表示监测状态等。
NOERROR 表示这个请求已正常解决,id 是一个随机数字,它用于将请求和响应绑定在一起。
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0 这一行都是一些标志位,其中
下面是问题区域
;; QUESTION SECTION: ;www.baidu.com. IN A
依次是正在查询的域名,IN 我们上面提到了它表示互联网查询,A 表示域名映射到 IPv4 地址。
下面是答案部分
;; ANSWER SECTION: www.baidu.com. 183 IN CNAME www.a.shifen.com. www.a.shifen.com. 57 IN A 220.181.38.150 www.a.shifen.com. 57 IN A 220.181.38.149
中间的数字表示 TTL ,即可以缓存记录的时间间隔。
最后是统计部分,这块没什么好说的了。
除此之外,dig 还有一些其他查询方式。
-x 进行反向 DNS 查询
我们知道,DNS 可以把域名转换为 IP ,同时也可以把 IP 转换成对应的域名,其中 -x 就是进行反向 DNS 查询,如下所示:
图 7-27
可以看到 QUESTION SECTION 和 ANSWER SECTION 中都是 PTR,这表示反向 DNS 查询,后面的域名显示了这是一个 google 的 DNS。反向 DNS 查询中,IP 地址要加上 in-addr.arpa。
同样的,我们还可以在查询的时候加上 in-addr.arpa,其结果是一样的。
图 7-28
我们通常喜欢使用 -x,因为这会减少输入的工作量。
+noall +answer
这告诉 dig 只打印 DNS 响应中的ANSWER部分内容,如下所示
图 7-29
+short
dig +short 就像是 dig +noall +answer 的阉割版,它只显示很少的内容。
图 7-30
+trace
dig +trace 能够模仿 DNS 解析器在查找域名时的做法 ,即它会从根服务器开始查询,一直到权威 DNS 服务器。相当于链路追踪的一个作用。
图 7-31
除了我们上面介绍的 nslookup 和 dig 之外,还有其他 DNS 检测工具,比如 dog 、drill ,都是很好用的 DNS 网络排查工具,大家可以查阅相关资料进行使用,这里我就不再进行详细的介绍了。
DNS 安全
几乎所有的网络请求都会经过 DNS 查询,而且 DNS 和许多其他的 Internet 协议一样,系统设计时并未考虑到安全性,并且存在一些设计限制,这为 DNS 攻击创造了机会。
DNS 攻击主要有下面这几种方式:
那么该如何防御 DNS 攻击呢?
防御 DNS 威胁的最广为人知的方法之一就是采用 DNSSEC 协议。
DNSSEC
DNSSEC 又叫做 DNS 安全扩展,DNSSEC 通过对数据进行数字签名来保护其有效性,从而防止受到攻击。它是由 IETF 提供的一系列 DNS 安全认证的机制。DNSSEC 不会对数据进行加密,它只会验证你所访问的站点地址是否有效。
DNS 防火墙
有一些攻击是针对服务器进行的,这就需要 DNS 防火墙的登场了,DNS 防火墙是一种可以为 DNS 服务器提供许多安全和性能服务的工具。DNS 防火墙位于用户的 DNS 解析器和他们尝试访问的网站或服务的权威名称服务器之间。防火墙提供限速访问,以关闭试图淹没服务器的攻击者。如果服务器确实由于攻击或任何其他原因而导致停机,则 DNS 防火墙可以通过提供来自缓存的 DNS 响应来使操作员的站点或服务正常运行。
除了上述两种防御手段外,本身 DNS 区域的运营商就会采取进一步措施保护 DNS 服务器,比如配置 DNS 基础架构,来防止 DDoS 攻击。
总结
这篇文章我用较多的字数为你介绍了 DNS 的基本概述,DNS 的工作机制,DNS 的查询方式,DNS 的缓存机制,我们还通过 WireShark 抓包带你认识了一下 DNS 的报文,最后我为你介绍了 DNS 的攻击手段和防御方式。
这是一篇入门 DNS 较全的文章,花了我一周多的时间来写这篇文章,这篇文章了解清楚后,基本上 DNS 的大部分问题你应该都能够回答,面试我估计也稳了。
如果文章对你有帮助,希望各位小伙伴们留下你的三连呀!