先来了解几个 TCP Flags
- URG:紧急指针标志
- ACK:确认序号标志
为1表示确认号有效
为0表示报文中不包含确认信息,忽略确认号字段 - PSH:push标志
- RST:重置连接标志
- SYN:同步序号,用于建立连接过程
当SYN=1 ACK=0 表示数据段没有带上确认域
当SYN=1 ACK=1 表示连接应答 - FIN:finish标志,用于释放连接
为1时表示发送方已经没有数据发送了,即关闭本方数据流
TCP三次握手
在TCP/IP协议中,TCP提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送SYN包(seq = x) 到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN(ack = x+1),同时自己也发送一个SYN包(seq = y) ,即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack = y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
为什么需要三次握手才能建立连接
为了初始化 sequence Number 的初始值
首次握手的隐患—SYN超时
问题起因分析
Server 收到Client的SYN,回复SYN-ACK的时候未收到ACK确认
Server不断重试直至超时,LINUX默认等待63秒(重试间隔从1秒开始每次都翻倍,1+2+4+8+16+32=63s)才断开连接。
后果:可能会使服务器遭到SYN Flood攻击,攻击者可把SYN连接的队列耗尽让正常的连接请求不能处理。
针对SYN Flood 的防护措施
SYN队列满后,通过tcp_syncookies参数回发SYN Cookie (原地址端口+目标地址端口+时间戳)
为攻击者则不会有响应,若正常连接则Client会回发SYN Cookie,直至建立连接
建立连接后,Client出现故障怎么办
TCP设有保活机制
在保活时间 keep-alivetime ,连接 处于非活动状态开启保活功能的一端将向对方发送保活探测报文,如果未收到响应则继续发送;直到尝试次数达到保活探测数仍未收到响应则中断连接。