Chinaunix首页 | 论坛 | 博客
  • 博客访问: 931366
  • 博文数量: 245
  • 博客积分: 11429
  • 博客等级: 上将
  • 技术积分: 2662
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-15 00:16
文章存档

2011年(56)

2010年(174)

2009年(15)

分类: LINUX

2011-04-08 16:05:27

1.检测user-agent
2.设定一个阀值,如果超过这个访问阀值,就进入灰名单,某个时间段联系两次进入灰名单,就干掉这个ip
3.检测开发提供的特殊连点,查过阀值并访问特殊连点,也限制它。
4.判断reffer,如果为空的链接记录数大于整体访问的某个阀值,也限制该IP
  1. #!/bin/bash

  2. PATH="/var/PROGRAM/MANAGEMENT/modules/xbash:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:"
  3. LANG=zh_CN
  4. export PATH LANG
  5. PATTERN_MIN=30
  6. PORT=8080 #暂时不需要
  7. MROOT="/data/resin-pro-3.1.6"
  8. ACCESS_LOG=$MROOT"/logs/access.log"
  9. IPTABLE="/tmp/.iptablestore"
  10. LIMITIPLOG=$MROOT"/logs/limitIP.log"
  11. CRITICAL=30 #系统并发数的阀值 当系统的连接数超过该值才运行脚本
  12. PY_ACCESS="/var/PROGRAM/MANAGEMENT/modules/xbash/access.py"
  13. SORT_D="/tmp/.sortd" #临时放置排序的选出来的段
  14. SORT_S="/tmp/.sorts" #临时放置排序的选出来的IP

  15. cd $MROOT

  16. now_time_hour=$(date +%H)
  17. now_time_min=$(date +%M)

  18. case $now_time_hour in
  19.   01|02|03|04|05|06|07|08|09)
  20.   now_time_hour=`echo $now_time_hour |  awk ' BEGIN { FS="0"} {print $2}'`
  21.   ;;
  22.   00)
  23.   now_time_min=0
  24.   ;;
  25. esac

  26. case $now_time_min in
  27.   01|02|03|04|05|06|07|08|09)
  28.   now_time_min=`echo $now_time_min |  awk ' BEGIN { FS="0"} {print $2}'`
  29.   ;;
  30.   00)
  31.   now_time_min=0
  32.   ;;
  33. esac

  34. now_year=$(date +%Y)
  35. now_month=$(date +%m)
  36. now_day=$(date +%d)


  37. if [[ $now_time_min -ge 0 && $now_time_min -le 20 && $now_time_hour -eq 8 && -e $IPTABLE ]] ; then
  38.   
  39.      
  40.    mv $MROOT/logs/limitIP.log $MROOT/logs/limitIP.log.$now_year$now_month$now_day
  41.    if [[ "$now_day" == "15" ]] ; then
  42.   
  43.        tar -cvf $MROOT/logs/limitIP.log.tar $MROOT/logs/limitIP.log.[0-9][0-9]*
  44.        rm  -f $MROOT/logs/limitIP.log.[0-9][0-9]*
  45.    fi
  46.    echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >> $LIMITIPLOG
  47.    echo "复制iptables" >> $LIMITIPLOG
  48.     iptables-restore < $IPTABLE
  49.   echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >> $LIMITIPLOG
  50.   rm -f $IPTABLE
  51.   exit
  52. fi


  53. if [[ $now_time_min -ge 0  && $now_time_min -le 50 && $now_time_hour -eq 2 ]] ; then
  54.   iptables-save > $IPTABLE
  55.   echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >> $LIMITIPLOG
  56.   echo "已备份iptables" >> $LIMITIPLOG
  57.   echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >> $LIMITIPLOG
  58.   iptables -F
  59.   exit
  60. fi
  61. connect=$(netstat -st | awk '/connections established/{print $1}')

  62. [[ $connect -lt $CRITICAL ]] && exit  #如果连接数少于阀值就退出

  63. BLACK=/tmp/.black #存储符合黑名单的IP和IP段
  64. GRAY=/tmp/.gray  #灰名单
  65. LIST=/tmp/.list  #存储符合相应条件的日志信息
  66. LISTT=/tmp/.listt #临时存储变量,存储不是ip段的IP
  67. LOGPID=/tmp/.sclogpid #存储灰名单的版本
  68. BFB=100 #百分比的分母
  69. FZ=2    #百分比的分子
  70. TOTALLINE=15000 #选取的总数
  71. #临时存放灰名单的IP
  72. patternGrayIP=""


  73. pattern_year=$(date +%Y)
  74. pattern_hour=$(date +%k)
  75. now_patter_hour=0
  76. min=`echo $PATTERN_MIN | awk ' BEGIN { FS="0"} {print $1}'`
  77. i=0
  78. head_min=`date +%M | awk '{print substr($1,1,1)}'`
  79. real_min=$head_min
  80. pattern_tap=0
  81. while [ $i -lt $min ]
  82. do
  83.    if [[ real_min -eq 0 ]] ; then
  84.    
  85.       if [[ "$pattern_hour" == " 0" ]] ; then
  86.       
  87.        pattern_hour=24
  88.       fi
  89.       pattern_hour=$(($pattern_hour-1))
  90.       head_min=6
  91.       pattern_tap=1
  92.    fi

  93.     if [[ $pattern_tap -eq 0 ]] ; then
  94.       
  95.        real_min=$(($head_min-$i-1))
  96.      else
  97.        real_min=$(($head_min+$i-$min))   
  98.     fi   

  99.      case $pattern_hour in
  100.         " 0"|" 1"|" 2"|" 3"|" 4"|" 5"|" 6"|" 7"|" 8"|" 9")
  101.         now_pattern_hour=`echo $pattern_hour | awk '{print substr($1,1,1)}'`
  102.         now_pattern_hour="0$now_pattern_hour"
  103.         ;;
  104.         0|1|2|3|4|5|6|7|8|9)
  105.         now_pattern_hour="0$pattern_hour"
  106.         ;;
  107.         *)
  108.         now_pattern_hour="$pattern_hour"
  109.         ;;
  110.         esac  
  111.     if [[ $i -lt $(($min-1)) ]] ; then
  112.       pattern_min="$pattern_min$pattern_year:$now_pattern_hour:$real_min|"
  113.      else
  114.       pattern_min="$pattern_min$pattern_year:$now_pattern_hour:$real_min"
  115.     fi
  116.     i=$(($i+1))  
  117. done

  118. time_pattern="$pattern_min"


  119. ############
  120. # 主机信息 #
  121. ############
  122. INTF=$(netstat -rn | tail -1 | awk '{print $NF}')
  123. IP=$(ifconfig $INTF | awk '/inet addr/{ split($2,tmp,":") ; print tmp[2] }')
  124. HOST_NAME=$(hostname --short)
  125. ###########
  126. ##########
  127. # 邮件环境#
  128. ##########
  129. #CHARTSET="zh_CN."
  130. MAIL_CLIENT=""
  131. MAIL_SENDER=""
  132. MAIL_SERVER=""
  133. case $IP in
  134.         192.168.230.*|192.168.1[0-1].*|192.168.238.*|202.*)
  135.         MAIL_SERVER=""
  136.         ;;
  137.         *)
  138.         MAIL_SERVER=""
  139.         ;;
  140. esac
  141. ##########
  142. LINECOUNT=0

  143. rm -f $LIST
  144. rm -f $LISTT

  145. testline=`wc -l $ACCESS_LOG | awk '{print $1}'`

  146. #### 以下是有时间匹配的样本数据的获取
  147. #tail -$TOTALLINE $ACCESS_LOG | grep -E "$time_pattern" > $LIST
  148. grep -E "$time_pattern" $ACCESS_LOG > $LIST
  149. TOTALLINE=`wc -l $LIST | awk '{print $1}'`
  150. if [[ -e $LIST ]]  ; then
  151. patternLINE=`wc -l $LIST | awk '{print $1}'`
  152. BFB=$(($patternLINE/$BFB))
  153. FZ=$(($FZ*$BFB))
  154. echo "##########################################################" >> $LIMITIPLOG
  155. date >> $LIMITIPLOG
  156. echo "匹配的时间模式是:"$time_pattern >> $LIMITIPLOG
  157. echo "Access_LOG的数据总数是:"$testline >> $LIMITIPLOG
  158. echo "获取的数据的总数是:"$TOTALLINE >> $LIMITIPLOG
  159. echo "阀值是:"$FZ >> $LIMITIPLOG
  160. else
  161. echo "##########################################################" >> $LIMITIPLOG
  162. date >> $LIMITIPLOG
  163. echo "-----------------------------------------------------------" >> $LIMITIPLOG
  164. echo "没有获取到样本数据" >> $LIMITIPLOG
  165. exit
  166. fi




  167. # 把agent中含有爬虫类代表的字符的先清除到黑名单中
  168. cat $LIST | \
  169. grep -iEv "googlebot|baiduspider" |grep -E "spider|bot|Yahoo|archiver|yodaoice" | awk '{print $1}' | sort | uniq  > $BLACK


  170. #缓存通过第一个条件的log数据
  171. cat $LIST | \
  172. #选取不包含特殊字符的数据
  173. grep  -Eiv "googlebot|archiver|spider|bot|Yahoo" | \
  174. #选取例外IP之外的数据
  175. grep -Ev "192.168.*.*|xx|127.0.0.1" > $LISTT
  176. cat $LISTT > $LIST
  177. rm -f $LISTT



  178. if [[ -e $BLACK ]] ; then
  179. spiderNum=`wc -l $BLACK | awk '{print $1}'`

  180. if [[ $spiderNum -gt 0 ]] ; then
  181. echo "-------------以下IP包含Spider等特殊字符--------------" >> $LIMITIPLOG
  182. cat $BLACK >> $LIMITIPLOG
  183. limitIP_num=`wc -l $BLACK | awk '{print($1)}'`

  184. cat $BLACK | sort | uniq -c > /tmp/.tmp_black

  185.     if [[ -e /tmp/.tmp_black ]] ; then
  186.         #########发送邮件############
  187.          env MAILRC=/dev/null charset="$CHARTSET" from="$MAIL_SENDER" smtp="$MAIL_SERVER" \
  188.          nail -n -s "$HOST_NAME($IP)含有爬虫等关键字名单的IP" $MAIL_CLIENT < /tmp/.tmp_black
  189.    fi

  190. fi

  191. fi


  192. cat $LIST | \
  193. $PY_ACCESS G -gh | \
  194. awk '{if( NR>2 && $1~/[0-9]+/&&"-"!~$2 && $3!="" )  print $1,$3}' | \
  195. while read num ip
  196. do
  197.   if [[ $num -gt $FZ ]]
  198.    then
  199.        echo "$ip"  >> $GRAY
  200.    else
  201.           continue
  202.    fi

  203. done









  204. if [[ -e $GRAY ]] ; then
  205. tmp_gray_line=`wc -l $GRAY | awk '{print $1}'`
  206. if [[ $tmp_gray_line -gt 0 ]] ; then
  207.   if [[ -e $LOGPID ]] ; then
  208.    last_hour=`cat $LOGPID | awk '{print $1}'`

  209.     if (( now_time_hour - last_now > 1 ))
  210.       then
  211.       cat $GRAY | sort | uniq -c | awk '{print($1,$2)}' | \
  212.        while read num ip
  213.        do
  214.          if [[ $num -gt 1 ]]
  215.            then
  216.            echo "$ip"
  217.          fi
  218.        done > $LISTT
  219.       
  220.      if [[ -e $LISTT ]] ; then  
  221.        logcount=`wc -l $LISTT | awk '{print($1)}'`
  222.    
  223.        if [[ $logcount -gt 0 ]] ; then
  224.          #########发送邮件############
  225.          env MAILRC=/dev/null charset="$CHARTSET" from="$MAIL_SENDER" smtp="$MAIL_SERVER" \
  226.          nail -n -s "$HOST_NAME($IP)两次连续进入灰名单名单的IP" $MAIL_CLIENT < $LISTT

  227.          echo "-------------以下字符是两次连续进入灰名单的------" >> $LIMITIPLOG
  228.          cat $LISTT >> $LIMITIPLOG
  229.          cat $LISTT > $GRAY
  230.          ############封灰名单##################
  231.      cat $GRAY >> $BLACK
  232.      cat $GRAY >>  $MROOT/logs/gray.log ####暂时存放灰名单IP用于观察
  233.        fi
  234.      fi

  235.     fi   

  236.   else
  237.      echo $now_time_hour > $LOGPID
  238.   fi
  239. fi
  240. fi


  241. rm -f $LISTT

  242.      echo "检查特殊文件的存在" >> $LIMITIPLOG

  243. if [[ $# -eq 0 ]]
  244.      then
  245.            echo "没有设置特殊连点文件,跳过特殊连点检查" >> $LIMITIPLOG
  246.      else
  247.             graylinecount=`wc -l $GRAY | awk '{print $1}'`
  248.             i=0
  249.         if [[ $graylinecount -gt 1 ]] ; then
  250.             cat $GRAY | awk '{print $1}' | \
  251.             while read ip
  252.             do
  253.               if [[ "$ip" ]] ; then
  254.                      
  255.                 cat $1 | awk '{print($1)}' | \
  256.                 while read limitedUrl
  257.                   do
  258.                    tap=`cat $LIST | access.py FG -gr -h $ip | grep -E "$limitedYrl" | awk '{if( NR>2 && $1~/[0-9]+/&&"-"!~$2 && $3!="" && $1>0  )  print $3}' | wc -l | awk '{print $1}'`
  259.                    if [[ tap -gt 0 ]] ; then
  260.                       echo $ip >> $LISTT
  261.                    fi
  262.                    done
  263.                
  264.               fi
  265.             done
  266.             if [[ -e $LISTT ]] ; then
  267.                cat $LISTT | uniq -c | awk '{print($2)}' > /tmp/.gray_tsld
  268.             tsldEmailTap=`wc -l /tmp/.gray_tsld | awk '{print $1}'`
  269.          if [[ $tsldEmailTap -gt 0 ]] ; then
  270.              #########发送邮件############
  271.          env MAILRC=/dev/null charset="$CHARTSET" from="$MAIL_SENDER" smtp="$MAIL_SERVER" \
  272.          nail -n -s "$HOST_NAME ($IP)爬虫检查过程中在灰名单发现有特殊连接的IP" $MAIL_CLIENT < /tmp/.gray_tsld
  273.             echo "----------------爬虫检查过程中在灰名单发现有特殊连接的IP-------------------" >> $LIMITIPLOG
  274.             cat /tmp/.gray_tsld >> $LIMITIPLOG
  275.             rm -f /tmp/.gray_tsld
  276.           fi
  277.          fi
  278.          fi

  279. fi


  280. rm -f $LISTT
  281. rm -f $LIST
  282. cat $BLACK | awk ' BEGIN { FS="."} {printf "%d.%d.%d\n",$1,$2,$3}' | uniq -c | \
  283. awk '{print($1,$2)}' | \
  284. while read num ip
  285. do
  286.   if [[ $num -gt 1 ]]
  287.   then
  288.     echo "$ip"
  289.     LINECOUNT=$(($LINECOUNT+$num))
  290.   else
  291.     LINECOUNT=$(($LINECOUNT+$num))
  292.     head -n "$LINECOUNT" $BLACK | tail -1 >> $LIST
  293.   fi
  294. done > $LISTT



  295. if [[ -e $LIST ]] ; then
  296. cat $LIST | awk '{print($1)}' | \
  297. # 封锁判断为异常的ip
  298. while read ip
  299. do
  300.     continuetap=`iptables -nL | grep $ip | wc -l | awk '{print $1}'`
  301.     if [[ $continuetap -gt 0 ]] ; then
  302.        continue
  303.     fi
  304.         diptap=`echo $ip | awk '{print($1".0/24")}'`
  305.         dtap=`iptables -nL | grep $diptap | wc -l | awk '{print $1}'`
  306.         if [[ dtap -gt 0 ]] ; then
  307.           continue
  308.         fi
  309.      #iptables -A INPUT -s $ip -p tcp --dport $PORT -j REJECT --reject-with tcp-reset
  310.      iptables -A INPUT -s $ip -p tcp -j DROP
  311. done
  312. fi


  313. # 封锁异常ip段

  314. if [[ -e $LISTT ]]  ; then
  315. cat $LISTT | awk '{print($1".0/24\n")}'  | \
  316. while read ip
  317. do
  318.     if [[ "$ip" ]] ; then

  319.        continuetap=`iptables -nL | grep $ip | wc -l | awk '{print $1}'`
  320.        if [[ $continuetap -gt 0 ]] ; then
  321.        continue
  322.        fi
  323.       #iptables -A INPUT -s $ip -p tcp --dport $PORT  -j REJECT --reject-with tcp-reset
  324.       iptables -A INPUT -s $ip -p tcp -j DROP
  325.     fi
  326. done
  327. fi




  328. if [[ $now_time_hour -eq 12 ]] ; then



  329.   ############排序iptables表###################
  330.   #选出超过数量1从而作为网段处理
  331.   iptables -nL | awk '/DROP/{print $4}' | awk -F"." '{print $1"."$2"."$3}' | sort | uniq -c | awk '{if($1>1) print $2}' > $SORT_D
  332.   iptables -nL | awk '/DROP/{print $4}'  | \
  333.   while read ip
  334.   do
  335.       ltmp=`echo $ip | awk -F"." '{print $1"."$2"."$3}'`
  336.      if  cat $SORT_D | grep -q "$ltmp"
  337.        then
  338.        echo $ip > /dev/null
  339.      else
  340.        echo $ip >> $SORT_S
  341.      fi
  342.   done

  343. iptables -F

  344. if [[ -e $SORT_S ]] ; then
  345.   cat $SORT_S | awk '{print($1)}' | \
  346.   # 封锁判断为异常的ip
  347. while read ip
  348. do
  349.      #iptables -A INPUT -s $ip -p tcp --dport $PORT -j REJECT --reject-with tcp-reset
  350.      iptables -A INPUT -s $ip -p tcp -j DROP
  351. done
  352. fi


  353. # 封锁异常ip段

  354. if [[ -e $SORT_D ]]  ; then
  355.    cat $SORT_D | awk '{print($1".0/24")}'  | \
  356. while read ip
  357. do
  358.       #iptables -A INPUT -s $ip -p tcp --dport $PORT  -j REJECT --reject-with tcp-reset
  359.       iptables -A INPUT -s $ip -p tcp -j DROP
  360. done
  361. fi


  362. rm -f $SORT_D
  363. rm -f $SORT_S

  364. fi
阅读(898) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~