前段时间theerrorlog.com和我的另一个域名在国内的解析速度开始变慢,后来甚至 到了完全解析不了的状态,而翻墙之后却一点问题都没有;上网一搜发现可能是 Godaddy的name server被墙了,于是找了个月黑风高的夜里把域名全都转移到 DNSPod去解析。效果么?和原来的速度比起来,简直快得丧心病狂啊……
转移教程到处都有而且操作很简单,问题是name server是个神马?为什么会对域名 解析有这么大影响?我也不知道,于是找来RFC、manpage还有奇怪小网 页若干,研究了一遍。
DNS简介
DNS的全称是Domain Name System,有时候也会被解释为 Domain Name Server;这里我们只用第一种含义,第二种含义其实和 “Name Server”是一个意思。
从最高的抽象级别来介绍DNS的话,只用一句话就够了:DNS是一个分布式键-值对数 据库。没错就是Redis和Riak那类东西,只不过DNS拥有无与伦比的冗余 性和世界级的分布。
不过光这样说的话是略坑爹啦,所以我们从这个抽象往下走一层,看看这个系统里 的两个要素:数据结构和算法。
DNS处理的数据
DNS包括两种数据:名字(“name”)和名字所映射的资源(“resource”)。这里的 “名字”就是我们平常说的域名,但是“资源”却不一定是IP. DNS的常用资源类型有 这些:
- A: 主机地址,一般就是主机的IP
- NS: 负责解析域名的Name Server,必须是域名
- CNAME: 别名指向的另一个域名
- MX: 邮件服务器的域名
- TXT: 任意字符串
可见资源的内容可以是IP、域名甚至任意字符串。而名字到资源的映射被RFC定义 为一对多的关系,也就是说一个域名可以用来指向4个IP、5个name server、6个 邮件服务器,等等。
DNS数据的存储和查找
既然是数据库,首要任务自然就是存储和查找数据了。
和许多分布式数据库一样,DNS根据键值——也就是域名——来决定数据的存储位置。 鉴于这是个动态的过程,我们也用DNS调试神器nslookup动态一把好了。
首先运行nslookup命令,进入debug模式,并禁止递归解析:
1 2 3 4 |
|
假设我想知道blog.theerrorlog.com对应的IP地址,于是我向系统的默认 name server(通常就称为DNS)发去请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
nslookup的输出标注了当前使用的name server是192.168.2.1,这是我 的TP-LINK路由器的地址,它会把发给它的DNS查询直接forward给电信的 name server——别问我怎么知道的——所以这里相当于是直接在问电信的 server这个域名的地址在哪里。
结果电信那边给的回复是——他们不知道,因为这个域名不是由他们管理 的,但是可以去问AUTHORITY RECORDS里面那些服务器,因为那些服务器 是负责管理.com域名的。
ADDITIONAL RECORDS那边还很贴心地附带了.com name server的IP地址, 既然有人说它们有线索,我们就直接向这些IP继续发请求看看吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
很可惜这台服务器回复说虽然它是管.com的,但是下一级的theerrorlog.com 不归它管,不过它知道是谁在管……“有关部门”既视感有没有?
没办法我们继续找下一级服务器问问看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
呕耶~终于有人肯告诉我们了泪流满面啊……只不过这里的答案是说, blog.theerrorlog.com只有CNAME记录,指向l04m33.github.io. 虽然还没 找到IP但是就此打住吧,因为接下去的过程其实大同小异,就是到处去找 负责域名管理的name server问问看。
现实世界的DNS存储和查找
上面介绍的查找过程基本上八九不离十啦,不过细心的同学应该有留意到,
我们在一开始用set norecursive
将递归解析禁用掉了,这是为什么呢?
你可以试试set recursive
再向电信(或者其他ISP)的name server查一
下域名,会发现马上就能得到结果;如果你打开Wireshark抓一下包,也只
能看见一个查询包和一个回复包。
这说明在递归解析模式下,ISP的name server帮你把上面我们用nslookup 手动做的许多次查询都做掉了,然后直接给了你结果。
实际上,网上的name server可以分为两种:一种是负责具体域名信息存储 的,只解析自己负责管理的域名信息,此外的信息一概回答“不知道”, DNSPod和Godaddy提供的name server就属于这种,其上存储的是域名信息 的“真身”,所以被称为“权威服务器”(Authoritative Servers);另一种是 负责查询和缓存域名信息的,通常这种name server并不参与域名信息管理, 当有客户端过来查询的时候——不管查的是什么域名——如果它们的缓存里有 未过期的对应信息,就会马上返回,反之如果没有,则会向其他权威服务器 查询,直到找到或者确认找不到为止,像OpenDNS、Google的8.8.8.8,还有 各大ISP自己提供的name server,都属于这种类型,它们会进行递归解析, 所以被称为“递归服务器”(Recursive Servers)。
通常管理一个域名的权威服务器会有不止一台,它们之间会互相同步并且 互为备份,再加上各种离线备份和分布在世界各地的递归服务器上的缓存, DNS应该是冗余度最高的分布式系统之一了吧,除了世界末日应该没有什么 自然灾害能完全摧毁这货了;但是DNS系统内成千上万台机器都在默默地同 步其他机器,这也导致在其自身内部出现的错误会很快被扩散开来……果然 无论多牛逼的家伙,最大的敌人都是自己呀XD.