第一次握手: 建立连接时,客户端A向服务端B发送请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x.TCP规定SYN=1报文段不能携带数据,但是消耗一个序列号.这时,TCP客户进程进入SYN-SENT(同步已发送)状态,等待服务器确认.
第二次握手: 服务器收到请求报文后,如同意连接,则向A发送确认,同时自己也发送一个确认报文段,确认报文段中SYN和ACK都置1,确认号ack=x+1,同时自己也为自己选择一个初始序号seq=y.这个报文段也不能携带数据,但同样要消耗掉一个序号.这时TCP服务器进程进入SYN-RCVD(同步收到)状态.
第三次握手: 客户端A接收到B的确认后,还要向B给出确认报文段.确认报文段的ACK=1,确认号ack=y+1,而自己的序号seq=x+1.此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手.
为什么客户端A还要发送一次确认呢?一是为了防止已失效的连接请求报文段突然又传送到了服务端B,因而产生错误.二是确保服务端与应用端都具有接收和发送的能力.
第三次握手数据发送失败的话,服务端有一个保活机制.TCP还设有一个保活计时器,服务器每次收到客户端的请求时都会重置这个保活计时器,时间通常设置为2个小时,如果两个小时内还未收到客户端发来的任何数据,服务器就会发送一个勘测报文段,以后每隔75分钟发送一次,若一连发送10个勘测报文任然没有反应,服务器就会认为客户端出现了故障,关闭连接.
泛洪攻击是利用了TCP建立连接需要三次握手的缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源被耗尽.
防御方式:
1.设置syn cookie
服务器在收到syn包时不马上分配存储连接的数据区,而是根据这个syn包计算出一个cookie(需要计算哈希值),把这个cookie填入tcp的Sequence Number字段发送syn+ack包,等对方回应ack包时检查回复的Acknowledgement Number字段的合法性,如果合法再分配专门的数据区.
2.缩短SYN Timeout时间
SYN Flood攻击的效果取决于服务器上保持的SYN半连接数,这个值=SYN攻击的频度 X SYN Timeout,可成倍的降低服务器的负荷(缩短SYN Timeout时间仅在对方攻击频度不高的情况下生效)
3.增大半连接数
第一次挥手: 数据传输结束后,通信的双方都可释放连接.现A的应用进程先向其TCP发送连接释放报文段,并停止再发送数据,主动关闭TCP连接.A的连接释放报文段的首部里的FIN=1,其序号seq=u,等待B的确认,进入FIN-WAIT-1状态.
第二次挥手: B发出确认,确认号ack=u+1,而这个报文段自己的序号seq=v.TCP服务器进程通知高层应用进程.从A到B这个方向的连接就释放了,TCP连接处于半关闭状态.B若要发送数据,A仍要接收.B进入CLOSE-WAIT状态,A进入FIN-WAIT-2状态.
第三次挥手: 若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接.B进入LAST-ACK状态.
第四次挥手: A收到连接释放报文段后,向B发送确认应答,此时A进入TIME-WAIT状态.该状态会持续2MSL时间,若该时间段内没有收到B的重发请求的话,就进入CLOSE状态.当B收到确认应答后也便进入CLOSE状态.