目录
数据链路层
认识以太网
局域网转发的原理
认识以太网的MAC报头
以太网帧格式
认识MAC地址
对比理解MAC地址和IP地址
基于MAC帧协议再次谈一谈局域网转发的原理
认识MTU
MTU对IP协议的影响
MTU对UDP协议的影响
MTU对于TCP协议的影响
ARP协议
ARP协议的作用
ARP数据报的格式
ARP协议的工作流程
其他重要协议或技术(简单了解)
DNS(Domain Name System)
DNS背景
域名简介
ICMP协议
ICMP功能
ICMP的报文格式(了解)
ping命令
traceroute命令
NAT技术
NAT技术背景
NAT IP转换过程
NAPT
NAT技术的缺陷
NAT和代理服务器
用于两个设备(同一种数据链路节点)之间进行传递。
上一篇文章里讲了网络层IP协议,知道了IP数据包通过路由器转发可以一跳一跳的到目标主机,但是实际在网络中“跑”的并不是IP数据包,而是MAC帧协议封装的数据包。
要想将数据包从主机A跨网络发送给主机B,首先主机A要将数据包发送给离它最近的那个路由器,这个路由器要和主机A处在同一个子网内,然后通过路径选择、路由器转发,最终将数据包发送给主机B。而跨网络传输的本质是由无数个局域网(子网)转发的结果。要彻底理解跨网络转发,首先要理解局域网中报文的转发原理。
问个问题:在同一个局域网的主机能不能直接通信?当然可以!
举个例子:就好比老师上课时,叫某一个同学的名字,并问他为什么作业没做?此时处在教室的其他同学也是可以听到老师说话的,然后那个同学对老师说:老师我做了只不过还没有上交,此时其他同学依旧可以听到消息,在局域网中也是一样的,只不过其他主机辨识到该消息并不是给自己发的,所以丢弃了。通过上面的例子我们知道,每台主机都要有唯一标识符。
IP报文封装好以后还需要继续向下交付给数据链路层,而数据链路层要继续对数据包进行封装,接下来让我们一起认识MAC报头格式。
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址), 长度是48位,是在网卡出厂时固化的;
- 帧协议类型字段有三种值,分别对应IP、ARP、RARP;
- 帧末尾是CRC校验码。
这里还是那两个问题,如何分离?如何分用?
MAC地址用来识别数据链路层中相连的节点,长度为48位,及6个字节, 一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)。在网卡出厂时就确定了,不能修改, MAC地址通常是唯一的(虚拟机中的MAC地址不是真实的MAC地址, 可能会冲突, 也有些网卡支持用户配置MAC地址)。
IP地址描述的是路途总体的 起点 和 终点;
MAC地址描述的是路途上的每一个区间的起点和终点。
我们现在知道了每个主机都有自己的MAC地址,那么在局域网中发送数据时,封装好MAC帧报文,再将报文发送到局域网中,局域网中的每个主机都会将报文拿上来,进行解析,去对比目的地址和自己的地址是否相同,如果不是发送给自己的就直接丢弃,如果是发送给自己,那就解析后交付给上层协议。既然有发送,那就有回复,回复也是一样的,
拓展知识:
在局域网中,网卡有一种模式叫混杂模式,表示不放弃任何一个数据帧,直接向上交付,这就是局域网抓包工具的原理。
我们的数据能被抓到,那么明文传输是不安全的(http),所以又产出了新的加密解密的方式以及整数签名。这个在前面的文章HTTPS中有讲,有兴趣可以去看一看。
HTTPS协议原理_晚风不及你的笑427的博客-CSDN博客
在局域网中一台主机可以给另一个主机发送数据,但是在同一时刻会不会有其他主机也再向网络中发送数据呢?就好比一间教室,老师在向某个同学提问,同时其他学生也在下面说话,那么整个教室就会乱糟糟的。所以在局域网中,任何一个时刻,只能有一个主机向网络发送数据。
那么问题来了,我们怎么知道某个时刻是否有其他主机在发送消息呢?我们不知道,如果同一个时刻多个数据被发送到网络中,就会导致局域网中的数据发生碰撞,发生碰撞之后数据就变成了无效数据,也就是说如果发生数据碰撞,那个该数据会直接被丢弃。那么我们怎么知道数据是否发生碰撞了呢?因为是局域网,所以我们发送的数据自己也能收到,如果我们发现数据和之前发送的对不上,检验通不过,我们就知道发生问题了。而我们把一个局域网称为一个碰撞域。
那我们怎么保证一个时刻只允许一个主机向网络发送数据呢?不同的局域网通信标准,就有不同的实现方案,1.是令牌环,在局域网中有一部分令牌的数据,只有持有令牌的主机才能发送消息,发送消息后将令牌转到网络中带给下一个人;2.以太网,简单来说就是主机发送数据后检测到发生碰撞了,那先不发了,等一等,这个等的时间根据情况来定,等过一会再进行重发策略。这个重发的策略可不止TCP有数据链路层也有对应的策略,叫主机的碰撞检测和碰撞避免算法。只要每个主机在MAC帧层都能遵守这个碰撞避免的规则,那么就能保证一个时刻只有一个主机发送数据。
用一个新的视角(系统视角)重新看待局域网,因为同一个时刻只有有一个主机发送消息,局域网就相当于是一个临界资源,那么临界资源就需要被保护起来,保护的方式有很多,碰撞检测和碰撞避免就是一种,所以说知识是有关联性的!
- 局域网能不能很大呢?为什么?
不能!因为局域网太大,主机很多,那么任何时刻发生碰撞的概率就会增加。
那如果局域网就是很大怎么办呢?会在局域网中添加一个交换机,将局域网一分为二,如果左半部分内主机想给右半部分的主机发数据,交换机识别到左半部分有局部碰撞,那么对碰撞数据不做转发;正常情况下,也是该转发转发,但是左半部分内的主机对左半部分内的主机发送数据,交换机是不会做数据转发的。这样就是把大的局域网划成了两个子区域,子区域内的主机发送数据是正常的,要跨区域发送数据就需要交换机来转发数据了,感觉很像路由器有没有。
- 因为有碰撞域,所以一台主机发送的数据量是长了好?还是短了好?为什么?
如果把两个方向推向极端化,数据量特别长的时候,占用网络这个资源的时间就特别长,那么局域网中碰撞的概率就会大大增加,太短的话,一直频繁的发也不好,影响效率。所以就规定MAC帧最大长度不超过1500字节,这个称为MTU。
MTU相当于发快递时对包裹尺寸的限制,这个限制是不同的数据链路对应的物理层,产生的限制。以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位。最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU。
如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation)。不同的数据链路层标准的MTU是不同的。
由于数据链路层MTU的限制,对于较大的IP数据包要进行分包。将较大的IP包分成多个小包,并给每个小包打上标签,每个小包IP协议头的 16位标识(id) 都是相同的,每个小包的IP协议头的3位标志字段中, 第2位置为0,表示允许分片,第3位来表示结束标记(当前是否是最后一个小包, 是的话置为0,否则置为1)。
到达对端时再将这些小包按顺序重组,拼装到一起返回给传输层,一旦这些小包中任意一个小包丢失,接收端的重组就会失败,但是IP层不会负责重新传输数据。
我们知道如果数据长度超过MTU,IP会进行分片,那么问题来了,路由器会分片吗?答案是会的,前面说过数据链路层的标准不同MTU也是不同的,比如下个路由器要求只能收500字节的数据包,你这个路由器要传给下一个路由器,就只能进行分片,而IP协议中分片的三个字段也是支持路由器进行再次分片和组装的。
我们要知道将数据包从A主机跨网络传输到B主机,可能并不是只有一条路径供选择,如果数据包在主机已经分过片了,将三个标志位中禁止分片的标志位设为1,表示路上节点的路由器禁止分片,如果数据长度超过该路由器的MTU,该路由器会直接将数据包丢掉,丢掉之后发送方就要进行超时重传,重传时就要重新进行路径选择,那么就有可能重新找到一条支持我们这个数据包长度转发的路径,所以我们就找到一条最大吞吐量的网络路径。网络的世界很复杂,但是演变到今天,一定是有依据做支撑的。
在之前TCP滑动窗口那里有一个细节没有说,就是滑动窗口范围内为什么要有多个报文段?直接把滑动窗口内的数据搞成一个报文发送不就完了吗,为什么还要按一段一段的发送呢?
那是因为数据链路层不允许一次发送太大的单个数据段,如果执意要发送大数据段,那么压力就到了IP身上,IP被迫进行分片,分片之后丢包概率增加,IP还要背锅,不能可着一个羊薅毛啊,所以这几层协议之间是相互有影响的。
让我们回顾一下UDP协议:
一旦UDP携带的数据超过1472(1500 - 20(IP首部) - 8(UDP首部)), 那么就会在网络层分成多个IP数据报。这多个IP数据报有任意一个丢失,都会引起接收端网络层重组失败。那么这就意味着,如果UDP数据报在网络层被分片,整个数据被丢失的概率就大大增加了。
让我们再回顾一下TCP协议:
TCP的一个数据报也不能无限大, 还是受制于MTU。TCP的单个数据报的最大消息长度,称为MSS(MaxSegment Size)。
TCP在建立连接的过程中,通信双方会进行MSS协商,最理想的情况下, MSS的值正好是在IP不会被分片处理的最大长度(这个长度仍然是受制于数据链路层的MTU)。
双方在发送SYN的时候会在TCP头部写入自己能支持的MSS值,然后双方得知对方的MSS值之后, 选择较小的作为最终MSS,MSS的值就是在TCP首部的40字节变长选项中(kind=2)。
MSS和MTU的关系
使用ifconfig命令,即可查看ip地址、 mac地址和MTU。
ARP协议不是一个单纯的数据链路层的协议,而是一个介于数据链路层和网络层之间的协议。
数据跨网络传输时通过路由器转发,千里迢迢来到了目标主机的子网路由器入口处,但是数据包中只有目的主机的IP地址,并没有目的主机的MAC地址,那么路由器是不知道要把数据发给子网中的哪台主机的,所以需要有一个过程或功能,让路由器知道你要发给它子网内的哪台主机,所以就有了ARP协议。他可以通过IP地址,获取目标主机的MAC地址。
ARP协议建立了主机 IP地址 和 MAC地址 的映射关系。
在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址。数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃,因此在通讯前必须获得目的主机的硬件地址。
前面的三个类型是属于MAC帧协议的字段,前面有说过,这里就不介绍了。
ARP是先对op字段进行解析,看看是请求还是响应,如果是请求就要封装响应并向下交付,如果是响应就构建IP和MAC的映射关系到缓存表中。为什么不先考虑前四个字段,因为前四个字段一般是固定的。
从上图可以看到,ARP协议是在MAC帧协议之上的单独的一个协议,是一个工具类协议。
路由器收到了一个数据包,这个数据包要转给主机B,但是路由器此时并不知道主机B的MAC地址,只知道IP地址,怎么办呢?那路由器只好封装一个ARP请求,再封装一个MAC帧,以广播的形式发送到子网中(MAC帧头部的目的MAC地址全F)。这时子网内的所有主机都可以收到这个MAC帧报文,收到后解析发现是ARP请求,交给ARP协议,ARP对这个请求进行解析,发现目的IP不是自己就直接丢弃,如果是自己,那么就填写自己的信息,封装一个ARP应答,此时这个应答是知道要发给谁的,所以直接发送即可,那么路由器收到应答后,每台主机/路由器都有缓存一个ARP缓存表,将IP地址和MAC地址建立映射关系,就知道主机B的MAC地址了,那么路由器就可以直接把数据包转发给主机B了。
注: 局域网中的发送不是像我们平时微信聊天一样直接发给某一个人,而是将目的MAC地址填写成具体的主机,这时局域网中的所有主机对对比这个目的MAC地址看是否是给自己发的,不是就丢弃,是就再继续向上层交付。
因为这个缓存表中的表项长时间不使用会失效,所以数据包在跨网络传输时ARP是会伴随着数据包一直发生的。
从上面可以看到ARP协议也是比较繁琐的,你不能来一次数据就查一次ARP,短时间内数据比较频繁的话,这不是消耗资源、浪费时间嘛,所以内部会有缓存表。
之前的文章中说过,因为是路由器是动态分配IP地址,所以在局域网中IP地址是会变的。IP地址会发生变化,这个表项长时间存在也没有意义。
虽然这种情况的概率很小,但是也会发生,此时就需要RARP,又叫逆地址解析(通过MAC地址得到IP地址),通过ARP我们知道RARP是比较简单的,为什么?因为ARP不知道对方的MAC地址,需要进行广播,但是RARP知道对方的MAC地址呀,所以直接针对MAC地址进行封装RARP,属于是定向发送,所以就会简单很多。
我们知道ARP里有缓存表,并且不用会消失,所以ARP收到应答的时候,一般会以最新的为主。
假设在一个子网中,有一个黑客(中间人),它把自己主机的IP地址伪装成路由器的IP,但是MAC地址是它自己的,然后不断地给子网内的某台主机(假设是主机B)发送ARP请求。因为IP地址和MAC地址只是一串数字,这个主机B它并不知道不断发送的ARP请求中的IP地址被更改过了,它就把这个黑客的主机当成路由器,同时黑客也在用同样的手段去不断地给路由器发送ARP请求,那么主机B以为黑客是路由器,而路由器以为黑客是主机B。如果有数据要发给主机B时,路由器就会将数据转给黑客的主机,而黑客获取到数据解析后、封装好再次转给主机B,主机B是不知道自己的数据被截取了的;而主机B向外发送数据,则先把数据交给黑客,黑客获取到数据解析后、封装好再次转给路由器,这样黑客能神不知鬼不觉的截取到主机B的消息,这就叫ARP欺骗。那么只要能截取到一台主机,那就能截取到局域网内的所有主机。
这里不涉及网络安全方面的知识,只是抛开现象见本质,当然现在互联网的网络安全还是可以的。在之前的HTTPS一文中有讲解,为了应对中间人攻击,而做的一些策略。
DNS是一整套从域名映射到IP的系统。
TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序,但是IP地址不方便记忆,于是人们发明了一种叫主机名的东西,是一个字符串,并且使用hosts文件来描述主机名和IP地址的关系。
最初, 是通过互连网信息中心(SRI-NIC)来管理这个hosts文件的,如果一个新计算机要接入网络,或者某个计算机IP变更,都需要到信息中心申请变更hosts文件。其他计算机也需要定期下载更新新版本的hosts文件才能正确上网,这样就太麻烦了,于是产生了DNS系统。
DNS系统:一个组织的系统管理机构, 维护系统内的每个主机的IP和主机名的对应关系。
如果新计算机接入网络, 将这个信息注册到数据库中,用户输入域名的时候, 会自动查询DNS服务器, 由DNS服务器检索数据库,得到对应的IP地址。至今,我们的计算机上仍然保留了hosts文件,在域名解析的过程中仍然会优先查找hosts文件的内容。
用指令 cat /etc/hosts 可以查看hosts文件的的内容。
主域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称。
www.baidu.com
域名使用 . 连接,
com:一级域名,表示这是一个企业域名。同级的还有 "net"(网络提供商),"org"(非盈利组织) 等。
baidu:二级域名,表示公司名。
www:只是一种习惯用法,之前人们在使用域名时,往往命名成类似于ftp.xxx.xxx/www.xxx.xxx这样的格式,来表示主机支持的协议。
ICMP协议是一个 网络层协议。
一个新搭建好的网络,往往需要先进行一个简单的测试,来验证网络是否畅通。 但是IP协议并不提供可靠传输,如果丢包了,IP协议并不能通知传输层是否丢包以及丢包的原因。
ICMP正是提供这种功能的协议, ICMP主要功能包括:
- 确认IP包是否成功到达目标地址;
- 通知在发送过程中IP包被丢弃的原因;
- ICMP也是基于IP协议工作的,但是它并不是传输层的功能,因此人们仍然把它归结为网络层协议;
- ICMP只能搭配IPv4使用,如果是IPv6的情况下, 需要是用ICMPv6;
ICMP大概分为两类报文:
- 一类是通知出错原因
- 一类是用于诊断查询
注意!!!有些面试官可能会问: telnet是23端口,ssh是22端口,那么ping是什么端口?
ping命令基于ICMP, 是在网络层。而端口号, 是传输层的内容, 在ICMP中根本就不关注端口号这样的信息!
也是基于ICMP协议实现, 能够打印出可执行程序主机, 一直到目标主机之前经历多少路由器。
之前我们讨论了, IPv4协议中,IP地址数量不充足的问题。NAT技术当前解决IP地址不够用的主要手段,是路由器的一个重要功能。
NAT能够将私有IP对外通信时转为全局IP,也就是就是一种将私有IP和全局IP相互转化的技术方法:很多学校,家庭,公司内部采用每个终端设置私有IP, 而在路由器或必要的服务器上设置全局IP,全局IP要求唯一, 但是私有IP不需要。 在不同的局域网中出现相同的私有IP是完全不影响的。
NAT路由器将源地址从10.0.0.10替换成全局的IP 202.244.174.37,NAT路由器收到外部的数据时, 又会把目标IP从202.244.174.37替换回10.0.0.10。在NAT路由器内部,有一张自动生成的,用于地址转换的表。当 10.0.0.10 第一次向 163.221.120.9 发送数据时就会生成表中的映射关系 。
那么问题来了, 如果局域网内,有多个主机都访问同一个外网服务器,那么对于服务器返回的数据中,目的IP都是相同的。那么NAT路由器如何判定将这个数据包转发给哪个局域网的主机呢?
这时候NAPT来解决这个问题了,使用IP + port来建立这个关联关系。那么有人会说,怎么还要port呢,直接将主机的源IP+目的IP 和 路由器的源IP + 目的IP 将这两个二元组建立映射关系不就好了?
我们要知道NAPT不光要解决的是 不同的主机访问相同的服务器的IP地址转化问题,还要解决同一台主机的 不同进程访问相同服务器的IP地址转化问题。如果没有端口号,怎么分辨哪个IP是主机的哪个进程呢。
上图中,在内网环境中一个主机的四元组(目的IP + 端口,源IP + 端口)一定是唯一的,通过NAT路由器转化之后 ,也一定是一个唯一的四元组。也就是说一台主机的四元组中有任意一元不同,转化后的四元组就是不同的。这个NAT转化表,是一个互为键值 的映射表。
这种关联关系也是由NAT路由器自动维护的,例如在TCP的情况下, 建立连接时,就会生成这个表项; 在断开连接后,就会删除这个表项。
由于NAT依赖这个转换表, 所以有诸多限制:
假如有一台主机从来没有访问过外网,那么外网是无法直接访问到内网的主机的,为什么呢?因为如果你没有访问过外网,那么NAT转换表中是没有你和外网的映射关系的,所以外网也无法准确找到你。
虽然NAT技术有缺陷,但是他的价值远远大于缺陷。
路由器往往都具备NAT设备的功能, 通过NAT设备进行中转,完成子网设备和其他子网设备的通信过程。代理服务器看起来和NAT设备有一点像,客户端像代理服务器发送请求,代理服务器将请求转发给真正要请求的服务器,服务器返回结果后,代理服务器又把结果回传给客户端。
那么NAT和代理服务器的区别有哪些呢?
- 从应用上讲,NAT设备是网络基础设备之一,解决的是IP不足的问题, 代理服务器则是更贴近具体应用,比如通过代理服务器进行, 另外像迅游这样的加速器,也是使用代理服务器。
- 从底层实现上讲, NAT是工作在网络层,直接对IP地址进行替换,代理服务器往往工作在应用层。
- 从使用范围上讲, NAT一般在局域网的出口部署,代理服务器可以在局域网做,也可以在广域网做, 也可以跨网。
- 从部署位置上看,NAT一般集成在防火墙, 路由器等硬件设备上,代理服务器则是一个软件程序, 需要部署在服务器上。
代理服务器是一种应用比较广的技术。
- :广域网中的代理。
- 负载均衡:局域网中的代理。
代理服务器又分为正向代理和反向代理。
- 反向代理用于请求的转发(例如借助代理绕过反爬虫)。
- 正向代理往往作为一个缓存。
举个例子:海南芒果很有名,到了成熟的季节,我自己去海南买费时还不省钱很不方便,但是我可以让在海南工作的表姐去超市买了快递给我。此时超市看到的买家是我表姐, 我的表姐就是 "反向代理";后来找我表姐买芒果的人太多了, 我表姐觉得天天去超市太麻烦,干脆去超市买了一大批芒果屯在家里, 如果有人来找她代购, 就直接把屯在家里的货发出去,而不必再去超市。 此时我表姐就是 "正向代理"。
一句话总结,离服务器近的是反向代理,离客户端近的是正向代理。