Linux下防御DDOS攻击工具(DDoS deflate)分析与改造

浏览:
字体:
发布时间:2013-12-09 23:23:39
来源:
DDoS deflate其实是一个Shell脚本,使用netstat和iptables工具,对那些链接数过多的IP进行封锁,能有效防止通用的恶意扫描器,但它并不是真正有效的DDoS防御工具。

工作过程描述:
同一个IP链接到服务器的连接数到达设置的伐值后,所有超过伐值的IP将被屏蔽,同时把屏蔽的IP写入ignore.ip.list文件中,与此同时会在tmp中生成一个脚本文件,这个脚本文件马上被执行,但是一运行就遇到sleep 预设的秒,当睡眠了这么多的时间后,解除被屏蔽的IP,同时把之前写入ignore.ip.list文件中的这个被封锁的IP删除,然后删除临时生成的文件。

一个事实:如果被屏蔽的IP手工解屏蔽,那么如果这个IP继续产生攻击,那么脚本将不会再次屏蔽它(因为加入到了ignore.ip.list),直到在预设的时间之后才能起作用,加入到了ignore.ip.list中的IP是检测的时候忽略的IP。可以把IP写入到这个文件以避免这些IP被堵塞,已经堵塞了的IP也会加入到ignore.ip.list中,但堵塞了预定时间后会从它之中删除。

安装:
wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 0700 install.sh
./install.sh

卸载:
wget http://www.inetbase.com/scripts/ddos/uninstall.ddos
chmod 0700 uninstall.ddos
./uninstall.ddos

安装完成后在/usr/local/ddos目录下产生了ddos.conf、ddos.sh、ignore.ip.list和LICENSE这四个文件,ddos.conf是配置文件,ddos.sh是一个Shell文件,ignore.ip.list是存放忽略IP的文件,LICENSE是版权声明文件,安装完成后还在/etc/cron.d/下生产了ddos.cron文件,内容如下:
SHELL=/bin/sh
0-59/1 * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1
意思是每隔一分钟执行一下/usr/local/ddos/ddos.sh

这个cron任务是依赖ddos.conf文件中的NO_OF_CONNECTIONS变量产生的,如果修改了此值,可以通过运行如下命令更新(实际也是在安装是运行了如下命令):
/usr/local/ddos/ddos.sh -c 或 /usr/local/ddos/ddos.sh –cron

以下主要针对ddos.conf和ddos.sh进行分析:

ddos.conf内容:

##### Paths of the script and other filesPROGDIR="/usr/local/ddos"PROG="/usr/local/ddos/ddos.sh"IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list"CRON="/etc/cron.d/ddos.cron"APF="/etc/apf/apf"IPT="/sbin/iptables"##### frequency in minutes for running the script##### Caution: Every time this setting is changed, run the script with --cron#####          option so that the new frequency takes effect# 设置检测时间间隔,默认是分钟,由于系统使用crontab功能,最小单位是分钟FREQ=1##### How many connections define a bad IP? Indicate that below.# NO_OF_CONNECTIONS默认是150,这是一个经验值,如果服务器性能比较高,可以设置200以上,以避免误杀NO_OF_CONNECTIONS=150##### APF_BAN=1 (Make sure your APF version is atleast 0.96)##### APF_BAN=0 (Uses iptables for banning ips instead of APF)# 使用APF屏蔽IP,如果设置为0就使用iptables,如果使用APF则需要先安装,比如centos中默认就没有安装APF_BAN=0##### KILL=0 (Bad IPs are'nt banned, good for interactive execution of script)##### KILL=1 (Recommended setting)KILL=1##### An email is sent to the following address when an IP is banned.##### Blank would suppress sending of mails# 如果不希望发送邮件,设置为空EMAIL_TO=""##### Number of seconds the banned ip should remain in blacklist.# 解锁的时间,单位为秒,可以设置更长时间BAN_PERIOD=86400

ddos.sh内容:

# 载入配置文件load_conf(){        CONF="/usr/local/ddos/ddos.conf"	# $CONF是文件,使用source载入        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 <zaf@vsnl.com>"        echo}# 显示帮助,比如如果要收到干掉当前超过N个连接的IP,使用sh ddos.sh -k 150, sh ddos.sh -h 显示帮助, sh ddos.sh -c创建cron jobshowhelp(){        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                '}# 解除对IP的封锁unbanip(){        UNBAN_SCRIPT=`mktemp /tmp/unban.XXXXXXXX`	# 产生随机文件,解除IP封锁时        TMP_FILE=`mktemp /tmp/unban.XXXXXXXX`		# 临时文件        UNBAN_IP_LIST=`mktemp /tmp/unban.XXXXXXXX`	# 将被解除封锁的IP        echo '#!/bin/sh' > $UNBAN_SCRIPT		# 产生解除IP封锁的脚本内容        echo "sleep $BAN_PERIOD" >> $UNBAN_SCRIPT	# $BAN_PERIOD睡眠时间,表示$UNBAN_SCRIPT睡眠多久后继续,这个变量在配置文件中定义        if [ $APF_BAN -eq 1 ]; then			# 使用APF堵塞IP                while read line; do                        echo "$APF -u $line" >> $UNBAN_SCRIPT                        echo $line >> $UNBAN_IP_LIST                done < $BANNED_IP_LIST        else						# 使用iptables封锁IP                while read line; do                        echo "$IPT -D INPUT -s $line -j DROP" >> $UNBAN_SCRIPT		# 解除IP封锁                        echo $line >> $UNBAN_IP_LIST	# 把将要解除堵塞的IP写入$UNBAN_IP_LIST,跟当前的$BANNED_IP_LIST是对应的                done < $BANNED_IP_LIST			# 输入重定向,行对于$line变量,是当前需要堵塞的IP,脚本运行过程中产生        fi        echo "grep -v --file=$UNBAN_IP_LIST $IGNORE_IP_LIST > $TMP_FILE" >> $UNBAN_SCRIPT   # 从$IGNORE_IP_LIST中去掉$UNBAN_IP_LIST,把结果写入$TMP_FILE        echo "mv $TMP_FILE $IGNORE_IP_LIST" >> $UNBAN_SCRIPT    # 移动$TMP_FILE到$IGNORE_IP_LIST,$IGNORE_IP_LIST在配置文件中定义,则本次操作是覆盖        echo "rm -f $UNBAN_SCRIPT" >> $UNBAN_SCRIPT	# 删除$UNBAN_SCRIPT        echo "rm -f $UNBAN_IP_LIST" >> $UNBAN_SCRIPT	# 删除$UNBAN_IP_LIST        echo "rm -f $TMP_FILE" >> $UNBAN_SCRIPT 	# 删除$TMP_FILE,经过上面的移动操作,$TMP_FILE其实已经不存在	. $UNBAN_SCRIPT &				# 在后台运行$UNBAN_SCRIPT}# 添加到计划任务add_to_cron(){        rm -f $CRON				# 删除/etc/cron.d/ddos.cron        sleep 1        service crond restart			# 计划任务重启        sleep 1        echo "SHELL=/bin/sh" > $CRON		# 创建计划任务        if [ $FREQ -le 2 ]; then		# $FREQ在配置文件中定义,表示多少分钟执行一次,如果小于2,Linux最小是每分钟		# 以下语句得到 0-59/1 * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1,每分钟以root执行ddos.sh,把输出结果丢弃                echo "0-59/$FREQ * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1" >> $CRON        else					# 大于1分钟设置                let "START_MINUTE = $RANDOM % ($FREQ - 1)"	# $RANDOM是环境变量随机数  let是shell内建命令,就是执行计算                let "START_MINUTE = $START_MINUTE + 1"                let "END_MINUTE = 60 - $FREQ + $START_MINUTE"                echo "$START_MINUTE-$END_MINUTE/$FREQ * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1" >> $CRON        fi        service crond restart}# 加载配置load_conf# 判断$1,是第一个参数,提供帮助,如果没有提供则不会进入循环while [ $1 ]; do        case $1 in                '-h' | '--help' | '?' )                        showhelp		# 显示帮助                        exit                        ;;                '--cron' | '-c' )                        add_to_cron		# 添加到计划任务                        exit                        ;;                '--kill' | '-k' )                        KILL=1			# KILL在配置文件中指定,用来指定是否堵塞IP                        ;;                 *[0-9]* )                        NO_OF_CONNECTIONS=$1	# 第二个参数,指定阀值,NO_OF_CONNECTIONS在配置文件中指定,这里覆盖                        ;;                * )                        showhelp                        exit                        ;;        esac        shift					# 减少变量,就是现在$1是原来的$2,shift后可以指定减少几个doneTMP_PREFIX='/tmp/ddos'TMP_FILE="mktemp $TMP_PREFIX.XXXXXXXX"BANNED_IP_MAIL=`$TMP_FILE`			# 产生临时文件,发送邮件,邮件内容BANNED_IP_LIST=`$TMP_FILE`			# 产生临时文件,存放已经被堵塞的IPecho "Banned the following ip addresses on `date`" > $BANNED_IP_MAIL  构建邮件内容echo >> $BANNED_IP_MAILBAD_IP_LIST=`$TMP_FILE`				# 产生临时文件,存放当前可能被堵塞的IPnetstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LISTcat $BAD_IP_LIST				# 输出这个列表if [ $KILL -eq 1 ]; then			# 如果配置为需要堵塞        IP_BAN_NOW=0        while read line; do                CURR_LINE_CONN=$(echo $line | cut -d" " -f1)			# 当前这个IP有多少个连接                CURR_LINE_IP=$(echo $line | cut -d" " -f2)			# 当前IP                if [ $CURR_LINE_CONN -lt $NO_OF_CONNECTIONS ]; then		# 如果这个IP链接数小于预设,终止(因为数据经过排序)                        break                fi                IGNORE_BAN=`grep -c $CURR_LINE_IP $IGNORE_IP_LIST`		# 计算当前IP在$IGNORE_IP_LIST出现了多少次                if [ $IGNORE_BAN -ge 1 ]; then					# 如果当前IP已经在$IGNORE_IP_LIST,跳过,可以通过这个方式设置永不堵塞某些IP                        continue                fi                IP_BAN_NOW=1							# 进入到这里表示当前必定有IP要被堵塞                echo "$CURR_LINE_IP with $CURR_LINE_CONN connections" >> $BANNE_IP_MAIL  # 把堵塞信息写入邮件内容                echo $CURR_LINE_IP >> $BANNED_IP_LIST				# 添加堵塞了的IP到当前堵塞列表,$BANNED_IP_LIST会应用到下面的unbanip函数                echo $CURR_LINE_IP >> $IGNORE_IP_LIST				# 添加堵塞了的IP到$IGNORE_IP_LIST                if [ $APF_BAN -eq 1 ]; then                        $APF -d $CURR_LINE_IP                else                        $IPT -I INPUT -s $CURR_LINE_IP -j DROP			# 开始iptables封锁                fi        done < $BAD_IP_LIST        if [ $IP_BAN_NOW -eq 1 ]; then						# $IP_BAN_NOW等于1表示有IP被封锁了                dt=`date`                if [ $EMAIL_TO != "" ]; then					# $EMAIL_TO设置不为空则发邮件,留空则不发邮件                        cat $BANNED_IP_MAIL | mail -s "IP addresses banned on $dt" $EMAIL_TO    # $EMAIL_TO在配置文件中指定                fi                unbanip								# 同时开始运行解除堵塞程序        fifirm -f $TMP_PREFIX.*								# 清除临时产生的文件

可以看到如果有堵塞IP,将调用mail发送邮件,但是作为前端代理,视乎没有必要特意去安装sendmail,所以我们可以使用curl把数据推送到远程,由另一台专门的服务器发送这些信息,改造如下:

if [ $EMAIL_TO != "" ]; then    cat $BANNED_IP_MAIL | mail -s "IP addresses banned on $dt" $EMAIL_TOelse    curl --data "d=IP addresses banned on $dt -- $(cat $BANNED_IP_MAIL)" "http://domain.com/blockip.php" >> /dev/nullfi

除此,尽管默认到达150才堵塞,但你可能希望把那些超过100链接的IP都记录下来,可以在cat $BAD_IP_LIST之后添加如下代码:

NUM_CONNECTIONS=100  # 超过100就记录# 按照日期存放CNTS_LOG="/usr/local/ddos/$(date +%Y)/$(date +%m)/"mkdir -p $CNTS_LOGCNTS_LOG="$CNTS_LOG$(date +%Y%m%d).log"while read line; do        CURR_CONN=$(echo $line | cut -d" " -f1)        CURR_IP=$(echo $line | cut -d" " -f2)        if [ $CURR_CONN -lt $NUM_CONNECTIONS ]; then                break        fi        echo "$CURR_IP with $CURR_CONN connections at `date`" >> $CNTS_LOGdone < $BAD_IP_LIST

 

>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2023 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();