SYN flood攻击
SYN flood攻击
也称SYN洪水攻击,拒绝服务攻击的一种。其他还有ack-flood攻击,udp-flood攻击,icmp-flood攻击。今天,就以syn-flood攻击为例说明。
原理:
利用TCP建立连接时3次握手的“漏洞”,通过原始套接字发送源地址虚假的SYN报文,使目标主机永远无法完成3次握手,占满了系统的协议栈队列,资源得不到释放,进而拒绝服务,是互联网中最主要的DDOS攻击形式之一。
正常的三次握手
-
客户端透过发送
SYN
同步(synchronize)信息到服务器要求创建连线。 -
服务器透过响应客户端
SYN-ACK
以抄收(acknowledge)请求。 -
客户端答应
ACK
,连线随之创建。
非正常的两次握手
Client发出的第一个里按揭请求报文段,因为网络延迟,在连接释放以后的某个时间才能到达server 是一个早已失效的连接请求,但server收到此请求后,误认为是client再次发送的新的请求,server就向client发出确认报文,同意建立连接。于是,syn-flood攻击方法变由此而出。通过不断地发送syn数据包,导致服务器疲于应对而出现无法正常运行业务。
安装第三方scapy库:
源码:
from scapy.all import *
def sendpacket3(tar):
p = IP(dst=tar, id=1111, ttl=99) / TCP(sport=RandShort(), dport=8090, seq=12345, ack=1000, window=1000,
flags="S") / "HaX0r SVP"
ans, unans = srloop(p, inter=0.1, retry=2, timeout=1)
ans.summary()
unans.summary()
sendpacket3('169.254.88.56')
攻击效果:
防御
-
调整内核参数的方法,可以减少等待及重试,加速资源释放,在小流量syn-flood的情况下可以缓解,但流量稍大时完全不抵用。
-
syn proxy
在服务器前端的防火墙上使用
当防火墙收到syn包,自己就回复一个syn-ack的包给发起方,在自己内部建立连接
等发起方将ack包返回后,再重新构造syn包发给服务器,建立真正的tcp连接。(这个过程中防火墙要给发起方发送SYNACK一个包,给服务器发送SYN和ACK两个包,通信的后续包防火墙都应该注意修改序列号或确认号,因为防火墙回复发起方的SYNACK包的序列号基本不可能等于服务器发送的SYNACK包的序列号,所以要进行调整。)
作用:
当客户端SYN包到达BGW时,BGW并不转发SYN包,而是以服务器的名义主动回复SYN/ACK包给客户,如果收到客户的ACK包,表明这是正常的访问,此时向服务器发送ACK包并完成三次握手。BGW事实上代替了RS去处理SYN攻击。BGW后面的服务器设备不会受到攻击,因为实际的攻击压力都由BGW承担,但同时也带来新的问题BGW承担的防攻击压力过大,BGW与BFE的结合可以有效缓解DDOS的压力。
-
syn cookies
syn cookies 主要是应对syn-flood攻击的单机技术(主要是内核做的服务器防护策略)。实现方案是利用SYN ACK的ISN(init seq number)携带信息加上检测的手段拒绝非法的建立连接请求。
一旦开启syn cookie,将在ack阶段直接创建tcp sock,而不缓存syn队列。
构造ISN的方法是:
-
令 t 为一个缓慢递增的时间戳(通常为
time() >> 6
,提供 64 秒的分辨率,就是分钟数); -
令 m 为服务器会在 SYN 队列条目中存储的最大分段大小(maximum segment size,简称为 MSS,存储的是索引,一般这几种值):
static __u16 const msstab[] = { 536, 1300, 1440, /* 1440, 1452: PPPoE */ 1460, };
-
令 s 为一个加密函数对服务器和客户端各自的 IP 地址和端口号以及 t 进行运算的结果。返回得到的数值 s 必须是一个24位值。
当来了一个SYN报文后,我们先根据配置填充pre-cookie的值。最后的cookie值是这样计算的:
hash(4-tupel,0, 0) + syn.seq + (超时时间 << 24) + (hash(4-tuple, 超时时间, 1) + mstab_index)& 0x00FFFFFF
解释一下hash函数,对如下几个参数做crc。src_ip, src_port, dst_ip, dst_port,num1,num2。num1目前看是超时时间(分钟),num2,目前只有0和1两种选择,用来生成cookie的密钥(固定的)。
-
hash(4-tuple,0,0)
-
client发来是syn包的seq值
-
超时的分钟数放到最高8bit
-
hash(4-tuple, 超时时间,1)
怎么检查呢?
-
主要看头部8bit的时间(分钟),不能超过2分钟;
-
判断从ack的ack num算出来的msstab是不是合法;
-
-
首包(第一次请求的syn包)丢弃等。