三次握手

image.png
image.png

三次握手原因

1.三次握手才可以阻止历史重复连接的初始化(主要原因) 防止历史的syn连接导致初始化混乱,两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求 SYN 报文,而造成重复分配资源
2.三次握手才可以同步双方的初始序列号 ,第三次握手表示发起者响应了第二次握手的结果,确保可靠

3.三次握手才可以避免资源浪费,全双工通信的最少可靠连接

SYN泛洪攻击(tcp半开连接)

SYN攻击利用的是TCP三次握手机制,攻击端利用伪造的IP地址向被攻击端发出请求,而被攻击端发出的响应 报文将永远发送不到目的地,那么被攻击端在等待关闭这个连接的过程中消耗了资源,如果有成千上万的这种连接,主机资源将被耗尽,从而达到攻击的目的

修改 Linux 内核参数,控制队列大小和当队列满时应做什么处理。

  • 当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。控制该队列的最大值如下参数:

net.core.netdev_max_backlog

  • SYN_RCVD 状态连接的最大个数:

net.ipv4.tcp_max_syn_backlog

  • 超出处理能时,对新的 SYN 直接回 RST,丢弃连接:

net.ipv4.tcp_abort_on_overflow

tcp_syncookies 的方式可以应对 SYN 攻击的方法

  • 当 「 SYN 队列」满之后,后续服务器收到 SYN 包,不进入「 SYN 队列」;
  • 计算出一个 cookie 值,再以 SYN + ACK 中的「序列号」返回客户端,
  • 服务端接收到客户端的应答报文时,服务器会检查这个 ACK 包的合法性。如果合法,直接放入到「 Accept 队列」。
  • 最后应用通过调用 accpet() socket 接口,从「 Accept 队列」取出的连接。

image.png

初始序列号 ISN 是如何随机产生的?

起始 ISN 是基于时钟的,每 4 毫秒 + 1,转一圈要 4.55 个小时。
RFC1948 中提出了一个较好的初始化序列号 ISN 随机生成算法。

ISN = M + F (localhost, localport, remotehost, remoteport)

M 是一个计时器,这个计时器每隔 4 毫秒加 1。
F 是一个 Hash 算法,根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。要保证 Hash 算法不能被外部轻易推算得出,用 MD5 算法是一个比较好的选择。

四次挥手

image.png
image.png

四次挥手原因

再来回顾下四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了。

1.关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
2.服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。

TIME_WAIT 2MSL

  • 防止旧连接的数据包,网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间
  • 保证连接正确关闭,等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭

MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为 TCP 报文基于是 IP 协议的,而 IP 头中有一个 TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机