域名系统DNS
(Domain Name System
)协议,是一个用来 将域名转化为 IP
地址的应用层协议
。
我们知道,TCP/IP
中通过 IP
地址和端口号的方式,来确定网络中一个主机上的一个程序。但 IP
地址是一长串数字,并不便于人们记忆,于是人们发明了一种叫做主机名的东西,并用 hosts
文件夹来描述主机名和 IP
地址之间的对应关系。
最初,这个 hosts
文件是由互联网信息中心(SRI-NIC
)来管理的。
IP
变更,都需要到信息中心申请变更 hosts
文件。
hosts
文件才能正确上网。
hosts
文件中找到其对应的 IP
地址,然后再用这个 IP
地址去访问对应的服务。
但这样太麻烦了,于是产生了 DNS
系统。
IP
和主机名的对应关系。
IP
变更,就需要将对应信息注册到数据库中。
DNS
服务器,由 DNS
服务器检索数据库,得到对应的 IP
地址。
至今,我们的计算机上仍然保留了 hosts
文件,这个 hosts
文件当中一般存储的是主机名与 IP
地址之间的映射,用户也可以在 hosts
文件中自主添加域名和 IP
映射关系,在域名解析的过程中会优先查找 hosts
文件的内容。
通过 cat /etc/hosts
可以 linux
中查看 hosts
文件当中的内容:
此外,DNS
是基于 UDP
协议的!
域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称,例如www.baidu.com
。
com
:一级域名,表示这是一个工商企业域名。同级的还有 .net
(网络提供商)和 .org
(开源组织或非盈利组织)等。baidu
:二级域名,一般对应的就是公司名。www
:只是一种习惯用法,之前人们在使用域名时,往往命名成类似于ftp.xxx.xxx/www.xxx.xxx这样的格式,来表示主机支持的协议。在浏览器中输入 url
后,如果 url
当中包含域名,则需要进行域名解析。
DNS
缓存 中去查询是否有对应的记录,如果查询到记录就可以直接得到对应的 IP
地址,完成解析。DNS
缓存中没有找到,就会去查询操作系统中的 DNS
缓存,如果查询到对应的 IP
地址则完成解析。DNS
缓存 中没有找到,就会去查找本地的 hosts
文件,如果查询到对应的 IP
地址则完成解析。hosts
文件 中也没有找到,就会去本地 DNS
服务器中查找。本地 DNS
服务器 IP
地址一般由本地网络服务商提供,如电信、移动等公司,一般通过 DHCP
自动分配。目前使用的比较多的是谷歌提供的公用 DNS 8.8.8.8
和国内公用 DNS 114.114.114.114
。如果在本地 DNS
服务器中有对应域名的缓存,则直接返回对应的 IP
地址,完成解析。DNS
服务器 中仍然没有找到,那么本地 DNS
服务器就会拿着域名去 根 DNS
服务器 中询问,根 DNS
服务器会告诉本地 DNS
顶级域名服务器的 IP
地址。DNS
拿到顶级域名服务器的 IP
地址后,就会拿着域名去找 顶级 DNS
服务器,顶级域名服务器会告诉本地 DNS
权威域名服务器的 IP
地址。DNS
服务器拿着域名去 权威域名服务器 中,查询域名对应的 IP
地址,最终将该域名对应的 IP
地址返回给浏览器,此时整个域名解析过程就完成了。 我们可以使用 dig
工具来查看域名解析的过程,例如查看百度域名www.baidu.com
的解析过程。
dig
工具的分析结果如下:
结果解释:
dig
工具的版本号。status
参数为 NOERROR
表示查询成功。QUESTION SECTION
表示待查询的域名。ANSWER SECTION
表示查询的结果,其说明 www.baidu.com 被查询成了两个具体的 IP
地址。DNS
服务器的地址等。更多 dig
的使用方法,参考:linux dig 命令使用方法
向浏览器输入框中输入 url
如果 url
中存在域名,那么就会触发 DNS
DNS
的查找有以下过程: 应用层向目标 web
服务器发送 HTTP
请求
应用层客户端会发送一个HTTP请求,内容如下:
GET /sample.jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=liren&password=1234
这里的请求包含三个部分:
传输层进行 TCP
协议进行通信
网络层 IP
协议进行路由的选择,并且通过 ARP
协议进行对目标主机 MAC
地址的查询
数据链路层传输
服务端接收到数据,根据每层的协议格式和内容,层层往上交付
服务端应用层拿到了 HTTP
请求之后,拆下请求报头进行分析
根据 HTTP
请求需要,获取服务端的 HTML
等静态资源并进行响应
浏览器发送并获取嵌入到 HTML
文档里边的对象
浏览器通过 AJAX
向服务端进行异步请求
至此,所有的准备工作都已做好,你就可以开始和网页进行交互了!
网际控制报文协议 ICMP
(Internet Control Message Protoco
)用于在 IP
主机、路由器之间传递控制信息,是一个 网络层之上,传输层之下的一个协议。
一个新搭建好的网络,往往需要先进行一个简单的测试,来验证网络是否畅通。但是 IP
协议并不提供可靠传输,如果丢包了,IP
协议并不能通知传输层是否丢包以及丢包的原因。
在 TCP/IP
四层模型中,网络协议栈自顶向下分为应用层、传输层、网络层和数据链路层。
其中应用层最典型的协议有 HTTP
、HTTPS
和 DNS
等,传输层最典型的协议有 TCP
和 UDP
,网络层最典型的协议就是 IP
,数据链路层最典型的协议就是 MAC
帧协议,但实际网络层还有两种协议叫做 ICMP
和 IGMP
。
ICMP
、IGMP
、IP
协议虽然都属于网络层的协议,但 ICMP
和 IGMP
协议其实属于 IP
的上层协议。
IP
的上层协议不一定就直接是传输层的协议,IP的上层协议有可能也属于网络层的协议,但就是位于 IP
的上层。ARP
协议和 RARP
协议,这两个协议虽然与 MAC
帧协议都属于数据链路层,但这两个协议属于 MAC
帧的上层协议。ICMP
的主要功能包括:
IP
包是否成功到达目标地址ICMP
只能搭配 IPv4
使用,如果是 IPv6
的情况下,需要使用 ICMPv6
举个例子,比如当主机 A
在向主机 B
发送数据的过程中,主机 B
因为某些原因已经离线了。
当发送的数据包到达主机 B
所在局域网的入口路由器时,入口路由器为了获得主机 B
的 MAC
地址,于是会向主机 B
发送 ARP
请求包,但由于主机 B
已经离线了,因此路由器在多次发送 ARP
请求包而得不到响应后,就会返回一个 ICMP Destination Unreachable
的包给主机 A
,此时主机 A
就知道自己发送的数据无法到达主机 B
。
ICMP
大概分为两类报文:
ICMP
包常见类型如下:
ping
命令是基于 ICMP
协议实现的,通常用于测试本地主机与另一台主机之间的通信信道是否正常。
例如,使用 ping www.baidu.com
命令,测试本地主机与百度服务器之间的通信信道是否正常。
ping
的是百度的域名,该域名会由 DNS
解析成 IP
地址。ping
命令不仅能验证网络的连通性,同时也会统计响应时间和生存时间 TTL
(IP包中的Time To Live)。ping
命令会先发送一个 ICMP Echo Request
给对端;当对端接收到之后,会返回一个 ICMP Echo Reply
。 一个很坑的问题:telnet
对应的端口号是 23
,ssh
对应的端口号是 22
,那 ping
对应的端口号是多少❓❓❓
这是问问题的人设的一个圈套,ping
命令是基于网络层的 ICMP
协议,而端口号是属于传输层的内容,因此 ICMP
协议根本就不关心端口号这样的信息。
因此,ping
命令实际是绕过了传输层的,在 Linux
当中实际也有绕过传输层的一套网络编程接口,叫做 原生套接字。
traceroute
命令也是基于 ICMP
协议实现的,traceroute
命令可以遍历数据包传送到目标主机所经过的所有路由器。
例如,使用 traceroute www.baidu.com
命令,遍历数据包传送到百度服务器所经过的所有路由器。
原理简述:
traceroute
命令底层实际是 通过增加存活时间 TTL
值来实现的。TTL
值就会减 1
,当 TTL
值减为 0
时对应路由设备就会将该数据包丢弃,并传送一个 ICMP TTL
数据包给发送主机。traceroute
命令底层可以发出多个数据包,并给这些数据包设置不同的 TTL
值,最后该主机就能够得到一连串的数据包路径。 网络地址转换 NAT
(Network Address Translation)技术,是 缓解 IP 地址不足的主要手段,并且能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。
在 IPv4
协议中,IP
地址数量不足是一个大问题,而 NAT
技术就是当前解决IP地址不够用的主要手段,是路由器的一个重要功能。
在进行对外通信时,NAT
能够将私有 IP
经过一系列替换操作最终转为全局 IP
,也就是说,NAT
是一种将私有 IP
和全局 IP
相互转化的技术方法。而其中 装有 NAT
软件的路由器叫做 NAT
路由器,所有使用私有 IP
的主机在和外界通信时,都要在 NAT
路由器上将其私有 IP
转换成全局 IP
。
很多学校、家庭、公司内部每个终端设置的 IP
都是私有 IP
,而只在路由器或必要的服务器上设置全局 IP
。全局 IP
要求唯一,但是私有 IP
不需要,在不同的局域网中出现相同的私有 IP
是完全不影响的。
NAT
:实现固定私网主机地址到公网地址的一对一转换,适用于上网用户少,且同时上网用户数量与公网地址数量相同的场景NAT
:私网主机地址与公网地址的动态转换,并没有固定映射关系NAPT
:同时进行地址和端口的转换的 NAT
,可以实现多个私网地址对应同一个公网地址的转换,不同的私网地址数据使用相同公网地址时使用不同的端口进行转换,适用于公网地址数量少,但是私网用户数量大的场景。 假设某个局域网当中有 A
、B
、C
三台主机,在公网当中有一台服务器,以主机 A
访问公网中的这台服务器为例,我们来看看数据包在传输过程中 IP
地址的转换过程。
主机 A
向服务器发起数据请求的过程中,数据包中 IP
地址的转换过程如下:
IP
地址就是主机 A
的私有 IP
地址,目的 IP
地址就是服务器的公网 IP
地址。NAT
路由器时,路由器会将该数据包的源 IP
地址替换成自己的 WAN
口 IP
地址,此时该数据包的源和目的 IP
地址就都是公网 IP
了。A
的数据请求并处理后,就会对主机 A
发来的请求进行响应。服务器向主机 A
进行响应的过程中,数据包中 IP
地址的转换过程如下:
IP
地址就是服务器的公网 IP
地址,目的 IP
地址就是路由器的 WAN
口 IP
地址。A
所在局域网的 NAT
路由器,此时路由器会将该数据包的目的 IP
地址替换成主机 A
的私有 IP
地址。A
。 所以我们就能看出,这台从局域网到公网的 NAT
路由器是很重要,它实现了进出的 IP
转化!
问题来了,因为有可能一个局域网中有多台主机都访问了外网中同一个服务器,那 NAT
路由器是如何判断,应该将从外网收到的响应数据包转发给局域网中的哪一台主机呢?
NAT
路由器内部有一张自动生成的,用于地址转换的表。该转换表中维护的就是局域网中主机的私有 IP
,与其对应访问的外网当中的某个公网 IP
之间的映射关系。TCP
建立连接时,会建立对应的映射关系,在 TCP
断开连接后,就会删除对应的映射关系。 在刚才的例子中,主机 A
第一次向服务器发起数据请求时,路由器中就会建立以下映射关系。
当 NAT
路由器收到服务器向主机 A
发来的响应数据时,就可以通过查表得知该响应数据是发送给局域网当中的主机 A
的。
但如果转换表中维护的只是局域网中主机的私有 IP
,与其对应访问的外网当中的某个公网 IP
之间的映射关系,那么就会出现某些问题:如果局域网中的主机 A
和主机 B
同时都在访问该服务器,那么此时转换表中就会建立如下两对映射关系:
此时这张转换表只能保证从左到右的唯一性,而 不能保证从右到左的唯一性,当服务器发来响应数据时,该数据包中的目的 IP
地址都是路由器的 WAN
口 IP
,此时 NAT
路由器就无法判断该数据包应该转发给主机 A
还是主机 B
,这时候 NAPT
就来解决这个问题了!
网络地址端口转换 NAPT
(Network Address Port Translation)可以将多个内部地址映射为一个合法公网地址。
原理就是 NAPT
在 建立转换表的映射关系时,除了建立局域网中私有 IP
与其对应访问的公网 IP
之间的映射关系外,还会加上一个由 NAT
路由器选定的端口号。
此时当局域网中的多台主机同时访问同一个外网服务时,虽然外网发来的响应数据的目的 IP
地址都是路由器的 WAN
口 IP
,但发给局域网中不同主机的响应数据对应的目的端口号是不同的,此时路由器就能通过 IP + Port
的方式来区分发给不同主机的数据包。
举个例子,比如局域网中的主机 A
和主机 B
都在访问同一个服务器,并且它们访问服务器时采用的端口号都是 1025
。
A
发送的数据包先到达路由器,此时路由器将数据包的源 IP
地址替换成自己的 WAN
口 IP
地址,由于路由器用于访问该服务器的 1025
号端口没有被使用,因此该数据包的源端口号可以不变。B
发来的数据包到达路由器时,路由器同样将数据包的源 IP
地址替换成自己的 WAN
口 IP
地址,但此时路由器用于访问该服务器的 1025
号端口已经被主机 A
使用了,因此路由器会重新选定一个端口号对数据包的源端口号进行替换。此时转换表中就会建立如下两队映射关系:
此时这张转换表既能保证从左到右的唯一性,也能保证从右到左的唯一性。
A
和主机 B
的数据包对应的目的 IP
地址是一样的。但路由器是用自己的 1025
号端口代替主机 A
进行数据请求的,而用的是 1026
号端口代替主机 B
进行数据请求的。A
还是主机 B
,进行对数据包中的目的 IP
地址和目的端口号进行替换,然后转发给局域网内对应的主机。 路由器是工作在网络层的一个设备,负责将数据包从一个网络转发到另一个网络,但不能狭义的认为路由器只能工作在网络层。
NAT
路由器在进行数据转发时,不仅有能力替换数据包的源和目的 IP
地址,而且在必要的情况下还可能会替换数据包的源和目的端口号,而端口号实际是传输层的概念。IP
地址进行动态管理,大部分路由器都带有 DHCP
功能,而 DHCP
实际是应用层的一个协议。 因此 现在的路由器其实并不仅仅提供网络层相关的服务,网络协议栈中的各层路由器可能都有涉及。
NAT
技术进行私网和公网之间的替换,主要就是依赖 NAT
路由器当中维护的网络地址转换表,但这张转换表也体现出了 NAT
的一些缺陷:
NAT
外部向内部服务器建立连接,因为 外部无法知道内部的私网 IP
,也就无法主动与内部服务器建立连接。NAT
设备异常,即使存在热备,所有的 TCP
连接也都会断开。 代理服务器(Proxy Server
)的功能就是代理网络用户去取得网络信息,代理服务器又分为 正向代理和反向代理。
正向代理,是一个位于客户端和目标服务器之间的服务器,客户端并不直接访问目标服务器,而是先访问代理服务器,由代理服务器代替客户端去访问对应的目标服务器,并将目标服务器的响应结果返回给客户端。
比如公司内部一般都会有自己的服务器,当我们使用公司内网上网时。
正向代理的好处:
反向代理,也是一个位于客户端和目标服务器之间的服务器,对于客户端而言,反向代理服务器就相当于目标服务器,用户不需要知道目标服务器的地址,用户只需要访问反向代理服务器就可以获得目标服务器提供的服务。
比如域名 www.baidu.com 对应的服务器实际就是一个反向代理服务器。
反向代理的好处:
需要注意的是,代理服务器的主要工作只是对数据进行转发,因此代理服务器处理数据的压力不会特别大,并且代理服务器也可以有多个,因此 不必担心代理服务器过载的情况。
正向代理和反向代理的相同点:
正向代理和反向代理的不同点:
正向代理,代理的是客户端,类似于房产中介,替我们跟房东交互,把我们的请求交给房东,把房东的回复交给我们,比较典型的就是 VPN
以及一些翻墙代理服务器,一般都是客户端架设的。
反向代理,代理的是服务器,类似于二房东,你以为你跟房东交互租房呢,其实不是,你是在跟二房东租房,反向代理通常由服务器端假设,隐藏服务器 IP
,并实现静态资源缓存以及负载均衡的作用。
NAT
和代理服务器都是代替我们向服务器发起数据请求的,但它们有如下区别:
NAT
设备是网络基础设备之一,解决的是 IP
不足的问题;而 代理服务器则是更贴近具体应用,解决的是加速资源访问以及服务器的负载均衡等,比如通过代理服务器进行翻墙,另外像迅游这样的加速器,也是使用的代理服务器。NAT
工作在网络层,直接对 IP
地址进行替换,而 代理服务器往往工作在应用层。NAT
一般在局域网的出口部署,而代理服务器可以在局域网代理,也可以在广域网代理,也可以跨网代理。NAT
一般集成在防火墙、路由器等硬件设备上,而 代理服务器则是一个软件程序(比如 Nginx
和 Apache
),需要部署在服务器上。