首先我们来看下TCP报文格式:

标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN,具体含义如下:
URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。
PSH:接收方应该尽快将这个报文交给应用层。
RST:重置连接。
SYN:发起一个新连接。
FIN:释放一个连接

注意:ACK标志位不是ack确认号,ack是seq(随机序号)+1。

正文来了

 

上图

上图的步骤来,从右边开始指向的Client端开始

  1. Client发起TCP连接,TCP报文的SYN标志位置为1,表明是发起连接,且生成一个随机串(i)放入序号域,自身状态变为SYN_SEND。
  2. Server端收到TCP连接,将新建一个报文,SYN标志位置1,ACK标志位置1,发送随机串(k)放入序号域,且ack域放入(client发送来的序号+1),发送给Client端,自身状态变为SYN_RECV。
  3. 这时候我们称步骤[1,2]为TCP的半连接状态。接着Client端接收到ack后,验证ack是不是等于i+1,如果是的话(等于i+1,证明消息确实是由Server收到自身的请求连接后再转给Client),新建一个TCP报文,ACK标志置1,ack域放置收到服务器的随机串+1(k+1)。
  4. 服务器收到报文后,验证ack是不是等于(K+1),是的话,建立双方连接状态,ESTABLISHED

 

SYN攻击(DDOS攻击其中一种)

记得上面所说的TCP半连接状态吗,如果有多个或一个(虚拟伪造的)IP地址的client发起大量的TCP连接,那么Server端便会对这些client进行回答,如果发送不到对应IP的Client,则Server等待时间(Timeout)过后,重新发送N次到Client,没有则放弃。那么如果有大量的虚拟Client,则会把SYN队列长度都占满了,那么正常Client发起Tcp请求是不是意味着被Server端丢弃?那么将会引起网络杜塞,服务器网络瘫痪。

 

检测是否有SYN攻击

  • 查看网络连接#netstat -anp|grep SYN_RECV   ,查看所有状态为SYN_RECV的TCP连接进程,然后若有大量随机IP,我们认为Server被DDOS攻击了。

 

如何预防&防止攻击

  1. 设置SYN cookie(防止同一IP不断发送)
  2. 缩短SYN Timeout 时间
  3. 加长SYN队列长度
  4. 减少SYN重连次数
  5. 限制SYN并发数量

 

 

您或许感兴趣

[2018-05-16]Java socket通信实现DES加密与解密
[2018-06-05]RSA传递AES密钥进行通信(Java 实现)

发表评论

电子邮件地址不会被公开。