0%

计算机网络学习(todo)

既然是干网安的,计网知识还是得恶补一下的,(之前学的太水了)

基础篇

TCP/IP网络模型有几层

为什么要有TCP/IP网络模型

对于不同设备上的进程间通信,需要网络通信,但是设备是多样的,所以要兼容多种多样的设备,因此协商出了一套通用的网络协议。这个网络协议是分层的,每一层各有作用和职责。

应用层

最上层的,我们能直接接触到的就是应用层(Application Layer)。应用层只需要专注于为用户提供应用功能,比如HTTP、FTP、Telnet、DNS、SMTP等。应用层不关心数据如何传输,类似于寄快递只需把包裹交给快递员,而不用关心如何运输。

应用层是工作在操作系统中的用户态,而传输层及以下工作在内核态。

传输层

应用层的数据包会传给传输层,传输层(Transport Layer)是为应用层提供网络支持的。传输层有两个协议,分别是TCP和UDP。

TCP(Transmission Control Protocol),传输控制协议,大部分应用使用的是TCP传输层协议,比如HTTP应用层协议,TCP比UDP多了很多特性,比如流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。

UDP相对比较简单,只负责发送数据包,不保证数据包能否抵达对方,但它的实时性更好,传输效率更高。UDP也可以实现可靠传输,把TCP的特性在应用层实现就可以了,但是要实现一个可靠的UDP传输协议不是一个简单的事。

当传输层的数据包大小超过MSS(TCP最大报文段长度),就要将数据包分块,这样即使中途有一个分块丢失或者损坏了,只需要重新发送这一个分块,而不用发送整个数据包。在TCP协议中,我们把每个分块称为一个TCP段(TCP Segment)

当设备作为接收方时,传输层则要负责将数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据,因此需要用一个编号将应用区分开来,这个编号就是端口。比如80端口通常给Web服务器,22端口通常是远程登录服务器用的,而浏览器的每个标签页都代表一个独立的进程,会分配临时的端口号。

在传输层的报文中会携带端口号,因此接收方可以识别出该报文是发送给哪个应用。

网络层

网络层(Internet Layer),实际负责传输功能,最常用的协议是IP协议,IP协议会将传输层的报文作为数据部分,再加上IP包头组装成IP报文,如果IP报文大小超过MTU(以太网中一般为1500字节)就会再次分片,得到一个即将发送到网络的IP报文。

网络层负责将数据从一个设备传输到另一个设备,世界上那么多设备,又该如何找到对方呢?因此网络层需要有区分设备的编号。

我们一般用IP地址给设备进行编号,对于IPv4协议,IP地址总共32位,分成了4段,每段8位。只有一个单纯的IP地址可以做到区分设备,但是寻址起来就特别麻烦,全世界那么多设备,怎么可能一个一个去匹配?

因此需要将IP地址分成两种意义:

  • 一个是网络号,负责标识该IP地址是属于哪个[子网]的。
  • 一个是主机号,负责标识同一[子网]下的不同主机。

这里需要配合子网掩码才能算出IP地址的网络号和主机号。

比如10.100.122.0/24,后面的/24表示255.255.255.0子网掩码,其二进制有24个1,为了简化子网掩码的表示,用/24代替255.255.255.0。

对10.100.122.0/24和255.255.255.0进行按位与运算,就可以得到网络号。

将255.255.255.0取反后与IP地址进行按位与运算,就可以得到主机号。

在寻址中,先匹配到相同的网络号,即找到同一子网,再去找对应的主机。

除了寻址能力,IP协议还有另一个重要的能力就是路由。在实际场景中,两台设备并不是用一条网线连接起来的,而是通过很多网关、路由器、交换机等众多网络设备连接起来的,那么就会形成很多条网络的路径,因此当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径。

路由器寻址中,就是要找到目标地址的子网,找到后进而把数据包转发给对应的网络内。

所以,IP协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走,路由则是根据下一个目的地选择路径。寻址更像是在导航,路由更像是操作方向盘。

网络接口层

生成IP头部后,接下来要交给网络接口层(Link Layer)在IP头部的前面加上MAC头部,并封装成数据帧(Data Frame)发送到网络上。

IP头部中的接收方IP地址表示网络包的目的地,通过这个地址我们就可以判断要将包发到哪里,但在以太网的世界中,这个思路是行不通的。

什么是以太网呢?电脑上的以太网接口,Wi-Fi接口,以太网交换机,路由器上的千兆、万兆以太网接口,还有网线,它们都是以太网的组成部分,以太网就是一种在[局域网]内,把附近的设备连接起来,使它们之间可以进行通讯的技术。

以太网在判断网络包目的地时和IP的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而MAC头部就是干这个用的,所以,在以太网进行通讯要用到MAC地址。

MAC头部是以太网使用的头部,它包含了接收方和发送方的MAC地址等信息,我们可以通过ARP协议获取对方的MAC地址。所以说,网络接口层主要是为网络层提供[链路级别]传输的服务,负责在以太网、WiFi这样的底层网络上发送原始数据包,工作在网卡这个层次,使用MAC地址来标识网络上的设备。

总结

TCP/IP网络通常是由上到下分成4层,分别是应用层,传输层,网络层和网络接口层

网络接口层的传输单位是帧(frame)IP层的传输单位是包(packet)TCP层的传输单位是段(Segment)HTTP层的传输单位是消息或者报文。它们没有什么本质区别,可以统称为数据包。

键入网址到网页显示,期间发生了什么

HTTP

首先浏览器做的第一步工作就是对URL进行解析,从而生成发送给Web服务器的请求信息。我们现在来对URL进行解析。

所以这个请求实际上是请求服务器里的文件资源,若是上述蓝色部分的URL元素都省略了,则是请求根目录下设置的默认文件,这样就不会造成混乱了。

URL解析后,浏览器确定了Web服务器和文件名,接下来就是根据这些信息来生成HTTP请求消息了。

真实地址查询——DNS

通过浏览器解析URL并生成HTTP消息后,需要委托操作系统将消息发送给Web服务器。发送之前,必须查询服务器域名对应的IP地址,因为委托操作系统发送消息时,必须提供通信对象的IP地址。而这需要通过DNS服务器,这种服务器专门保存了Web服务器域名与IP的对应关系。

  • 域名的层级关系:DNS中的域名都是用句号分割的,如www.server.com,这里的句号代表了不同的界限。在域名中,越靠右的位置表示其层级越高

实际上,域名最右边还有一个句号,如www.server.com.,最后一个点代表根域名。也就是说,.根域在最顶层,它的下一层就是.com顶级域,再下面是server.com。所以域名的层级关系类似一个树状结构。

  • 根DNS服务器.
  • 顶级域DNS服务器.com
  • 权威DNS服务器.server.com

根域的DNS服务器保存在互联网中所有的DNS服务器中,任何DNS服务器就都可以找到并访问根域DNS服务器了,因此,客户端只要能找到任意一台DNS服务器,就可以通过它找到根域DNS服务器,再一路找到位于下层的某台目标DNS服务器。

域名解析工作流程

  1. 客户端首先会发出一个DNS请求,询问www.server.com的IP是啥,并发给本地DNS服务器(也就是客户端的TCP/IP设置中的DNS服务器地址)。
  2. 本地域名服务器收到客户端请求后,如果缓存中能找到www.server.com,则它直接返回IP地址。如果没有,本地DNS会去问它的根域名服务器,根域名服务器是最高层次的,它不直接用于域名解析,但是能指明一条明路。
  3. 根DNS服务器收到来自本地DNS的请求后,发现后置是.com,于是将.com顶级域名服务器地址返回给本地DNS服务器。
  4. 本地DNS服务器收到顶级域名服务器地址后,于是询问顶级域名服务器获取IP地址。
  5. 顶级域名服务器给出www.server.com区域的权威域名服务器地址。
  6. 本地域名服务器向权威域名服务器请求获取IP地址。
  7. 权威域名服务器查询后将对应的IP地址告诉本地DNS。
  8. 本地DNS再将IP地址返回客户端,客户端与目标建立连接。

DNS解析域名的过程是只指路不带路

缓存系统

浏览器解析域名并不是每次都会经历这么多步骤,因为有缓存的存在。浏览器会先看看自身有没有这个域名的缓存,如果没有,则去问操作系统,若操作系统也无,则去问hosts文件,都没有,才会去询问本地DNS服务器。

协议栈

DNS获取到IP后,就会把HTTP的传输工作交给操作系统中的协议栈

应用程序调用Socket库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的TCP和UDP协议,这两个传输协议会接受应用层的委托执行收发数据的操作。

协议栈的下半部分是用IP协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由IP负责的。

IP中还包括ICMP协议和ARP协议。

  • ICMP协议用于告知网络包传送过程中产生的错误以及各种控制信息。
  • ARP用于根据IP地址查询相应的以太网MAC地址。

IP下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收操作。

可靠传输——TCP

先看一下TCP报文头部的格式

首先,源端口号目的端口号不可缺少,不然数据不知道该发给哪个应用。

接下来有包的号,用于解决包的乱序问题。

还有就是确认号,目的是确认发出去对方有没有接收到。若没有则重新发送,用于解决丢包问题。

然后是状态位SYN代表发起一个连接,ACK为回复,RST为重新连接,FIN是结束连接。TCP是面向连接的,因而双方要维护连接的状态,这些带状态位的包的发送,会引起双方的状态变更。

窗口大小,TCP要做流量控制,通信双方各声明一个窗口(缓存大小),标识当前的处理能力。

TCP还会做拥塞控制,对于真正的通路堵车不堵车,它无能为力,唯一能做的就是控制自己。

TCP传输数据前,要先进行三次握手建立连接

  • 一开始,客户端和服务端都处于CLOSED状态,先是服务端主动监听某个端口,处于LISTEN状态。
  • 然后客户端主动发起连接SYN,之后处于SYN-SENT状态。
  • 服务端收到发起的连接,返回SYN,并且ACK客户端的SYN,之后处于SYN-RCVD
  • 客户端收到服务端发送的SYNACK之后,发送对SYN确认的ACK,之后处于ESTABLISHED状态,因为他一发一收成功。
  • 服务端收到ACK后,处于ESTABLISHED状态,因为它也一发一收成功了。

三次握手的目的是保证双方都有发送和接收的能力

如何查看TCP的连接状态?

TCP的连接状态查看,在linux中可以用netstat -napt命令查看。

TCP分割数据

如果HTTP请求的消息比较长,超过了MSS的长度,这时TCP就需要把HTTP的数据拆解成一块块的数据发送,而不是一次性发送所有的数据。

  • MTU:一个网络包的最大长度,以太网中一般为1500字节。
  • MSS:除去IP和TCP头部之后,一个网络包所容纳的TCP数据的最大长度。

数据会被以MSS的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。也就是在每个被拆分的数据加上TCP头信息,然后交给IP模块来发送数据。

TCP报文生成

TCP协议中会有两个端口,一个是浏览器监听的端口(通常是随机生成的),一个是Web服务器监听的端口(HTTP默认端口号是80,HTTPS默认端口号是443)。

在双方建立连接后,TCP报文中的数据部分就是存放HTTP头部+数据,组装好TCP报文之后,就需要交给下面的网络层处理。

至此,网络包的报文如下图:

远程定位——IP

TCP模块在执行连接、收发、断开等各阶段操作时,都需要委托IP模块将数据封装成网络包发送给通信对象。

IP报文头部的格式

在IP协议里面需要有源地址IP目的地址IP

  • 源地址IP,即是客户端输出的IP地址。
  • 目的地址,即是通过DNS域名解析得到的Web服务器IP。

因为HTTP是经过TCP传输的,所以在IP包头的协议号,要填写为06(十六进制),表示协议为TCP。

假设客户端有多个网卡,就会有多个IP地址,那IP头部的源地址应该选择哪个IP呢?

当存在多个网卡时,在填写源地址IP时,就需要判断到底需要填写哪个地址。这个判断相当于在多个网卡中判断应该使用哪个网卡来发送包。

这个时候就需要根据路由表规则,来判断哪一个网卡作为源地址IP。

在linux操作系统,我们可以使用route -n命令查看当前系统的路由表。