网域名称系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。
它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。
DNS使用TCP和UDP端口53。当前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。
DNS最早于1983年由保罗·莫卡派乔斯(Paul Mockapetris)发明;原始的技术规范在882号因特网标准草案(RFC 882)中发布。1987年发布的第1034和1035号草案修正了DNS技术规范,并废除了之前的第882和883号草案。在此之后对因特网标准草案的修改基本上没有涉及到DNS技术规范部分的改动。
早期的域名必须以英文句号“.”结尾,当用户访问www.maxiecloud.com
的HTTP服务时必须在地址栏中输入:http://www.maxiecloud.com.
,这样DNS才能够进行域名解析。如今DNS服务器已经可以自动补上结尾的句号。
DNS:Domain Name Service 域名解析服务
DNS服务是一个基于C/S架构的协议,在传输层的TCP和UDP协议的53号端口上运行。
TCP协议: Transmission Control Protocol
TCP是面向连接的协议:双方通信之前需要事先建立虚拟连接;
UDP协议: User Datagram Protocol
UDP是无连接的协议:双方通信之前无需建立虚拟连接;
简单的来说:
|
|
域名空间
域名系统作为一个层次结构和分布式数据库,包含各种类型的数据,包括主机名和域名。DNS数据库中的名称形成一个分层树状结构称为域命名空间。域名包含单个标签分隔点,例如:blog.maxiecloud.com
对于Internet来说,域名层次结构的顶级由ICANN(互联网名称与数字地址分配机构)负责管理。目前,已经有超过250个顶级域名,每个顶级域名可以进一步划为一些子域(二级域名),这些子域可被再次划分(三级域名),依此类推。所有这些域名可以组织成一棵树,如下图所示:
域名资源记录
DNS设计之初是用来建立域名到IP地址的映射,理论上对于每一个域名我们只需要在域名服务器上保存一条记录即可。这里的记录一般叫作域名资源记录,它是一个五元组,可以用以下格式表示:
|
|
其中,常见的记录类型TYPE包括:
记录类型 | 含义 |
---|---|
SOA:(StartOf Authority,起始授权记录) | 一个区域解析库有且只能有一个SOA记录,而且必须放在第一条 |
A记录(Address,主机记录) | 用于名称解析的重要记录,将特定的主机名映射到对应主机的IP地址上 |
CNAME记录(Canonical Name,别名记录) | 用于 返回另一个域名,即当前查询的域名是另一个域名的跳转,主要用于域名的内部跳转,为服务器配置提供灵活性 |
NS记录(Name Service,域名服务器记录) | 用于返回保存下一级域名信息的服务器地址。该记录只能设置为域名,不能设置为IP地址 |
PTR记录(Pointer,指针记录) | PTR记录是A记录的逆向记录,又称做IP反查记录或指针记录,负责将IP反向解析为域名 |
MX(Mall eXchanger,邮件记录) | 用于返回接收电子邮件的服务器地址 |
IPv6主机记录(AAAA记录) | 与A记录对应,用于将特定的主机名映射到一个主机的IPv6地址。 |
域名服务器
域名服务器用于响应DNS查询,由不同层级的域名服务器协同完成。下面讲解下如何将所有的域名资源记录存储到不同的域名服务器上。前面说过域名空间可以组织为一棵树,这里我们可以进一步将其划分为不重叠的区域(DNS zone),针对上图的域名空间,一种可能的域名划分如下图:
然后将每个区域的域名服务器(当然每个DNS zone内应该是由集群组成,包括master,和slave服务器用来提供数据备份、加快解析速度、保证服务可用性)关联起来,称这些域名服务器为该区域的权威域名服务器(Authoritative Name Servers ),它保存两类域名资源记录:
- 该区域内所有域名的域名资源记录。
- 父区域和子区域的域名服务器对应的域名资源记录(主要是NS记录)。
这样,所有的域名资源记录都保存在多个域名服务器中,并且所有的域名服务器也组成了一个层次的索引结构,便于域名解析。下面以一个简化的域名空间为例子,说明域名资源记录是如何保存在域名服务器中的,如下图:
图中域名空间划分为A, B, C, D, E, F, G七个DNS区域,每个DNS区域都有多个权威域名服务器(作为一个集群),这些域名服务器里面保存了许多域名解析记录。对于上图的DNS区域E来说,它的权威域名服务器里面保存的记录如图中表格所示。
仔细观察上图会发现区域A、B并没有父区域,他们之间并没有一条路径连在一起。这将导致一个很麻烦的问题,那就是区域A的权威域名服务器可能根本不知道区域B的存在。认识到这一点后,可能会想到的一个很自然的解决方案,就是在A中记录B域名服务器的地址,同时在B中记录A的,这样它们两个就联系起来了。但是考虑到有超过250个顶级域名,这样做并不是很恰当。
域名系统则采用了一种更加聪明的方法,那就是引入根域名服务器,它保存了所有顶级区域的权威域名服务器记录。现在通过根域名服务器,我们可以找到所有的顶级区域的权威域名服务器,然后就可以往下一级一级找下去了。根域名服务器(root name server)是DNS中最高级别的域名服务器,负责返回顶级域名的权威域名服务器的地址,全球13组根域名服务器以英文字母A到M依序命名,网域名称格式为“字母.root-servers.net”。其中有11个是以任播技术在全球多个地点设立镜像站。。更多关于根域名服务器的内容,可以参考:根域名服务器-维基百科
现在为止,域名服务器和根域名服务器其实组成了一个树,树根为根域名服务器,下面每个节点都是一个区域的权威域名服务器,对于上图中各个DNS区域的权威域名服务器,它们组成了下面这棵树(事实上,一个权威域名服务器可能保存有多个DNS区域的记录,因此权威域名服务器之间的联系并不构成一棵树。为了容易理解,将其简化为一棵树):
域名解析
Local DNS(本地域名服务器):本地由网络服务提供商(ISP)分配的DNS(一般为两个),或自行设置的公共DNS。
当需要查询一个域名对应的IP地址时,在检查完本地hosts文件、操作系统DNS缓存后,会向本地域名服务器(LDNS)发起请求,如果该域名恰好在Local DNS所辖属的域名区域(DNS zone)内,那么可以直接返回记录。
如果LDNS没有发现该域名的资源记录,就需要在整个域名空间搜索该域名。而整个域名空间的资源记录存储在一个分层的、树状联系的一系列域名服务器上,所以本地域名服务器首先要从根域名服务器开始往下搜索。这里有一个问题就是本地域名服务器如何找到根域名服务器在哪里呢?其实域名服务器启动的时候,就会加载一个配置文件,里面保存了根域名服务器的NS记录(因为根域名服务器地址一般非常稳定,不会轻易改变,并且数量很少,所以这样配置文件会很小)。找到根域名服务器之后,就可以一级一级地往下查找。
假设访问www.google.com ,则请求过程大致如下:
在浏览器中输入www.google.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
如果hosts与本地操作系统缓存都没有相应的网址映射关系,则向本地设置的Local DNS服务器发起域名解析请求。LDNS收到查询后,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
如果要查询的域名,不由Local DNS服务器区域解析,但该服务器已缓存了此网址映射关系,且缓存未过期,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
如果该域名不在Local DNS所辖属的域名区域(DNS zone)内,且没有有效缓存,则根据Local DNS的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的NS地址及其对应IP。本地DNS服务器收到IP信息后,将会请求.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,便将.com域的下一级DNS服务器地址(qq.com)给的NS地址及其IP响应给Local DNS。当Local DNS收到这个地址后,再向qq.com域服务器,重复上面查询,直至找到www.qq.com主机对应的记录。
如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,则请求根DNS或把转请求转至上上级,以此循环。不管是Local DNS用的是转发,还是向根DNS请求,最终都能获得查询结果,然后再返回给最初查询的客户端。
缓存
由于绝大部分的DNS请求都集中在少部分的域名。因此可以将已经访问过域名的解析结果缓存在本地,下次访问的时候可以直接读取结果,不用再次重复DNS查询过程,客户端和域名服务器都节省了麻烦。
当然,这样做的一个前提是要缓存的解析结果不能频繁更改。绝大多数的域名解析确实是这样基本固定不变的。但是难免有一些“善变”的域名,他们可能会频繁更改自己的解析结果。为了使缓存机制适应这两类情况,在域名资源记录里面添加一个Time_to_live字段,表明这条记录最多可以缓存多久。对于那些解析基本不变的域名,给一个比较大的值,而那些需要经常变动解析的域名,则可以给定一个小的值。
同样,域名服务器会将那些查询过的域名资源记录缓存下来,再次收到来自客户端的请求时,只要缓存不过期,就可以直接返回缓存结果,不用再次向上查询。
端口号
DNS协议使用udp/tcp的53端口提供服务,客户端向DNS服务发起请求时,使用udp的53端口;DNS服务器间(包括主从之间)进行区域传送的时候使用TCP的53端口。
DNS服务器类型
主DNS服务器:为客户端提供域名解析的主要区域,主DNS服务器宕机,会启用从DNS服务器提供服务。
从DNS服务器:主服务器DNS长期无应答,从服务器也会停止提供服务。主从区域之间的同步采用周期性检查+通知的机制,从服务器周期性的检查主服务器上的记录情况,一旦发现修改就会同步,另外主服务器上如果有数据被修改了,会立即通知从服务器更新记录。
缓存服务器:服务器本身不提供解析区域,只提供非权威应答。
- 转发服务器:当DNS服务器的解析区域(包括缓存)中无法为当前的请求提供权威应答时,将请求转发至其它的DNS服务器,此时本地DNS服务器就是转发服务器。
区域数据库 记录类型详解
资源记录的定义格式:
|
|
SOA:一个区域的第一条资源记录:
|
|
实例:
|
|
NS:域名服务记录,一个区域解析库可以有多个NS记录
|
|
实例:
|
|
A:地址记录,FQDN –> IPv4
|
|
实例:
|
|
AAAA:IPv6地址记录,FQDN –> IPv6
|
|
PTR:指针记录,反向解析,IP –> FQDN
|
|
实例:
|
|
CNAME:别名记录
|
|
实例:
|
|
注意:
(1) TTL可以从全局继承
(2) @可以表示当前区域的名称 –> maxiecloud.com
(3) 相邻的两条记录其name相同时,后面的可省略
(4) 对于正向区域来说,各MX,NS等类型的记录的value为FQDN,此FQDN应该有一个A记录
前面我们介绍了DNS的一些基础概念和进阶的知识,但是DNS
是一种模型,需要使用软件去实现。
Bind(Berkeley Internet Name Domain)就是伴随DNS
出生的软件。
Bind程序包
|
|
Bind配置文件
主配置文件: /etc/named.conf
其他配置文件
解析库文件:/var/named/
目录下;一般名字为:ZONE_NAME.zone
注意:
(1) 一台DNS服务器可同时为多个区域提供解析;
(2) 必须要有根区域解析库文件:named.ca
(3) 还应该有两个区域解析库文件:localhost和127.0.0.1的正反向解析库
配置一个正向解析区域
修改主配置文件 /etc/named.conf
把主配置文件中 options
中的监听端口和dnssec功能修改了:
|
|
主要修改的是:
- listen-on port 53 { 127.0.0.1;172.16.1.51; }; 在127.0.0.1后添加一条监听本机网卡IP地址的信息
- allow-query { any; }; 把这里的允许查询的范围改为
any
- dnssec-enable no; dnssec-validation no; 这两个防火墙功能设置为
no
,也就是关闭其功能
定义一个zone
|
|
创建区域解析库文件
|
|
检查、启动并测试DNS服务
|
|
解析域名
|
|
配置一个反向解析区域
定义一个zone
|
|
创建区域反向解析库文件
|
|
检查、启动并测试DNS服务
|
|
测试
|
|
主从配置
在两台或多台Linux主机上进行实验或操作时,最先要做的是时间同步
|
|
如果时间不同步,后面出现的问题就不是几分钟能解决的了。
在上面的实验中,我们已经配置好了一台具有DNS解析功能的服务器了,我们就把那一台当做主服务器,下面我们开始配置从服务器:
从节点的配置:安装bind以及修改配置文件
|
|
定义一个从区域
|
|
开启服务并测试
|
|
子域授权
现在我们开始配置子域授权,我们在主DNS服务器上进行授权
在maxiecloud.zone
中添加如下信息:
|
|
在子域DNS服务器上配置
安装bind并修改配置文件信息:
|
|
在/etc/named.rfs1912.zones中添加子域的信息:
|
|
定义子域解析库:
|
|
测试:
|
|
但是我们可能会发现一个问题,如果我需要解析父域中的主机名,只能通过递归到根域去解析,这是非常不便的,所以我们要设置转发器。
设置区域转发
区域转发:仅转发对特定区域的解析请求
|
|
重载、测试:
|
|
由于中国的运营商之间的带宽是非常低,但是无论我们是哪个运营商的宽带,访问那些大型电商站点都是非常的快,那是因为在dns服务器中定义了来自哪些IP的请求解析成哪些地址,这就是视图的功能。
配置视图
初始化设置与上面的实验操作无异:
- 安装bind
- 修改主配置文件的监听IP和allow-query、dnssec的配置
初始化完毕之后,我们开始配置视图:
定义acl
|
|
这里需要注意的是,因为主配置文件中有一段 zone的配置信息,我们需要把其剪切出来,粘贴到/etc/named.rfc1912.zones的view local视图中:
配置/etc/named.rfc1912.zones文件:
|
|
创建maxiecloud.zone目录以及文件:
|
|
测试验证:
自建根域+HTTPD服务教程:
bilibili(视频源):