免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5381 | 回复: 12
打印 上一主题 下一主题

[网络管理] [原創] [分享] 一支反砍站的 iptables script [复制链接]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-11-20 02:09 |只看该作者 |倒序浏览
所謂"砍站"就是使用 teleport, getright 等離線閱覽軟件,
對某一站台進行持續性的完整下載。
這對於只使用靜態網頁的站台來說,應還可以接受,
但對那些運行大量 CGI 或需要調用後端數據庫的站台來說,
一旦連線數目過多或 CPU 不夠力,則很容易被"砍倒"...

相信絕大多數的網站管理員都不歡迎此類行為,
若你也為此所苦,又同時使用  Linux 系統、且能執行 iptables 程式的話,
那本 script 或可值一試的。

不過,聲明在先:
1) 本  script 僅在 RedHat Linux 7.x 平台上測試過,不保證也能用於其他系統版本。
2) script 不盡完善,錯漏難免。請自行評估風險。
3) 若 script 造成任何損失,作者概不負責。

script 的大致工作原理如下:
1) 偵測系統連線數目及 CPU 使用情況,若皆在可接受範圍內,不作任何限制處理。
2) 若超過限制值,從連線抓出黑名單。
3) 第一次抓獲,並不作處分。若被抓獲一定次數(可調整變量),
則啟用 iptables 的 limit 規則,將連線限制於每秒一個封包。
4) 若接線出現在 limit 清單中一定次數(可調整變量),
則啟用 iptables 的 DROP 規則,暫時阻斷該連線來源。
5) script 每次重跑,都會更新黑名單。
若在清單出現次數下降到限制值以下,則刪除該連線的 DROP 或 limit 規則。
6) 若接線出現在 DROP 清單中一定次數(可調整變量),
則啟用 iptables 的永久 DROP 規則,不再刪除其 DROP 規則。

script 執行需知:
1) 你需要 root 權限來執行 script ,script 會在 /root 目錄下建立 BLOCK 子目錄。
2) script 本身沒設循環,請自行設定 crontab 以決定 script 的執行間隔時間。
3) 若系統還有其他 iptables 重整設定(如 portsentry 之類),請自行解決規則一致性。
4) script 建立的永久性 DROP 規則,請自行決定刪除時機。(可另寫 script 再設 crontab)
5) script 會針對 httpd 作重啟偵測處理。
若對 web server 造成不便,請自行註解或刪除程式碼。
(段落提示:#-- restart httpd if dead --# )

script 代碼(歡迎一起 debug):
  1. #!/bin/bash
  2. # Purpose: to block httpd connection
  3. # Author: netman(netman@study-area.org)
  4. # Lisence: GPL
  5. # Date: 2003/10/09
  6. # Version: 1.19

  7. #-- change log --#
  8. # [deleted]

  9. PATH=$PATH:/sbin:/usr/sbin

  10. EXT_IF=eth0     # extenal interface
  11. HTTP_NU=16      # connection number to be added to list
  12. LIMIT_NU=2      # number to be limited
  13. DROP_NU=5       # number to be dropped
  14. PERM_NU=5       # number to be dropped permanently
  15. CL_S=8          # CPU loading for system
  16. CL_U=65         # CPU loading for user
  17. HC_N=200        # HTTP connection number for session
  18. HC_U=20         # HTTP connection number for source
  19. TW_N=40         # TIME_WAIT number for session
  20. HTTP_PORT=80    # HTTP port number
  21. UD_HTTP=30      # minutes to update http list
  22. UD_LIMIT=2      # hours to update limit list
  23. UD_DROP=1       # days to update drop list

  24. HTTP_SCRIPT=/etc/rc.d/init.d/httpd
  25. HTTP_USER=apache
  26. HTTP_CMD=httpd
  27. IPCRM_CMD=ipcrm
  28. IPCS_CMD=ipcs
  29. SAR_CMD=sar
  30. NETSTAT_CMD=netstat
  31. MAIL_CMD=mail
  32. AWK_CMD=awk
  33. IPT_CMD=iptables
  34. IPT_SAVE_CMD=iptables-save

  35. BASED_DIR=/root/BLOCK
  36. PID_FILE=${BASED_DIR}/${0##*/}.pid
  37. HTTP_LIST=${BASED_DIR}/http.list
  38. HTTP_LIST_TMP=${HTTP_LIST}.tmp
  39. HTTP_TW_TMP=${HTTP_LIST}.tw
  40. LIMIT_LIST=${HTTP_LIST}.limit
  41. DROP_LIST=${HTTP_LIST}.drop
  42. PERM_LIST=${HTTP_LIST}.perm
  43. # NOTE: using '|' between each ip in a single line in the EXCP_LIST
  44. EXCP_LIST=${HTTP_LIST}.excp



  45. #-- check programs --#
  46. for pgr in $HTTP_CMD $IPCRM_CMD $SAR_CMD $NETSTAT_CMD $MAIL_CMD $AWK_CMD $IPT_CMD $IPT_SAVE_CMD
  47. do
  48.         which $pgr &>;/dev/null || {
  49.                 echo "${0##*/}: ERROR: $pgr not found or not in the PATH."
  50.                 exit 1
  51.         }
  52. done

  53. #-- create based dir --#
  54. if [ ! -d $BASED_DIR ]; then
  55.         mkdir $BASED_DIR || {
  56.                 echo "${0##*/}: ERROR: can NOT create directory $BASED_DIR."
  57.                 exit 2
  58.         }
  59. fi

  60. #-- create file and set timestampt --#
  61. touch --date="$UD_HTTP minutes ago" $HTTP_LIST
  62. touch --date="$UD_LIMIT hours ago" $LIMIT_LIST
  63. touch --date="$UD_DROP days ago" $DROP_LIST
  64. touch $EXCP_LIST
  65. touch $PERM_LIST

  66. #-- detect process --#
  67. if [ -e $PID_FILE ]; then
  68.         echo "${0##*/}: WARNING: There is a running copy of script."
  69.         echo "  exiting..."
  70.         exit 3
  71. else
  72.         echo "$$" >; $PID_FILE
  73. fi

  74. #-- restart httpd if dead --#
  75. ps u -C $HTTP_CMD | grep -q -E -v '^USER|^root' || {
  76.         $HTTP_SCRIPT stop
  77.         sleep 2
  78.         for i in $($IPCS_CMD | sed '/semid/,/^---/!d' \
  79.         | awk '/^0x/ {print $2}'); do
  80.                 $IPCRM_CMD sem $i
  81.         done
  82.         $HTTP_SCRIPT start
  83.         date | $MAIL_CMD -s "httpd restarted" root
  84.         exit 3
  85. }

  86. #-- create source list --#
  87. touch $HTTP_LIST_TMP
  88. $NETSTAT_CMD -na | grep ":$HTTP_PORT " | awk '{print $5}' | cut -d: -f1 | sort \
  89.         | sed '/0.0.0.0/d' >; $HTTP_LIST_TMP
  90. $NETSTAT_CMD -na | grep ":$HTTP_PORT " | grep "TIME_WAIT" | awk '{print $5}' \
  91.         | cut -d: -f1 | sort | sed '/0.0.0.0/d' >; $HTTP_TW_TMP

  92. #-- check loading --#
  93. cpuload=$($SAR_CMD -u 1 3 | tail -1 | awk '{printf("%i:%i",$3,$5)}')
  94. cpuusr=${cpuload%:*}
  95. cpusys=${cpuload#*:}
  96. http_cn=$(cat $HTTP_LIST_TMP | wc -l)
  97. http_un=$(uniq $HTTP_LIST_TMP | wc -l)
  98. http_tw=$(uniq $HTTP_TW_TMP | wc -l)
  99. echo    "       limit   current"
  100. echo    "CL_U:  $CL_U   $cpuusr"
  101. echo    "CL_S:  $CL_S   $cpusys"
  102. echo    "HC_N:  $HC_N   ${http_cn##* }"
  103. echo    "HC_U:  $HC_U   ${http_un##* }"
  104. echo    "TW_N:  $TW_N   ${http_tw##* }"

  105. #-- function update lists --#
  106. ud_list () {
  107.         for i in $@; do
  108.                 touch ${i}.1 ${i}.2 ${i}.3 ${i}.4
  109.                 mv ${i}.4 ${i}.5
  110.                 mv ${i}.3 ${i}.4
  111.                 mv ${i}.2 ${i}.3
  112.                 mv ${i}.1 ${i}.2
  113.                 mv ${i} ${i}.1
  114.                 sort ${i}.[1-5] >; ${i}.new
  115.         done
  116. }

  117. #-- list is added? or nothing change in the period? --#
  118. if [ -s $HTTP_LIST -o $HTTP_LIST.new -ot $HTTP_LIST ]; then
  119.         #-- remove old limit rules --#
  120.         for i in $(cat $LIMIT_LIST); do
  121.                 echo remove $i from LIMIT
  122.                 $IPT_CMD -D INPUT -p TCP --dport $HTTP_PORT \
  123.                         -s $i -m limit --limit 1/s -j ACCEPT
  124.                 $IPT_CMD -D INPUT -p TCP --dport $HTTP_PORT \
  125.                         -s $i -j DROP
  126.         done
  127.         #-- update http list --#
  128.         ud_list $HTTP_LIST
  129. fi
  130. if [ -s $LIMIT_LIST -o $LIMIT_LIST.new -ot $LIMIT_LIST ]; then
  131.         #-- remove old drop rules --#
  132.         for i in $(cat $DROP_LIST); do
  133.                 echo remove $i from DROP
  134.                 $IPT_CMD -D INPUT -p TCP --dport $HTTP_PORT \
  135.                         -s $i -j DROP
  136.         done
  137.         #-- update limit list --#
  138.         ud_list $LIMIT_LIST
  139. fi
  140. if [ -s $DROP_LIST -o $DROP_LIST.new -ot $DROP_LIST ]; then
  141.         #-- update drop list --#
  142.         ud_list $DROP_LIST
  143.         #-- sort perm list --#
  144.         sort -u $PERM_LIST >; $DROP_LIST.new
  145.         cat $DROP_LIST.new >; $PERM_LIST
  146. fi

  147. #-- limiting http connection --#
  148. if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o "$http_cn" -gt "$HC_N" \
  149.         -o "$http_un" -gt "$HC_U" -o "$http_tw" -gt "$TW_N" ]
  150. then

  151.         #-- function: create list --#
  152.         cr_list () {
  153.                 address="0.0.0.0"
  154.                 count=1
  155.                 for i in $(cat $1); do
  156.                   if [ "$address" != "$i" ]; then
  157.                         if [ "$count" -ge "$2" ]; then
  158.                                 echo $address >;>; $3
  159.                         fi
  160.                         address=$i
  161.                         count=1
  162.                   else
  163.                         count=$(($count+1))
  164.                   fi
  165.                 done
  166.                 if [ "$count" -ge "$2" ]; then
  167.                         echo $address >;>; $3
  168.                 fi
  169.         }

  170.         #-- collect high rate connection --#
  171.         cr_list $HTTP_LIST_TMP $HTTP_NU $HTTP_LIST
  172.         #-- create limit list --#
  173.         if [ -s $HTTP_LIST ]; then
  174.                 cr_list $HTTP_LIST.new $LIMIT_NU $LIMIT_LIST
  175.                 #-- make exception --#
  176.                 if [ -s $EXCP_LIST ]; then
  177.                         grep -v -E -f $EXCP_LIST $LIMIT_LIST \
  178.                                 >; $HTTP_LIST_TMP
  179.                         mv $HTTP_LIST_TMP $LIMIT_LIST
  180.                 fi
  181.         fi
  182.         #-- create drop list --#
  183.         if [ -s $LIMIT_LIST ]; then
  184.                 cr_list ${LIMIT_LIST}.new $DROP_NU $DROP_LIST
  185.         fi
  186.         #-- create perm list --#
  187.         if [ -s $DROP_LIST ]; then
  188.                 cr_list ${DROP_LIST}.new $PERM_NU $PERM_LIST
  189.         fi

  190.         #-- start limit --#
  191.         for i in $(cat $LIMIT_LIST); do
  192.                 echo LIMIT $i
  193.                 $IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT -s $i \
  194.                         -j DROP
  195.                 $IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT -s $i \
  196.                         -m limit --limit 1/s -j ACCEPT
  197.         done
  198.         #-- start blocking --#
  199.         for i in $(cat $DROP_LIST); do
  200.                 echo DROP $i
  201.                 $IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
  202.         done
  203.         #-- start permanent blocking --#
  204.         for i in $(cat $PERM_LIST); do
  205.                 $IPT_SAVE_CMD | grep $i | grep $EXT_IF &>;/dev/null || {
  206.                         host $i | $MAIL_CMD -s "drop $i" root
  207.                         echo permanently DROP $i
  208.                         $IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT \
  209.                                 -s $i -i $EXT_IF -j DROP
  210.                 }
  211.         done

  212. fi

  213. #-- clean PID file --#
  214. rm -f $PID_FILE
  215. exit 0
复制代码


本 script 最新版本可以從如下 URL 下載:
http://study-area.ks.edu.tw/linux/src/block.http.sh.tgz

论坛徽章:
0
2 [报告]
发表于 2003-11-20 09:00 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

好文章  我试试

论坛徽章:
0
3 [报告]
发表于 2003-11-20 10:18 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

uping

论坛徽章:
0
4 [报告]
发表于 2003-11-20 11:49 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

好呀,试试

论坛徽章:
0
5 [报告]
发表于 2003-11-20 14:40 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

up

论坛徽章:
0
6 [报告]
发表于 2003-11-27 11:21 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

哇,这么长啊,有空慢慢看

论坛徽章:
0
7 [报告]
发表于 2003-11-27 12:46 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

up

论坛徽章:
0
8 [报告]
发表于 2003-11-27 13:32 |只看该作者

[原創] [分享] 一支反砍站的 iptables script

对于流量大的站点这个东西还是不要用为妙

论坛徽章:
0
9 [报告]
发表于 2009-08-26 17:14 |只看该作者
好文。

我有过类似的想法。

但刚接触Linux。没有能力写出来Script。

也一直没有找到范文。

今天终于在看soft link 和hard link的时候。找到哥们儿的精华贴了。

下来学习学习。3k

论坛徽章:
13
15-16赛季CBA联赛之同曦
日期:2016-01-28 19:52:032015亚冠之北京国安
日期:2015-10-07 14:28:19NBA常规赛纪念章
日期:2015-05-04 22:32:03处女座
日期:2015-01-15 19:45:44卯兔
日期:2014-10-28 16:17:14白羊座
日期:2014-05-24 15:10:46寅虎
日期:2014-05-10 09:50:35白羊座
日期:2014-03-12 20:52:17午马
日期:2014-03-01 08:37:27射手座
日期:2014-02-19 19:26:54子鼠
日期:2013-11-30 09:03:56狮子座
日期:2013-09-08 08:37:52
10 [报告]
发表于 2012-05-19 17:37 |只看该作者
或许有用吧,先收藏了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP