本文最后更新于:星期一, 九月 14日 2020, 10:55 上午

本文主要梳理与介绍 DNS 的基础知识,如果有些地方没懂不如带着疑问继续往下看。涉及 DNS 攻防的将在下一篇介绍。

起源

很久很久以前,是没有“域名”这个概念的。我服务器的 ip 是 100.100.100.100,对外暴露一个端口,比如 80,用于提供 http 服务,用户就得输入 http://100.100.100.100 ,浏览器一看是 http 协议,就自动向 100.100.100.100 的 80 端口发起 http 请求,于是你就开始愉快地网上冲浪了。

问题在于,手动输入 ip 实在是过于麻烦,也不好记,并且如果你的网站改了 ip,还得提前声明一下:“本站的 ip 即将改为 200.200.200.200,请使用新的 ip 地址”。所以人们发明了域名,通常是一些好记的、有意义的单词组合,并将域名与 ip 绑定到一块,这样我们输入域名之后,浏览器就会先把域名解析成 ip 地址,然后向这个 ip 地址发起请求。

还有一个小故事,在我懵懂无知的年纪,特别喜欢使用 360 管家,因为真的能解决很多小问题。有一天我的电脑没法上网,着急下 CF 呢,这怎么行呢?掏出 360 管家,找到上网诊断,一键解决。我还记得有个提示大意是“…如果 qq 能正常聊天但是浏览器无法上网…”。当时当然看不懂了,现在就知道原因就是 DNS 出了问题,导致域名无法解析成 ip,那么使用域名的服务自然也就无法使用了,而 qq 聊天直接用 ip 进行通信,所以功能正常。

那么,这一切都是怎么实现的呢?

解析流程

DNS 解析其实比较简单,但是涉及到的细节会多一些。

区域(Zone)

其中顶级域(TLD)有 arpacomedugov

顶级域分为两种类型:

  1. gTLDs: .com.org 等叫做一般通用顶级域(generic Top-Level Domains)
  2. ccTLDs: .cn.jp 等叫做国家顶级域(country code Top-Level Domains)
  3. arpa:特殊域,比较特殊放在下面讲

一个 DNS 子树(独立管理的)就称为一个区域,举个例子,比如 sina.com.cn 这个二级域,可以将它的区域划分为更小的区域,比如一般会根据用途来划分区域,假设 blog.sina.com.cn 为博客相关的域名等等。划分完子区域之后,需要经过父区域的授权,这样父区域遇到属于子区域下的域名,就会转给子区域来解析。

查询方式

在说流程之前,先说一下查询方式。很简单,分为 2 种:

  1. 递归查询:A -> B -> C,A 向 B 发起 DNS 解析的请求之后,B 帮 A 去 C 那里查找,拿到结果之后返回给 A,这个时候 A、B 各发起了一次解析请求。
  2. 迭代查询:A -> B, A -> C,A 向 B 发起 DNS 解析的请求之后,B 告诉 A 要去 C 那里查找,A 再向 C 发起 DNS 解析请求,这个时候 A 各发起了两次解析请求,C 没有发起 DNS 解析请求。

Hosts 文件(静态 DNS 服务器)

如果你用的是 macOS 或者 Linux,可以看一下这个文件:/etc/hosts

其中有我们上小学就知道的 127.0.0.1localhost。所以你访问 localhost 就是访问 127.0.0.1

Hosts 文件,可以直接理解为是本地静态的 DNS 服务器。需要解析 DNS 的时候,系统会首先自动从 Hosts 文件中寻找对应的 ip-域名 映射关系,一旦找到那么就完成解析了,如果没有找到,则继续解析流程。

显然,配置 Hosts 像极了没有域名的年代,谁会把所有的要访问的域名都加到 Hosts 里呢?但是,它的确可以加快域名解析、屏蔽垃圾网站、广告等等…具体的留在下一篇介绍吧~

LocalDNS 服务器

若 Hosts 文件中没有相关域名的记录,则来到了 LocalDNS。

如果你用的是 macOS 或者 Linux,可以看一下这个文件:/etc/resolv.conf

这个文件一般是自动生成的,什么时候生成的呢?DHCP 的时候。需要注意的是,这个文件里的 ip 经常是内网 ip,并且 LocalDNS 里面有个 “local”,大家可能会认为 LocalDNS 的服务器 ip 都是内网 ip,实际上也可以是外网 ip,比如其他组织提供的 DNS,像谷歌的8.8.8.8啦,国内的114.114.114.114啦。个人感觉是这些 DNS 的地址填写在我们本地的电脑或者移动设备上,所以称为 LocalDNS。

需要注意的是,LocalDNS 本身不具备真正的解析域名的功能。它的作用有两个:

  1. 代替用户的设备参与域名解析
  2. 缓存域名的查询记录,当其他设备发起相同的域名查询请求时可以直接返回查询结果,可以加快域名查询速度。

用户设备 -> LocalDNS 一般是递归查询,而 LocalDNS 发现它自己没有缓存对应的数据后,则需要向 DNS 根服务器发起查询请求,这个请求,一般是迭代查询。所以任何 LocalDNS 都需知道 DNS 根服务器的 ip 地址,这没得说。

DNS 根服务器

DNS 根服务器(root name server),全球只有 13 个,编号从 a.root-servers.net 一直到 m.root-servers.net。之所以不说 13 台,是因为每个 DNS 根节点都会有多个服务器负责均衡查询(即任播节点),你可以在这个网站查询:https://root-servers.org/ 。例如杭州就有 JF 根服务器的任播节点:

现在解析 DNS 的时候,已经不再需要知道 DNS 根服务器的真正的 ip 地址,只需要知道任播地址就可以在世界各地与当地的最优节点进行通信了,所以现在大多数的 DNS 根服务器的 ip 地址都是任播节点 的 ip 地址。

至于为什么是 13 这个数字,这有一篇挺不错的文章,大家可以参考一下:https://zhuanlan.zhihu.com/p/107492241

所以,DNS 根服务器掌管着所有 DNS 顶级域名服务器 的地址,比如大家熟悉的 .com.org.edu.gov 等等。假如我们查询的顶级域名是 .com,DNS 根服务器会将.com 顶级域名服务器的地址发回给 LocalDNS 服务器,让它自己去那里查。于是 LocalDNS 服务器再向手握 .com 的 DNS 顶级域名服务器发起查询。

DNS 顶级域名服务器

手握 .com 的 DNS 顶级域名服务器一看来源的查询是 xxx.com,按理来说应该可以找到对应的 ip 并直接返回了。但是现在基本上都是授权给其他厂家去做的,被授权的叫DNS 权威域名服务器,例如万网,或者企业自建的 DNS 服务器。举个例子,对 weibo.com 进行 DNS 解析:

这里表明对于 weibo.com,DNS 权威域名服务器是 ns1.sina.com.cn.,也就是 DNS 查询的请求到了 .com DNS 顶级域名服务器的时候,它会返回经过自己授权的 DNS 权威域名服务器:ns1.sina.com.cn.,告诉 LocalDNS 服务器自己去那里查吧。

这个时候 LocalDNS 服务器就会缓存 weibo.com 的 DNS 权威域名服务器,免得下次查的时候还得再走一遍之前的流程(当然是在缓存未过期的情况下)。

DNS 权威域名服务器

DNS 权威域名服务器要提前申请 DNS 解析授权,这类 DNS 域名服务器一般掌管着特定域下所有的子域和主机,比如它不仅知道 weibo.com 的 ip,同样也知道 www.weibo.com 的 ip。所以它可以直接返回结果,这一步没啥好说的。

同样, LocalDNS 服务器也会缓存 weibo.com 的 ip,免得下次查的时候还得再走一遍之前的流程(当然也是在缓存未过期的情况下)。

各大公司一般都有自己的权威域名服务器,自己维护 DNS,好处有很多,比如:

  1. 方便管理。假如不自己维护域名信息,域名生效时间和缓存时间都是不可控的,而自己搭建可以避免这些问题。
  2. 动态管理。比如通过一些软件来更新自己的 DNS 信息更方便,还可以做动态域名解析。

流程总结

(以下流程以 A 记录为例)

  1. 设备 -> LocalDNS 服务器(递归查询)
  2. LocalDNS 服务器 -> DNS 根服务器(迭代查询)
  3. LocalDNS 服务器 <- DNS 根服务器(返回顶级域名服务器的地址)
  4. LocalDNS 服务器 -> DNS 顶级域名服务器(迭代查询)
  5. LocalDNS 服务器 <- DNS 顶级域名服务器(返回权威域名服务器的地址)
  6. LocalDNS 服务器 -> DNS 权威域名服务器(迭代查询)
  7. LocalDNS 服务器 <- DNS 权威域名服务器(返回 ip)
  8. 设备 <- LocalDNS 服务器(返回 ip)

DNS 的几个重要概念

在掌握了流程之后,再来看这些概念会更容易理解。

DNS 资源记录(Resource Record, RR)

DNS 服务器有自己的域文件(zone file),zone file 是由多个记录组成的,每一个记录就被称为资源记录。

假如你买了一个域名,需要绑定到对应的 ip 上来提供 web 服务,或者要提供其他服务,这个时候域名的销售方会让你选择解析的类型,常见的有以下几种:

  1. A 记录:将域名指向一个 IPv4 地址(例如:100.100.100.100)
  2. CNAME 记录:将域名指向一个域名,实现与被指向域名相同的访问效果,可以简单地理解为域名的别名。比如 www.weibo.com 就是 cname 到 weibo.com 上,然后 weibo.com 是有自己的 A 记录的,这样有个好处就是假如有很多个域名,a.weibo.comb.weibo.com…,但是 ip 只有 1 个,如果不用 cname,当这个 ip 变更的时候,每个与此 ip 绑定的域名都要去改 A 记录;用了 cname 之后,只需要改 cname 的域名(weibo.com)的 A 记录即可。(CDN 加速就是这样做的对吧~)
  3. MX 记录:指向电子邮件服务器地址,一般会根据邮箱服务商提供的 MX 记录填写此记录。
  4. NS 记录:权威域名服务器记录,即将某些域名指定让某个 DNS 域名服务器来解析。需要注意的是,只有一级或者顶级域名才有 ns 记录,比如 www.weibo.com 是没有 ns 记录的。
  5. TXT 记录:可任意填写、可为空。一般做一些验证记录时会使用此项,例如:SPF 记录(用于反垃圾邮件)
  6. AAAA 记录:将域名指向一个 IPv6 地址(例如:ff03:0:0:0:0:0:0:c1)
  7. SOA 记录:SOA(Start of Authority)叫做起始授权机构记录。通俗地来讲,一个域名可能有很多个 NS 记录,因为会有多台服务器在进行解析(负责均衡或者备份),但哪一个才是主 DNS 权威服务器呢?这个就要看 SOA 记录了,它说明了在众多 NS 记录里哪一台才是主 DNS 权威服务器。这个主 DNS 权威服务器会负责其他事情,比如告诉其他 NS 权威服务器什么时候该更新数据(通过域传送的方式,下面会讲),甚至记录里还有对应联系人的邮件、TTL 等信息,这里就不多赘述了。
  8. PTR 记录:PTR 记录是 A 记录的逆向记录,负责将 IP 反向解析为域名,这个内容稍多,单独放在下面讲
  9. AXFRIXFR 记录:涉及区域传送,单独放在下面讲

其他的都比较好理解,SOA 可能稍微有点饶,举个例子:

下面红框里的就是联系方式,在 SOA 记录中,admin.example.com 等效于 admin@example.com

FQDN

FQDN(Fully Qualified Domain Name),完整合格域名(不知道是不是这样翻译的…)。与我们日常见到的域名相比,最后还有一个.,例如 weibo.com.。其实这样反应出了 DNS 系统完整的层级关系,最开始是 .,即根(root)域名,接下来是 TLDs,表示顶级域名

所以如果我们查询 . 的 DNS NS 记录得到的是什么呢?

所以 . 是由 DNS 根服务充当 DNS 权威服务进行解析,但是 . 其实是没有 A 记录的。

DDNS

DDNS 相比 DDNS 多了一个 D,即“动态”的意思,可以通过 DDNS 提供动态域名解析服务。

举个例子,如果你想搞一个自己的网站,并且有自己的公网服务器,那么一般都有一个公网 ip,绑定在某个域名之后,其他人就可以直接访问了。但是如果你没有一个公网服务器,想要用自己的家庭网络来搭建网站,首先不说大部分人都是运营商的内网 ip,即便少部分人申请到了公网 ip 也都不是固定的。那么你虽然可以把自己家的 ip 地址绑定在域名上,但是你可能需要一天换绑一次 ip…因为 IPv4 资源还是很紧张的,不可能给每个人都分配公网 ip,这个问题虽然到 IPv6 可以解决,但是那也是以后的事情了。所以自己去做 发现出口 ip 变化 + 更换 DNS 绑定 显然是反人类的。

但是我们就想在外网想要访问我们在家里的台式机上搭建的网站怎么办呢?这就需要 DDNS 了。DDNS 会将用户的动态 ip 地址映射到一个固定的域名解析服务上:当台式机出口 ip 变化的时候,DDNS 客户端程序就会把新的出口 ip 地址传给位于 DDNS 服务商主机上的服务端程序,而服务端程序负责提供 DNS 服务并实现换绑 DNS。相当于把 发现出口 ip 变化 + 更换 DNS 绑定 给自动化了。当然,最大缓存时间需要调短一些,要不因为 DNS 的缓存机制,可能用户用的还是之前的解析记录。大家比较熟悉的“花生壳”就可以搞这个事情。

其他零碎的细节

Non-authoritative answer

nslookup 经常会出现 Non-authoritative answer,这是什么意思?

示例:

其实这个意思就是这个解析记录是从 LocalDNS 的缓存里拿来的,而不是向真正负责这个域名的 DNS 权威服务器拿来的。

PTR,ip 反查域名

ip 反查域名主要用在到电子邮件服务器中来拦截垃圾邮件,不过现在用的似乎也不多了。

举个例子:比如你用 admin@tr0y.wang 这个邮箱给我的邮箱 macr0phag3@qq.com 发了一封邮件,qq 邮件服务器收到这封信之后,会查看这封信是由哪个 ip 地址发出来的,然后根据这个 ip 地址进行反向域名解析,如果反向解析到这个 ip 所对应的域名是 tr0y.wang 那么就说明这封邮件真的是 tr0y.wang 发出来的,那么就接受这封邮件;反之就拒收这封邮件。

但是这就引起了另一个问题:反查域名的过程是什么样的?或者说是怎么实现的?由于一个 ip 地址可以对应多个域名,因此从 ip 出发去找域名,理论上应该遍历整个域名树去挨个找,但这肯定是不现实的,因为效率太低下了。所以为了快速完成反向域名解析,前辈发明了特别域,称为逆向解析域 in-addr.arpa。在上面的例子里,就是需要 tr0y.wang 提供一个 特别域。这样要反向解析的 ip 地址就会变成一种像域名一样的形式,后缀是逆向解析域的域名 in-addr.arpa

例如一个 ip 地址:12.23.34.45,其逆向域名表达方式为:45.34.23.12.in-addr.arpa(注意,逆向域名中的 ip 地址部分与原 ip 的顺序是相反的)。举个例子:

如果你不想用手动写逆向解析域,也可以用 dig 提供的 -xdig ptr 179.189.99.211.in-addr.arpa. 等价于 dig -x 211.99.189.179

最后,建议可以自己试试 dig +trace -x 211.99.189.179,你就能看到解析的顺序是 . -> in-addr.arpa. -> 211.in-addr.arpa. -> 99.211.in-addr.arpa. -> 189.99.211.in-addr.arpa.

DNS 区域传送

DNS 区域传送,是一台从 DNS 服务器用来获取主 DNS 服务器(SOA 记录的那个服务)的数据,更新自己数据用的,可以防止在主 DNS 服务器因意外故障时,从服务器也可以正常工作。DNS区域传送有两种方式:

  1. axfr:完整区域传送
  2. ixfr:增量区域传送

所以,正常情况下 DNS 区域传送操作只有经过授权的 DNS 服务器才有权执行,但许多 DNS 服务器却被错误地配置成只要有人发出请求,就直接提供一个 zone 的 DNS 内容。DNS 域传送漏洞会在下一篇详细介绍,这个手段是前些年用于信息收集的手段之一。

ADDITIONAL SECTION

如果你用过 dig,你就会发现查询结果里经常会有一个 ADDITIONAL SECTION

那么这个是干嘛用的呢?简单来说,ADDITIONAL SECTION 里的所有数据都不是你没有明确要求返回的数据,就是服务器认为你可能会有用,就给你了。举个例子,假如你查询 . 的 ns 记录,查询到了 DNS 根服务器之后,它会认为你在查询完 ns 记录(例如 a.root-servers.net.)之后大概率会继续查 a.root-servers.net. 的 A 记录,所以它就在 ADDITIONAL SECTION 里告诉你 a.root-servers.net. 的 ip 是 198.41.0.4,这样你的 localDNS 就会缓存这个记录,等你真正去查 a.root-servers.net. ip 的时候就直接从缓存拿里给你了,省得你又去绕一大圈。

完结撒花

DNS 内容其实还有一些,但不是很重要就不梳理了,如果下一篇需要某个知识点,会再补讲一下。DNS 是很重要的协议,后面很多攻击手段,如果对 DNS 的一些重要细节模棱两可,很难完全理解。

来呀快活呀


经验总结      DNS

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

从一个绕过长度限制的 XSS 中,我们能学到什么? 下一篇