文章目录
前言
我们都知道DNS协议是用来将人类可记忆的域名映射为计算机所记忆的ip地址,最终去获取ip地址对应服务器上存储的内容,那么DNS协议在实际网络请求中扮演了哪些角色或者说它是由哪些角色组成呢?
我们以打开一个网页过程进行展示
一、DNS缓存
当浏览器输入一个网址敲下回车后,浏览器并不会直接向远程DNS服务器请求该域名对应的ip地址,而是会就近检查缓存中是否有浏览器想要得到的结果
浏览器缓存
浏览器检查缓存的第一个地方是浏览器缓存,这个缓存就是 DNS 记录。
浏览器会为你访问过的网站在固定期限内维护 DNS 记录。因此,它是第一个运行 DNS 查询的地方。 浏览器首先会检查这个网址在浏览器中是否有一条对应的 DNS 记录,用来找到目标网址的 IP 地址。
Windows下可以通过
chrome://net-internals/#dns
进行查找
DNS(Domain Name System) 是一个分布式的数据库,它用于维护网址 URL 到其 IP 地址的映射关系。在互联网中,IP地址是计算机所能够理解的一种地址,而 DNS 的这种别名地址是我们人类能够理解和记忆的地址,DNS就负责把人类记忆的地址映射成计算机能够理解的地址,每个 URL 都有唯一的 IP 地址进行对应。
说白了,在查找浏览器缓存过程中,浏览器本身便可以理解为一个分布式的数据库,自身向自身去拿想要的对应数据
操作系统缓存
浏览器第二个需要检查的地方就是操作系统缓存。如果 DNS 记录不在浏览器缓存中,那么浏览器将对操作系统发起系统调用,Windows 下就是getHostName。 在 Linux 和大部分 UNIX 系统上,除非安装了 nscd,否则操作系统可能没有 DNS 缓存。
nscd 是 Linux 系统上的一种名称服务缓存程序。
路由器缓存
浏览器第三个需要检查的地方是路由器缓存,如果 DNS 记录不在自己电脑上的话,浏览器就会和与之相连的路由器共同维护 DNS 记录。
ISP缓存
如果与之相连的路由器也没有 DNS 记录的话,浏览器就会检查 ISP 中是否有缓存。ISP 缓存就是你本地通信服务商的缓存,因为 ISP 维护着自己的 DNS 服务器,它缓存 DNS 记录的本质也是为了降低请求时间,达到快速响应的效果。一旦你访问过某些网站,你的 ISP 可能就会缓存这些页面,以便下次快速访问。
缓存带来了许多好处,给予了上网的用户高效的上网体验,同时减小了上网流量,但是也不可避免地造成了隐私被记录和隐私泄漏的风险
二、DNS查询
1.发起DNS查询
在上一步的搜索结果中,如果本地DNS缓存无法提供给浏览器正确的从域名到IP地址的映射,那么浏览器便会向多台DNS服务器发起查询请求
Q:为什么是向多台DNS服务器发起请求,而不是向一台DNS服务器发起请求呢?
A:因为 DNS 是分布式域名服务器,每台服务器只维护一部分 IP 地址到网络地址的映射,没有任何一台服务器能够维持全部的映射关系。
在 DNS 的早期设计中只有一台 DNS 服务器。这台服务器会包含所有的 DNS 映射。这是一种集中式的设计,这种设计并不适用于当今的互联网,因为互联网有着数量巨大并且持续增长的主机,这种集中式的设计会存在以下几个问题
- 单点故障(a single point of failure),如果 DNS 服务器崩溃,那么整个网络随之瘫痪。
- 通信容量(traaffic volume),单个 DNS 服务器不得不处理所有的 DNS 查询,这种查询级别可能是上百万上千万级,一台服务器很难满足。
- 远距离集中式数据库(distant centralized database),单个 DNS 服务器不可能 邻近 所有的用户,假设在美国的
DNS 服务器不可能临近让澳大利亚的查询使用,其中查询请求势必会经过低速和拥堵的链路,造成严重的时延。 - 维护(maintenance),维护成本巨大,而且还需要频繁更新。
为了提高DNS服务器的可扩展性,因而其不能是单服务器设计
2.DNS服务器设计结构
首先分布式设计首先解决的问题就是 DNS 服务器的扩展性问题,因此 DNS 使用了大量的 DNS 服务器,它们的组织模式一般是层次方式,并且分布在全世界范围内。没有一台 DNS 服务器能够拥有因特网上所有主机的映射。相反,这些映射分布在所有的 DNS 服务器上。
DNS服务器大致分为以下三种类型
- 根DNS服务器
- 顶级域DNS服务器
- 权威DNS服务器
1.根 DNS 服务器 ,有 400 多个根域名服务器遍及全世界,这些根域名服务器由 13 个不同的组织管理。根域名服务器的清单和组织机构可以在https://root-servers.org/ 中找到,根域名服务器提供 TLD 服务器的 IP 地址。
2. 顶级域 DNS服务器,对于每个顶级域名比如 com、org、net、edu 和 gov 和所有的国家级域名 uk、fr、ca 和 jp 都有 TLD服务器或服务器集群。所有的顶级域列表参见 https://tld-list.com/ 。TDL 服务器提供了权威 DNS 服务器的 IP地址。
3.权威 DNS 服务器,在因特网上具有公共可访问的主机,如 Web 服务器和邮件服务器,这些主机的组织机构必须提供可供访问的 DNS记录,这些记录将这些主机的名字映射为 IP 地址。一个组织机构的权威 DNS 服务器收藏了这些 DNS 记录。
3.DNS服务器查询步骤
DNS查询主要分为三大类:
- DNS递归查询
在递归查询中,DNS客户端要求DNS服务器(一般为 DNS 递归解析器)将使用所请求的资源记录响应客户端,或者如果解析器无法找到该记录,则返回错误消息。
注:这里的递归解析器一般为ISP维护的DNS服务器
DNS递归查询的特点是,被查询方若不存在该记录,则会向其他服务器发起查询请求,例如:resolver向DNS A查询,DNS A向DNS B查询,DNS B向DNS C 查询。然后DNS C返回结果给DNS B,DNS B再返回给DNS A,DNS A返回给resolver。
- DNS迭代查询
在迭代查询中,如果所查询的 DNS 服务器与查询名称不匹配,则其将返回对较低级别域名空间具有权威性的 DNS 服务器的引用。然后,DNS 客户端将对引用地址进行查询。此过程继续使用查询链中的其他 DNS 服务器,直至发生错误或超时为止。
DNS迭代查询的具体样子如下:resolver 向DNS A查询,DNS A回复,我不知道,你去找DNS B,然后resolver 询问DNS B,…
- 非递归查询
当 DNS 解析器客户端查询 DNS 服务器以获取其有权访问的记录时通常会进行此查询,因为其对该记录具有权威性,或者该记录存在于其缓存内。DNS 服务器通常会缓存 DNS 记录,查询到来后能够直接返回缓存结果,以防止更多带宽消耗和上游服务器上的负载。
非递归查询的重要特点是不会向上传递,例如:resolver查询某一个DNS 服务器。服务器返回结果,可能有记录,也可能没有。但是不管如何,DNS查询结束
上面负责开始 DNS 查找的介质就是 DNS 解析器,它一般是 ISP 维护的 DNS 服务器,它的主要职责就是通过向网络中其他 DNS 服务器询问正确的 IP 地址。
例如,对于maps.google.com 这个域名来说,如果 ISP 维护的服务器没有 DNS 缓存记录,它就会向 DNS根服务器地址发起查询,根名称服务器会将其重定向到 .com 顶级域名服务器。 .com 顶级域名服务器会将其重定向到google.com权威服务器。google.com 名称服务器将在其 DNS 记录中找到 maps.google.com 匹配的 IP 地址,并将其返回给您的DNS 解析器,然后将其发送回你的浏览器。
4.ARP请求
ARP 协议的全称是 Address Resolution Protocol(地址解析协议),它是一个通过用于实现从 IP 地址到 MAC 地址的映射,即询问目标 IP 对应的 MAC 地址 的一种协议。
简而言之,ARP 就是一种解决地址问题的协议,它以 IP 地址为线索,定位下一个应该接收数据分包的主机 MAC 地址。如果目标主机不在同一个链路上,那么会查找下一跳路由器的 MAC 地址。
Q:为何要有ARP协议
A:看这个网址如果让你来设计网络
这里先看看ARP的大致工作流程
假设 A 和 B 位于同一链路,不需要经过路由器的转换,主机 A 向主机 B 发送一个 IP 分组,主机 A 的地址是 192.168.1.2 ,主机 B 的地址是 192.168.1.3,它们都不知道对方的 MAC 地址是啥,主机 C 和 主机 D 是同一链路的其他主机。
主机 A 想要获取主机 B 的 MAC 地址,通过主机 A 会通过广播 的方式向以太网上的所有主机发送一个 ARP 请求包,这个 ARP 请求包中包含了主机 A 想要知道的主机 B 的 IP 地址的 MAC 地址。
主机 A 发送的 ARP 请求包会被同一链路上的所有主机/路由器接收并进行解析。每个主机/路由器都会检查 ARP 请求包中的信息,如果 ARP 请求包中的目标 IP 地址 和自己的相同,就会将自己主机的 MAC 地址写入响应包返回主机 A
由此,可以通过 ARP 从 IP 地址获取 MAC 地址,实现同一链路内的通信。
所以,要想发送 ARP 广播,我们需要有一个目标 IP 地址,同时还需要知道用于发送 ARP 广播的接口的 MAC 地址。
这里会涉及到 ARP 缓存的概念。
现在你知道了发送一次 IP 分组前通过发送一次 ARP 请求就能够确定 MAC 地址。那么是不是每发送一次都得经过广播 -> 封装 ARP 响应 -> 返回给主机这一系列流程呢?
想想看,浏览器是如何做的?浏览器内置了缓存能够缓存你最近经常使用的地址,那么 ARP 也是一样的。ARP 高效运行的关键就是维护每个主机和路由器上的 ARP 缓存(或表)。这个缓存维护着每个 IP 到 MAC 地址的映射关系。通过把第一次 ARP 获取到的 MAC 地址作为 IP 对 MAC 的映射关系到一个 ARP 缓存表中,下一次再向这个地址发送数据报时就不再需要重新发送 ARP 请求了,而是直接使用这个缓存表中的 MAC 地址进行数据报的发送。每发送一次 ARP 请求,缓存表中对应的映射关系都会被清除。
通过 ARP 缓存,降低了网络流量的使用,在一定程度上防止了 ARP 的大量广播。
形如这样ARP缓存表,构成了ARP请求的核心
一开始该表为空,在不断广播请求后,最终电脑里的arp缓存表将得到更新
不过,MAC 地址的缓存有一定期限,超过这个期限后,缓存的内容会被清除。
5.封装TCP数据包
浏览器得到目标服务器的 IP 地址后,根据 URL 中的端口可以知道端口号 (http 协议默认端口号是 80, https 默认端口号是 443),会准备 TCP 数据包。数据包的封装会经过下面的层层处理,数据到达目标主机后,目标主机会解析数据包,完整的请求和解析过程如下。
6.浏览器与目标服务器建立起TCP连接
在经过上述 DNS 和 ARP 查找流程后,浏览器就会收到一个目标服务器的 IP 和 MAC地址,然后浏览器将会和目标服务器建立连接来传输信息。这里可以使用很多种 Internet 协议,但是 HTTP 协议建立连接所使用的运输层协议是 TCP 协议。所以这一步骤是浏览器与目标服务器建立 TCP 连接的过程。
这一阶段便是要经历TCP三次握手确认的过程,具体可看图片
具体三次握手的连接流程如下:
- 服务端进程准备好接收来自外部的 TCP 连接。然后服务端进程处于 LISTEN 状态,等待客户端连接请求。
- 客户端向服务器发出连接请求,请求中首部同步位 SYN = 1,同时选择一个初始序号 sequence ,简写 seq = x。SYN 报文段不允许携带数据,只消耗一个序号。此时,客户端进入 SYN-SEND 状态。
- 服务器收到客户端连接后,,需要确认客户端的报文段。在确认报文段中,把 SYN 和 ACK 位都置为 1 。确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。此时,TCP 服务器进入 SYN-RECEIVED(同步收到) 状态。
- 客户端在收到服务器发出的响应后,还需要给出确认连接。确认连接中的 ACK 置为 1 ,序号为 seq = x + 1,确认号为 ack = y + 1。TCP 规定,这个报文段可以携带数据也可以不携带数据,如果不携带数据,那么下一个数据报文段的序号仍是 seq = x + 1。这时,客户端进入 ESTABLISHED (已连接) 状态
- 服务器收到客户的确认后,也进入 ESTABLISHED 状态。
这样三次握手建立连接的阶段就完成了,双方可以直接通信了。
7.浏览器发送HTTP请求到Web服务器
一旦 TCP 连接建立完成后,就开始直接传输数据办正事了!此时浏览器会发送 GET 请求,要求目标服务器提供 maps.google.com 的网页,如果你填写的是表单,则发起的是 POST 请求,在 HTTP 中,GET 请求和 POST请求是最常见的两种请求,基本上占据了所有 HTTP 请求的九成以上。
HTTP请求类型字段和其对应的值内容很多,这里就不进行赘述了,有兴趣的朋友可以看看《图解HTTP》里关于HTTP请求体内容的部分。
8.服务器处理请求并发回一个响应
这个服务器包含一个 Web 服务器,也就是 Apache 服务器,服务器会从浏览器接收请求并将其传递给请求处理程序并生成响应。
请求处理程序也是一个程序,它一般是用 .net 、php、ruby等语言编写,用于读取请求,检查请求内容,cookie,必要时更新服务器上的信息的这么一个程序。它会以特定的格式比如JSON、XML、HTML 组合响应。
9.浏览器显示HTML的相关内容
浏览器会分阶段显示 HTML 内容。 首先,它将渲染裸露的 HTML 骨架。 然后它将检查 HTML 标记并发送 GET 请求以获取网页上的其他元素,例如图像,CSS 样式表,JavaScript 文件等。这些静态文件由浏览器缓存,因此你再次访问该页面时,不用重新再请求一次。最后,您会看到网址对应显示的内容出现在你的浏览器中。
总结