整个 DNS 具有复杂的层次,这对刚开始购买域名的人有很大的疑惑。本文将详尽的介绍 DNS 的工作原理,有助于更深刻的理解。本文将介绍:
在客户端上是如何解析一个域名的
在 DNS 缓存服务器上是如何逐级解析一个域名的
同时还包含:
域名的分类
什么是 Glue 记录
为什么 CNAME 不能设置在主域名上
先从本地的 DNS 开始讲起。
本地 DNS
本地的 DNS 相对于全球 DNS 要简单的多。所以先从本地 DNS 开始讲起。 127.0.0.1 常被用作环回 IP,也就可以作为本机用来访问自身的 IP 地址。通常,这个 IP 地址都对应着一个域名,叫 localhost。这是一个一级域名(也是顶级域名),所以和 com 同级。系统是如何实现将 localhost 对应到 127.0.0.1 的呢?其实就是通过 DNS。在操作系统中,通常存在一个 hosts 文件,这个文件定义了一组域名到 IP 的映射。常见的 hosts 文件内容如下:
1 2
127.0.0.1 localhost ::1 localhost
它就定义了 localhost 域名对应 127.0.0.1 这个 IP(第二行是 IPv6 地址)。这样,当你从浏览器里访问这个域名,或者是在终端中执行 Ping 的时候,会自动的查询这个 hosts 文件,就从文件中得到了这个 IP 地址。此外,hosts 文件还可以控制其他域名所对应的 IP 地址,并可以 override 其在全球 DNS 或本地网络 DNS 中的值。但是,hosts 文件只能控制本地的域名解析。hosts 文件出现的时候,还没有 DNS,但它可以说是 DNS 的前身。 如果需要在一个网络中,公用同一个 DNS,那么就需要使用 IP 数据包向某个服务器去获取 DNS 记录。 在一个网络里(此处主要指本地的网络,比如家庭里一个路由器下连接的所有设备和这个路由器组成的网络),会有很多主机。在与这些主机通信的时候,使用域名会更加的方便。通常,连接到同一个路由器的设备会被设置到路由器自己的一个 DNS 服务器上。这样,解析域名就不仅可以从 hosts 去获取,还可以从这个服务器上去获取。从另一个 IP 上去获取 DNS 记录通过 DNS 查询,DNS 查询通常基于 UDP 或者 TCP 这种 IP 数据包,来实现远程的查询。我的个人电脑的网络配置如下,这是在我的电脑连接了路由器之后自动就设置上的:
网络配置截图
重点是在路由器和搜索域上。 我的电脑的主机名(也是电脑名)设置的是 ze3kr,这个内容在连接路由器时也被路由器知道了,于是路由器就给我的主机分配了一个域名 ze3kr.local,local 这个一级域名专门供本地使用。在这个网络内所有主机通过访问 ze3kr.local 这个域名时,路由器(10.0.1.1)就会告知这个域名对应的 IP 地址,于是这些主机够获得到我的电脑的 IP 地址。至于搜索域的作用,其实是可以省去输入完整的域名,比如:
1 2 3 4 5 6
$ ping ze3kr PING ze3kr.local (10.0.1.201): 56 data bytes 64 bytes from 10.0.1.201: icmp_seq=0 ttl=64 time=0.053 ms --- ze3kr.local ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.053/0.053/0.053/0.000 ms
当设置了搜索域时,当你去解析 ze3kr 这个一级域名时,便会先尝试去解析 ze3kr.local,当发现 ze3kr.local 存在对应的解析时,便停止进一步解析,直接使用 ze3kr.local 的地址。 现在你已经了解了本地 DNS 的工作方式。DNS 的基本工作方式就是:获取域名对应 IP,然后与这个 IP 进行通信。 当在本地去获取一个完整域名(FQDN)时(执行 getaddrbyhost),通常也是通过路由器自己提供的 DNS 进行解析的。当路由器收到一个完整域名请求且没有缓存时,会继续向下一级缓存 DNS 服务器(例如运营商提供的,或者是组织提供的,如 8.8.8.8)查询,下一级缓存 DNS 服务器也没有缓存时,就会通过全球 DNS 进行查询。具体的查询方式,在 “全球 DNS” 中有所介绍。
总结
在本地,先读取本地缓存查找记录,再读取 Hosts 文件,然后在搜索域中查找域名,最后再向路由器请求 DNS 记录。
全球 DNS
在全球 DNS 中,一个完整域名通常包含多级,比如 example.com. 就是个二级域名, www.example.com. 就是个三级域名。通常我们常见到的域名都是完整的域名。
先从根域名开始,未命名根也可以作为 . 。你在接下来的部分所看到的很多域名都以 .结尾,以 .结尾的域名是特指的是根域名下的完整域名,然而不以 . 结尾的域名大都也是完整域名,实际使用时域名末尾的 .也常常省略。在本文中,我使用 dig 这一个常用的 DNS 软件来进行查询,我的电脑也已经连接到了互联网。 假设目前这个计算机能与互联网上的 IP 通信,但是完全没有 DNS 服务器。此时你需要知道根 DNS 服务器,以便自己获取某个域名的 IP 地址。根 DNS 服务器列表可以在这里下载到。文件内容如下:
$ dig @198.41.0.4 . any ;; QUESTION SECTION: ;. IN ANY ;; ANSWER SECTION: . 518400 IN NS a.root-servers.net. . 518400 IN NS b.root-servers.net. . 518400 IN NS c.root-servers.net. . 518400 IN NS d.root-servers.net. . 518400 IN NS e.root-servers.net. . 518400 IN NS f.root-servers.net. . 518400 IN NS g.root-servers.net. . 518400 IN NS h.root-servers.net. . 518400 IN NS i.root-servers.net. . 518400 IN NS j.root-servers.net. . 518400 IN NS k.root-servers.net. . 518400 IN NS l.root-servers.net. . 518400 IN NS m.root-servers.net. . 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2016122400 1800 900 604800 86400 ;; ADDITIONAL SECTION: a.root-servers.net. 518400 IN A 198.41.0.4 b.root-servers.net. 518400 IN A 192.228.79.201 c.root-servers.net. 518400 IN A 192.33.4.12 d.root-servers.net. 518400 IN A 199.7.91.13 e.root-servers.net. 518400 IN A 192.203.230.10 f.root-servers.net. 518400 IN A 192.5.5.241 g.root-servers.net. 518400 IN A 192.112.36.4 h.root-servers.net. 518400 IN A 198.97.190.53 i.root-servers.net. 518400 IN A 192.36.148.17 j.root-servers.net. 518400 IN A 192.58.128.30 k.root-servers.net. 518400 IN A 193.0.14.129 l.root-servers.net. 518400 IN A 199.7.83.42 m.root-servers.net. 518400 IN A 202.12.27.33 a.root-servers.net. 518400 IN AAAA 2001:503:ba3e::2:30 b.root-servers.net. 518400 IN AAAA 2001:500:84::b c.root-servers.net. 518400 IN AAAA 2001:500:2::c d.root-servers.net. 518400 IN AAAA 2001:500:2d::d e.root-servers.net. 518400 IN AAAA 2001:500:a8::e f.root-servers.net. 518400 IN AAAA 2001:500:2f::f g.root-servers.net. 518400 IN AAAA 2001:500:12::d0d h.root-servers.net. 518400 IN AAAA 2001:500:1::53 i.root-servers.net. 518400 IN AAAA 2001:7fe::53 j.root-servers.net. 518400 IN AAAA 2001:503:c27::2:30 k.root-servers.net. 518400 IN AAAA 2001:7fd::1 l.root-servers.net. 518400 IN AAAA 2001:500:9f::42 m.root-servers.net. 518400 IN AAAA 2001:dc3::35
其中,可以看到 TTL 与刚才文件中的内容不一样,此外还多了一个 SOA 记录,所以实际上是以这里的结果为准。这里还有一个 SOA 记录,SOA 记录是普遍存在的,具体请参考文档,在这里不做过多说明。
SOA 记录:指定有关 _DNS 区域_的权威性信息,包含主要名称服务器、域名管理员的电邮地址、域名的流水式编号、和几个有关刷新区域的定时器。(RFC 1035)
DNS 区域:对于根域名来说,DNS 区域就是空的,也就是说它负责这互联网下所有的域名。而对于我的网站,DNS 区域就是 guozeyu.com.,管理着 guozeyu.com. 本身及其子域名的记录。
此处的 ADDITIONAL SECTION 其实就包含了 Glue 记录。
一级域名
根域名自身的 DNS 服务器服务器除了被用于解析根自身之外,还用于解析所有在互联网上的一级域名。你会发现,几乎所有的 DNS 服务器,无论是否是根 DNS 服务器,都会解析其自身以及其下级域名。 从之前的解析结果中可以看出,根域名没有指定到任何 IP 地址,但是却给出了 NS 记录,于是我们就需要用这些 NS 记录来解析其下级的一级域名。下面,用所得到的根 NS 记录中的服务器其中之一来解析一个一级域名 com.。
$ dig @198.41.0.4 com any ;; QUESTION SECTION: ;com. IN ANY ;; AUTHORITY SECTION: com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. com. 172800 IN NS m.gtld-servers.net. ;; ADDITIONAL SECTION: a.gtld-servers.net. 172800 IN A 192.5.6.30 b.gtld-servers.net. 172800 IN A 192.33.14.30 c.gtld-servers.net. 172800 IN A 192.26.92.30 d.gtld-servers.net. 172800 IN A 192.31.80.30 e.gtld-servers.net. 172800 IN A 192.12.94.30 f.gtld-servers.net. 172800 IN A 192.35.51.30 g.gtld-servers.net. 172800 IN A 192.42.93.30 h.gtld-servers.net. 172800 IN A 192.54.112.30 i.gtld-servers.net. 172800 IN A 192.43.172.30 j.gtld-servers.net. 172800 IN A 192.48.79.30 k.gtld-servers.net. 172800 IN A 192.52.178.30 l.gtld-servers.net. 172800 IN A 192.41.162.30 m.gtld-servers.net. 172800 IN A 192.55.83.30 a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
$ dig @192.5.6.30 com any ;; QUESTION SECTION: ;com. IN ANY ;; ANSWER SECTION: com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1482571852 1800 900 604800 86400 com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS m.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. ;; ADDITIONAL SECTION: e.gtld-servers.net. 172800 IN A 192.12.94.30 m.gtld-servers.net. 172800 IN A 192.55.83.30 i.gtld-servers.net. 172800 IN A 192.43.172.30 k.gtld-servers.net. 172800 IN A 192.52.178.30 b.gtld-servers.net. 172800 IN A 192.33.14.30 b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 j.gtld-servers.net. 172800 IN A 192.48.79.30 a.gtld-servers.net. 172800 IN A 192.5.6.30 a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 d.gtld-servers.net. 172800 IN A 192.31.80.30 g.gtld-servers.net. 172800 IN A 192.42.93.30 c.gtld-servers.net. 172800 IN A 192.26.92.30 h.gtld-servers.net. 172800 IN A 192.54.112.30 f.gtld-servers.net. 172800 IN A 192.35.51.30 l.gtld-servers.net. 172800 IN A 192.41.162.30
也和根域名解析的情况类似,此时多了一个 SOA 类型的记录。
二级域名
和解析一级域名 com. 时类似,继续使用 com. 的域名服务器解析 guozeyu.com.。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$ dig @192.5.6.30 guozeyu.com any ;; QUESTION SECTION: ;guozeyu.com. IN ANY ;; AUTHORITY SECTION: guozeyu.com. 172800 IN NS a.ns.guozeyu.com. guozeyu.com. 172800 IN NS b.ns.guozeyu.com. guozeyu.com. 172800 IN NS c.ns.guozeyu.com. ;; ADDITIONAL SECTION: a.ns.guozeyu.com. 172800 IN AAAA 2001:4860:4802:38::6c a.ns.guozeyu.com. 172800 IN A 216.239.38.108 b.ns.guozeyu.com. 172800 IN AAAA 2001:4860:4802:36::6c b.ns.guozeyu.com. 172800 IN A 216.239.36.108 c.ns.guozeyu.com. 172800 IN AAAA 2001:4860:4802:34::6c c.ns.guozeyu.com. 172800 IN A 216.239.34.108
$ dig @216.239.38.108 guozeyu.com any ;; QUESTION SECTION: ;guozeyu.com. IN ANY ;; ANSWER SECTION: guozeyu.com. 21600 IN A 104.199.138.99 guozeyu.com. 172800 IN NS a.ns.guozeyu.com. guozeyu.com. 172800 IN NS b.ns.guozeyu.com. guozeyu.com. 172800 IN NS c.ns.guozeyu.com. guozeyu.com. 21600 IN SOA a.ns.guozeyu.com. support.tlo.xyz. 1 21600 3600 259200 300 guozeyu.com. 172800 IN MX 100 us2.mx1.mailhostbox.com. guozeyu.com. 172800 IN MX 100 us2.mx2.mailhostbox.com. guozeyu.com. 172800 IN MX 100 us2.mx3.mailhostbox.com. ;; ADDITIONAL SECTION: a.ns.guozeyu.com. 604800 IN A 216.239.38.108 a.ns.guozeyu.com. 604800 IN AAAA 2001:4860:4802:38::6c b.ns.guozeyu.com. 604800 IN A 216.239.36.108 b.ns.guozeyu.com. 604800 IN AAAA 2001:4860:4802:36::6c c.ns.guozeyu.com. 604800 IN A 216.239.34.108 c.ns.guozeyu.com. 604800 IN AAAA 2001:4860:4802:34::6c
可以发现增加了 A、SOA 和 MX 记录。
MX 记录:邮件交换记录,让发送到一个域名的邮件由其他的主机去接受,用于与 A 记录共存。(RFC 1035)
$ dig @216.239.38.108 www.guozeyu.com any ;; QUESTION SECTION: ;guozeyu.com. IN ANY ;; ANSWER SECTION: www.guozeyu.com. 172800 IN CNAME guozeyu.com. guozeyu.com. 21600 IN A 104.199.138.99 guozeyu.com. 172800 IN NS a.ns.guozeyu.com. guozeyu.com. 172800 IN NS b.ns.guozeyu.com. guozeyu.com. 172800 IN NS c.ns.guozeyu.com. guozeyu.com. 21600 IN SOA a.ns.guozeyu.com. support.tlo.xyz. 1 21600 3600 259200 300 guozeyu.com. 172800 IN MX 100 us2.mx1.mailhostbox.com. guozeyu.com. 172800 IN MX 100 us2.mx2.mailhostbox.com. guozeyu.com. 172800 IN MX 100 us2.mx3.mailhostbox.com. ;; ADDITIONAL SECTION: a.ns.guozeyu.com. 604800 IN A 216.239.38.108 a.ns.guozeyu.com. 604800 IN AAAA 2001:4860:4802:38::6c b.ns.guozeyu.com. 604800 IN A 216.239.36.108 b.ns.guozeyu.com. 604800 IN AAAA 2001:4860:4802:36::6c c.ns.guozeyu.com. 604800 IN A 216.239.34.108 c.ns.guozeyu.com. 604800 IN AAAA 2001:4860:4802:34::6c
可以看到,使用 host 命令获得 IP 地址的域名与使用 dig 获取的相同,均为 99.138.199.104.bc.googleusercontent.com. 。可以看出,这个 IP 是属于 Google 的。此外,需要注意的是 in-addr.arpa. 下的字域名正好与原 IPv4 地址排列相反。 这个记录通常可以由 IP 的所有者进行设置。然而,IP 的所有者可以将这项记录设置为任何域名,包括别人的域名。所以通过这种方法所判断其属于 Google 并不准确,所以,我们还需要对其验证:
1 2
$ dig 99.138.199.104.bc.googleusercontent.com a +short 104.199.138.99
$ dig 138.199.104.in-addr.arpa. any ;; QUESTION SECTION: ;138.199.104.in-addr.arpa. IN ANY ;; ANSWER SECTION: 138.199.104.in-addr.arpa. 21583 IN NS ns-gce-public1.googledomains.com. 138.199.104.in-addr.arpa. 21583 IN NS ns-gce-public2.googledomains.com. 138.199.104.in-addr.arpa. 21583 IN NS ns-gce-public3.googledomains.com. 138.199.104.in-addr.arpa. 21583 IN NS ns-gce-public4.googledomains.com. 138.199.104.in-addr.arpa. 21583 IN SOA ns-gce-public1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300
可以看到,上一级 138.199.104.in-addr.arpa. 下配置了 Google 的域名服务器,所以 104.199.138.0/24(104.196.123.0 - 104.196.123.255)都是属于 Google 的。然而,既然这个域名下的域名服务器可以设置为 Google 自己的,所以这个域名下就可以设置任何记录,不只是 PTR,所以也可以添加 A 记录把 arpa 域名当作网站! 我虽然没有那么大块的 IPv4 地址,但是我有这个 IPv6 地址:2001:470:f913::/48 并且能够设置在 arpa. 下的 NS 记录。这个 /48 的 IPv6 地址对应着 arpa. 反向解析的完整域名是 3.1.9.f.0.7.4.0.1.0.0.2.ip6.arpa. ,可以看到 IPv6 的反向解析在另一个二级域名 ip6.arpa. 下,此外其地址是将 IPv6 的每一个十六进制为拆开为一个字域并反向排列的。 我已把这个地址设置为了我自己可以控制的 NS,然后配置了 A 记录,瞬间这个反向解析域名就可以当作正常的解析使用了!