前言
TCP/IP(Transmission Control Protocol/Internet Protocol) 是能够在多个不同网络间实现信息传输的协议簇。
TCP(传输控制协议)
- TCP 用于从应用程序到网络的数据传输控制。
- TCP 负责在数据传送之前将它们分割为 IP 包,然后在它们到达的时候将它们重组。
IP(网际协议)
- IP 负责计算机之间的通信。
- IP 负责在因特网上发送和接收数据包
TCP 报文
- 16位源端口号:16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是标识报文的返回地址
- 16位目的端口号:16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口
- 32位序号:32位的序列号由接收端计算机使用,重新分段的报文成最初形式。当SYN出现,序列码实际上是初始序列码(Initial Sequence Number,ISN),而第一个数据字节是ISN+1。这个序列号(序列码)可用来补偿传输中的不一致。
- 32位确认序号:32位的序列号由接收端计算机使用,重组分段的报文成最初形式。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码
- 4位首部长度:4位包括TCP头大小,指示何处数据开始
- 保留(6位):6位值域,这些位必须是0。为了将来定义新的用途而保留
-
标志:6位标志域
- URG:紧急指针(urgent pointer)有效
- ACK:确认序号有效
- PSH:接收方应该尽快将这个报文交给应用层
- RST:重置连接
- SYN:发起一个新连接
- FIN:释放一个连接
- 16位窗口大小:用来表示想收到的每个TCP数据段的大小。TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16字节字段,因而窗口大小最大为65535字节
- 16位校验和:16位TCP头。源机器基于数据内容计算一个数值,收信息机要与源机器数值 结果完全一样,从而证明数据的有效性。检验和覆盖了整个的TCP报文段:这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证的
- 16位紧急指针:指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段
- 选项:长度不定,但长度必须为1个字节。如果没有选项就表示这个1字节的域等于0
- 数据:该TCP协议包负载的数据
三次握手
建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。
进行三次握手的主要作用就是为了:确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
三次握手流程
- 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=X,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认
- 第二次握手:server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=X+1,随机产生一个值seq=Y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态
- 第三次握手:Client收到确认后,检查ack是否为Y+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=Y+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手
1. 为什么需要三次握手?
需要三次握手才能确认双方的接收与发送能力是否正常。
2. 半连接队列
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,称之为半连接队列。
3. ISN(Initial Sequence Number)是固定的吗?
ISN 是动态生成的:三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号。
4. 三次握手过程中可以携带数据吗?
第一次、第二次握手不可以携带数据,第三次可以。
5. SYN攻击
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的。
SYN攻击:Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
防御
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies技术
四次挥手
断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。
这是因为由TCP的半关闭(half-close)造成的:TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
四次挥手流程
- 第一次挥手:Client发送连接释放报文(FIN=1,序号seq=u),并停止再发送数据,Client进入FIN_WAIT状态,等待服务端的确认
- 第二次挥手:Server收到连接释放报文后,发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),Server进入CLOSE_WAIT状态,此时的TCP处于半关闭状态
- 第三次挥手:Server端传输完数据或者要断开连接,Server发送连接释放报文(FIN=1,ACK=1,确认号ack=u+1,序号seq=w),Server进入LAST_ACK状态,等待客户端的确认
- 第四次挥手:Client收到释放报文后,发出确认报文段(ACK=1,seq=u+1,ack=w+1),Client进入TIME_WAIT状态,此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态
1. 挥手为什么需要四次?
因为TCP的半关闭,客户端节数发送后仍然可以接受数据,确保服务端的数据完全传输完成。
2. 四次挥手释放连接时,等待2MSL的意义
MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
为了保证客户端发送的最后一个ACK报文段能够到达服务器。
SYN 相当于是询问,ACK 相当于是确认