DDOS-deflate工具:ddos.sh脚本解读(预防DDOS攻击脚本)

DDOS-deflate工具:ddos.sh脚本解读(预防DDOS攻击脚本)

[root@server ddos]# cat ddos.sh 
#!/bin/sh
##############################################################################
# DDoS-Deflate version 0.6 Author: Zaf <[email protected]>                        #
##############################################################################
# This program is distributed under the "Artistic License" Agreement         #
#                                                                            #
# The LICENSE file is located in the same directory as this program. Please  #
#  read the LICENSE file before you make copies or distribute this program   #
##############################################################################
load_conf()     # 定义一个加载DDOS配置文件的函数,DDOS配置文件存在则加载,否则输出head()并退出。
{
    
    
	CONF="/usr/local/ddos/ddos.conf"
	if [ -f "$CONF" ] && [ ! "$CONF" ==	"" ]; then
		source $CONF
	else
		head
		echo "\$CONF not found."
		exit 1
	fi
}

head()          # 定义固定文本的函数
{
    
    
	echo "DDoS-Deflate version 0.6"
	echo "Copyright (C) 2005, Zaf <[email protected]>"
	echo
}

showhelp()      # 定义显示帮助信息的函数
{
    
    
	head
	echo 'Usage: ddos.sh [OPTIONS] [N]'
	echo 'N : number of tcp/udp	connections (default 150)'
	echo 'OPTIONS:'
	echo '-h | --help: Show	this help screen'
	echo '-c | --cron: Create cron job to run this script regularly (default 1 mins)'
	echo '-k | --kill: Block the offending ip making more than N connections'
}

unbanip()    # 等待指定时间后,删除无效的规则链,解除拒绝的IP
{
    
    
	UNBAN_SCRIPT=`mktemp /tmp/unban.XXXXXXXX`   # mktemp创建临时文件,文件名参数为:文件名.XXXX。使用iptables操作拒绝IP访问服务器的脚本文件。
	TMP_FILE=`mktemp /tmp/unban.XXXXXXXX`
	UNBAN_IP_LIST=`mktemp /tmp/unban.XXXXXXXX`     # 已拒绝的IP都放到这个文件中
	echo '#!/bin/sh' > $UNBAN_SCRIPT
	echo "sleep $BAN_PERIOD" >> $UNBAN_SCRIPT    # 等待600s
	if [ $APF_BAN -eq 1 ]; then    # APF_BAN值为1
		while read line; do
			echo "$APF -u $line" >> $UNBAN_SCRIPT
			echo $line >> $UNBAN_IP_LIST
		done < $BANNED_IP_LIST      
	else         # APF_BAN值为0
		while read line; do    # 
			echo "$IPT -D INPUT -s $line -j DROP" >> $UNBAN_SCRIPT    # 把上一次被拒绝的IP地址重新设置为允许,即删除对应的DROP规则链
			echo $line >> $UNBAN_IP_LIST                  # 重新设置允许的IP都写入该文件
		done < $BANNED_IP_LIST              # 输入的文件,历史访问次数统计信息
	fi
	echo "grep -v --file=$UNBAN_IP_LIST $IGNORE_IP_LIST > $TMP_FILE" >> $UNBAN_SCRIPT   # IGNORE_IP_LIST文件根据UNBAN_IP_LIST文件中的匹配规则,筛选出匹配不上的IP地址,并写入到临时文件中。
	echo "mv $TMP_FILE $IGNORE_IP_LIST" >> $UNBAN_SCRIPT   # 将TMP_FILE文件重命名为IGNORE_IP_LIST,即不删除DROP规则链的IP地址。仍然设置为拒绝访问服务器。
	# 删除以下三个临时文件
	echo "rm -f $UNBAN_SCRIPT" >> $UNBAN_SCRIPT
	echo "rm -f $UNBAN_IP_LIST" >> $UNBAN_SCRIPT
	echo "rm -f $TMP_FILE" >> $UNBAN_SCRIPT
	. $UNBAN_SCRIPT &     # 后台执行脚本UNBAN_SCRIPT
}

add_to_cron()   # 定义更新定时任务的函数
{
    
    
	rm -f $CRON    # 若ddos.cron定时任务存在,删除定时任务
	sleep 1
	service crond restart    # 重启crond服务
	sleep 1
	echo "SHELL=/bin/sh" > $CRON
	if [ $FREQ -le 2 ]; then   # 检查间隔小于等于2分钟,检查时间间隔的取值范围一般为0-59,单位分钟。
		echo "0-59/$FREQ * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1" >> $CRON
	else    # 检查间隔大于2分钟
		let "START_MINUTE = $RANDOM % ($FREQ - 1)"  # 若FREQ是5,START_MINUTE为0 1 2 3
		let "START_MINUTE = $START_MINUTE + 1"      # START_MINUTE为1 2 3 4
		let "END_MINUTE = 60 - $FREQ + $START_MINUTE"     # END_MINUTE = 60 - 5 + [1 2 3 4] = [56 57 58 59]
		echo "$START_MINUTE-$END_MINUTE/$FREQ * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1" >> $CRON    # 0-59之间的第一个检查时间START_MINUTE,最后一个检查时间END_MINUTE
	fi
	service crond restart  # 重启crond服务
}


load_conf   # 加载ddos.conf配置文件
while [ $1 ]; do
	case $1 in
		'-h' | '--help' | '?' )
			showhelp     # 显示帮助信息的函数
			exit
			;;
		'--cron' | '-c' )   # 添加定时任务
			add_to_cron
			exit
			;;
		'--kill' | '-k' )  # 启用拒绝IP的功能
			KILL=1
			;;
		 *[0-9]* )
			NO_OF_CONNECTIONS=$1    # 指定阈值,用于手动执行ddos.sh脚本时使用,默认的阈值为ddos.conf文件中的NO_OF_CONNECTIONS
			;;
		* )
			showhelpcatcat 
			exit
			;;
	esac
	shift
done

TMP_PREFIX='/tmp/ddos'   # 临时文件前缀
TMP_FILE="mktemp $TMP_PREFIX.XXXXXXXX"    # 创建一个临时文件的命令
BANNED_IP_MAIL=`$TMP_FILE`      # 执行创建一个临时文件
BANNED_IP_LIST=`$TMP_FILE`      # 执行创建一个临时文件
echo "Banned the following ip addresses on `date`" > $BANNED_IP_MAIL    # 在当前时间下禁止以下IP地址
echo >>	$BANNED_IP_MAIL    # 空一行
BAD_IP_LIST=`$TMP_FILE`
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST # 统计访问服务器的IP地址机器访问次数,并把结果写入文件BAD_IP_LIST
cat $BAD_IP_LIST    # 显示BAD_IP_LIST文件中的统计信息
if [ $KILL -eq 1 ]; then   # KILL的值等于1
	IP_BAN_NOW=0
	while read line; do
		CURR_LINE_CONN=$(echo $line | cut -d" " -f1)   # 次数
		CURR_LINE_IP=$(echo $line | cut -d" " -f2)     # IP地址
		if [ $CURR_LINE_CONN -lt $NO_OF_CONNECTIONS ]; then    # 次数小于阈值,跳出当前整个循环。
			break
		fi
		IGNORE_BAN=`grep -c $CURR_LINE_IP $IGNORE_IP_LIST`   # 计算统计信息中的IP地址在IGNORE_IP_LIST文件中的IP个数,即白名单IP
		if [ $IGNORE_BAN -ge 1 ]; then   # 若在文件IGNORE_IP_LIST文件中的IP个数大于等于1
			continue     # 继续循环
		fi
		IP_BAN_NOW=1
		echo "$CURR_LINE_IP with $CURR_LINE_CONN connections" >> $BANNED_IP_MAIL  # 说明某个IP访问多少次
		echo $CURR_LINE_IP >> $BANNED_IP_LIST   # 把IP写入到BANNED_IP_LIST文件中
		echo $CURR_LINE_IP >> $IGNORE_IP_LIST   # 把IP写入到IGNORE_IP_LIST文件中
		if [ $APF_BAN -eq 1 ]; then
			$APF -d $CURR_LINE_IP   # 当APF_BAN的值为1时,使用APF的方式拒绝IP
		else
			$IPT -I INPUT -s $CURR_LINE_IP -j DROP   # 当APF_BAN不等于1时,使用iptables的方式添加规则拒绝指定IP访问服务器
		fi
	done < $BAD_IP_LIST    # 访问服务器的统计信息作为输入
	if [ $IP_BAN_NOW -eq 1 ]; then     # IP_BAN_NOW的值为1
		dt=`date`
		if [ $EMAIL_TO != "" ]; then    
			cat $BANNED_IP_MAIL | mail -s "IP addresses banned on $dt" $EMAIL_TO # 把被拒绝的IP地址,发送到邮箱EMAIL_TO
		fi
		unbanip    # 取消拒绝IP地址
	fi
fi
rm -f $TMP_PREFIX.*   # 删除创建的临时文件

ddos.sh 脚本总结:

  1. 脚本结构说明:
    声明了5个函数,分别为load_conf、head、showhelp、unbanip、add_to_cron。各函数作用如下:
    load_conf:加载ddox.conf文件的内容
    head:输出的固定表头
    showhelp:显示帮助信息
    unbanip:等待指定时间后,删除全部无效的规则链,解除拒绝的IP。
    add_to_cron:添加定时任务

  2. 主体说明【除函数声明外的部分】:
    ①创建临时文件BAD_IP_LIST,并把访问服务器的统计信息写入其中。
    ②KILL参数决定是否屏蔽IP,当KILL的值为1时,访问次数超过阈值的才会被屏蔽,并指定了屏蔽方式时APF还是iptables,建议使用iptables。
    ③当IP_BAN_NOW的值为1时,发送拒绝IP的消息给指定邮箱EMAIL_TO,然后执行unbanip函数,即等待BAN_PERIOD时间后,将已拒绝的IP地址对应的iptables规则链删除,允许其访问服务器。
    ④最后删除所有的临时文件。

  3. 整体流程说明:
    首先通过netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr 获取到访问服务器的IP地址和次数的统计信息,然后对访问次数超过阈值的IP地址进行拒绝访问操作,即添加DROP的规则链,最后等待BAN_PERIOD时间后,删除之前添加的DROP规则链。以上流程设置定时任务,默认是每分钟都进行一次。

猜你喜欢

转载自blog.csdn.net/weixin_36522099/article/details/109699242