DNS 服务原理详解

目录:

  • 一些基本概念
    • 主机名
    • DNS
    • 名称解析
      • DNS 解析的后端存储
      • 名称解析总结
  • 大规模域名解析的体系架构
    • DNS 解析需要分布式的架构
      • 早期使用本地 hosts 文件解析方式
      • 中期由中心 DNS 服务器提供 hosts 文件
      • 域名解析查找结果被缓存,以减轻服务器压力
      • 域名解析进入分布式阶段
  • 真正域名查询的过程
  • DNS 中涉及的概念详解
    • DNS正向解析,反向解析
    • DNS 的 zone(区域解析库)
    • 区域解析库详解(zone)
    • 主DNS服务器/权威DNS服务器是怎么工作的
      • DNS 服务器负责本地域内主机名的解析
      • DNS 服务器如何处理非本地域名的解析
    • DNS客户端进行域名解析的流程
      • 非权威应答
      • 缓存DNS服务器
      • DNS 转发器
    • 辅助(从)DNS服务器
      • 主从服务器间的区域传送
      • 完全区域传送
      • 增量区域传送
    • 区域解析库中的资源记录类型

一些基本概念


主机名


www.magedu.com: 这是一个常见的网站主机名,这个名称被称为:FQDN - Full Qualified Domain Name

DNS


DNS:Domain Name Service - 域名解析服务

DNS 也是 C/S 架构的,有客户端、服务器两个部分。

服务器端一般是 BIND,BIND - Berkley Internet Name Domain
客户端一般是共享库 - 由其他应用调用

DNS端口: 53/udp, 53/tcp

主机名和域名是不同的:

www.magedu.com - 这是主机名
.magedu.com. - 这是域名

名称解析


名称解析是什么:名称解析 - 把一种名称转换为另一种名称。
名称是一个“字符串” <—-> “数字” 相互转换

DNS 解析的后端存储


DNS 的解析,在背后依靠解析库进行转换。在“某种存储”中,存储了每一个“名称”和“数字”的对应关系。

“某种存储” 指不同格式的存放:

1,文本文件

缺陷,当文本信息过大时,如 100w 条信息,这时查找一条信息是非常低效的。所以文本文件不适合大量数据的存储,因为检索效率不好。

另一方面,文本文件过大时,因为需要将整个文件载入内存中,这也很可能造成性能问题(大量 I/O 操作)。

2,关系型数据库 - 支持索引,快速的检索效率

它把“搜索键值”单独抽取出来,即“索引”,单独做成小型数据库用于检索,查找时,只需要查找到“索引”,即可返回对应的查找条目。

“索引” 可看做一条信息的 “特征信息”,与 “hash特征码” 的思路有点类似。它指向对应的那一条信息在文件中的存储位置(磁盘 block,因为文件以 block 为单位存放数据)。

关系型数据库仍然存在的问题,即当数据达到“百万”、“千万”、“上亿”的级别时,索引文件就变成很大,其效率并不一定会很理想。

有时为提高效率,会给索引再作一次索引(将一定范围内的索引,做成一个索引),乃至多级索引,以减小索引文件的大小,以提高检索的效率。

索引有“稠密”索引和“稀疏”索引之分

  • “稠密”索引 - 每一条数据对应一条索引
  • “稀疏”索引 - 比如二级索引,将100条一级索引做成一个索引,相当于划分段落。

3,LDAP

比关系型数据库的索引检索效率,高不止一个数量级的:

LDAP: Lightweight Directory Access Protocol, 389/tcp

LDAP 尤其适用于 “用户名” 检索。

名称解析总结

所以,解析库,就是以某种合适的方式存储“键值对”信息的数据库(文本文件、关系型数据
库、LDAP 等等)

解析: 根据用户提供的名称,去查询(以名称为“键值”)解析库,最终得到期望得到的另一
种名称,这一过程被称为“解析”的过程。

对客户的而言,这一过程,是查询请求,对于服务端,是将查询结果返回给客户端。
这就是“名称解析”的概念。

大规模域名解析的体系架构


互联网上的域名的数量的规模之大(100亿+),放在什么存储里面合适呢? 解析的速度怎么提升? 而且全球对于域名解析的请求何其多,怎么响应每一个请求呢?

每秒100w的请求,能够支撑吗? 什么是解析过程,DNS 背后的工作机制是怎样的?

有多个用户请求时,进程是怎么响应的呢? 这也就是并发用户请求的概念,有很多用户,很多请求,同时连接到当前主机上来。每一个请求都要去响应的。

DNS 解析需要分布式的架构


一般来讲,进程需要用一个建立连接的套接字,而非监听的套接字来响应请求。早期的并发用户响应模型,都是使用“进程”来响应的。 来一个用户请求,启动一个进程响应该用户的请求,有多个用户,就启动多个进程响应请求。 如果有100w个用户请求进来会发送什么情况呢? 假设一个进程需要 “5M” 内存,100w个请求,需要100w个进程,
需要的内存就是 “500万M” 内存。这对于一台服务器是不可能的,任何一台服务器,都不可能满足互联网上名称解析请求的要求。

所以,这些请求,将他们分散至多个不同服务器上,才能承担起这个量级的压力。

这即是分布式的应用

进一步的,分布式的每个服务器,存储的是整个互联网的“名称解析”数据,还是一部分呢。如果是一部分,怎么把用户请求,路由到正确的位置(存储了跟请求的名称相关数据的服务器)? 这些都是 “DNS” 需要解决的问题。

早期使用本地 hosts 文件解析方式


在早期来说,互联网上的主机数量还不多的时候,因为IP地址难以记忆,所以催生了对于“主机名” 的需求,人们希望使用“主机名” 与服务器通信。而在那时,完成这个工作的实现方式,是在本地的文件中存放 “IP地址” 与 “目标主机名” 的对应关系,这个文件就是“hosts” 文件。

最初的互联网发展速度很慢,几年之间,也不过增加百十来台服务器,所以通过文本文件记录这些信息仍然足够使用。 但到后来,互联网上的服务器开始成倍增加时,就需要一种更好地方式来管理 ”主机名” 和 “IP地址” 之间的关系了。

中期由中心 DNS 服务器提供 hosts 文件


IANA: 负责互联网地址分配,管理互联网上 ”主机名” 和 “IP地址” 对应关系。早期的实现,是将解析库(文本文件)通过 ftp 发布出来。 各地的Unix主机管理员,需要设定任务计划,去定时的获取解析库文件到本地,实时更新。

客户端应用当有名称解析的请求时,通过调用 DNS客户端的”共享库”(现在已经成为 glibc 标准库的一部分),去本地的 hosts 文件获取到希望获取的解析结果。

后来,由 ftp 共享文件的方式,发展到 DNS(这时还是一个中心服务器),使用了高可用集群避免其中一台当机使整个服务中断。 这时本地应用有名称解析的需求时,会通过调用DNS共享库,除了向本地hosts查询以外,也向中心服务器开放监听端口发起请求,服务器启动一个进程响应请求,进行查询后,返回结果给本地应用。这两种方式,都保留了下来,而且会优先查询本地的 hosts 文件。

我们需要 DNS 快速相应请求,默认使用 UDP 协议(不需要3次握手建立连接)。

域名解析查找结果被缓存,以减轻服务器压力


我们客户端每一次都用主机名发起请求,是不是每一次都需要向 DNS 服务器请求进行名称解析呢,不是的,因为IP地址并不经常变动的。所以本地DNS客户端可以将解析结果存储在本地,建立缓存(内存中的存储空间)。意味着,只有第一次查询时,才需要去DNS服务器取得解析数据。 我们后面发起请求,会首先检查缓存中是否有结果,没有,才会去向DNS服务器请求。 所以缓存在这里,既可以加速我们的访问,又能减轻DNS服务器的压力。假设我们的缓存有效期是1小时,在1小时发起的请求是20个,那么在一小时内,向DNS服务器请求的次数就减少到1次,也即是20倍,所以压力减轻的效果是尤其明显的。

随着互联网的发展,即使有本地缓存等技术减轻DNS服务器的压力,但是渐渐地一台中心服务器已经难以应付这个工作,这是DNS服务器就进入了下一个阶段:将名称实现分布式应用。

域名解析进入分布式阶段


将名称实现分布式应用:

  • 将整个互联网的主机名,划分成多个不同的部分
  • 整个名称空间,被划分多个自治的完整的小空间。如同国家的行政划分,中央 —-> 省 —-> 市

DNS也采用了这种机制:授权管理机制。

  • 最上层的区域:根域 - Root Domain
  • 根域下面是“一级域”:Top-Level Domain
  • 再下一层是扁平化管理的:二级域,公司,组织或个人可直接申请
  • 最后一层,可以直达主机了

“根域” 和 “一级域” 是由“IANA”直接管理。
二级域,公司,组织或个人可直接申请。二级域申请好之后,在这个域内就可以建立主机了。

组织和公司里通常“约定俗成”地使用 “www” 为主机名。

整个名称,是自底向上,逐级追溯的模式。

DNS 是一个树状的结构:

Snip20160730_8.png

在“根域”这里,只关心“一级域名”的情况,记录了如 com、net、org 这几个域名分区的负责人的信息。

这里有两种查找模型:

1,层级递归查询

A -> B -> C -> D

A 问 B,B不知道,但 B 知道 C 知道,于是B问C,C也不知道,但C知道D知道。
逐级查询,逐级返回。

2,迭代查询

A -> B
A -> C
A -> D

A 问 B,B不知道,但 B 知道 C 知道,于是A去问C,C也不知道,但C知道D知
道,于是A去问D。

真正的DNS查询使用的哪种模式? 互联网上的绝大多数查找模型都是迭代的。但 DNS 是递归+迭代的,是先递归,后迭代的。

真正域名查询的过程


真正域名查询的过程是: 先递归,后迭代。

比如当客户端查询 www.qq.com 的时候,不是直接去找根的,你想一下配置网络地址时,你的DNS服务器填写的是什么,一般是本地的一个服务器,可能是公司内部的一个服务器,如果公司没有,你的宽带运营商一定会提供一个DNS服务器地址。

在DNS的模型中,上级知道下级,但下级不知道自己的上级是谁,虽然知道自己在哪个域名内,但那个域名的管理者(服务器)是谁,其实是不知道的。

当我们请求域名解析时,把请求发送到本地的某个DNS服务器,如果是请求解析 “www.qq.com”,当DNS服务器要查询一个非本地管理的域名时,会去找“根”。每一个DNS服务器都预先设置了“根”的地址,大部分默认法则,它们仅知道”根”的IP地址,并不知道其他一级域名管理者的地址。

“根” 返回说查询的主机名归 com 管理,返回 com 的管理者地址,本地的DNS服务就去 com 的服务器进行查询。com 返回说归 qq.com 的二级域名管理者管理,于是本地DNS又去查询 qq.com 这个域名的管理者的域名服务器,最终得到 www.qq.com 的IP地址,返回给客户端。

客户端到本地 DNS 这一步,是“递归查询”的方式,要求 DNS 服务器必须返回结果,只发出一次请求。DNS 服务器进行查询的方式,是“迭代查询”的方式,可能多次发起查询请求。

全球的根节点服务器是固定的,一共有13个,国内连根服务器的镜像都没有。

比较常见的顶级域:

组织域:.com , .org, .net, .mil, .edu, .gov
国家域:.cn, .us, .uk, .jp, .tw, .hk
反向域:.in-addr.arpa - 从IP地址解析成主机名称时使用

组织域、反向域,由IANA管理。
国家域,由各国统一的DNS服务商来管理。

DNS 涉及的概念详解


DNS 中的名称与对应主机的“主机名”不要求是一样的,注意它们不是同一个概念。

在 DNS 中:
一个“名称”可以对应多个IP(即有多个主机)
一个IP上也可以有多个“名称”

DNS正向解析,反向解析


1,FQDN —-> IP地址
2,IP地址 —-> FQDN

一开始,反向解析几乎不可能,后来利用特殊技术才能做到。

国内一般都没有配置“反向解析”,但是,邮件服务器必须配置反向解析,否则会认为你是垃圾邮件。

DNS 的 zone(区域解析库)


域:domain
区域:zone(解析库)

正向解析:FQDN —-> IP地址,依赖于解析库 - 一个解析库是一个 zone(区域)
反向解析:IP地址 —-> FQDN,依赖于反向解析库

域中包含一个或两个区域(zone),或者说是解析库。

区域解析库详解(zone)


在解析库中,每一个行是一个解析条目,叫做“资源记录” - resource record(rr)。

资源记录有类型的概念,用于表示解析条目的属性,下面依次说明:

NS(Name Server)
本区域的“名称服务器”,负责本地域内主机的 DNS 解析,可能有多个。

SOA(Start of Authority)
起始授权记录:用来标记区域内的 DNS主服务器 是谁,主服务器一个区域内只能有一个。

MX(Mail eXchage)
邮件交换器

当我们发邮件时,比如:tom@163.com - 163.com 是域名,tom在域内的哪个服务器上呢?MX 是 域内负责邮件接收的服务器。假设域内有多个 MX,那tom在哪个服务器上呢?实际上,tom用户在每一个 MX 服务器上都有记录,而这多个 MX 服务器,有优先级的区分(0-99),数字越小,优先级越高。

A
FQDN—->IP :A,负责“正向名称解析”

PTR
IP地址 —-> FQDN:PTR,负责“反向名称解析”

AAAA
FQDN—->IPv6:AAAA,负责IPv6地址的“正向名称解析”

CNAME(Canonical Name)
正式名称:CNAME(Canonical Name),正式名称

A CNAME B: A 的正式名称是 B

总结一下,解析库中的条目的类型有:NS,SOA,MX,A,PTR,AAAA,CNAME 等

主DNS服务器/权威DNS服务器是怎么工作的


我们申请了一个域名之后,需要为这个域建立一台DNS服务器,来负责这个域内的所有主机名的解析。这个DNS服务器就是这个域的“权威DNS服务器”,除了这台DNS服务器,没有其他人知道该域内的主机的解析名。一个域内可以有备用的DNS服务器,但主服务器只能有一个。

DNS 服务器负责本地域内主机名的解析

假设我们注册了域名:magedu.com, 意味着我们要负责对该域名内的所有主机进行“名称解析”。要解析,就得有解析库,要找一台主机来负责存放解析库,并负责响应对于该域名内的主机名的“解析请求”。如果本地主机发起一个请求,假设本地的DNS服务器的主机名叫做 ns.magedu.com,客户端向 ns 主机请求 www.magedu.com 的解析地址,这个主机名的解析是不是就是由 ns 这台服务器负责呢? 假如这个域内只有这一台 DNS 主机,很显然这个域内的所有主机,只有这台 ns 主机才能知道。

这台ns主机会负责,本地的所有“名称解析”请求,或来自网络的对于本域的查询请求。

这台ns主机的IP地址,需要注册到上级服务器。

这台DNS服务器,被称为“主DNS服务器”。

DNS 服务器如何处理非本地域名的解析

如果客户端向 ns 主机请求 www.ibm.com 的解析地址,如果 ns 本地没有缓存的话,就向根域询问,这个根的地址是预先存放在ns主机上的,然后按照上面讲述过的步骤,进行查询。全球有13个根节点,在向根查询的时候,是向谁查询的呢? 根域 . 这个名称对应了 13 个IP地址,ns 主机默认是轮流去查询的。 同理,.com 服务器也不止一个(为了实现冗余或备份的效果),根在返回 .com 的地址时,也会轮流返回其中一个,或者全部返回了,ns 也只是选择第一个地址。同理,ibm.com 域名服务器也可能不止一个,.com 或者轮流返回其中一个,或者全部返回,ns 主机也同样选择其中第一个地址。

DNS客户端进行域名解析的流程


客户端进行域名解析的流程:

  1. 先查hosts文件
  2. 若没有,查本地DNS缓存
  3. 若没有,再查DNS服务器:
    • 先查DNS服务器的本地DNS缓存
    • 若没有,再查DNS服务器的解析库
    • 都没有,那DNS向根域发起请求,开始迭代查询

如果缓存的有效期为1天的话,能极大减轻DNS服务器的压力,所以对于DNS的架构,“缓存”是很重要的。

非权威应答

如果通过缓存返回名称解析的请求,由于缓存与实际的情况存在时间差,所以被称为:“非权威应答”

缓存DNS服务器

那本地的DNS服务可不可以只做一半的工作呢,比如不负责“本地域内主机名”的解析,只负接收本地客户端的“名称解析”请求,然后向根发起迭代查询,以及对查询结果进行缓存。答案是可以的。

这样做的好处是什么呢,好处在于这个缓存,一个域名进行一次查询之后,缓存在服务器上,本地的其他客户端请求同一个域名的解析时,可以通过缓存的结果进行响应,这就可以加快本地客户端的名称解析速度,减轻网络带宽的压力。这种服务器,被称为“缓存DNS服务器”。

DNS 转发器

还有一种DNS服务器,只负责转发DNS请求,转发给另一台DNS主机做查询,本地不做缓存,称为“转发器”。

辅助(从)DNS服务器


主从服务器间的区域传送

辅助DNS服务器的用处,是冗余和备用。备用的可以有多个,它有和主服务器同样的“解析库”,它会去同步主服务器上的解析库,这个同步过程(传送zone文件),被称为“区域传送” - zone transfer,它是单向的,所有的修改,只能在 DNS 主服务器上进行。

从服务器有多个的时候,一个从服务器可从另一个从服务器获取“区域文件”。这是多级从服务器。

完全区域传送

第一次传送区域文件,通常是传送完整的区域文件,这叫做“完全区域传送” - axfr

增量区域传送

后续传送区域文件,通常是传送增量的区域文件,这叫做“增量区域传送” - ixfr

区域文件,一方面是定期由从服务器去向主服务器询问和拉取。一方面当主服务器发生更新,会向从服务器发送更新通知,让从服务器来拉取。

而且传送区域文件,为了保证文件的完整性,使用的是 TCP 协议进行传输。前面我们知道 DNS 工作在 TCP 和 UDP 协议下,UDP 是负责监听查询请求的。

如果主服务器出现问题,不响应从服务的询问,经过一段时间的尝试,发现仍然没有响应,从服务器就不再对DNS请求做应答,放弃解析。从服务器不会取而代之,而是在必要时提供冗余的能力。

区域解析库中的资源记录类型


在区域解析库中,资源记录的格式如下:

Name [ttl]  IN  RRType  VALUE

分别为:名称,有效缓存时间,固定字段,资源记录类型,值

在解析库中,如果定义了变量 $TTL, 那么在每一条资源记录中,可以不写 ttl。如果想定义不同的ttl,仍然可以写出来,它会覆盖 $TTL 的值。

任何解析库文件的第一条记录必须是SOA,SOA是用于标记域内的主服务器是谁。

SOA: Start of Authority

name: 当前区域名称,通常可以简写为 "@";
ttl: 略
RRTtype: SOA
VALUE: 主 DNS 服务器的名称(FQDN),也可以是当前区域的区域名称;这里为 ns.magedu.com;

例如:

@ IN SOA ns.magedu.com. admin.magedu.com. (
    serial number   ; 解析库的版本号,例如:2014080401(分号是注释)
    refresh time    ; 周期性同步的时间间隔(从服务器的同步时间)
    retry time      ; 重试的时间间隔(主不响应时,从服务器的重试时间间隔)
    expire time     ; 过期时长(从服务器的过期时间)
    nagtive answer ttl  ; 查无此人时,会给出否定答案,这是否定答案的缓存时长
    )
  • 注意在解析库文件内,域名最后的’.’不能省略。
  • admin.magedu.com.是 DNS 服务器管理员的邮箱地址,因为 @ 字符在 DNS 配置文件中有特殊意义,不能直接在邮箱地址中使用,所以这里用’.’取代。

NS: name server

name: 区域名称,可以简写为 “@”
value: DNS 服务器名称(FQDN)

例如:

@ IN NS ns.magedu.com. 

注意:

  • 如果有多台NS服务器,每一台都必须有对应的 NS 记录,否则不会被识别为 DNS 服务器。
  • 对于“正向解析文件”来讲,每一个 NS 的 FQDN 都应该有一个A记录

MX: Mail eXchanger

name: 区域名称,可以简写为@
priority: 优先级
value: 邮件服务器的FQDN

例如:

@ IN MX 10 mail.magedu.com.
@ IN MX 20 mail2.magedu.com.

注意:

  • 如果有多台 MX 服务器,每一台都必须有对应的MX记录,但各个MX记录还有优先级属性。
  • 但是注意,如果第一个MX服务器还能响应,就不会找第二个。
  • 对于“正向解析文件”来讲,每一个 MX 的 FQDN 都应该有一个A记录。

A: Adress

A 记录

name: FQDN
value: IP

例如:

www.magedu.com. IN A 10.0.0.2
www.magedu.com. IN A 172.0.0.3

pop3.magedu.com. IN A 10.0.0.10
imap.magedu.com. IN A 10.0.0.10

同一个名字可以有多个地址,可以实现类似于负载均衡的效果。

同一个IP可能对应多个名称,比如一台服务器同时提供多种服务的情况。

AAAA: IPv6

name: FQDN
value: IPv6地址

其他同上

CNAME: 正式名称是什么

name: FQDN
value: FQDN

一个 FQDN 的正式名称是另一个 FQDN。

例如,一个IP地址对应多个名称,还可以这样写:

www.magedu.com. IN A 10.1.1.5
web.magedu.com. IN CNAME www.magedu.com.

这里表示:web.magedu.com. 的正式名称是 www.magedu.com.

这里为什么不直接写IP地址呢,假设一个主机有十个别名,如果主机的 IP 地址改变了,只需要改一次就行了, 就好像BASH里变量的作用。

有别名这种机制,在 CDN 上做 C 类应用时,提供一个公共 CDN 时,通常都是通过别名的方式指定的:比如访问的是 www.magedu.com. ,背后却指向一个CDN的名字。

PTR: pointer 反向解析

name: 逆向的主机IP地址,加后缀 in-addr.arpa,注意不包含网段,是主机地址。

例如 172.16.100.9/16, 网络地址是 172.16, 主机地址是 100.7,那么,这里的 name 就是 “7.100.in-addr.arpa.”,注意最后有’.’。

value: FQDN

例如:

7.100.in-addr.arpa. IN PTR www.magedu.com.

推荐阅读更多精彩内容