TCP三次握手之-awl工具-SYN洪水攻击
一、TCP三次握手
1.1 TCP报文段的头部格式
1.1.1 报文格式
1.1.2 部分报文内容
- ACK:TCP协议规定,只有ack=1时,有效,也规定连接建立后,所有发送的报文ack必须为1。
- SYN :在连接建立时用来同步序列号,当SYN=1,而ACK=0时,表明这是一个连接请求报文,对方若同意建立连接,则应在响应报文中使SYS=1,和ACK=1,因此,SYN置1,就表示这是一个连接请求或连接接受报文。
- FIN 终结,用来释放一个连接,当FIN=1,表明此报文段的发送方数据已经发送完毕,并要求释放连接
1.2 三次握手流程
建立tcp 连接是的tcp三次握手,断开tcp 连接的四次挥手
三次握手过程:
- Client:我可以给你发数据吗
- Server:可以
- Client:好的,知道了
二、syn-洪水攻击
2.1 概念
网站被攻击多次,其中最猛烈的就是TCP洪水攻击,即SYN Flood。
SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来海量的请求连接的第一个握手包(SYN包),被攻击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。
2.2 原理
- SYN 洪水攻击的过程:
在服务端返回一个确认的SYN-ACK包的时候有个潜在的弊端,如果发起的客户是一个不存在的端,那么服务端需要耗费一定的数量的系统内存来等待这个未决的连接。直到等待关闭超时,一般是等待30~40s,并且可以重传5,才能释放连接。
- 如果恶意者通过IP 欺骗,发送大量SYN包给受害者系统,导致服务端存在大量未决的连接,并占用大量内存和tcp 连接,从而导致客户端无法访问服务端,这就是SYN洪水攻击的过程。
2.2 模拟攻击
2.2.1 上传安装包
1 [root@localhost ~]# cd /usr/src/
2 [root@localhost src]# ls awl软件进行SYN洪水攻击-开源没有后门-awl-0.2.tar.gz
2.2.2 解压、编译安装
[root@localhost src]# tar -zxvf awl软件进行SYN洪水攻击-开源没有后门-awl-0.2.tar.gz
[root@localhost ~]# cd /usr/src/awl-0.2/
[root@localhost awl-0.2]# ./configure #检查安装环境
[root@localhost awl-0.2]# make -j 1
[root@localhost awl-0.2]# make install
[root@localhost ~]# awk awl
[root@localhost ~]# which awl #查看安装的位置
/usr/local/bin/awl
2.2.3 开始实战
[root@localhost ~]#
- 开始攻击
- awl 使用参数:
- 发送包的接口,如果省略默认是 eth 0
- -m 指定目标mac,如果-m 没有指定mac,默认目标mac 就是FF.FF.FF.FF.FF.FF
- 全 F 就是向同以往段所有主机发出arp 广播,进行SYN攻击,还容易使整个局域网瘫痪
- -d 被攻击的主机ip
- -p 被攻击的主机端口
- 配置服务端
[root@localhost ~]# yum -y install httpd [root@localhost ~]# systemctl start httpd [root@localhost ~]# getenforce #关闭selinux Disabled [root@localhost ~]# systemctl stop firewalld #关闭防火墙 [root@localhost ~]# [root@localhost ~]# iptables -F [root@localhost ~]# 当我们安装好后,过滤端口,发现默认只有一个80. [root@localhost ~]# [root@localhost ~]# netstat -antup |grep 80 tcp6 0 0 :::80 ::: LISTEN 1412/httpd
- 客户端发起攻击
[root@localhost ~]# arp -n # 查看arp 缓存,如果没有看到167 的ip ,说明没有产生连接,可以使用167 ssh 到121 ,然后退出,再次查看。
[root@localhost ~]# awl -i ens33 -m 00:0c:29:3a:6a:7b -d 192.168.43.167 -p 80
注意:默数几秒,ctrl +C停止操作,在去过滤167httpd服务
[root@localhost ~]# netstat -antup |grep 80
tcp 0 0 192.168.43.167:80 62.106.87.42:18854 SYN_RECV -
tcp 0 0 192.168.43.167:80 33.252.16.75:40378 SYN_RECV -
tcp 0 0 192.168.43.167:80 40.8.124.43:56068 SYN_RECV -
tcp 0 0 192.168.43.167:80 79.61.217.54:63452 SYN_RECV -
tcp 0 0 192.168.43.167:80 240.6.234.16:35346 SYN_RECV -
……
会发现产生大量未知的ip地址,并且连接状态为 SYN-RECV---- 在收到和发送一个连接请求后等待对方连接请求的确认
2.2.4 小结
- tcp 三从握手,提供可靠连接
- udp 支持vxlan ,用于OpenStack 私有云、vlan 不够用
- 如果编译出现以下问题:
- configure: error:no acceptable C compiler found in $PATH
- 解决:熟悉tcp 三次握手协议
- yum -y install gcc-c++
- 熟悉tcp 三次握手协议
三、SYN Flood检测和解决
3.1 问题检测
3.1.1 检查系统syslog
我们看到业务曲线大跌时,检查机器和DNS,发现只是对外的web机响应慢、CPU负载高、ssh登陆慢甚至有些机器登陆不上,检查系统syslog:
# tail -f /var/log/messages
Apr 18 11:21:56 web5 kernel: possible SYN flooding on port 80. Sending cookies.
3.1.2 利用netstat 命令验证
3.1.2.1 指令
1 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
3.1.2.2 异常情况下的输出
检查连接数增多,并且SYN_RECV 连接特别多:
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 16855
CLOSE_WAIT 21
SYN_SENT 99
FIN_WAIT1 229
FIN_WAIT2 113
ESTABLISHED 8358
SYN_RECV 48965
CLOSING 3
LAST_ACK 313
3.1.2.3 正常情况下的输出
根据经验,正常时检查连接数如下:
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 42349
CLOSE_WAIT 1
SYN_SENT 4
FIN_WAIT1 298
FIN_WAIT2 33
ESTABLISHED 12775
SYN_RECV 259
CLOSING 6
LAST_ACK 432
以上就是TCP洪水攻击的两大特征。执行netstat -na>指定文件,保留罪证。
3.1.2.4 小结
处于SYN_RECV状态的半连接 再正常情况下不会有很多。
3.2 解决
3.2.1 应急处理
根据netstat查看到的对方IP特征:
# netstat -na |grep SYN_RECV|more
利用iptables临时封掉最大嫌疑攻击的IP或IP号段,例如对方假冒173.*.*.*号段来攻击,短期禁用173.*.*.*这个大号段(要确认小心不要封掉自己的本地IP了!)
# iptables -A INPUT -s 173.0.0.0/8 -p tcp –dport 80 -j DROP
再分析刚才保留的罪证,分析业务,用iptables解封正常173.*.*.*号段内正常的ip和子网段。这样应急处理很容易误伤,甚至可能因为封错了导致ssh登陆不了服务器,并不是理想方式。
3.2.2 使用F5阻挡攻击
应急处理毕竟太被动,因为本机房的F5设备比较空闲,运维利用F5来挡攻击,采用方式:让客户端先和F5三次握手,连接建立之后F5才转发到后端业务服务器,实际上有点向代理。后来被攻击时F5上看到的现象:
- 1. 连接数比平时多了500万,攻击停止后恢复。
- 2. 修改F5上我们业务的VS模式后,F5的CPU消耗比平时多7%,攻击停止后恢复。
- 3. 用F5挡效果明显,后来因攻击无效后,用户很少来攻击了,毕竟攻击也是有成本的。
3.2.3 调整系统参数挡攻击
没有F5这种高级且昂贵的设备怎么办?我测试过以下参数组合能明显减小影响,准备以后不用F5抗攻击。
3.2.3.1 tcp_synack_retries (服务端SYN重传次数)
第一个参数tcp_synack_retries = 0是关键,表示回应第二个握手包(SYN+ACK包)给客户端IP后,如果收不到第三次握手包(ACK包)后,不进行重试,加快回收“半连接”,不要耗光资源。
如果不修改这个参数,模拟攻击,10秒后被攻击的80端口即无法服务,机器难以ssh登录; 用命令netstat -na |grep SYN_RECV检测“半连接”hold住180秒;然后修改这个参数为0,再模拟攻击,持续10分钟后被攻击的80端口都可以服务,响应稍慢些而已,只是ssh有时也登录不上;检测“半连接”只hold住3秒即释放掉。
修改这个参数为0的副作用:网络状况很差时,如果对方没收到第二个握手包,可能连接服务器失败,但对于一般网站,用户刷新一次页面即可。这些可以在高峰期或网络状况不好时tcpdump抓包验证下。
根据以前的抓包经验,这种情况很少,但为了保险起见,可以只在被tcp洪水攻击时临时启用这个参数。
tcp_synack_retries默认为5,表示重发5次,每次等待30~40秒,即“半连接”默认hold住大约180秒。
之所以可以把tcp_synack_retries改为0,因为客户端还有tcp_syn_retries参数,默认是5,即使服务器端没有重发SYN+ACK包,客户端也会重发SYN握手包。
3.2.3.1 tcp_max_syn_backlog (处于SYN_RECV的TCP最大连接数)
第二个参数net.ipv4.tcp_max_syn_backlog = 200000也重要,具体多少数值受限于内存。内核参数net.ipv4.tcp_max_syn_backlog定义了处于SYN_RECV的TCP最大连接数,当处于SYN_RECV状态的TCP连接数超过tcp_max_syn_backlog后,会丢弃后续的SYN报文。
以下配置,第一段参数是最重要的,第二段参数是辅助的,其余参数是其他作用的:
# vi /etc/sysctl.conf
插入语句:net.ipv4.tcp_max_syn_backlog = 200000
使配置生效:sysctl -p
注意,以下参数面对外网时,不要打开。因为副作用很明显,具体原因请google,如果已打开请显式改为0,然后执行sysctl -p关闭。因为经过试验,大量TIME_WAIT
状态的连接对系统没太大影响。
为了处理大量连接,还需改大另一个参数:
# vi /etc/security/limits.conf
在底下添加一行表示允许每个用户都最大可打开409600个文件句柄(包括连接):
* – nofile 409600
此外需要注意,文件句柄不要超过系统限制/usr/include/linux/fs.h
,相关链接:http://blog.yufeng.info/archives/1380
1 #define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */
3.3 TCP内核参数
TCP内核参数详细解释:http://www.frozentux.net/ipsysctl-tutorial/chunkyhtml/tcpvariables.html
四、参考文章
https://blog.csdn.net/weixin_42313749/article/details/104686758
https://www.cnblogs.com/zengkefu/p/5563636.html
http://www.360doc.com/showweb/0/0/990691790.aspx
本文来自博客园,作者:Mr-xxx,转载请注明原文链接:https://www.cnblogs.com/MrLiuZF/p/15132068.html