一文搞清楚 DNS 的来龙去脉

时间:2024-03-12 16:19:13

想象下面的对话:

“老大,这个问题怎么处理?”

“去问 14.215.177.39!”

你是不是一脸懵逼?

计算机只喜欢数字,每台联网设备都有一个用数字表示的唯一编号叫 IP(类似我们的身份证号),联网的设备之间就通过这个叫 IP 的编号相互联系——比如我们在个人电脑上输入 http://14.215.177.39 就能访问百度公司的服务器。

但人类天生对数字不敏感(想想高中背历史年代的场景,是不是心里抖三抖?),IP 对于人类来说毫无意义(你能从 14.215.177.39 想到百度?),需要有种人类可读可记忆的方式来标记联网设备——这玩意就叫域名

于是我们大致可以像这样访问百度服务器了:

域名英文叫 Domain Name,那这个将域名转换成 IP 的转换器就叫 Domain Name System(域名系统),简称 DNS。域名系统服务(DNS Server)就是一台装了相关软件(一般是用 BIND,即 Berkeley Internet Name Domain,最初是由美国加州大学伯克利分校开发和维护的)的服务器,本质上就是一个“电话本”,用来查找某个域名对应哪个IP。

这个域名到 IP 的转换,想起来很简单,但要实施起来有很多事情要考虑。

首先一点是,谁来负责域名、IP的分配与转换呢?我们在浏览器输入 www.baidu.com 后,我们的电脑要去问谁关于这个域名的 IP 呢?

美国霸权

一个直觉是,互联网属于全球范围的网络,应该是有个全球性的机构来负责这件事情(而不能每个公司或国家自己搞自己的)。

如无例外,这个机构应该位于互联网发源地。

我们知道,互联网发迹于美国,20 世纪 90 年代之前,互联网并没有普及,那时候主要用于军事和科研,主要是美国*和大学关注这些——具体来说就是美国*在掌管着互联网,也就是说,互联网具体怎么玩,全是美国说了算——所谓霸权,就是我的地盘我做主,游戏规则都是我定的。

美国*需要解决两方面的事情:域名(字母地址)的管理IP(数字地址)的管理,即如何给全世界的计算机分配 IP 和域名,以及如何将域名翻译成对应的 IP。美国*(美国国家科学基金会)将域名委托给 NSI 公司(Network Solutions)管理,将 IP 地址委托给IANA(The Internet Assigned Numbers Authority,互联网数字分配机构,从其名字就知道是干嘛的)管理。

随着互联网的发展与普及,其他国家对美国这种独家垄断越来越不满(美国商业部在 1998 年初发布了个绿皮书,说美国*有对 Internet 的直接管理权,让其他国家毛炸)。互联网是世界的,不是你美国的,现在IP由你分配,域名由你解析,哪天你对某个国家不爽,就把那里来的域名解析请求全给屏蔽了,那还得了?

但一个事实是,当时全世界的根域名解析和 IP 地址分配基本都是美国机构管理的,所以这事离开美国还真玩不转。所以比较可行的方案是,对这些机构进行改革,让其成为类似联合国的国际性组织,脱离美国*的管辖。

ICANN:互联网界的联合国

在其他国家一致反对的情况下,美国*在 1998 年*对原来的绿皮书做了修订(人称白皮书),提议成立个独立的民间组织 ICANN(Internet Corporation for Assigned Names and Numbers,互联网名称与数字地址分配机构,官网 https://www.icann.org,总部在美国加州),参与管理 Internet 域名及地址资源的分配。起初,虽然 ICANN 参与(注意是参与)互联网的管理,但仍然是在美国*的授权框架下行事,受到美国*(商务部)的监管。直到 2016 年 10 月 1 日,美国*将互联网域名管理权完全交给 ICANN,两者之间的授权管理合同在这一天失效,不再续签——就是说,从这天起,ICANN才是个名副其实的全球性独立机构,不再受美国*的监管(至少在名义上)。

ICAAN 官网介绍如下:

ICANN 的使命在于确保全球互联网的稳定、安全与统一。要与其他 互联网用户联系,您必须在自己的电脑或其他设备中输入地址 — 可 以是一个名称或是一串数字。这个地址必须独一无二,只有这样电 脑之间才能互相识别。ICANN 则负责协调并支持这些分布在全球各 地的唯一标识符。ICANN 成立于 1998 年,是一家非营利公益型机 构,其社群成员遍布全球各地。

上面说的就是以前美国*委托 NSI 和 IANA 管的事——现在 IANA 是 ICANN 的一个下设机构,其实上面说的事情主要还是由 IANA 在管,去看下IANA 官网 https://www.iana.org/ 就知道了,其首页说明:

The global coordination of the DNS Root, IP addressing, and other Internet protocol resources is performed as the Internet Assigned Numbers Authority (IANA) functions.

主要职能:全球的根 DNS、IP 地址以及其它互联网协议资源的协调。

我们看看 ICANN 的组织架构:

ICANN 的最高权力机构是董事会,其成员由 ICANN 社群选取。ICANN 的日常事务由 ICANN 组织(也就是真正的实体机构)执行,而董事会则负责监督 ICANN 组织的政策制定与执行情况。

做个类比,ICANN 社群就相当于全体中国公民,董事会相当于中国的最高权力机关人民代表大会,而 ICANN 则相当于中国的各级*机关单位。

ICANN 董事会成员来自美国、中国、澳大利亚、巴西、法国、德国等等全世界各个国家,社群成员则分布更广。各国*则以咨询委员会的方式参与 ICANN 事务。

IP 地址分配

在说域名解析前要简单说下 IP 地址的分配,因为域名最终是要被解析成 IP 的,离开 IP 域名玩不转。

由上一节可知,全球互联网 IP 资源是由 ICANN 管理的,具体来说是由其下设机构 IANA 管理的。

(这里需要注意,虽然 IANA 现在是 ICANN 的下设机构,但 IANA 比 ICANN 要早得多,其历史可追溯到 20 世纪 70 年代——而 ICANN 在 1998 年才成立。可以理解为 ICANN 是对 IANA 等机构组织的改革与重组——IANA 还是那个 IANA,但其上层监管机构由美国*转为 ICANN。)

然而,中国的一家公司想要申请个 IP,肯定不是跑到美国找 IANA——IANA 并不管这些鸡毛蒜皮的事。IP 资源是以分层组织架构来管理的,IANA 是全球总的 IP 资源管理机构,其在各大洲/区域设立多个区域互联网注册机构(Regional Internet Registry,RIR),IANA 主要做的事就是按照 IETF 制定的相关策略给这些 RIR 分配 IP 资源池(一批 IP),这些 RIR 再将这些 IP 以更小的批次粒度分配给下级机构(如本地互联网注册机构LIR、国家互联网注册机构NIR,也有可能直接分配给 ISP),这些下级机构再以更小的批次粒度分配给辖区的 ISP(Internet Server Provider,互联网接入服务商,如中国电信),而个体或公司则是从 ISP 那里申请最终的 IP。

比如中国一家公司要向中国电信申请一个 IP,而中国电信则要向中国互联网络信息中心(China Internet Network Information Center,CNNIC,属于 NIR)申请,而 CNNIC 要向亚太互联网络信息中心(Asia-Pacific Network Information Center,APNIC,属于 RIR)申请,APNIC 要向 IANA 申请(说是申请,其实是预先分配)。

目前 IANA 下设的RIR:

这里是 IPV4 地址分配情况

域名解析架构

现在我们知道谁在管理全世界的域名和 IP 了(ICANN),接下来的问题是:如何将域名解析到指定的 IP?

我们还是回到上面的图:

很简单嘛,弄台电脑,里面有个数据库存储了域名到 IP 的映射目录,装个 DNS Server 软件监听某个端口(一般是 53 端口)对外提供服务,然后广而告之让全世界的主机都来这里查询就行了。

这样的服务器撑不了一秒钟。

一个直接的问题是,这样一台服务器如何扛得住每天百万亿次的请求?

更严重的问题是,如果这台服务器被 DDoS 了,更有甚数据库被黑了,岂不是全世界断网摸黑了?

所以,鸡蛋不能放一个篮子里。DNS 这玩意要玩分布式。

分层架构:

现实中的域名结构和 DNS 解析架构跟 IP 一样,也是分层的——所以域名和 IP 一样也是用多个“.”隔开的。

全球的 DNS 解析从逻辑上分成三个层次:根 DNS 服务器(Root DNS)* DNS 服务器(TLD)权威 DNS 服务器

dns-06

对应地,我们看看域名的层次结构:

dns-05

图片来自阿里云

对比两张图我们发现,域名的结构和 DNS 解析架构是一致的——这很好理解,域名终归是用来解析的嘛,有什么样的解析架构决定了有什么样的域名结构。所以百度的域名叫 www.baidu.com,而不是我们开始随便写的 baidu12345678。

有了这样的层级结构,现在我们在浏览器输入 www.baidu.com,浏览器为了得到这个域名的 IP,就要在这个层级结构中从上往下问——不过实际上不是浏览器自己去问,而是有个叫本地 DNS 服务器(local DNS server,也叫 DNS Resolver)的家伙代劳,浏览器问本地 DNS 服务器 www.baidu.com 的 IP 是多少,本地 DNS 服务器说”稍等,我帮你问问“,然后就开始了类似下面的对话:

(下面我们称本地 DNS 服务器叫”小助手“)

  • 小助手先问根 DNS 服务器:”大哥,请问 www.baidu.com 的 IP 是多少?“

    根 DNS 服务器说:”我不知道,但你可以问问 com * DNS 服务器,他知道些 com 的内情。他的 IP 是 192.26.92.30。“

  • 然后小助手跑去问那个 com * DNS 服务器:”二哥,请问 www.baidu.com 的 IP 是多少?“

    com * DNS 服务器说:”我不知道,但你可以问问权威服务器 A,他知道些 baidu.com 的内情。他的 IP 是 220.181.33.31。“

  • 然后小助手又屁颠屁颠去问权威服务器 A:”三哥,请问 www.baidu.com 的 IP 是多少?“

    权威服务器 A 说:”算你问对人了,www.baidu.com 的 IP 是 14.215.177.38。“

  • 于是小助手终于拿到了 www.baidu.com 的 IP,高高兴兴地给到浏览器。

(注意:实际上 www.baidu.com 做了 CNAME 解析,并且最终 IP 也不止一个。)

即先从域名的根(即”.“,有些场合下 www.baidu.com 会写成 www.baidu.com.,最后那个”.“就是根域名)开始顺藤摸瓜:. -> com -> baidu.com -> www.baidu.com。

上面过程画成图就是这样:

dns-07

DNS 缓存:

这个本地 DNS 服务器虽然最终问到了 IP,但心里其实很不爽:我为了问个 IP 就周游了一遍全世界啊。

浏览器也不爽:问个 IP 花这么久,你属乌龟啊?

另外刚才说通过层级架构解决访问量问题,但从上面例子也没发现访问量降低啊,每层服务器都被访问了一遍。

所以在这种分层架构中有个核心要点:DNS 缓存(DNS Cache)。

域名和 IP 的映射关系有个重要的事实是,它们不常变化,特别越往上层变动频率越低(13 台根 DNS 服务器的域名和 IP 更是固定不变的),这种数据非常适合做缓存。

所以实际上在上面的查询中,浏览器所在的本地电脑和本地 DNS 服务器都是先查它们自己的缓存,查不到才往上查。

具体是,浏览器发出 DNS 查询请求给本地电脑的 DNS 客户端,DNS 客户端先查本地 DNS 缓存有没有对应域名的 IP 信息(且未过期),有则直接返回;没有则去询问本地 DNS 服务器,本地 DNS 服务器先查本地缓存中有没有对应域名的 IP,有则返回,没有则往上层查。

本地 DNS 服务器一般是 ISP 的 DNS Server 或者公共 DNS(如 114DNS),对于一些大量访问的知名网站,基本都是有缓存的。另外,即使没有缓存,它也不一定就是从根 DNS 服务器开始查,因为多半它也持有 TLD DNS 服务器以及相应域名权威 DNS 服务器的缓存,所以多数时候它是抄近道查的。

也就是说,对于绝大部分的 DNS 解析请求,在本地电脑和本地 DNS 服务器两层已经解决掉了,压根不会跑到外面那三层体系中——即便这样,全球 13 台根 DNS 服务器每天仍要承接数百亿次查询。

dns-08

根 DNS 服务器:

全世界一共有 13 台(逻辑上)根 DNA 服务器,分别用 a 到 m 命名,如 a.root-servers.net,b.root-servers.net。之所以是 13 台是有其历史原因的,根据RFC 791规定,为保证 UDP 数据包传输成功率,尽量将数据包控制在 571 字节以使数据包不会被分片传输,所以算来算去这个数据报就只能放 13 个服务器信息。

这 13 台根服务器中,一台是主服务器(就是 a 服务器),12 台辅助服务器,有 10 台在美国,2 台在欧洲,1台在日本。

说 13 台有点不确切,准确说应该是 13 组,因为 a - m 每个都是全球范围的分布式集群,到目前为止,一共有1487 个 ROOT 实例(instance),这么多集群节点一方面大大提高请求承载能力和访问速度(通过 BGP 路由协议分配最近的节点),同时大大提高抗 DDoS 的能力。

这一千多个根实例分布如下:

dns-09

我们点开中国地区的看看:

dns-10

上面显示在重庆有个 F 根,贵阳有个 K 根,武汉有两个 L 根(L 的运营机构就是 ICANN 自己)。当然中国其他地方还有很多不同的 Root 实例。

这不是说现在中国就有 IPV4 根服务器了,你看武汉那个 Root,他的 Operator 是 ICANN,在美国呢(中国有 IPV6 的根服务器,后面会说到)。

这 13 台(我们仍然习惯用”台“,要知道这是逻辑单位)根服务器由 ICANN 委托 12 家不同的机构运营管理(当然大部分都是美国的),可以在 https://root-servers.org 看到详情。我们看其中一个:

dns-11

这是 J 根的情况,它是由 Verisign 公司运营管理的(这家公司在 2000 年收购了 Network Solutions 公司——美国*曾指派它来管理域名——所以 Verisign 同时还运营主根(A Root)一点不奇怪)。J 根在全球一共有 118 个实例(这个数字未来应该还会增加),这些实例都是用同一个 IP:192.58.128.30,采用一种叫任播(AnyCast)的技术从中选一台处理请求。

我们看看 J 根一天的访问量:

dns-12

2022 年 1 月 11 日一天的 UDP 请求(DNS 主要就是 UDP)约 55 亿。

从前面 DNS 查询过程可知,根服务器的主要作用就是告知查询者各*域名(如com)对应的* DNS 服务器(TLD)的 IP 是什么,好让查询者继续往下查。所以根服务器需要维护一个*域名到 TLD 服务器地址的映射目录,这个目录叫 DNS 根区(DNS root zone),可以在这里查看完整的根区列表。下面是部分内容:

;; 一共 5 列依次是:域名、有效期、类别(IN 表示互联网 Internet)、记录类型(NS 表示 Name Server,A 表示 Address)、DNS 服务器或者 IP(取决于记录类型是 NS 还是 A),这些在后面讲 DNS 协议里面详细说明
cn.			172800	IN	NS	a.dns.cn.
cn.			172800	IN	NS	b.dns.cn.
cn.			172800	IN	NS	c.dns.cn.
cn.			172800	IN	NS	d.dns.cn.
cn.			172800	IN	NS	e.dns.cn.
cn.			172800	IN	NS	f.dns.cn.
cn.			172800	IN	NS	g.dns.cn.
cn.			172800	IN	NS	ns.cernet.net.
......
a.dns.cn.		172800	IN	A	203.119.25.1
a.dns.cn.		172800	IN	AAAA	2001:dc7:0:0:0:0:0:1
b.dns.cn.		172800	IN	A	203.119.26.1
c.dns.cn.		172800	IN	A	203.119.27.1
d.dns.cn.		172800	IN	A	203.119.28.1
d.dns.cn.		172800	IN	AAAA	2001:dc7:1000:0:0:0:0:1

前面是*域名 cn. 对应的 DNS 服务器。cn. 一共有 8 台 TLD 服务器,其中 7 台是 CNNIC (中国互联网络信息中心)的,1 台是 35 互联的。注意服务器也是用域名表示的,所以后面还需要个 A 记录列出域名对应的 IP 地址(A 是 IPV4,AAAA 是 IPV6)。

不过,在请求根服务器获取 TLD 服务器信息之前,我们的本地 DNS 服务器怎么知道根服务器的 IP 呢?

答案是写死。ICAAN 提供了一份 named.cache 文件,这个文件提供了 13 台根服务器的 IP 地址,这玩意是不会变的,我们把它 down 下来放入本地 DNS Server 配置文件中就行了。

* DNS 服务器(TLD):

本地 DNS 服务器从根服务器那里拿到*域名(如 com)对应的 TLD Server 的 IP 后,要访问 TLD Server 获取一级域名(如 baidu.com)对应的权威 DNS 服务器的 IP。

*域名分通用*域名(gTLD,如 com、org、edu、net)和国家*域名(ccTLD,如 cn、jp、uk)。这些*域名(以及 TLD Server)由 ICANN 委托不同的机构管理维护,如 .com 和 .net 由 VeriSign 公司维护,.cn 由 CNNIC 维护,还有些不怎么通用的域名如 ”.google“ 由 google 运营,”.中国“由 CNNIC 运营。所谓委托,就是 ICANN 跟这些机构签署委托合同(在 ICANN 之前是由美国*和相关机构签委托合同),这些机构在合同框架下实际管理维护这些*域名和 DNS 服务器——这其实是一块肥水,想想我们去万网注册个 abc.com 的域名,每年都要交钱给万网,而这钱很有一部分是交给这些*机构的(还有一小部分交给 ICANN 作为管理费)。

可以在 IANA 网站上看到所有的*域名以及运营机构:https://www.iana.org/domains/root/db。

我们可以在网站或者命令行用 whois 工具查看某个*域名的详细信息,如通过whois com查看*域名 com 的信息:

% IANA WHOIS server
% for more information on IANA, visit http://www.iana.org
% This query returned 1 object

domain:       COM

organisation: VeriSign Global Registry Services
address:      12061 Bluemont Way
address:      Reston Virginia 20190
address:      United States

......

nserver:      A.GTLD-SERVERS.NET 192.5.6.30 2001:503:a83e:0:0:0:2:30
nserver:      B.GTLD-SERVERS.NET 192.33.14.30 2001:503:231d:0:0:0:2:30
......

whois:        whois.verisign-grs.com

status:       ACTIVE
remarks:      Registration information: http://www.verisigninc.com

created:      1985-01-01
changed:      2017-10-05
source:       IANA

第一行说明域名是归 IANA 管辖的,具体的运营机构是 VeriSign Global Registry Services,后面是用来解析该*域名的 DNS 服务器信息,可以看到有 13 组 DNS 服务器(只截取了部分),这些 DNS 服务器同时支持 IPV4 和 IPV6。.com 下面的域名 whois 信息都是 whois.verisign-grs.com 提供的(一般域名的 whois 信息都是由相应*域名服务商提供的,如如 whois 查 baidu.com 的信息,该信息就是来自 Verisign 的数据库)。最后一部分说明 com *域是在 1985 年 1 月 1 日启用的。

权威 DNS 服务器:

TLD 服务器同样不能告诉我们 www.baidu.com 的 IP 到底是什么,它的数据库里面只有一级域名 baidu.com 对应的权威 DNS 服务器的 IP,所以我们还要根据其指示去相应的权威 DNS 服务器查最终的 IP。

一般来说大公司会搭建自己的权威 DNS 服务器解析自己的域名,我们可以通过 whois 命令查看域名对应的权威服务器。

比如百度的:

# whois baidu.com
......
Name Server: ns3.baidu.com
Name Server: ns7.baidu.com
Name Server: ns4.baidu.com
Name Server: ns2.baidu.com
Name Server: ns1.baidu.com

淘宝的:

# whois taobao.com
......
Name Server: NS4.TAOBAO.COM
Name Server: NS5.TAOBAO.COM
Name Server: NS6.TAOBAO.COM
Name Server: NS7.TAOBAO.COM

新浪的:

# whois sina.com.cn
......
Name Server: ns3.sina.com.cn
Name Server: ns2.sina.com.cn
Name Server: ns4.sina.com.cn
Name Server: ns1.sina.com.cn

一般中小公司会选择租用某些大型服务商提供的付费权威 DNS(当然也可以自己搭建,但没必要),比如我们公司域名 weicheche.cn 用的阿里旗下万网的权威 DNS 服务器:

# whois weicheche.cn
......
Name Server: dns31.hichina.com
Name Server: dns32.hichina.com

和根服务器需要知道各 TLD 服务器的 IP 信息一样(上面提到的 DNS 根区),TLD 服务器也必须事先知道相应的权威服务器的域名和 IP 信息。当百度希望用 ns1.baidu.com 作为 baidu.com 的权威 DNS 服务器时,它必须将该信息(ns1.baidu.com 域名以及其 IP )写到 com TLD 服务器的数据库中,如果以后百度想换 baidu.com 这个域名的权威 DNS 服务器(如换成 ns1.xiaodu.com),则必须修改 com TLD 服务器的那条记录(一般一个域名的权威 DNS 至少要有两台)。

权威 DNS 是可以有多级的。假如有个家政公司其一级域名叫 jiazheng.com,其 DNS 服务器是 dns.jiazheng.com,该公司想按省份管辖服务,每个省份有自己的域名和 DNS 解析,如湖北省的叫 hb.jiazheng.com,其 DNS 服务器是 dns-hb.jiazheng.com,广东的叫 gd.jiazheng.com,其 DNS 服务器是 dns-gd.jiazheng.com。另外该公司业务分家庭业务和公司业务两大板块,也分别有自己的域名,比如湖北的家庭板块域名叫 jt.hb.jiazheng.com,公司板块叫 gs.hb.jiazheng.com。

这家公司需要将(而且只需要)将一级域名 jiazheng.com 对应的 DNS 服务器 dns.jiazheng.com 注册到 com TLD Server 数据库中,然后将二级域名 hb.jiazheng.com 的 DNS 服务器 dns-hb.jiazheng.com 以及 gd.jiazheng.com 的 DNS 服务器 dns-gd.jiazheng.com 注册到 dns.jiazheng.com 的数据库中。

当用户访问 jt.hb.jiazheng.com 时,其本地 DNS 服务器依次查根服务器、com TLD 服务器,com TLD 服务器会告诉说你到 dns.jiazheng.com 这台服务器上去查,他的 IP 是 X.X.X.X;当本地 DNS 服务器去 dns.jiazheng.com 上查时,dns.jiazheng.com 并不能直接告诉其 IP 是多少,只能说你要到 dns-hb.jiazheng.com 上去查,他的 IP 是 Y.Y.Y.Y(具体是返回一个 NS 报文而非 A 报文,后面会说 DNS 报文类型);最终本地 DNS 服务器从 dns-hb.jiazheng.com 上查到了 jt.hb.jiazheng.com 的 IP 是 Z.Z.Z.Z。

本地 DNS:

本地 DNS 并不在三级层次结构中,但它对 DNS 解析非常重要。一般个人电脑上都不会安装 DNS Server,浏览器也不会去各层 DNS Server 上去查,这个查询任务是由本地 DNS 服务器代理完成的,它接收浏览器(其实是浏览器所在电脑上的 DNS Client)的查询请求,其间无论查询道路多么曲折,最终总要返回该域名的 IP 给到浏览器。

一般来说,个人的本地 DNS Server 是 ISP 自动分配的,或者是路由器里面集成的。公司可能会搭建自己的本地 DNS 服务器。也可以使用一些公共的 DNS 服务,如 114DNS(114.114.114.114)、google DNS 服务(8.8.8.8)。

Windows 上在”网络和 Internet“中可以看到自己电脑的本地 DNS:

dns-14

Mac 上在”网络偏好设置->高级->DNS“中:

dns-15

DNS 协议

概览:

DNS 查询是用 DNS 协议实现的,DNS 协议是应用层协议,其底层主要使用 UDP(某些场景会使用 TCP)。

DNS 服务器存储的那些域名到 IP 的映射叫资源记录(Resource Record,RR),资源记录(RR)是一个包含下列字段的 4 元祖:

(Name, Value, Type, TTL)

TTL(Time To Live)大家都熟悉,表示这条资源的缓存有效期,前面不是提过 DNS 缓存嘛,到底要缓存多久就取决于这个 TTL 的值,一般越上层的 TTL 越长。

Type 表示这是个什么类型的报文,它决定了 Name 和 Value 的具体含义。主要用到的 Type 有 A、AAAA、CNAME、NS、MX:

A:Address 的缩写,此时 Name 表示域名(一般是二级或多级域名),Value 表示该域名的 IPV4 地址。本地 DNS 服务器拿到 A 记录就可以返回给客户端了;

AAAA:类似 A 记录,表示的是 IPV6 地址(因为 IPV6 是 16 字节,是 IPV4 4 字节长度的 4 倍,所以写了 4 个 A);

CNAME:别名记录,表示 Name 域名是 Value 域名的别名。如 www.baidu.com 就 CNAME 到了 www.a.shifen.com,本地服务器拿到 CNAME 记录后需要继续解析 CNAME 过来的新域名,如需要继续去问 www.a.shifen.com 的 IP 是什么。CNAME 解析是 CDN 中重要一步;

NS:Name Server 的缩写,表示 Name 这个域名要去 Value 这个 DNS 服务器继续查。整个多层级 DNS 解析架构就靠这玩意——我们看前面的 DNS 根区文件中有大量的 NS 记录表示某*域名需要去哪个 TLD 服务器解析;

MX:和 CNAME 类似,都是做别名,不同的是 MX 表示 Value 是邮件服务器;

一个 DNS 报文结构长这样:

dns-16

是不是感觉说了等于没说?下面我们用工具抓包实操下你就明白了。

我们用到两个工具:dig 和 wireshark,分别用来发送 DNS 查询和分析数据报。

dig 一下:

先在命令行用 dig 工具看下 www.baidu.com 的 DNS 解析过程:

# dig +trace www.baidu.com
; +trace 表示查看 DNS 解析的整个过程
;; 第一阶段:从本地 DNS 服务器拿到根服务器的信息(因为 dig 工具自己没有这些信息),一共拿到 13 个
.			244973	IN	NS	d.root-servers.net.
.			244973	IN	NS	b.root-servers.net.
.			244973	IN	NS	f.root-servers.net.
;; ...... 这里省略掉了 10 个
;; Received 811 bytes from 192.168.30.1#53(192.168.30.1) in 35 ms

;; 第二阶段:从其中一台根服务器(j)获取*域名 com. 对应的解析服务器(TLD 服务器),一共拿到 13 个。DS 和 RRSIG 是签名用的
com.			172800	IN	NS	a.gtld-servers.net.
com.			172800	IN	NS	b.gtld-servers.net.
com.			172800	IN	NS	c.gtld-servers.net.
;; ...... 这里省略掉了 10 个
com.			86400	IN	DS	30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766
com.			86400	IN	RRSIG	DS 8 1 86400 20220126210000 20220113200000 9799 . ......(省略掉一长串签名信息)
;; Received 1173 bytes from 192.58.128.30#53(j.root-servers.net) in 241 ms

;; 第三阶段:从其中一台*服务器(h.gtld-servers.net)获取一级域名 baidu.com. 对应的解析服务器(权威 DNS 服务器),一共拿到 5 个
baidu.com.		172800	IN	NS	ns2.baidu.com.
baidu.com.		172800	IN	NS	ns3.baidu.com.
baidu.com.		172800	IN	NS	ns4.baidu.com.
baidu.com.		172800	IN	NS	ns1.baidu.com.
baidu.com.		172800	IN	NS	ns7.baidu.com.
;; 这里省去了两个签名记录
;; Received 761 bytes from 192.54.112.30#53(h.gtld-servers.net) in 228 ms

;; 第四阶段:从其中一台权威服务器(ns7.baidu.com)拿到二级域名 www.baidu.com. 的信息,这里拿到的是 CNAME 记录,在实际解析中还需要继续去拿 www.a.shifen.com. 的 IP
www.baidu.com.		1200	IN	CNAME	www.a.shifen.com.
;; Received 72 bytes from 240e:bf:b801:1002:0:ff:b024:26de#53(ns7.baidu.com) in 21 ms

上面的第一阶段在实际 DNS 解析中是事先在本地 DNS 服务器配置文件中写好的,不需要另行获取(因为 dig 的配置文件没这些东西,所以必须从本地 DNS 服务器那里获取)。

我们发现各层 DNS 服务器都有多个,这是为了防止一台挂了就整个瘫痪。

DNSSEC:如何证明”你妈是你妈“:

上面的数据除了 NS 记录还有 DS、RRSIG 记录,这是用于对返回的数据做签名用的,因为网络是不受信任的环境,我们发出个请求,然后接收到回复,怎么能保证这个回复就是真正的合法服务器返回的并且数据在途中没有被其他人修改?比如我们访问 www.baidu.com,本地 DNS 经过几轮查询,从 ns7.baidu.com 拿到了 www.baidu.com 的 CNAME 值 www.a.shifen.com——这过程中你能保证拿到的数据一定是 ns7.baidu.com 给你的?就没有中间人拦截你的请求然后给你发个伪造的应答包,给你 CNAME 到某个日本动作片网址?

这不是瞎猜的,2014 年 9 月,CMU 的研究人员发现,本应通过 Yahoo!、Hotmail 和 Gmail 服务器发送的电子邮件变成通过流氓邮件服务器发送。攻击者就是利用了 DNS 系统接受应答前不会检查凭据这一漏洞实现的攻击。

然而为了性能 DNS 底层选择使用 UDP,而 UDP 是无连接传输协议,所以 DNS 并不能学 HTTP 那样加个 SSL 层变成 DNSS。

IETF 为了 DNS 数据传输的安全性搞了个 DNSSEC(Domain Name System Security Extensions,即 DNS 安全扩展),具体内容参见 RFC2535。大致是说既然你 UDP 数据报是无连接的,那我就在数据报身上(而不是连接)做文章,为那些数据(A、NS等记录)生成一个签名(如 SHA256),然后对这个签名用非对称加密算法(私钥)加密一下,放在这些记录后面(Type 叫 RRSIG,就是 Resource Record Signature 资源记录签名的意思),客户端拿到数据报后,用公钥解密出签名信息,并和客户端自己对这些记录做的签名结果比对一下,如果不一样说明数据就是非法的(当然客户端用的签名算法肯定要和服务器端一样的,比如都用 SHA256)。

但问题是,客户端(本地 DNS 服务器)怎么知道公钥是多少呢?所以客户端必须再请求服务器端(如权威 DNS 服务器)要公钥。

这是不是很有问题?如果请求被某个贼人拦截了,那拿到的公钥岂不也是假的?

所以 DNSSEC 设计了个叫做信任链的校验流程,一句话就是:”如果你不信任儿子,就去问老子“——上层服务器持有下层服务器的身份验证信息。

客户端不信任这个”权威服务器“给的公钥,就去问其上级 TLD 服务器,TLD 服务器返回个叫 DS 的记录告诉客户端:”他是长这样的,你检查下,如果不匹配,就是个 Fake DNS。“

当然 TLD 返回的这条 DS 记录同样也要签名并加密,所以客户端同样需要再请求 TLD 服务器讨要公钥来解密。

问题又来了:客户端怎么能相信这个"TLD"就是真 TLD 呢(它提供的公钥是不是真的)?

答案是:”继续问他老子!“

TLD 的上层就是根服务器——那自然的一个问题就是:客户端如何能相信这个”根服务器“是真的呢?

根服务器没有上层了,自然不能再”问他老子“了——其实也不尽然,根服务器的老子就是人类啊。根区的公钥私钥对是在根区域签名仪式(Root Signing Ceremony)上由几个特定的人在严格的安保环境下生成并形成记录的——这里关键的关键就是那个私钥,是一定不能泄露到外面的,否则这个 DNSSEC 体系就如同废纸。生成完了将公钥公布于世,大家就都知道根区的公钥是 XYZ,谁也伪造不了了。

DNSSEC 出现时间晚于 DNS 本身(RFC2535 草案是 1999 年提的,是对 1997 年一版的修订案,而 DNS 在 20 世纪 80 年代就有了),另外这种信任链机制要求所有层次的 DNS 服务器都要严格实现这个验证机制(因为这种机制是用上级来验证下级的合法性,整个链条真正能够相信的只有根服,所以必须能够从最底层一直追溯到根),哪个环节没有做,就如同废纸了,所以至今并非所有 DNS 服务器都支持 DNSSEC(当然根服和绝大部分 TLD 服都支持),有些 DNS 服务商的 DNSSEC 功能是付费的,所以说,很多域名解析仍然是”裸奔“的。

(这里只说了大致流程,没有展示技术细节,感兴趣的可以去研究下 RFC2535Cloudflare 官网也有比较详细的介绍)

DNS 数据报分析:

讲了这么久还不知道 DNS 数据究竟长啥样有点过意不去,接下来我们就用 wireshark 抓个包玩玩(就是上面 dig www.baidu.com 那个的报文)。

打开 wireshark,选择相应的网卡进入抓包界面,过滤 dns 协议的数据。

先看下概览:

dns-17

从上往下按时间排列,一共 4 对问答(每对的 ID 相同,如 No.8,9 的 ID 是 0x8a60),编号 8、10、17、19 是请求包(问),9、16、18、20 是响应包(答)。

192.168.30.10 是我电脑的 IP,192.168.30.1 是我电脑的本地 DNS 服务器。

(注意:dig tace 的数据是 dig 自己向各层 DNS 服务器发请求,实际中是本地 DNS 服务器做这些事情。)

解析过程:

  1. No.8,9:本机向本地 DNS 服务器发送请求询问根 DNS 服务器信息,本地 DNS 服务器返回 13 台根服的域名和 IP。
  2. No.10,16:本机向 192.5.5.241 这台根服务器(f.root-servers.net.)询问 www.baidu.com 的 IP(A 记录)。根服务器返回了一组 NS 记录告诉本机要去这些 TLD 服务器解析域名。
  3. No.17,18:本机向 192.33.14.30 这台 TLD 服务器(b.gtld-servers.net.)询问 www.baidu.com 的 IP。该 TLD 服务器返回了一组 NS 记录告诉本机要去这些权威服务器解析域名。
  4. No.19,20:本机向 14.215.178.80 这台权威服务器(ns4.baidu.com)询问 www.baidu.com 的 IP。该权威服务器返回了一条 CNAME 记录,指向 www.a.shifen.com.。在实际 DNS 解析中,本地 DNS 服务器要继续上面的过程解析 www.a.shifen.com. 的 IP。

下面我们用 No.19,20 为例看看请求数据报和响应数据报的具体内容。

dns-18

这是四层网络结构,我们这里仅关注应用层里面的东西。

再贴下前那张概要图对比着看下:

dns-16

dns-19

Queries 之前的都是头部(一共 12 字节。另外因为这是个查询请求,body 部分没有”回答“和”权威“信息)。

展开看看各部分长啥样:

dns-20

应答包结构上和查询包基本一样,我们展开 No.20 应答包:

dns-21

上面是百度的权威 DNS 服务器给出了 CNAME 应答,而对于 TLD 服务器,它不会给出 CNAME 或 A 应答,只会给出 NS 应答,指示客户端去以下 DNS 继续解析。我们看看 No.18 的应答信息:

dns-22

上面的 Queries 部分都是都是指定想要 A 记录,其实客户端也可以指定想要其他类型记录(如 MX、CNAME 等)。

至此,DNS 基本讲得差不多了,下面我们讲讲一个基于 DNS 的应用:CDN。

CDN

CDN(Content Delivery Network)即内容分发网络,就是个大 Cache,把原本放在你公司服务器的内容(主要是静态内容)缓存到世界各地,让用户能够就近访问。

图片来自阿里云

如图所示,CDN 就是一个分层的缓存系统(这些 L1、L2 可类比我们平时开发用到的服务本地缓存、Redis 缓存,源站则相当于数据库系统),通过 DNS 调度策略为用户(客户机)提供一个离他最近的缓存服务器 IP,实现最快下载速度的同时减轻源站的压力。

我们现在关注的是如何让 DNS 返回一个离用户最近的 IP。

CNAME 解析:

前面说过,CNAME 解析是玩 CDN 的重要一步,你去各大 CDN 服务商(阿里云、腾讯云、七牛云等)开通 CDN 服务,他们都会为你生成一个加速域名,让你把你公司需要加速的域名 CNAME 解析到这个加速域名。

理论上,CNAME 解析并不是 CDN 的必要步骤,你完全可以直接使用服务商提供的那个 URL 嘛。但你想想,你得把网站所有地方的相关域名改成那个域名(而且如果这个域名有被外界用户或公司使用,外界也要改——这几乎不现实),而且(更要命的)后面如果你想换 CDN 服务商(如从阿里云换成腾讯云),你又得大动干戈去改代码里面的域名。

所以从现实来说,玩 CDN 的第一步就是将公司域名 CNAME 到 CDN 加速域名。

这里假设公司需要加速的源域名是 www.test.com,公司使用腾讯云的 CDN,腾讯云 CDN 提供的加速域名是 www.test.com.cdn.dnsv1.com。

调度 DNS 服务器:

我们同样 dig 以下看看 DNS 解析过程(从加速域名开始 dig):

# dig www.test.com.cdn.dnsv1.com +trace
......
dnsv1.com.		172800	IN	NS	ns3.dnsv5.com.
dnsv1.com.		172800	IN	NS	ns4.dnsv5.com.
......
www.test.com.cdn.dnsv1.com. 600	IN	CNAME	www.test.com.tweb.sched.ovscdns.com.
......

发现该域名被 CNAME 到 www.test.com.tweb.sched.ovscdns.com. 了,且从名字看跟调度(sched)有关,我们继续 dig:

# dig www.test.com.tweb.sched.ovscdns.com. +trace
......
ovscdns.com.		172800	IN	NS	ns1.ovscdns.com.
ovscdns.com.		172800	IN	NS	ns2.ovscdns.com.
ovscdns.com.		172800	IN	NS	ns3.ovscdns.com.
ovscdns.com.		172800	IN	NS	ns4.ovscdns.com.
......
www.test.com.tweb.sched.ovscdns.com. 60	IN A	43.132.83.43
www.test.com.tweb.sched.ovscdns.com. 60	IN A	101.33.27.53
www.test.com.tweb.sched.ovscdns.com. 60	IN A	43.132.83.42
www.test.com.tweb.sched.ovscdns.com. 60	IN A	43.132.83.41
www.test.com.tweb.sched.ovscdns.com. 60	IN A	101.33.27.45
......

终于找到 IP 了,返回了很多。

这里 ns1.ovscdns.com. 等 DNS 服务器就是调度服务器,它是在传统 DNS 服务器的基础上根据来源 IP 归属信息(哪个地区、哪个主干网)选择对应最近的 CDN 节点的 IP 返回给客户端以实现最近访问(当然我们上面是 dig 的,不是实际场景,里面返回的有日本的有新加坡的)。

核心原理就是这么简单:通过 CNAME 将原始域名解析到加速域名,而该加速域名的权威 DNS 服务器具有智能调度的能力(就是说这个加速域名并不是对应哪一台服务器的 IP,而是对应该服务商的整个 CDN 节点,可以被调度 DNS 服务器解析到任何一个结点)。

实际中会复杂很多,为了竞争,各 CDN 服务商的调度能力花样百出,远远不止仅通过来源 IP 调度这么简单,一般都会提供应用层调度(HttpDNS),可根据 Http 内容(如 url 参数、Header、path 内容执行调度)执行调度策略。

IPV6 和雪人计划

虽然说现在全球互联网的最高监管机构是 ICANN,然而 ICANN 总部在美国(而且虽然 ICANN 名义上不再受美国*监管,但权力交接仍在进行中),13 台根服务器有 10 台在美国,另外有两台分别在英国和日本——这两家跟美国的关系你我都懂。另外现在互联网大部分标准也是美国公司/机构制定的,在这种情况下,你敢相信美国*对互联网完全没有监管能力?

前车缺芯之鉴历历在目,说好的全球化大分工相互取长补短呢,人家说翻脸就翻脸,不但不让本国公司跟你玩,还逼着不让外国公司跟你玩,就问你怕不怕。

如果说中国担心美国哪天给中国来个大断网——这种担心并非杞人忧天。

(有人说这没关系啊,我们自己搭建个根服务器,中国所有 DNS 服务器都指向这个根不就行了吗?是可以,问题是这样的互联网只能在国内自嗨。有人可能觉得我们本来就是被墙在国内嘛,自嗨也没关系嘛——那是你我这种普通人的感觉,真正重要的东西你我感觉不到,中国的互联网不可能跟世界其他国家断开——根服务器必须是全球性的,一个世界只能有一个互联网。)

另外 IPv4 地址行将枯竭,IPv6 的推广势在必行,而且现在的根服以及 DNS 解析体系存在一些固有缺陷,这个档口给了后入局者一个机会。

中国是个大国,不仅是说地大人多,而是说这几年中国的互联网产业发展得相当迅速,大有赶超美国的势头,未来的目标是万物互联,那时候联网的就远不止电脑和手机了——现在 IP 快没了,人家不给你分配了,怎么办,都玩内网?一群 192.168 在那互通有无?

所以中国将 IPV6 的普及提高到了国家战略层面,印发了《推进互联网协议第六版(IPv6)规模部署行动计划》,提出了明确的阶段性推广指标(所以现在你看到很多网站页脚都有”某某某支持 IPv6“的字样,国家战略得支持啊)。

为啥 IPv6 就不怕地址枯竭啊,因为 IPv4 是 4 个字节,理论上最多能有 2^32 个地址,也即是不到 43 亿个地址。IPv6 是 16 个字节,理论上最多能有 2^128 个地址,这是个天文数字,可以给地球上每一粒沙子编址。

dns-24

4 字节的 IPv4

dns-25

16 字节的 IPv6

设想中国几经奋斗终于把 IPv6 普及开来了(这可不是一件简单的事情,涉及到大量基础设施的升级改造),全民欢天喜地,你看我们都在用 IPv6 了,多么先进,比漂亮国还先进——结果关键的解析服务还捏在人家手里,漂亮国一个不高兴,一发淫威,照样给你断了网,这谁能受得了?

所以光普及 IPv6 还不行,还得在域名解析权上摆脱美国的控制。

所以中国于 2015 年领衔发起了雪人计划(其他发起人还包括日本的 WIDE 机构——M 根服的运营机构、域名软件之父保罗·维克西等人),面向全球招募 25 个根服务器运营志愿单位,共同运营 IPv6 根服务器。

看看大咖们怎么说的:

"IPv4 MTU(最大传输单元)限制导致了现有13个根服务器的格局,“雪人计划”将在纯IPv6环境下建设,会尝试更多的可能和DNS协议的改动。"

—— 前欧洲网络中心IPv6主席、下一代互联网工程中心首席架构师肖恩·科尔

"互联网是由自治网络组成的,全球域名系统更需要自愿合作的精神,在全球互联网领域推行单边主义是行不通的,而且长期以来人们都认为现有13个根服务器就代表了一个命名系统,其实从技术角度更多的根服务器不会破坏现有的命名系统。”

—— 国际互联网名人堂入选者保罗·维克西博士 、“雪人计划”发起人之一

“这是我国争取根服务器管理权行动的有意义的切入点!美国*并不会真正放弃已在全球互联网事务中确立的优势地位,利用ICANN管理权变更和向IPv6过渡的机会,从根服务器组数量扩展入手,推动全球互联网管理迈向多边共治将是一个良好的开端。”

—— 中国工程院原副院长、院士,国家物联网标准化专家委员会组长邬贺铨

到 2016 年 25 个根服务器已经在 16 个国家架设完毕:

dns-26

资料来自百度百科

这 25 台中有 3 台主根(分别在中国、美国、日本),22 台辅根。从国家分布看比旧的 13 台要分散多了,终于不再一家独大了。

中国部署了 4 台,是所有国家中部署数量最多的,美国部了 3 台。