TCP通过三次握手建立连接
为什么需要三次握手而不是两次或者四次?
三次握手是为了保证可靠传输,两次握手只能保证客户端知道服务端准备好了,而服务端并不知道客户端也准备好了。三次握手的关键在于序列号seq的交换确认。如果有一个包丢了,就会周期性超时重传,直到确认。(但是第三次握手例外,当client与server的第三次握手失败了之后,即client发送至server的确认建立连接报文段未能到达server,server在等待client回复ACK的过程中超时了,那么server会向client发送一个RTS报文段并进入关闭状态,即:并不等待client第三次握手的ACK包重传,直接关闭连接请求,这主要是为了防止泛洪攻击,即坏人伪造许多IP向server发送连接请求,从而将server的未连接队列塞满,浪费server的资源。)
syn泛洪攻击
通俗的理解是:当第三次握手没有发送确认信息时,等待一段时间后,主机就会断开之前的半开连接并回收资源,这为dos(deny of service)攻击埋下隐患,当主动方主动发送大量的syn数据包,但并不做出第三次握手响应,server就会为这些syn包分配资源(但并未使用),就会使server占用大量内存,使server连接环境耗尽,这就是syn洪泛攻击
三次握手的过程
(1):第一次握手:客户端发送syn包服务器,并进入SYN_SEND状态,等待服务器确认
(2):第二次握手:服务器收到syn包,确认客户的SYN,同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态。
(3):第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”
三次握手有什么缺陷可以被黑客利用,用来对服务器进行攻击?
黑客仿造IP大量的向server发送TCP连接请求报文包,从而将server的半连接队列(上文所说的未连接队列,即server收到连接请求SYN之后将client加入半连接队列中)占满,从而使得server拒绝其他正常的连接请求。
怎么防范这种攻击?
1,缩短服务器接收客户端SYN报文之后的等待连接时间,即SYN
timeout时间,也就是server接收到SYN报文段,到最后放弃此连接请求的超时时间,将SYN
timeout设置的更低,便可以成倍的减少server的负荷,但是过低的SYN
timeout可能会影响正常的TCP连接的建立,一旦网络不通畅便可能导致client连接请求失败
2,SYN cookie + SYN proxy 无缝集成(较好的解决方案)
- SYN
cookie:当server接收到client的SYN之后,不立即分配资源,而是根据client发送过来的SYN包计算出一个cookie值,这个cookie值用来存储server返回给client的SYN+ACK数据包中的初始序列号,当client返回第三次握手的ACK包之后进行校验,如果校验成功则server分配资源,建立连接。- SYN proxy代理,作为server与client连接的代理,代替server与client建立三次握手的连接,同时SYN
proxy与client建立好了三次握手连接之后,确保是正常的TCP连接,而不是TCP泛洪攻击,那么SYN
proxy就与server建立三次握手连接,作为代理(网关?)来连通client与server。(类似VPN了解一下。)
为什么断开连接需要四次挥手
注:
FIN 表示关闭连接
ACK 表示确认
因为当服务端收到客户端的 FIN 数据包后(第一次挥手),服务端不会立即close,为什么不立即close?因为可能还有数据没发完,服务端会先将 ACK 发过去告诉客户端我收到你的断开请求了(第二次挥手),但请再给我一点时间,这段时间用来发送剩下的数据报文,发完之后再将 FIN 包发给客户端表示现在可以断了(第三次挥手)。客户端收到 FIN 包后发送 ACK 确认断开信息给服务端(第四次挥手)。