最近,新接触到了hexo这个博客工具,并利用它搭建了基于git hub pages静态页面的个人博客站,绑定了自己的域名,在绑定域名这个环节,逐步学习并理解了域名解析这个过程,想到之前有个有趣的面试题就是“当你在浏览器地址栏中输入一个网址,并按下回车键后,发生了什么”,于是就想把此记录下。
DNS基础知识
DNS(domain name system)
- 从概念上来说,Internet被分成200多个顶级域,每个域名有多个主机。顶级域有两种:
通用域
和国家域
。 - 域名不区分大小写
资源记录
每个域都可以有一组与它相关联的资源记录。对于一台主机来说,最常见的资源记录就是他的IP地址,但除此之外,还存在许多其他种类的资源记录。因此DNS的基本功能是将域名映射到资源记录上
。
资源记录是一个五元组,使用如下格式:
1 | Domain_name(域名) Time_to_live(生存周期) Class(类别) Type(类型) Value(值) |
Type(类型)指出了这是什么类型的记录。
类型 | 含义 | 值 |
---|---|---|
SOA | 授权的开始 | 本区域的参数 |
A | 一台主机的IP地址 | 32位整数 |
MX | 邮件交换 | 优先级,希望接受该域电子邮件的机器 |
NS | 名字服务器 | 本域的服务器名称 |
CNAME | 规范名 | 域名 |
PTR | 指针 | 一个IP地址的别名 |
HINFO | 主机的描述 | 用ASCII表示的CPU和操作系统 |
TXT | 文本 | 未解释的ASCII文本 |
- 最重要的是A(Address,地址)记录,他包含了某一台主机的32位IP地址,每台Internet主机必须有一个IP地址,以便其他机器能与他进行通信。
- 其次最重要的记录类型是MX记录,他也指定一台主机的名字,该主机将为这个特定的域接受电子邮件。之所以使用MX记录,是因为并非每台机器都做好了接受电子邮件的准备。
- NS记录指定名字服务器。
- CNAME记录允许创建别名。例如,如果一个人很熟悉Internet的常规命名规则,他打算给MIT计算机科学西的一个人发送一个消息,而且他只知道此人的登录名为paul,那么,他可能猜测此人的邮件地址是paul@cs.mit.edu。事实上这个地址并不正常,因为MIT计算机科学系的域是lcs.mit.edu。但是,MIT可以创建一条CNAME记录,以便为那些不知情的人和程序指引到正确的方向上,这也算是为他们提供一项服务吧。
- 与CNAME一样,PTR也指向了另一个名字。但是CNAME只是一个宏定义,而PTR与CNAME不同,它是一种正规的DNS数据类型,他的确切含义要取决于他所在的上下文。在实践中,PTR几乎总是被用来将一个名字与一个IP地址关联起来,以便能够查找IP地址并返回对应机器的名字,这种功能被称为反向查找(reverse lookups)
- HINFO 记录允许人们找到一个域对应于哪种操作机器和操作系统。
- TXT 记录,每个域可以按照任意的方式来标识自己。
- Value域,他的值可以是数字,域名或者ASCII字符串,其语义取决于记录的类型。
DNS域名称类型
名称类型 | 说明 | 示例 |
---|---|---|
根域(Root domain) | 这是表示未命名的等级; 目录树的顶部它有时显示为两个空引号 (“”),表示空值。 DNS 域名中使用时,它规定由尾部句点 (.) 来指定名称位于根或更高级别的域层次结构。 在此情况下,DNS 域名被认为是完整和点到准确的位置在树中的名称。 | 单个句点 (.) 或句点用于末尾的名称,如”example.microsoft.com” |
顶级域(Top-level domain) | 用来指示某个国家/地区或组织使用的名称的类型名称。 | “”.com”,表示一个名称注册为在 Internet 上的商业使用的业务。 |
二级域(Second-level domain) | 可变长度的个体或组织,以便在 Internet 上使用的注册名称。 这些名称始终基于相应的顶级域,具体取决于组织或地理位置名称使用的位置的类型。 | “”microsoft.com。 “,这是由 Internet DNS 域的名称注册向 Microsoft 注册的二级域名称。 |
子域(Subdomain) | 其他名称的组织可以创建从已注册的二级域名派生的。 这些功能包括添加到组织中的名称的 DNS 树的增长,并将其分为部门或地理位置的名称。 | “example.microsoft.com”。 “,这是由 Microsoft 指定文档名称示例中用于虚构子域。 |
主机或资源名称(Host or resource name) | 代表名称的 DNS 树的叶节点并标识特定的资源的名称。 通常情况下,DNS 域名的最左侧的标签标识网络上的特定计算机。 例如,如果主机 (A) 资源记录中使用此级别的名称,则它用于查找基于其主机名的计算机的 IP 地址。 | “”主机-a.example.microsoft.com。”,其中第一个标签 (”主机-a”) 是网络上的特定计算机的 DNS 主机名。 |
域名解析
域名解析过程
- 浏览器缓存:浏览器会首先检查缓存中有没有该域名的缓存记录,如果有,解析过程结束,如果没有,继续下一步。浏览器会缓存DNS记录一段时间,时间,大小等通过TTL设置。
- 系统缓存:在浏览器缓存里没有找到记录,浏览器会做一个系统调用,查找系统缓存里是否有DNS记录。Windows系统中可以通过
C:\Windows\System32\drivers\etc\hosts
文件来设置,linux上配置文件是/etc/named.conf
。 - 路由器缓存:如果本地系统缓存也未找到,前面的查询请求发向路由器,路由器也会有自己的DNS缓存记录。
- ISP DNS缓存:接下来要检查的就是网络服务提供商缓存DNS的服务器,在这一般都能找到相应的缓存记录。ISP专门的域名解析服务器(LDNS)一般都会缓存域名解析记录,缓存时间受域名的失效时间控制,大约80%的域名解析到这里就已经完成了,所以,LDNS主要承担了域名的解析工作。
- 递归搜索:从根域名服务器开始进行递归搜索,到顶级域名服务器,再到第二层域服务器。
域名解析示意图
前面浏览器缓存,系统缓存及路由器缓存都是在本地完成的,所以,图中所示是从本地区的域名服务器LDNS开始的。
我们在网络配置中,都会有一个“DNS服务器地址”这一项,这个地址就是本地区域名服务器LDNS。这个DNS服务器通常是由提供给你网络服务的提供商提供,如联通或电信等。
如图中第三步,用户发起请求向LDNS查询,LDNS会查询其服务器上的缓存记录,如果有,返回,没有,继续。
如果LDNS没有查找到缓存记录,就直接到Root Server域名服务器请求解析。
根域名服务器返回给本地域名服务器一个所查询的主域名服务器(gTLD Server)地址,gTLD是国际顶级域名服务器,如.com,.cn,.org等,全球只有13台根域名服务器。
LDNS再向上一步返回的gTLD服务器发送请求。gTLD服务器查找并返回此域名对应的Name Server域名服务器的地址。
Name Server域名服务器会查询存储的域名和IP映射关系表,将ip连同一个TTL值返回给LDNS域名服务器
LDNS域名服务器会缓存这个域名和ip的对应关系,并将结果返回给用户。
用户本地根据TTL值缓存在本地系统中。
在实际DNS解析过程中,Name Server也可能有很多级,或者有一个GTM负载均衡控制,这都有可能会影响到域名解析过程。
hexo绑定域名过程
阿里云DNS解析
在阿里云解析域名的时候还遇到了小问题呢,一一记录下,也算是学习过程吧。
CNAME的@记录和MX的@记录不能共存
由于我的域名coolcao.com开通的时候,自动开通了企业邮箱,因此,在域名解析那里,阿里云自动生成了几条和邮件相关的解析记录,如下图:
从上图中可以看出,由于开通了企业邮箱,默认开启5条记录,两条不同优先级的MX记录,三条CNAME记录,当我添加解析到我的github pages的记录时报错了:
点开冲突记录规则,有如下规则:
也就是说,MX记录和CNAME在主机记录为 @
时不能共存,那该怎么办,企业邮箱和www站不能同时解析拥有么?
当然不是,经过上网查找资料,大致有下面两个办法:
- 采用Link类型解析
首先添加一条CNAME类型的www记录,解析到github pages地址。
然后再添加一条Link类型的@解析,这里解析到带www的完整地址,这里我的是:www.coolcao.com
但这里有个要求,是域名必须要经过备案,即coolcao.com
要必须备案,才能添加。由于我的还未备案,无从验证实验结果。如果有备案的,可以验证一下是否有效。 - 采用A类型解析
我的域名没有备案,因此用不了Link类型,可以采用A类型解析。
首先使用ping命令看一下自己的github pages的IP是多少。我这里查到的是:151.101.100.133
,因此添加如下记录:
同时添加一条CNAME类型的www解析,这样,可以通过coolcao.com
或www.coolcao.com
都能访问到我的小站。
但这种方式也有个问题,如果github的IP地址变化了的话,得需要再改变A记录的值,可以说是一种不稳定的因素吧。但是域名没备案,没办法的办法。
github pages项目下为什么还要添加CNAME文件
最开始,在设置未开通邮箱服务的愉快绑定时,很简单,直接添加了两条CNAME记录,一条@
,一条www
两条均解析到了coolcao.github.io
那时候还一直在想,为什么要在项目里添加CNAME文件呢?
我直接访问coolcao.github.io
直接访问到我的github pages主页,那么,我将我的域名coolcao.com
通过CNAME解析到coolcao.github.io
不就可以了么,但是结果却是,github提示找不到页面。
当资料整理到这里,我才慢慢理解了原因:
所有的DNS解析最终都是将域名解析成IP,如果直接使用A记录直接解析到github的ip的话,在github上有成千上万的pages项目,那么,当你输入coolcao.com
时,github怎么知道你的项目在哪里呢?这就是项目里CNAME文件的用处,把你的域名和项目进行绑定,当你访问coolcao.com
,DNS解析到github的IP时,由于请求头中会带有coolcao.com
,github通过CNAME的绑定,查询到了你具体的项目,才能正确找到你的项目。