TCP 连接建立

简介: TCP 连接建立

TCP 三次握手过程是怎样的?

客户端和服务端都处于 CLOSE 状态,服务端主动监听某个端口,处于 LISTEN 状态

第一次握手:客户端带着序号和SYN为1,把第一个 SYN 报文发送给服务端,客户端处于 SYN-SENT 状态

第二次握手:服务端收到客户端的 SYN 报文后,服务物端带着序号和SYN和ACK为1,把报文发送给客户端,服务端处于 SYN-RCVD 状态

第三次握手:客户端收到服务端报文后,把带着ACK为1的报文发送给服务端,这次报文可以携带客户到服务端的数据,客户端处于 ESTABLISHED 状态

服务端收到客户端的应答报文后,也进入 ESTABLISHED 状态

第三次握手是可以携带数据的,前两次握手是不可以携带数据的

2:如何在 Linux 系统中查看 TCP 状态?

TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看

3:为什么是三次握手?不是两次、四次?

三次握手才可以阻止重复历史连接的初始化(主要原因)

三次握手才可以同步双方的初始序列号,序列号能够保证数据包不重复、不丢弃和按序传输。

三次握手才可以避免资源浪费

不使用「两次握手」和「四次握手」的原因:

「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;

「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

4:为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?

主要原因有两个方面:

为了防止历史报文被下一个相同四元组的连接接收(主要方面);

为了安全性,防止黑客伪造的相同序列号的 TCP 报文被对方接收;

注意:

每次初始化序列号不一样很大程度上能够避免历史报文被下一个相同四元组的连接接收,注意是很大程度上,并不是完全避免了(因为序列号会有回绕的问题,所以需要用时间戳的机制来判断历史报文

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

起始 ISN 是基于时钟的,每 4 微秒 + 1,转一圈要 4.55 个小时。

RFC793 提到初始化序列号 ISN 随机生成算法:ISN = M + F(localhost, localport, remotehost, remoteport)。

M 是一个计时器,这个计时器每隔 4 微秒加 1。

F 是一个 Hash 算法,根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。要保证 Hash 算法不能被外部轻易推算得出,用 MD5 算法是一个比较好的选择。

可以看到,随机数是会基于时钟计时器递增的,基本不可能会随机成一样的初始化序列号。

6:既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢?

MTU:一个网络包的最大长度,以太网中一般为 1500 字节;

MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度;

因为IP 层本身没有超时重传机制,由传输层的 TCP 来负责超时和重传。那么当如果一个 IP 分片丢失,整个 IP 报文的所有分片都得重传。

所以建立连接的时候通常要协商双方的 MSS 值,进行重发时也是以 MSS 为单位,不用重传所有的分片,大大增加了重传的效率。

7:第一次握手丢失了,会发生什么?

当客户端超时重传 3 次 SYN 报文后,由于 tcp_syn_retries 为 3,已达到最大重传次数,于是再等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到服务端的第二次握手(SYN-ACK 报文),那么客户端就会断开连接。

8:第二次握手丢失了,会发生什么?

当客户端超时重传 1 次 SYN 报文后,由于 tcp_syn_retries 为 1,已达到最大重传次数,于是再等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到服务端的第二次握手(SYN-ACK 报文),那么客户端就会断开连接。

当服务端超时重传 2 次 SYN-ACK 报文后,由于 tcp_synack_retries 为 2,已达到最大重传次数,于是再等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到客户端的第三次握手(ACK 报文),那么服务端就会断开连接。

9:第三次握手丢失了,会发生什么?

当服务端超时重传 2 次 SYN-ACK 报文后,由于 tcp_synack_retries 为 2,已达到最大重传次数,于是再等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到客户端的第三次握手(ACK 报文),那么服务端就会断开连接。

10:什么是 SYN 攻击?如何避免 SYN 攻击?

在 TCP 三次握手的时候,Linux 内核会维护两个队列,分别是:

半连接队列,也称 SYN 队列; 全连接队列,也称 accept 队列;

假设攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的半连接队列,使得服务端不能为正常用户服务。

解决:

调大 netdev_max_backlog;当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。控制该队列的最大值如下参数 net.core.netdev_max_backlog = 10000

增大 TCP 半连接队列;增大 net.ipv4.tcp_max_syn_backlog 增大 listen() 函数中的 backlog 增大 net.core.somaxconn

开启 tcp_syncookies;开启 syncookies 功能就可以在不使用 SYN 半连接队列的情况下成功建立连接,相当于绕过了 SYN 半连接来建立连接。

                   net.ipv4.tcp_syncookies 参数主要有以下三个值:0 值,表示关闭该功能;1 值,表示仅当 SYN 半连接队列放不下时,再启用它;2 值,表示无条件开启功能;

                   修改 echo 1 > /proc/sys/net/ipv4/tcp_syncookies

减少SYN+ACK重传次数:修改 echo 1 > /proc/sys/net/ipv4/tcp_synack_retries

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
5月前
|
网络协议 Unix Linux
TCP 三次握手、四次断开
TCP 三次握手、四次断开
|
6月前
|
网络协议
|
7月前
|
网络协议 Linux 网络安全
TCP三次握手的相关问题及解答
TCP三次握手的相关问题及解答
62 0
|
存储 缓存 网络协议
TCP三次握手详解
TCP是面向连接的协议,它基于运输连接来传送TCP报文段,TCP运输连接的建立和释放,是每一次面向连接的通信中必不可少的过程。
208 0
|
网络协议
TCP三次握手
TCP三次握手
100 0
|
网络协议 Linux
tcp的三次握手
tcp的三次握手。
183 0
tcp的三次握手
|
缓存 网络协议
TCP连接的 三次握手
TCP连接的 三次握手
|
网络协议 Linux
tcp的三次握手。
tcp的三次握手。
135 0
|
网络协议
TCP的四次挥手
TCP的四次挥手
141 0
|
缓存 网络协议
【计算机网络】传输层 : TCP 连接管理 ( TCP 连接建立 | 三次握手 | TCP 连接释放 | 四次挥手 )
【计算机网络】传输层 : TCP 连接管理 ( TCP 连接建立 | 三次握手 | TCP 连接释放 | 四次挥手 )
189 0
【计算机网络】传输层 : TCP 连接管理 ( TCP 连接建立 | 三次握手 | TCP 连接释放 | 四次挥手 )

热门文章

最新文章