网路是怎样连接的(四)DNS

思考重点

  • 如何利用DNS协议查找相应的IP位置?
  • 服务器是怎麽存储那麽多相应的域名消息?
  • DNS是使用TCP还是UDP协议为基础传输?

核心知识

为甚麽我们需要DNS

DNS是一个与HTTP同样位於应用层的协议,它提供了域名转IP地址的解析服务(1)

不过问题来了,既然电脑(计算机)可以同时拥有域名与IP地址,何不使用域名来表示?同理为何我们输入网址时不直接使用IP作为输入?

IP太难记啦

TCP/IP为了识别网路中的主机,会分配唯一的IP地址给主机,再依据IP地址来进行通讯,但由於真的很难记住,於是TCP/IP协议就利用主机名帮每一台电脑命名,也就是域名系统

其实我们可以想像使用域名地址与IP地址的两种场景,假设今天我们手上没有任何记事工具,单纯靠记忆记住该网站的访问地址,哪一种地址解释方法更为直观、好懂?

  • www.example.com (域名)
  • 123.123.123.12 (IP地址)

可能有人不服,这种简单的数学排列组合那可是轻而易举,背个100条也是小菜一叠,不过以面向使用者的,或者单就效率来说,利用最节省资源的方法,使更多人能够理解与运用才是更好的方法。既然如此何不让看得懂文字的使用者使用域名系统,让脑子里只有01的电脑使用IP地址呢?

你可以把DNS想像成是一个储存域名地址与IP地址对应关系的资料库,电脑会向DNS询问这个域名对应的IP地址是多少

DNS原理

从图中我们可以看到DNS服务器的工作就是返回请求的IP地址给主机,每台主机中都会存储预设的DNS服务器地址,当主机想要查询IP地址时,都会委托它进行查找。不过问题来了,世界上的网站是何其多,一个服务器是没有办法一次储存那麽多条地址讯息的,到底DNS服务器们是怎麽达成这个任务的?

域名结构

真实的网路世界往往存在无数多台服务器,而且每一个域名都是不可重复的,想让每一台DNS服务器记下所有域名对应的IP地址是不切实际的,因此工程师们想出一个办法,何不让DNS服务器们合力记住所有对应地址?

因此设计者使用分布式分层架构来设计整个DNS系统,让下级的DNS服务器的IP注册到它们的上级,上级服务器再注册IP到它们的更上级,从而使我们可以从最高级别DNS服务器完成域名查询任务

当主机端发起请求时,DNS服务器就可以直接回复储存的地址,或者可以向主机端提供更低阶级同时也更仔细的DNS服务器地址,让主机向指定DNS服务器发起请求,如此环环相扣的连续收发,最终可以取得对应的IP地址

DNS服务器的分层架构如上图所示,还记得我们的电脑会储存离主机最近的DNS服务器地址吗,首先该DNS服务器会向root(根域服务器)(2)发起请求,而根域服务器,你可以想像成一切的开端,它储存了多个顶级网域服务器地址,因此透过根域服务器可以率先访问储存最高等级域名的DNS服务器,以此类推,当到达第一层级域名服务器时,我们会查询它储存的第二级域名,有点像侦探办案一样一个线索一个线索找出最终答案

另外我们也发现既然层次最高的是国家或地区顶级域,但是有些网站并没有填入阿,依然是.com或.edu结尾,这到底是怎麽一回事?其实.com是代表国际域名,而.com.tw则是台湾域名,它们都代表着第一层级域名,差别只在於搜寻的优先度,假若我们使用.com.tw那麽网页搜寻就会以台湾范围为优先

寻找指定DNS服务器

我们从DNS原理框架图可以看出,主机端会让它储存的预设DNS服务器代替他来进行DNS域名查找,而我们也知道所有服务器都拥有根域服务器地址,有了根域地址就可以展开一系列的寻址动作啦

第一步让我们来看看域名吧,URL的最右侧域名区段是.com.tw(最高级别),该服务器可能储存的资料如下表:

域名 IP地址 Class Type
myblog.com.tw 192.168.0.1 IN A
herblog.com.tw 192.168.0.2 IN A
hisblog.com.tw 192.168.0.3 IN A
www.haha.com.tw 192.168.0.4 IN A

其中域名列就是该服务器上总共储存几条域名消息,我们可以看到域名消息不一定通通都是同样类型的,它可能有不同等级的域名,或者不同的储存类型(A代表域名对应的响应数据是IP地址),而Class In代表Internet

有了! myblog.com.tw这条域名最接近我们的请求域名,於是DNS服务器将它代表的IP地址返回给预设DNS服务器,好让它向下一台DNS服务器发起请求,这一系列动作会直到被访问的DNS服务器确实拥有完整的请求域名为止,我们用找人问事来比喻DNS的查找行为

由此可知预设的DNS服务器会代替主机从最高级别一步步搜寻完整的域名地址,当被访问DNS服务器在接收到请求时,会查找保存的资料表,并把它所知道的最接近域名的IP地址回报出去

一旦预设的DNS服务器在某台DNS服务器上找到储存完整域名的服务器地址时(这时它访问到的只是储存该条域名的服务器地址),将会主动将该服务器IP地址告知主机端,让主机端与这台服务器直接建立沟通,以获取最终的IP地址

Resolver

Resolver又名解析器,是DNS查找原理的实现,因为应用层不负责连线的工作,因此必须仰赖OS调用Socket函式库来进行操作,解析器其实就是Socket函式库中的一个function API,我们在上面也介绍了,主机端向DNS服务器发起请求,发起请求就代表一定存在一对服务器端与客户端,解析器就担当主机上的DNS客户端角色

#include <netdb.h>
#include <sys/socket.h>
...
	address = gethostbyname("www.myblog.com..tw"); //解析器
...

上图简单的说明了应用程序调用了 socket库函式中的gethostbyname()(3)後会发生的事。首先函式会根据DNS服务器的类型规格生成特定的DNS请求(二进制形式)接下来OS会委托*Protocol Stack(协议栈或协议叠)(4)来执行DNS请求的发送(5),该请求会透过网卡确实传到DNS手里,这里刚好沿续上一小节所讲的寻找指定DNS服务器,存储对应IP位置的DNS服务器会将响应结果透过网卡回传给主机端,经过协议栈的提取与处理,最终将IP地址消息回传给指定变数,既然有了IP地址应用程序就可以考虑发送请求的事啦。

(1):其实DNS也提供IP转域名的查找服务
(2):根域约储存13个第一层级IP地址,另外根域服务器地址存在於所有DNS服务器中
(3):目前gethostbyname()已经被淘汰,改而使用功能更强大的getaddrinfo()
(4):协议栈是OS内部关於网路协定的软件实现
(5):传输层使用UDP协议,省去握手机制,假如发生掉包协议栈会立刻在重新发送消息


<<:  准备工作 - day02

>>:  连续 30 天 玩玩看 ProtoPie - Day 2

Day29-实作(地图) (part1)

进入到尾声,范例的最後一片拼图,马上开始吧!!! 地图的部分使用了leaflet JS和OpenSt...

[Day21]浅谈solidity

今天要介绍的是solidity,那今天会先跟大家简单介绍solidity以及浅谈开发环境! Sol...

Day10:今天来讲一下microsoft defender for endpoint的装置执行动作

在我们导入microsoft defender for endpoint後,我们主要工作是修复事件。...

GNU Debugger

GNU Debugger,简称 GDB,是 GNU 软件系统中的除错器,由於其具有可移植的优点,在现...

Day-30 不知不觉面试题完赛!感谢大家!

不敢相信今天是第30天了! 我完赛了!好感动啊~ 真的很感谢帮过我的老师/助教/同学/亲友…很多啦...