从搭建hexo个人博客过程中理解学习DNS解析

最近,新接触到了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主要承担了域名的解析工作。
  • 递归搜索:从根域名服务器开始进行递归搜索,到顶级域名服务器,再到第二层域服务器。

DNS递归查找

域名解析示意图

域名解析

前面浏览器缓存,系统缓存及路由器缓存都是在本地完成的,所以,图中所示是从本地区的域名服务器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负载均衡控制,这都有可能会影响到域名解析过程。

域名解析示意图
解析 www.163.com示例

hexo绑定域名过程

阿里云DNS解析

在阿里云解析域名的时候还遇到了小问题呢,一一记录下,也算是学习过程吧。

CNAME的@记录和MX的@记录不能共存

由于我的域名coolcao.com开通的时候,自动开通了企业邮箱,因此,在域名解析那里,阿里云自动生成了几条和邮件相关的解析记录,如下图:
阿里云域名解析
从上图中可以看出,由于开通了企业邮箱,默认开启5条记录,两条不同优先级的MX记录,三条CNAME记录,当我添加解析到我的github pages的记录时报错了:
MX和CNAME冲突
点开冲突记录规则,有如下规则:
冲突记录规则
也就是说,MX记录和CNAME在主机记录为 @时不能共存,那该怎么办,企业邮箱和www站不能同时解析拥有么?
当然不是,经过上网查找资料,大致有下面两个办法:

  • 采用Link类型解析
    首先添加一条CNAME类型的www记录,解析到github pages地址。
    www解析
    然后再添加一条Link类型的@解析,这里解析到带www的完整地址,这里我的是:www.coolcao.com
    但这里有个要求,是域名必须要经过备案,即coolcao.com要必须备案,才能添加。由于我的还未备案,无从验证实验结果。如果有备案的,可以验证一下是否有效。
  • 采用A类型解析
    我的域名没有备案,因此用不了Link类型,可以采用A类型解析。
    首先使用ping命令看一下自己的github pages的IP是多少。我这里查到的是:151.101.100.133,因此添加如下记录:
    A记录解析
    同时添加一条CNAME类型的www解析,这样,可以通过coolcao.comwww.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的绑定,查询到了你具体的项目,才能正确找到你的项目。