网络基础

月伴飞鱼 2024-09-19 18:50:41
计算机基础
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

网络模型

OSI七层模型

物理层:

解决两个硬件之间怎么通信的问题,常见的物理媒介有光纤、电缆、中继器等。

它主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。

它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换),这一层的数据叫做比特。

数据链路层:

在计算机网络中由于各种干扰的存在,物理链路是不可靠的。

该层的主要功能就是:通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。

它的具体工作是接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层,这一层的数据叫做帧。

网络层:

网络层负责将数据从一个设备传输到另一个设备

计算机网络中如果有多台计算机,怎么找到要发的那台?

  • 如果中间有多个节点,怎么选择路径?

该层的主要任务就是:

  • 通过路由选择算法,为报文(该层的数据单位,由上一层数据打包而来)通过通信子网选择最适当的路径。

  • 通过IP地址寻址。

传输层:

当发送大量数据时,很可能会出现丢包的情况,另一台电脑要告诉是否完整接收到全部的包。

  • 如果缺了,就告诉丢了哪些包,然后再发一次,直至全部接收为止。

简单来说,传输层的主要功能就是:

  • 监控数据传输服务的质量,保证报文的正确传输。

应用层的数据包会传给传输层,传输层是为应用层提供网络支持的。

传输层有两个传输协议:分别是 TCPUDP

image-20240903183619471

会话层:

虽然已经可以实现给正确的计算机,发送正确的封装过后的信息了。

但我们总不可能每次都要调用传输层协议去打包,然后再调用IP协议去找路由,所以我们要建立一个自动收发包,自动寻址的功能。

于是会话层出现了:它的作用就是建立和管理应用程序之间的通信。

表示层:

表示层负责数据格式的转换,将应用处理的信息转换为适合网络传输的格式,或者将来自下一层的数据转换为上层能处理的格式。

应用层:

应用层是计算机用户,以及各种应用程序和网络之间的接口:

  • 其功能是直接向用户提供服务,完成用户希望在网络上完成的各种工作。

当两个不同设备的应用需要通信的时候,应用就把应用数据传给下一层,也就是传输层

  • 应用层是不用去关心数据是如何传输的

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

TCP/IP4层模型

TCP/IP 模型是事实上的标准模型:

  • 在 七 层模型的基础上将最上面三层的应用层、表示层、会话层统一为应用层
    • 将数据链路层和物理层统一为链路层或者叫网络接口层。
image-20231114142542365

网络接口层的传输单位是帧

IP 层的传输单位是包

TCP 层的传输单位是段

HTTP 的传输单位则是消息或报文

img

数据发送和接收过程

数据从应用层进入,到达传输层,添加上 TCP首部,将数据加工成 TCP 段,称为 Segment:这是为了保证数据的可靠性。

接着数据到达网络层,在网络层使用 IP 协议,被添加上 IP 首部,将数据加工成 IP数据报,称为 datagram 。

经过网络层 IP 协议的加工,指定目标地址和 MAC 地址,保证数据准确的发送到目标机器。

接着数据到达链路层,添加上以太网头部,将数据加工成以太网帧,称为 frame,包含了网卡等硬件相关的数据。

image-20231114142934648

网络接口层

网络接口层在 IP 头部的前面加上 MAC 头部,并封装成数据帧发送到网络上。

MAC 头部是以太网使用的头部:

  • 它包含了接收方和发送方的 MAC 地址等信息,可以通过 ARP 协议获取对方的 MAC 地址。

网络接口层主要为网络层提供 链路级别 传输的服务:

  • 负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。
img

应用层

HTTP

请求报文组成

HTTP请求报文由3部分组成: 请求行 + 请求头 + 请求体

请求行:

  • 请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。

  • 请求对应的URL地址,它和报文头的Host属性组成完整的请求URL。

  • 协议名称及版本号。

请求头:

  • 是HTTP的报文头,报文头包含若干个属性,格式为 属性名:属性值,服务端据此获取客户端的信息。

  • 与缓存相关的规则信息,均包含在header中

请求体:

  • 是报文体,它将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。

  • 不但报文体可以传递请求参数,请求URL也可以通过类似于/chapter15/user.html? param1=value1&param2=value2的方式传递请求参数。

响应报文结构

HTTP的响应报文也由三部分组成:响应行 + 响应头 + 响应体

状态码

状态码由三位数字组成,第一个数定义了响应的类别,有五种可能取值

1xx:指示信息,表示请求已接收,继续处理

2xx:成功,表示请求已被成功接收、处理成功

3xx:重定向

4xx:客户端错误,请求有语法错误或者请求无法实现

5xx:服务器端错误,服务器未能实现合法的请求

301:永久重定向,在location响应首部的值为当前的url(隐式)

302:临时重定向,在location响应首部的值为新的url(显式)

GET和POST的区别

GET请求参数是通过URL进行传递的,POST请求的参数包含在请求体当中。

GET请求比POST请求更不安全,因为参数直接暴露在URL中,所以,GET请求不能用来传递敏感信息。

GET请求在url中传递的参数是有长度限制的(在HTTP协议中并没有对URL的长度进行限制,限制是特定的浏览器以及服务器对他的限制,不同浏览器限制的长度不同。),POST对长度没有限制。

GET请求参数会完整的保留在浏览器的历史记录中,POST请求的参数不会保留。

GET请求进行url编码(百分号编码),POST请求支持多种编码方式。

GET请求产生的URL地址是可以被bookmark(添加书签)的,POST请求不可以。

GET请求在浏览器回退的时候是无害的,POST请求会.再次提交数据。

GET请求在浏览器中可以被主动cache(缓存),而POST请求不会,可以手动设置。

GET产生一个TCP数据包。POST产生两个TCP数据包。

对于GET请求,浏览器会把http header和data一起发送出去,服务器响应200,请求成功。

对于POST请求,浏览器先发送header,服务器会响应100(已经收到请求的第一部分,正在等待其余部分),浏览器再次发送data,服务器返回200,请求成功。

Cookie

HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息)。

每个HTTP请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。

所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。

而这个状态需要通过 cookie 或者 session 去实现。

Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,实际上Cookie是服务器在本地机器上存储的一小段文本,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。

Cookie会根据 HTTP响应报文 里的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。

当下客户端再向服务端发起请求时,客户端会自动在请求报文中加入Cookie值之后发送出去。

之后服务端发现客户端发送过来的Cookie后,会检查是那个客户端发送过来的请求,然后对服务器上的记录,最后得到了之前的状态信息。

Set-Cookie: status=enable; expires=Wed, 13-Mar-2019 12:08:53 GMT; Max-Age=31536000; path=/;
 domain=fafa.com;secure; HttpOnly;

如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本 读取到该 cookie 的信息,但还是能通过 Application 中手动修改 cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全

Session

session 是基于 cookie 实现的,session 存储在服务器端,sessionID 会被存储到客户端的 cookie 中。

服务端执行session机制时候会生成 sessionID 值,这个ID值会发送给客户端,客户端每次请求都会把这个ID值放到HTTP请求的头部发送给服务端,而这个id值在客户端会保存下来,保存的容器就是cookie,因此当我们完全禁掉浏览器的cookie的时候,服务端的session也会不能正常使用。

在这里插入图片描述

Session认证流程:

用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session;

请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器;

浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名;

当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息;

如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息;

Cookie与Session的区别:

安全性:

  • Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。

存取值的类型不同:

  • Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。

有效期不同:

  • Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。

存储大小不同:

  • 单个 Cookie 保存的数据不能超过 3K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

HTTP1.1

支持长连接:

HTTP 1.0 规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。

HTTP 1.1 支持持久连接, 并且默认使用长连接,在同一个TPC的连接中可以传送多个HTTP请求和响应,多个请求和响应可以重叠,多个请求和响应可以同时进行。

HTTP 1.1的持续连接,也需要增加新的请求头来帮助实现:

  • Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接。
  • Connection请求头的值为Close时,客户端通知服务器返回本次请求结果后关闭连接。

提供了Cache缓存机制:

当缓存对象的Age超过Expire时变为Stale对象,Cache不需要直接抛弃Stale对象,而是与源服务器进行重新激活。

请求的流水线(Pipelining)处理:

在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。

例如:一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接,HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容。

增加Host字段:

在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名。

在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。

HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

100(Continue)Status:

客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);

如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。

Chunked机制:

发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。

这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。

HTTP2.0

HTTP2.0和HTTP1.X相比的新特性:

新的二进制格式

  • HTTP1.x的解析是基于文本。
  • HTTP2.0的协议解析采用二进制格式,实现方便且健壮。

多路复用

  • 一个Request对应一个ID,这样一个连接上可以有多个Request,每个连接的Request可以随机的混杂在一起,接收方可以根据Request的ID将Request再归属到各自不同的服务端请求里面。

Hseader压缩:

  • HTTP1.x的Header带有大量信息,而且每次都要重复发送。

  • HTTP2.0使用Encoder来减少需要传输的Header大小,通讯双方各自Cache一份Header Fields表,差量更新HTTP头部,只发送改变的,既避免了重复Header的传输,又减小了需要传输的大小。

服务端推送

  • HTTP2.0具有Server Push功能。

HTTP2.0的多路复用和HTTP1.1中的长连接复用有什么区别?

HTTP/1.0:

  • 一次请求-响应,建立一个连接,用完关闭。
  • 每一个请求都要建立一个连接;

HTTP/1.1:

  • 若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞。

HTTP/2.0:

  • 多个请求可同时在一个连接上并行执行。
  • 某个请求任务耗时严重,不会影响到其它连接的正常执行。

HTTP3.0

底层的传输协议由 TCP 协议改为使用基于 UDP 协议的 QUIC 协议:

  • 在应用层实现了拥塞控制、可靠传输的特性

HTTP2HTTP3 都默认建立在 HTTPS 之上

HTTPS

HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。

现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

HTTPS主要作用是:

对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全。

对网站服务器进行真实身份认证。

HTTP 与 HTTPS 的区别:

HTTPS比HTTP更加安全,对搜索引擎更友好,利于SEO,谷歌、百度优先索引HTTPS网页。

HTTPS需要用到SSL证书,而HTTP不用。

HTTPS标准端口443,HTTP标准端口80。

HTTPS基于传输层,HTTP基于应用层。

HTTPS在浏览器显示绿色安全锁,HTTP没有显示。

注意:要进行HTTPS通信,证书是必不可少的,而使用的证书必须向认证机构(CA)购买,成本高。

HTTPS工作流程:

img

Client发起一个HTTPS的请求。

Server把事先配置好的公钥证书返回给客户端。

Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,如果验证通过则继续,不通过则显示警告信息。

Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。

Server使用自己的私钥解密这个消息,得到对称密钥,至此,Client和Server双方都持有了相同的对称密钥。

Server使用对称密钥加密明文内容A,发送给Client。

Client使用对称密钥解密响应的密文,得到明文内容A。

Client再次发起HTTPS的请求,使用对称密钥加密请求的明文内容B,然后Server使用对称密钥解密密文,得到明文内容B。

传输层

TCP和UDP各自适用的场景

当要求通信数据可靠时,选择TCP协议:

  • 例如文件传输,邮件传输,金融交易,可靠通信,消息队列等。

当要求传输速度,不要求数据可靠时,选择UDP:

  • 适合多媒体信息分发的场景,如直播,视频,语音,实时信息(股票走势)等。

UDP

UDP特点

UDP是无连接的传输层协议。

UDP使用尽最大努力交付,不保证可靠交付。

  • 即不能保证数据在网络中是否丢失。

UDP是面向报文传输的,对应用层传输过来的数据不会进行任何处理(不合并,不拆分,保留原报文的边界)。

UDP没有拥塞控制,因此即使网络出现拥塞也不会降低发送速率。

  • 适用于一些实时场景,如直播、视频会议等。

UDP支持一对一,一对多,多对多的交互通信。

UDP的首部开销很小,总共只有8个字节。

如何保证UDP协议可靠?

模拟TPC的可靠机制来实现,保证四个无即可(无丢失、无失序、无错误、无重复)。

TCP

TCP特点

TCP是面向连接的传输层协议,也就是说,在双方传输数据之前,必须先建立起连接,传输完数据后要结束连接。

每一条TCP连接只能有两个端点,即点对点通信(一对一)。

TCP提供可靠的传输服务,通过TCP连接传送的数据,无差错、不丢失、不重复、按序到达。

TCP提供全双工的通信:

  • TCP允许通信双方的应用进程在任何时候都可以发送数据。

TCP是面向字节流的协议。

TCP段

应用需要传输的数据可能会非常大,当传输层的数据包大小超过 MSSTCP 最大报文段长度)

  • 就要将数据包分块
    • 这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。

每个分块称为一个 TCP 段(TCP Segment)。

img

端口

当设备作为接收方时,传输层则要负责把数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据

  • 因此需要用一个编号将应用区分开来,这个编号就是端口

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

流量控制

TCP 利用滑动窗口实现流量控制,流量控制是为了控制发送方发送速率,保证接收方来得及接收数据。

接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。

将窗口字段设置为 0,则发送方不能发送数据。

特殊的情况:

当接收方窗口大小为0时,发送方不能发送数据,在接收方把数据处理完之后,向接收方发送rwnd=1000,通知发送方我还可以接收1000个字节的数据,但是这个字段在传输时丢失了,接收方并没有接收到这个数据,默认接收方当前窗口为0。

可以通过定时器来解决这个问题。

当接收到窗口为0的消息,则启动定时器。

坚持定时器会每隔一段时间发送一个窗口探测报文,来询问接收方当前的窗口大小。

拥塞控制

网络传输过程中,某段时间如果网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就会变坏。

  • 这种情况就叫做网络拥塞

为解决这个问题,TCP中使用了四种拥塞控制算法。

慢开始:

发送方会维持一个拥塞窗口cwnd的状态变量。

  • 拥塞窗口的大小取决于拥塞程度,并且会在收发包过程中动态的进行变化。

核心思想:

  • 指数级由小到大逐渐增加拥塞窗口大小,如果网络出现阻塞,拥塞窗口就减小。

判断出现网络拥塞的依据:

  • 没有按时收到应当到达的确认报文(即发生重传)。

img

拥塞避免算法:

拥塞避免算法是让拥塞窗口缓慢增长,每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。

  • 拥塞窗口按线性规律缓慢增长。

不论是在慢开始期间还是拥塞避免期间:

  • 只要判断网络发生了拥塞ssthresh就设置为当前发送窗口大小的一半,然后重新开始执行慢开始算法。

这样做的目的是迅速减少主机发送到网络中的分组数:

  • 使发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。

具体过程:

维护一个慢开始门限ssthresh状态变量:

  • cwnd < ssthresh 时,使用慢开始算法。

  • cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。

  • cwnd = ssthresh 时,既可以使用慢开始算法,也可以使用拥塞避免算法。

假设发送方拥塞窗口cwnd的值为1,发送窗口swnd等于拥塞窗口cwnd

  • 那么目前发送方只能发送一个报文段,cwnd为几就能发送几个报文段。

接收方收到报文段后发送回复确认,发送方收到确认报文,会将拥塞窗口的值乘2,变为2。

  • 发送方此时一次就能发送两个报文段,接收方收到报文段后返回两次确认报文段,发送方收到之后拥塞窗口再乘2,cwnd=4

知道发送方发送16个报文段都按时收到确认报文,拥塞窗口变为32,但是这一次没有按时收到确认报文。

  • 即有报文需要重传,表示网络发生了拥塞。

这时候设定ssthresh为当前窗口cwnd的一半,即ssthresh = cwnd/2 = 16,重新开始慢开始。

  • 再一次cwnd=16的时候,开启拥塞避免算法。

6424c7d14d7bde967f2b5a7699473034

快速重传

在数据传送过程中,网络有可能不太稳定,个别报文段在网络中丢失了。

  • 但是实际上网络并没有发生拥塞。

这样会导致发送方超时重传,误以为网络上发生了拥塞。

由于有慢开始和拥塞避免机制,发送方错误的启动了慢开始算法,并且把拥塞窗口cwnd又设置为最小值1,因为降低了传输效率。

为解决这个问题,快重传要求接收方在收到一个失序的报文段后立即发出重复确认。

为的是让发送方知道有一个报文丢失了,快速重传算法规定:

  • 发送方只要一连收到三个重复确认就应当立即重传对方还没有接收到的报文段,而不必继续等待设置的重传计时器时间到期。

快恢复算法

快恢复算法适合快重传算法配合使用的。

当发送方连续收到三个重复确认的时候,执行 乘法减小 算法,将ssthresh门限减半(为了预防网络发生拥塞)。

但是接下来不执行慢开始算法:

  • 因为如果网络发生拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。

此时不会执行慢开始算法,而是将拥塞窗口cwnd设置为ssthresh减半后的值。

  • 然后执行拥塞避免算法,让cwnd缓慢变大。

7d4234f94f28de0310e53accec62ad90

四次挥手

第一次挥手:

客户端向服务器发送一个 FIN 数据包(FIN = 1,seq = u)主动断开连接,报文中会指定一个序列号。

告诉服务器:我要跟你断开连接了,不会再给你发数据了。

客户端此时还是可以接收数据的,如果一直没有收到被动连接方的确认包,则可以重新发送这个包。

此时客户端处于 FIN_WAIT1 状态。

第二次挥手:

服务器收到 FIN 数据包之后,向客户端发送确认包(ACK = 1,ack = u + 1),把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了。

这是服务器在告诉客户端:我知道你要断开了,但是我还有数据没有发送完,等发送完了所有的数据就进行第三次挥手。

此时服务端处于 CLOSE_WAIT 状态,客户端处于 FIN_WAIT2 状态。

第三次挥手:

服务器向客户端发送FIN 数据包(FIN=1,seq = w),且指定一个序列号,以及确认包(ACK = 1, ack = u + 1),用来停止向客户端发送数据。

这个动作是告诉客户端:我的数据也发送完了,不再给你发数据了。

此时服务端处于LAST_ACK状态,客户端处于TIME_WAIT状态。

第四次挥手:

客户端收到 FIN数据包 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值。

此时客户端处于 TIME_WAIT 状态。

需要过一了一定时间(2MSL)之后,客户端发送确认包(ACK = 1, ack = w + 1),此时客户端才会进入 CLOSED 状态,以确保发送方的ACK可以到达接收方,防止已失效连接请求报文段出现在此连接中。

至此,完成四次挥手。

等待计时器(TIME-WAIT):

MSL(Max Segment Lifetime):最长报文段寿命。

等待计时器等待的时间为2MSL,MSL一般设置为2分钟。

为什么需要等待2MSL?

确保发送方发送的第四次挥手ACK报文可以到达接收方。

确保当前连接的所有报文都已经过期。

在四次挥手时,只要发送方发出了第四次挥手的报文之后,发送方就进入了等待状态,这时最后一个报文其实是并没有确认的,这个等待计时器主要是为了确保发送方发送的第四次挥手ACK报文可以到达接收方。

2MSL是报文在网络中最长可以存活的时间,在2MSL时间里,如果第四次挥手ACK报文没到达服务端,接收方会重新发送第三次挥手的报文给客户端,客户端收到之后,就知道之前第四次挥手的 ACK 报文丢失了,然后再次发送 ACK 报文,确保正确地结束这次连接。

另外一个功能是为了确保当前连接的所有报文都已经过期,防止已失效的连接请求报文段出现在本连接中。

因为最后一个报文都已经等待了2MSL时间,所以对于其他报文,肯定也超过2MSL的时间,都是过期的报文。

如何保证有序

TCP保证有序的方式是通过序号和确认应答实现的。

在 TCP 中,每个数据包都有一个唯一的序号,序号的单位是字节(byte)。

发送方将数据分割成多个数据包,每个数据包都打上序号,并逐个发送到接收方,接收方会将接收到的数据包按照序号大小顺序进行排序,保证数据按照发送方发送的顺序被接收到。

接受方一旦收到了顺序化的数据,它就将这些数据按正确的顺序重组成数据流传递到高层进行处理。

同时,接收方会向发送方发送确认应答(ACK),表示接收到了哪些数据包。

这样发送方就能够知道哪些数据包已经被接收方正确接收了。

如果发送方没有收到确认应答,就会认为数据包没有被接收方正确接收,会重新发送这些数据包。

网络层

IP协议

IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文

  • 如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片
    • 得到一个即将发送到网络的 IP 报文。

IP协议是TCP\IP协议簇中最核心的协议,大部分的上层(传输层、应用层)应用都直接或间接的使用IP协议传输

  • TCP协议、UDP协议都会使用 IP 协议。

IP 协议是无连接的,不可靠的网络层协议

  • 它只负责数据的传输,但是并不能保证数据一定能到达,要想保证数据可靠,需要上层应用处理
  • 例如 TCP协议利用IP协议传输数据,但是丢包、超时等情况还是要靠 TCP 自己解决。
img

IP地址

对于 IPv4 协议, IP 地址共 32 位,分成了四段(比如:192.168.100.1),每段是 8 位。

IP 地址分成:

  • 网络号:负责标识该 IP 地址是属于哪个子网

  • 主机号,负责标识同一子网下的不同主机

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

路由

实际场景中,两台设备并不是用一条网线连接起来的

  • 而是通过很多网关、路由器、交换机等众多网络设备连接起来的
    • 那么就会形成很多条网络的路径

因此当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径。

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

IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走

  • 路由则是根据 下一个目的地 选择路径。
IP地址的网络号

ARP协议

ARP 的作用是根据 IP 地址获取对应的 MAC 地址。

在网络中最终传输的数据叫做数据帧,是数据链路层最后封装的

  • 而数据帧要根据 MAC 地址找到目的主机,一般是目的主机的某个网卡。

  • 而一般只知道目的主机的 IP,不知道 MAC 地址,所以需要 ARP 协议。

MAC地址

它是一个用来确认网路设备位置的位址。

在OSI模型中,第三层网路层负责IP地址,第二层数据链路层则负责MAC位址。

MAC地址用于在网络中唯一标示一个网卡:

  • 一台设备若有一或多个网卡,则每个网卡都需要并会有一个唯一的MAC地址。

网络安全

SQL注入

一种代码注入技术,通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

SQL注入攻击者通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,传入后端的SQL服务器执行。

  • 结果是可以执行恶意攻击者设计的任意SQL命令。

例如,Web应用程序具有以下登录页面:

User Name: admin
Password: 1234

攻击者在密码框中输入:

'1234 ' or '1'='1

之后构造的SQL查询为:

SELECT * FROM users WHERE name='admin' AND password='1234 ' or '1'='1';

由于’或’1’='1 总是为真,所以可以绕过密码验证登录系统。

如何防止SQL注入:

SQL注入可以通过多种方式进行防范,如使用参数化的SQL语句、输入验证和过滤等方法。

PreparedStatement防止SQL注入:

PreparedStatement会先将SQL语句发送到数据库进行预编译,之后再将参数值单独传递,从而避免了SQL语句拼接的过程。

Mybatis中#{}防止SQL注入:

在MyBatis中,可以使用#{}来防止SQL注入。

  • #{}是MyBatis提供的PreparedStatement的参数占位符。

  • MyBatis会自动将#{}替换为? ,并且对用户传入的参数自动进行Escape处理,以防止SQL注入。

对请求参数的敏感词汇进行过滤:

对用户请求参数中的敏感词汇进行过滤,可以防止多种注入攻击,包括SQL注入、XSS等。

常见的防范措施包括:

  • 构建敏感词汇库,收集所有可能的敏感词汇,如delete、drop、script等,并定期更新。
  • 对用户请求参数进行遍历,判断参数值是否包含敏感词汇,可以用正则表达式或包含关系来判断。
  • 对关键参数与业务规则进行校验,例如长度、类型、允许范围等。
  • 考虑在边界处过滤,如WAF、防火墙等。
  • 输出时对敏感数据编码或替换。

Nginx反向代理防止SQL注入:

可以使用nginx的ngx_http_rewrite_module模块,在server区域加入过滤规则,对请求参数中敏感字符进行过滤或拦截。

WAF功能

  • 启用nginx的Web应用防火墙功能,对疑似SQL注入的请求进行拦截,如检测特殊字符,语句规则等。

访问控制:

  • 通过nginx的access模,禁止某些IP地址或子网段访问,限制请求频率,以防止滥用。

隐藏数据库结构信息

  • 基于请求中的User-Agent等信息,显示不同的错误页面,避免泄露数据库元信息。

连接数据库的用户权限控制

  • 只允许访问应用需要的最小权限集。
if ($args ~* "select|insert|update|delete|drop|exec") {
 return 403;
}

XSS

Cross-Site Scripting(跨站脚本攻击),简称XSS,是一种代码注入攻击。

攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。

利用这些恶意脚本,攻击者可获取用户的敏感信息如Cookie、SessionID等,进而危害数据安全。

XSS注入方法:

任何可以输入的地方都有可能引起XSS攻击:

  • 在HTML内嵌的文本中,恶意内容以script标签形成注入

  • 在内联的JavaScript中,拼接的数据突破了原本的限制(字符串,变量,方法名)等

  • 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签

  • 在标签的 href、src 等属性中,包含 javascript: (伪协议)等可执行代码。

  • 在 onload、onerror、onclick 等事件中,注入不受控制代码。

防御XSS攻击的方法:

输入过滤:

  • 一般是用于对于输入格式的检查,例如:邮箱,电话号码,用户名,密码……等,按照规定的格式输入。

转义HTML:

  • 如果拼接 HTML 是必要的,就需要对于引号,尖括号,斜杠进行转义。

CSRF

CSRF(跨站请求伪造),是一种挟持用户在当前已登陆的Web应用程序上执行非本意的操作的攻击方法。

CSRF攻击流程:

攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。

利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

这样攻击者盗用了用户的身份,以用户的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以用户的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。

举例:Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

第一步:用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

第二步:在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

第三步:用户未退出网站A之前,在同一浏览器中,打开一个TAB页 访问 网站B;

第四步:网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

第五步:浏览器在接收到这些攻击性代码后:

  • 用户相当于无意中在自己的 浏览器 上执行了网站B返回的攻击代码中的http请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求;

  • 网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

防御CSRF的方法:

验证码:

  • 强制用户必须与应用进行交互,才能完成最终请求。

请求来源限制(Referer);

  • 不能保证 100% 有效,服务器并不是什么时候都能取到 Referer,而且低版本的浏览器存在伪造 Referer 的风险。

Token验证:

  • CSRF防御机制最合适的方案。

DOS

DOS(拒绝服务),一切能引起DOS行为的攻击都被称为DOS攻击。

该攻击的效果是使得计算机或网络无法提供正常的服务。

DOS攻击的原理:

首先攻击者向被攻击的服务器发送大量的虚假IP请求,被攻击者在收到请求后返回确认信息,等待攻击者进行确认,由于攻击者发送的请求信息是虚假的,所以服务器接收不到返回的确认信息,在一段时间内服务器会处与等待状态,而分配给这次请求的资源却被有被释放。

当被攻击者等待一定的时间后,会因连接超时而断开,这时攻击者在次发送新的虚假信息请求,这样最终服务器资源被耗尽,直到瘫痪。

DDOS:

分布式拒绝服务攻击,指的是攻击者控制多台主机同时向同一主机或网络发起DOS攻击。

DDOS究竟如何攻击?

目前最流行也是最好用的攻击方法就是使用SYN-Flood进行攻击,SYN-Flood也就是SYN洪水攻击。

SYN-Flood不会完成TCP三次握手的第三步,也就是不发送确认连接的信息给服务器。

  • 这样,服务器无法完成第三次握手,但服务器不会立即放弃,服务器会不停的重试并等待一定的时间后放弃这个未完成的连接,这段时间叫做SYN Timeout,这段时间大约30秒-2分钟左右。

  • 一个服务器若是处理这些大量的半连接信息而消耗大量的系统资源和网络带宽,这样服务器就不会再有空余处理普通用户的正常请求。

减少DDOS的攻击方法:

限制同时打开的SYN半连接数目。

缩短SYN半连接的time out时间。

正确设置防火墙。

禁止对主机的非开放服务的访问。

限制特定IP地址的访问。

启用防火墙的防DDOS的属性。

严格限制对外开放的服务器的向外访问。

运行端口映射程序祸端口扫描程序,要认真检查特权端口和非特权端口。

数字签名

用户认证,用来验证用户身份,用来确保信息发布人的身份和信息的完整性。

数字签名过程:

  • 将报文按双方约定的HASH算法计算得到一个固定位数的报文摘要。
  • 将该报文摘要值用发送者的私人密钥加密即称数字签名,然后连同原报文和数字证书(包含公钥)一起发送给接收者。
  • 接收方收到数字签名后,用同样的HASH算法对报文计算摘要值,然后将数字签名用发送者的公钥进行解签,并与报文摘要值相比较,如相等则说明报文确实来自所称的发送者。

为了防止公钥在传输过程中被调包,需要证书中心(简称CA)为公钥做认证。

证书中心用自己的私钥,对公钥和一些相关信息一起加密,生成数字证书,客户端用CA的公钥解开数字证书,从而确定公钥的真实性。

加密算法

MD5算法

MD5 用的是 哈希函数,它的典型应用是对一段信息产生 信息摘要,以 防止被篡改

严格来说,MD5 不是一种 加密算法 而是 摘要算法

无论是多长的输入,MD5 都会输出长度为 128bits 的一个串 (通常用 16 进制 表示为 32 个字符)。

对称加密

对称加密算法 中,使用的密钥只有一个,发送接收 双方都使用这个密钥对数据进行 加密解密

这就要求加密和解密方事先都必须知道加密的密钥。

image-20231011180653517

常见的 对称加密 算法主要有 DES3DESAES 等。

非对称加密

非对称加密算法有两个密钥,一个称为 公开密钥,即 公钥,另一个称为 私有密钥,即 私钥

如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密

如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密

image-20231011180711713

例子:甲方生成 一对密钥 并将其中的一把作为 公钥 向其它人公开,得到该公钥的 乙方 使用该密钥对机密信息 进行加密 后再发送给甲方,甲方再使用自己保存的另一把 专用密钥 (私钥),对 加密 后的信息 进行解密

常见的 非对称算法 主要有 RSADSA 等。

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!