标题:防止SYN洪水攻击的脚本 出处:沧海一粟 时间:Wed, 23 Nov 2011 07:02:41 +0000 作者:jed 地址:http://www.dzhope.com/post/856/ 内容: #! /bin/sh # 防止SYN_RECV攻击的脚本 PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin # 设置某个ip需要被列入黑名单的时间,单位是分钟 TIME_ZONE=30 DATE_ZONE=30 SYN_critical=500 DATE=$(date +%Y%m%d) HOUR=$(date +%H) MINITE=$(date +%M) DATE_AGO=$(date -d "$DATE_ZONE days ago" +%Y%m%d) DATE_1D_AGO=$(date -d "1 days ago" +%Y%m%d) TIME_AGO=$(date -d "$TIME_ZONE min ago" +%H%M) # 正常日志 LOG=/home/tools/syn_flood/syn.log # 30分钟前的ip记录 LOG_ago=/home/tools/syn_flood/syn.log.ago # 30分钟以内的ip记录 LOG_current=/home/tools/syn_flood/syn.log.current #设置轮转日志的大小范围,单位k LIMIT=16384 export PATH TIME_ZONE DATE_ZONE SYN_critical DATE HOUR MINITE DATE_AGO DATE_1D_AGO TIME_AGO # 将proc文件系统的文件放入tmp cat /proc/net/tcp6 /proc/net/tcp 2>/dev/null > /tmp/syn_recv # 取到黑名单列表 awk '{print $2,$3,$4}' /tmp/syn_recv | awk ' BEGIN { # set fs FS = "[ ]*|:" ; } # 只处理第五列是SYN_RECV的行 ( $5 ~ /03/ ){ # get ipv4addr from file /proc/net/tcp if (length($1) == 8) { rem_addr_ip4 = strtonum("0x"substr($3,1,2)) ; rem_addr_ip3 = strtonum("0x"substr($3,3,2)) ; rem_addr_ip2 = strtonum("0x"substr($3,5,2)) ; rem_addr_ip1 = strtonum("0x"substr($3,7,2)) ; } else # get ipv6addr from file /proc/net/tcp6 { rem_addr_ip4 = strtonum("0x"substr($3,25,2)) ; rem_addr_ip3 = strtonum("0x"substr($3,27,2)) ; rem_addr_ip2 = strtonum("0x"substr($3,29,2)) ; rem_addr_ip1 = strtonum("0x"substr($3,31,2)) ; } printf("%d.%d.%d.%d\n",rem_addr_ip1,rem_addr_ip2,rem_addr_ip3,rem_addr_ip4); }' | uniq -c | grep -v '192.168.' | awk 'BEGIN{ SYN_critical = ENVIRON["SYN_critical"]; DATE = ENVIRON["DATE"]; HOUR = ENVIRON["HOUR"]; MINITE = ENVIRON["MINITE"]; } ( $1 >= SYN_critical ){ printf("[ %d %d%d ] %s %d\n",DATE,HOUR,MINITE,$2,$1) }' >> $LOG # 得到旧的ip列表 if [ $HOUR = "00" ] && [ $MINITE -le 30 ] then export DATE=$DATE_1D_AGO fi awk 'BEGIN{ DATE = ENVIRON["DATE"]; time_ago = ENVIRON["TIME_AGO"]; } ( $2 == DATE && $3 < time_ago ){ print $5 }' $LOG | uniq > $LOG_ago # 得到30分钟内的ip列表 awk 'BEGIN{ DATE = ENVIRON["DATE"]; time_ago = ENVIRON["TIME_AGO"]; } ( $2 == DATE && $3 > time_ago ){ print $5 }' $LOG | uniq > $LOG_current NUM_LOG_ago=$(wc -l $LOG_ago | awk '{print $1}' ) NUM_LOG_current=$(wc -l $LOG_current | awk '{print $1}' ) # 看iptables是否运行 IPTAB_STATUS=$(service iptables status | grep -c 'Firewall is stopped.') # 如果30分钟以前有ip被列入黑名单,则删除掉 if [ $NUM_LOG_ago -ge 1 ] then if [ $IPTAB_STATUS -eq 0 ] then for IP in $(cat $LOG_ago) do # 确认此ip是否在当前iptables列表中,在则删除该ip NUM_ip=$(grep -c $IP /etc/sysconfig/iptables) if [ $NUM_ip -ge 1 ] then iptables -D INPUT -s $IP -i eth0 -j DROP service iptables save fi done fi fi # 处理30分钟内的ip列表,如果不在iptables里,则判断iptables的状态,并加入黑名单 if [ $NUM_LOG_current -ge 1 ] then # 看iptables是否打开 if [ $IPTAB_STATUS -eq 1 ] then service iptables start fi # 把ip加进去 for IP in $(cat $LOG_current) do # 确认此ip是否在当前iptables列表中,不在则加进去 NUM_ip=$(grep -c $IP /etc/sysconfig/iptables) if [ $NUM_ip -eq 0 ] then iptables -A INPUT -s $IP -i eth0 -j DROP service iptables save fi done fi # 如果iptables列表为空,判断其状态,如果是start ,则stop它 if [ $IPTAB_STATUS -eq 0 ] then # 判断iptables列表是否为空 NUM=$(iptables -L -n | wc -l) if [ $NUM -eq 8 ] then service iptables stop fi fi # 按大小轮转日志,注意,日志轮转都放在晚上1点,这样节省脚本每次运行的if判断开销 ################################## 日志轮转 ####################################### #if [ $HOUR == "01" ] # then # size=$(ls -l -k $LOG | cut -d " " -f 6) # # echo "$LOG size is $size, limit is $LIMIT" # # if [ $size -ge $LIMIT ] # # then # # echo "rolling log file" # awk 'BEGIN{ # DATE = ENVIRON["DATE"]; # time_ago = ENVIRON["TIME_AGO"]; # } # # ( $1 == DATE && $3 > time_ago ){ print }' $LOG > /tmp/syn_log_tmp # cp $LOG $LOG.$DATE # mv -f /tmp/syn_log_tmp $LOG # # else # # echo "not big enough" # # fi # # # 按日期轮转日志 # # 如果30天前有日志,说明是该到轮转的时候了 # DATE_NUM=$(grep "$DATE_AGO" $LOG | head | wc -l | awk '{print $1}') # if [ $DATE_NUM -ge 1 ] # then # awk 'BEGIN{ # DATE = ENVIRON["DATE"]; # time_ago = ENVIRON["TIME_AGO"]; # } # # ( $1 == DATE && $3 > time_ago ){ print }' $LOG > /tmp/syn_log_tmp # cp $LOG $LOG.$DATE # mv -f /tmp/syn_log_tmp $LOG # # fi # #fi ################################## 日志轮转 ####################################### Generated by Bo-blog 2.1.1 Release