Linux Shell脚本联动iptables实现DOS防护

解决DOS攻击生产案例:根据web日志或者或者网络连接数,监控当某个IP 并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频 率每隔5分钟。防火墙命令为:iptables -A INPUT -s IP -j REJECT

1 实验准备

1.1 攻击服务器环境准备

[root@localhost ~]# yum install hping3 -y

1.2 受攻击服务器环境准备

[13:42:52 root@centos8 ~]#yum install tcpdump httpd -y
[13:42:52 root@centos8 ~]#systemctl enable --now httpd

此时158上的80端口可以正常被访问.
在这里插入图片描述

2 实验开始

2.1 DOS攻击

对192.168.31.158进行

[14:10:14 root@centos8 ~]#hping3 -c 15000 -d 150 -S -w 64 -p 80 --flood 192.168.31.158
HPING 192.168.31.158 (ens33 192.168.31.158): S set, 40 headers + 150 data bytes
hping in flood mode, no replies will be shown

158上使用tcpdump可以看到大量来自157的请求

[root@localhost ~]# tcpdump src host 192.168.31.157

在这里插入图片描述

此时由于洪水攻击,造成网页无法访问
在这里插入图片描述
在158上可以看到有大量来自157的SYN-RECV连接
考虑到可能存在其他类型的攻击(比如ESTAB),就不用SYN-RECV进行过滤
在这里插入图片描述

2.2 获取IP信息

通过awk过滤后取到该列

ss -ano|awk '{print $6}'

在这里插入图片描述
再使用正则匹配到该列中的IP地址

ss -ano|awk '{print $6}'|grep -Eo "([0-9]{1,3}\.){3}[0-9]+"

在这里插入图片描述
再将这些ip进行排序

ss -ano|awk '{print $6}'|grep -Eo "([0-9]{1,3}\.){3}[0-9]+"|sort|uniq -c

在这里插入图片描述
最后再从多到少再次排序,这样获得了以下的结果
在这里插入图片描述

3 脚本编写

3.1 伪代码

1.监控当某个IP 并发连接数或者短时内PV达到100时

如果 某个IP的数量 -gt 100;那么执行
iptable 把对应的$IP加入到禁止访问列表中
否则 什么都不做.

2.代码每5分钟执行1次.用crontab实现

*/5 * * * * /data/scripts/flood_check.sh

3.2 伪代码进一步实现

3.2.1 取出与本机连接的IP并列出有多少个连接

ss -ano|awk '{print $6}'|grep -Eo "([0-9]{1,3}\.){3}[0-9]+"|sort|uniq -c|sort -r 

3.2.2 按行取出每行内容

while read line

这样读出每行的内容为
100______192.168.31.157
数字______IP

3.2.3 判断IP出现的次数

再通过awk取到$1的数字部分,并对其进行判断

if [ `echo $line|awk '{print $1}'` -gt 10 ];then

3.2.4 拼接iptables规则

通过命令拼接实现了将大于10个连接的ip加入到iptables的input链并禁止访问

iptables -AINPUT -s `echo $line|awk '{print $2}'` -j REJECT;

3.3 半成品代码

#!/bin/bash
ss -ano|awk '{print $6}'|grep -Eo "([0-9]{1,3}\.){3}[0-9]+"|sort|uniq -c|sort -r |while read line;do
	if [ `echo $line|awk '{print $1}'` -gt 10 ];then
		iptables -AINPUT -s `echo $line|awk '{print $2}'` -j REJECT;
	fi;
done

3.4 测试脚本

执行脚本前
在这里插入图片描述
执行脚本后
在这里插入图片描述

3.5 新问题

此时发现即便这个IP已经被禁止,由于禁止到完全断开需要一段时间,而此段时间内该IP会被重复添加,最终可能引起INPUT链过大不好管理
在这里插入图片描述

4 完善脚本

4.1 新增自定义链

iptables -N FLOOD_REJECT

判断iptables 有没有FLOOD_REJECT自定义证书链,如果没有则新建一个

iptables -L FLOOD_REJECT|grep -o FLOOD_REJECT  &>/dev/null;[ $? -eq 0 ]|| iptables -N FLOOD_REJECT

判断是否将自定义证书链FLOOD_REJECT应用到INPUT链上,如果没有则关联

iptables -L INPUT|grep -o FLOOD_REJECT  &>/dev/null;[ $? -eq 0 ]||iptables -IINPUT -j FLOOD_REJECT

将原来直接写入INPUT链的信息写入FLOOD_REJECT链

	IP=`echo $line|awk '{print $2}'`
	iptables -vnL FLOOD_REJECT|grep -o $IP &>/dev/null;[ $? -eq 0 ] || iptables -AFLOOD_REJECT -s $IP -j REJECT;

4.2 完善后的脚本

#!/bin/bash
iptables -L FLOOD_REJECT|grep -o FLOOD_REJECT &>/dev/null;[ $? -eq 0 ]|| iptables -N FLOOD_REJECT
iptables -L INPUT|grep -o FLOOD_REJECT &>/dev/null;[ $? -eq 0 ]||iptables -IINPUT -j FLOOD_REJECT
ss -ano|awk '{print $6}'|grep -Eo "([0-9]{1,3}\.){3}[0-9]+"|sort|uniq -c|sort -r |while read line;do
	if [ `echo $line|awk '{print $1}'` -gt 10 ];then
		IP=`echo $line|awk '{print $2}'`
		iptables -vnL FLOOD_REJECT|grep -o $IP &>/dev/null;[ $? -eq 0 ] || iptables -AFLOOD_REJECT -s $IP -j REJECT;
	fi;
done

现在不管短时间内脚本被执行几遍都不会再重复添加了
在这里插入图片描述

5 crontab添加

要求是每5分钟检查一次

[root@localhost ~]# crontab -e

*/5 * * * * /data/scripts/flood_check.sh

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值