作者 主題: 關於砍站  (閱讀 180799 次)

0 會員 與 1 訪客 正在閱讀本文。

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 於: 2002-11-28 16:14 »
由於目前的 phorum 與 www 都放在同一台較慢的機器上(Pentium Pro 200),負載能力備受考驗。今天曾因 "砍站" 行為而兩度中斷服務。

有鑑於此,在硬體設備改善之前,本站開始每 5 分鍾檢查 http 連線一次,若同一 IP 之連線數目超過 16 ,則被禁止連線,然後每 1 小時清一次舊記錄。

若您的連線不幸被擋掉,請於一小時後再嘗試,並確保連線數目不會太高。諸所不便,敬請原諒。

特此公告。謝謝!

CKS

  • 活潑的大學生
  • ***
  • 文章數: 224
    • 檢視個人資料
    • http://wiki.python.org.tw/CKS
Re: 關於砍站
« 回覆 #1 於: 2002-11-28 17:01 »
引述: "netman"
若同一 IP 之連線數目超過 16 ,則被禁止連線,然後每 1 小時清一次舊記錄。

請問此IP所指為何?16是指開十六個瀏覽器嗎?

VBird

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 1516
    • 檢視個人資料
    • http://linux.vbird.org
關於砍站
« 回覆 #2 於: 2002-11-28 17:02 »
原來學園也為此所苦吶!
為了大家的閱讀環境與網路傳輸品質,
希望大家不要再砍站了!
否則權益受損的將會是砍站者!

CKS

  • 活潑的大學生
  • ***
  • 文章數: 224
    • 檢視個人資料
    • http://wiki.python.org.tw/CKS
關於砍站
« 回覆 #3 於: 2002-11-28 17:08 »
引述: "VBird"
原來學園也為此所苦吶!
為了大家的閱讀環境與網路傳輸品質,
希望大家不要再砍站了!
否則權益受損的將會是砍站者!

何謂「砍站」?

VBird

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 1516
    • 檢視個人資料
    • http://linux.vbird.org
關於砍站
« 回覆 #4 於: 2002-11-28 17:34 »
就是使用類似多點連續下載軟體將整個網站的資料下載到自己電腦中的行為!
著名的有 telport, getright 等等!
這種砍站的行為,由於會產生很多的封包連線要求,所以造成 CPU 的負荷!
可以查看一下程序及 CPU loading 即可瞭解!

CKS

  • 活潑的大學生
  • ***
  • 文章數: 224
    • 檢視個人資料
    • http://wiki.python.org.tw/CKS
關於砍站
« 回覆 #5 於: 2002-11-28 18:31 »
引述: "VBird"
就是使用類似多點連續下載軟體將整個網站的資料下載到自己電腦中的行為!
著名的有 telport, getright 等等!
這種砍站的行為,由於會產生很多的封包連線要求,所以造成 CPU 的負荷!
可以查看一下程序及 CPU loading 即可瞭解!

瞭解了,謝謝!

damon

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 4225
    • 檢視個人資料
    • http://blog.damon.tw/
關於砍站
« 回覆 #6 於: 2002-11-28 20:00 »
可否考慮提供離線閱讀網頁內容的壓縮檔?這樣可以減少一些線上閱讀的流量與loading ?
有人要抓網頁內容離線閱讀的話也比較不會像現在這樣造成大家的不便

duncanlo

  • SA 苦力組
  • 俺是博士!
  • *****
  • 文章數: 7311
    • 檢視個人資料
關於砍站
« 回覆 #7 於: 2002-11-28 23:52 »
phpbb上的newsgroup gateway!
用nntp可read可post(中文ok),
缺點是文章直接可以整個dump回去...

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #8 於: 2002-11-29 02:58 »
引述: "damon"
可否考慮提供離線閱讀網頁內容的壓縮檔?這樣可以減少一些線上閱讀的流量與loading ?
有人要抓網頁內容離線閱讀的話也比較不會像現在這樣造成大家的不便


若是事先來信問我要,我會用 tar 包好,然後請對方來 download 。
但,要是不管三七二十一就來砍站,真不是很喜歡。
之前 loading 不重還好,但自從將 phorum 搬過來自後,
就實在吃不消....

想看今天慘況嗎:


為此,我寫了一個 script 來擋,
有需要的朋友可參考:
代碼: [選擇]
#!/bin/bash

HTTP_LIST=/root/http.list
HTTP_LIST_TMP=/root/http.list.tmp
CONN_NU=24

for i in $(cat $HTTP_LIST); do
        /sbin/iptables -D INPUT -p TCP --dport 80 -s $i -j DROP 2>/dev/null
done

cat /dev/null > $HTTP_LIST

# block http
netstat -na | grep ':80' | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
for i in $(cat $HTTP_LIST_TMP | uniq); do
        if [ $(cat $HTTP_LIST_TMP | grep $i | wc -l) -gt $CONN_NU ]; then
                echo $i >> $HTTP_LIST
        fi
done
for i in $(cat $HTTP_LIST); do
        /sbin/iptables -I INPUT -p TCP --dport 80 -s $i -j DROP
done


然後,我寫個 crontab ,讓它每兩分鍾跑一次。
這樣,我也不必再管它是否每一小時清舊規則了(與前面公佈的規則有所改良):
要修改連線的限制數目,就修改 CONN_NU 變數,
若是偶發性的超過限制,只要不在 script running 被抓到,那是 okay 的,
就算被誤抓,最多兩分鍾就可解除(用 -D 從舊 list 中移除)。
但若是砍站,應該會為持好一陣子的 high rate connection ,
那就每次 script running 都會被擋...
若想調整 running 時間間隔,那就改 crontab 就好。

若大家有更好的設計,歡迎分享。

duncanlo

  • SA 苦力組
  • 俺是博士!
  • *****
  • 文章數: 7311
    • 檢視個人資料
關於砍站
« 回覆 #9 於: 2002-11-29 23:10 »
有個小問題,
有程式可以把phpBB內容整個mirror回去嗎?

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #10 於: 2002-11-29 23:24 »
引述: "duncanlo"
有個小問題,
有程式可以把phpBB內容整個mirror回去嗎?


您是指砍站還是指檔案同步?

若是後者,用 rsync 軟體吧。若是前者,我就不知道了,
但是在 loading 最重的時侯,我發現 cpu 都給 httpd 與 mysqld 吃光了!我猜是砍站軟體不夠 smart 所至吧?

paulso

  • 俺是博士!
  • *****
  • 文章數: 1966
    • 檢視個人資料
Re: 關於砍站
« 回覆 #11 於: 2002-11-29 23:45 »
引述: "netman"
由於目前的 phorum 與 www 都放在同一台較慢的機器上(Pentium Pro 200),負載能力備受考驗。


怪不得有時連線上來那麼慢。

逸晨

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 1205
  • 我是逸晨
    • 檢視個人資料
Re: 關於砍站
« 回覆 #12 於: 2002-11-30 09:16 »
引述: "paulso"
引述: "netman"
由於目前的 phorum 與 www 都放在同一台較慢的機器上(Pentium Pro 200),負載能力備受考驗。


怪不得有時連線上來那麼慢。

非但慢,我這兒還慢到連逾時哩 @@
害得粉想拿起電話打到中華電信去罵一罵
因為以為又是中華搞的烏龍  :oops:
幸好沒打,不然這隻烏龍就要自己吃了  :wink:

paulso

  • 俺是博士!
  • *****
  • 文章數: 1966
    • 檢視個人資料
Re: 關於砍站
« 回覆 #13 於: 2002-11-30 09:52 »
引述: "逸晨"
引述: "paulso"
引述: "netman"
由於目前的 phorum 與 www 都放在同一台較慢的機器上(Pentium Pro 200),負載能力備受考驗。


怪不得有時連線上來那麼慢。

非但慢,我這兒還慢到連逾時哩 @@
害得粉想拿起電話打到中華電信去罵一罵
因為以為又是中華搞的烏龍  :oops:
幸好沒打,不然這隻烏龍就要自己吃了  :wink:


我也試過Time out@@

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #14 於: 2002-12-01 23:32 »
Okay,我作了一些修改,主要增加了  cpu loading 的檢測,
若是低於 85% ,則不作攔阻。

新版如下:
代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/01
# Version: 0.91

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
#

HTTP_LIST=/root/http.list
HTTP_LIST_TMP=${HTTP_LIST}.tmp
CONN_NU=16

#-- remove old rules --#
if [ -s $HTTP_LIST ]; then
        for i in $(cat $HTTP_LIST); do
          /sbin/iptables -D INPUT -p TCP --dport 80 -s $i -j DROP 2>/dev/null
        done
        #-- clean up list --#
        cat /dev/null > $HTTP_LIST
fi

#-- block http if loading is greater than 85 persent --#
if [ "$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $5}' \
        | sed 's/\..*$//')" -gt "85" ]; then
        netstat -na | grep ':80' | awk '{print $5}' | cut -d: -f1 \
                | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
        for i in $(cat $HTTP_LIST_TMP | uniq); do
          if [ $(cat $HTTP_LIST_TMP | grep $i | wc -l) -gt $CONN_NU ]; then
                echo $i >> $HTTP_LIST
          fi
        done
        for i in $(cat $HTTP_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport 80 -s $i -j DROP
        done
fi
exit 0

saga

  • 可愛的小學生
  • *
  • 文章數: 9
    • 檢視個人資料
關於砍站
« 回覆 #15 於: 2002-12-01 23:56 »
砍站當然不好啦。
可是硬體如果更新的話大家用起來可能就會更快啦。
也許可以來個徵硬體更新的活動  :p

--------
如果有的話,我就捐個 D600 。

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #16 於: 2002-12-02 00:03 »
引述: "saga"
砍站當然不好啦。
可是硬體如果更新的話大家用起來可能就會更快啦。
也許可以來個徵硬體更新的活動  :p

--------
如果有的話,我就捐個 D600 。


謝謝!

由於當前主機所在機房為縣網中心,不是我們想更新硬題就更新的,限制很多,公文流程繁瑣...  :(

當然,我會嘗試申請看看的...  ^_^
無論如何,還是非常感謝您的建議!

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #17 於: 2002-12-02 13:15 »
嗯~~~ 發現開得太鬆的話,還是遭殃...  :(
因此,再補上一些檢測及限制:

代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/02
# Version: 0.92

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
# Version 0.92
#       1) separate cpu loading test into system and user
#       2) add test for httpd connection number

LIMIT_CNU=24
CL_S=10
CL_U=75
HC_N=300
HC_U=30
HTTP_LIST=/root/http.list
HTTP_LIST_TMP=${HTTP_LIST}.tmp
netstat -na | grep ':80' | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
cpuload=$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $3":"$5}')
cpuusr=$(echo ${cpuload%:*} | sed 's/\..*$//')
cpusys=$(echo ${cpuload#*:} | sed 's/\..*$//')
http_cn=$(/bin/netstat -na | grep ':80' | wc -l)
http_un=$(cat $HTTP_LIST_TMP | uniq | wc -l)
#echo    "       limit   current"
#echo    "CL_U:  $CL_U   $cpuusr"
#echo    "CL_S:  $CL_S   $cpusys"
#echo    "HC_N:  $HC_N   $http_cn"
#echo    "HC_U:  $HC_U   $http_un"

#-- remove old rules --#
if [ -s $HTTP_LIST ]; then
        for i in $(cat $HTTP_LIST); do
          /sbin/iptables -D INPUT -p TCP --dport 80 -s $i -j DROP 2>/dev/null
        done
        #-- clean up list --#
        cat /dev/null > $HTTP_LIST
fi

#-- block http if loading reach the limis --#
if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o \
        "$http_cn" -gt "$HC_N" -o "$http_un" -gt "$HC_U" ]
then
        for i in $(cat $HTTP_LIST_TMP | uniq); do
          if [ $(cat $HTTP_LIST_TMP | grep $i | wc -l) -gt $LIMIT_CNU ]; then
                echo $i >> $HTTP_LIST
          fi
        done
        for i in $(cat $HTTP_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport 80 -s $i -j DROP
        done
fi
exit 0

CKS

  • 活潑的大學生
  • ***
  • 文章數: 224
    • 檢視個人資料
    • http://wiki.python.org.tw/CKS
關於砍站
« 回覆 #18 於: 2002-12-02 13:30 »
netman,辛苦您了,謝謝!

早上連了好久,都連不上,等等等、、、
想了好久:一定又是砍站,打電話給您,關機,不通。又打給梁楓,也是一樣。
後來上網時,首先看到VBird,是他修復的嗎?
可否建立聯絡管道,以便迅速解決此類問題?

CKS

  • 活潑的大學生
  • ***
  • 文章數: 224
    • 檢視個人資料
    • http://wiki.python.org.tw/CKS
Re: 關於砍站
« 回覆 #19 於: 2002-12-02 13:39 »
引述: "netman"
由於目前的 phorum 與 www 都放在同一台較慢的機器上(Pentium Pro 200),負載能力備受考驗。今天曾因 "砍站" 行為而兩度中斷服務。

若是將www 搬移到另外一個地方,會不會比較容易處理?

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #20 於: 2002-12-03 15:01 »
今天再次改良了 script,目前是,只要在如下條件之一:
    CL_U: 75 <--- CPU 之 user loading 超過 75%
    CL_S: 10 <--- CPU 之 system loading 超過 10%
    HC_N: 300 <--- HTTP 連線超過 300 個 connection
    HC_U: 30 <--- HTTP 連線超過 30 個 client source

然後就會抓出當時超過 24 個 connection 的主機,
再將之 block 掉。

我是用 crontab 每 2 分鍾跑,每次抓一次清單,
然後保持 5 份記錄,若您的 IP 出現其中 3 次,才會擋...
(通常是那些"頑強"的砍站者)
當然,您要是本站"忠實"擁躉(每次連線超多且每抓必中)、同時使用固定 IP 的話,那可以來信告訴我,將您的 IP 加入豁免清單中。
遺憾的是:若透過 isp proxy 而導致誤判,我目前還沒良策.... 希望大家能提供機制。謝謝!

最新版本的 script (v0.93),其內容如下:
代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/03
# Version: 0.93

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
# Version 0.92
#       1) separate cpu loading test into system and user
#       2) add test for httpd connection number
# Version 0.93
#       1) change to block frequently existed list
#       2) add excepted list

FREQ_NU=3
LIMIT_CNU=24
CL_S=10
CL_U=75
HC_N=300
HC_U=30
HTTP_LIST=/root/http.list
HTTP_LIST_OLD=${HTTP_LIST}.old
HTTP_LIST_TMP=${HTTP_LIST}.tmp
FREQ_LIST=${HTTP_LIST}.freq
EXCP_LIST=${HTTP_LIST}.excp
netstat -na | grep ':80' | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
cpuload=$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $3":"$5}')
cpuusr=$(echo ${cpuload%:*} | sed 's/\..*$//')
cpusys=$(echo ${cpuload#*:} | sed 's/\..*$//')
http_cn=$(/bin/netstat -na | grep ':80' | wc -l | awk '{print $1}')
http_un=$(cat $HTTP_LIST_TMP | uniq | wc -l | awk '{print $1}')
echo    "       limit   current"
echo    "CL_U:  $CL_U   $cpuusr"
echo    "CL_S:  $CL_S   $cpusys"
echo    "HC_N:  $HC_N   $http_cn"
echo    "HC_U:  $HC_U   $http_un"

#-- remove old rules --#
if [ -s $HTTP_LIST -o -s $FREQ_LIST ]; then
        for i in $(cat $FREQ_LIST); do
          /sbin/iptables -D INPUT -p TCP --dport 80 -s $i -j DROP 2>/dev/null
        done
        #-- update lists --#
        mv ${HTTP_LIST}.4 ${HTTP_LIST}.5
        mv ${HTTP_LIST}.3 ${HTTP_LIST}.4
        mv ${HTTP_LIST}.2 ${HTTP_LIST}.3
        mv ${HTTP_LIST}.1 ${HTTP_LIST}.2
        mv ${HTTP_LIST}  ${HTTP_LIST}.1
        touch $HTTP_LIST
        cat /dev/null > $FREQ_LIST
fi

#-- block http if limits are reached --#
if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o \
        "$http_cn" -gt "$HC_N" -o "$http_un" -gt "$HC_U" ]
then
        #-- collect high rate connection --#
        for i in $(cat $HTTP_LIST_TMP | uniq); do
          if [ $(cat $HTTP_LIST_TMP | grep $i | wc -l) -gt $LIMIT_CNU ]; then
                echo $i >> $HTTP_LIST
          fi
        done
        #-- block frequent list --#
        for i in $(cat ${HTTP_LIST}.[1-5] | sort | uniq); do
          if [ $(cat ${HTTP_LIST}.[1-5] | grep $i | wc -l) -gt $FREQ_NU ]; then
                echo $i >> $FREQ_LIST
          fi
        done
        #-- make exception --#
        if [ -s $EXCP_LIST ]; then
                cat /dev/null > $HTTP_LIST_TMP
                for i in $(cat $EXCP_LIST); do
                  grep -v $i $FREQ_LIST >> $HTTP_LIST_TMP
                  mv $HTTP_LIST_TMP $FREQ_LIST
                done
        fi
        #-- start blocking --#
        for i in $(cat $FREQ_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport 80 -s $i -j DROP
        done
fi
exit 0

dou

  • 可愛的小學生
  • *
  • 文章數: 1
    • 檢視個人資料
關於砍站
« 回覆 #21 於: 2002-12-03 18:38 »
anyway... 其實在 iptables1.2.7a 的 patch-o-matic 裡.
有一個  ip-limit 的 patch.

做的事情是一樣的...
他可以限制單一 IP 連線不得超過 多少個.
或是 Class C, .. 不能超過多少個連線...

但有個限制, 只能限制 tcp connections.  :o

http://www.netfilter.org/documentation/pomlist/pom-base.html#iplimit

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #22 於: 2002-12-04 18:06 »
多謝 dou 兄的資訊!

不過,我目前還不需要 implement patch-o-matic ,
但您得提議給了我一個很好的 idea :
也就是將 DROP 改成 limit ,
然後再將 limit 清單抓出來,彷照連線清單再將出現次數高的連線 DROP 掉。至於 DROP 規則的移除,將由其它 script 來定期清除...

今天晚上下課後我再來改,到時再將新版 post 給大家參考。

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #23 於: 2002-12-05 16:34 »
Okay,今天再改良一下,主要是引入了 limit 機制。
當前的設計概念如下:
    1) 若 loading 不高,則不會抓 session。
    2) 抓到 session 後,若 connection 不高,也不會抓到。
    3) 若被抓到多次 (5 次中有 4 次),開始 limit。
    4) 若被多次 limit (5 次中有 4 次),開始 drop。
    5) 每次執行,就刪舊 limit 與 drop rules。


曾有網友建議用 cbq 來限制,不過由於實作上我並沒把握,或許可考慮在將來的版本提供。

當前的版本 v0.94 ,其內容如下:
代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/05
# Version: 0.94

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
# Version 0.92
#       1) separate cpu loading test into system and user
#       2) add test for httpd connection number
# Version 0.93
#       1) change to block frequently existed list
#       2) add excepted list
# Version 0.94
#       1) remove list-file size testing which was added in v0.91
#       2) change iptables' rule from DROP to limit
#       3) create drop list for most limited connections

LIMIT_CNU=24    # max number of conncetion allowed at the time
LIMIT_NU=3      # max number of time allowed in the source list
DROP_NU=3       # max number of time allowed in the limit list
CL_S=10         # CPU loading for system
CL_U=75         # CPU loading for user
HC_N=300        # HTTP connection number for session
HC_U=30         # HTTP connection number for source
IPT_LTD=3       # limited number of packet in iptables rules
HTTP_PORT=80    # HTTP port number
HTTP_LIST=/root/http.list
HTTP_LIST_TMP=${HTTP_LIST}.tmp
LIMIT_LIST=${HTTP_LIST}.limit; touch ${HTTP_LIST}.limit
DROP_LIST=${HTTP_LIST}.drop; touch ${HTTP_LIST}.drop
EXCP_LIST=${HTTP_LIST}.excp; touch ${HTTP_LIST}.excp
#-- create source list --#
netstat -na | grep ":$HTTP_PORT" | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
cpuload=$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $3":"$5}')
cpuusr=$(echo ${cpuload%:*} | sed 's/\..*$//')
cpusys=$(echo ${cpuload#*:} | sed 's/\..*$//')
http_cn=$(/bin/netstat -na | grep ":$HTTP_PORT" | wc -l | awk '{print $1}')
http_un=$(cat $HTTP_LIST_TMP | uniq | wc -l | awk '{print $1}')
echo    "       limit   current"
echo    "CL_U:  $CL_U   $cpuusr"
echo    "CL_S:  $CL_S   $cpusys"
echo    "HC_N:  $HC_N   $http_cn"
echo    "HC_U:  $HC_U   $http_un"

#-- remove old limit rules --#
for i in $(cat $LIMIT_LIST); do
        /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT -s $i \
                -m limit --limit 1/s -j ACCEPT
done
#-- remove old drop rules --#
for i in $(cat $DROP_LIST); do
        /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
done
cat /dev/null > $DROP_LIST
#-- update lists --#
for i in $HTTP_LIST $LIMIT_LIST; do
        touch ${i}.1 ${i}.2 ${i}.3 ${i}.4
        mv ${i}.4 ${i}.5
        mv ${i}.3 ${i}.4
        mv ${i}.2 ${i}.3
        mv ${i}.1 ${i}.2
        mv ${i} ${i}.1
        cat ${i}.[1-5] > ${i}.new
        touch $i
done

#-- limiting http connection --#
if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o \
        "$http_cn" -gt "$HC_N" -o "$http_un" -gt "$HC_U" ]
then

        #-- function: create list --#
        cr_list () {
                for i in $(cat $1 | sort | uniq); do
                  if [ "$(cat $1 | grep $i | wc -l)" -gt "$2" ]; then
                        echo $i >> $3
                  fi
                done
        }

        #-- collect high rate connection --#
        cr_list $HTTP_LIST_TMP $LIMIT_CNU $HTTP_LIST
        #-- create limit list --#
        cr_list ${HTTP_LIST}.new $LIMIT_NU $LIMIT_LIST
        #-- make exception --#
        if [ -s $EXCP_LIST ]; then
                cat /dev/null > $HTTP_LIST_TMP
                for i in $(cat $EXCP_LIST); do
                  grep -v $i $LIMIT_LIST >> $HTTP_LIST_TMP
                  mv $HTTP_LIST_TMP $LIMIT_LIST
                done
        fi
        #-- create drop list --#
        cr_list ${LIMIT_LIST}.new $DROP_NU $DROP_LIST
        #-- start limit --#
        for i in $(cat $LIMIT_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i \
                        -m limit --limit ${IPT_LTD}/s -j ACCEPT
        done
        #-- start blocking --#
        for i in $(cat $DROP_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
        done
fi
exit 0

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #24 於: 2002-12-13 14:24 »
BUG FIX:

因發線 limit 規則中的 $IPT_LTD/s 若大於 1/s  會被改為 nnnnnnn/day ,且在移除舊規則時也不一致(我的疏忽, sorry)。
本 script 已作修改,並更新至 v0.95 版。若有引用本 script 的朋友請更新:

代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/13
# Version: 0.95

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
# Version 0.92
#       1) separate cpu loading test into system and user
#       2) add test for httpd connection number
# Version 0.93
#       1) change to block frequently existed list
#       2) add excepted list
# Version 0.94
#       1) remove list-file size testing which was added in v0.91
#       2) change iptables' rule from DROP to limit
#       3) create drop list for most limited connections
# Version 0.95
#       1) remove IPT_LTD variable and hardcode the limit rule to 1/s


LIMIT_CNU=24    # max number of conncetion allowed at the time
LIMIT_NU=3      # max number of time allowed in the source list
DROP_NU=3       # max number of time allowed in the limit list
CL_S=8          # CPU loading for system
CL_U=65         # CPU loading for user
HC_N=200        # HTTP connection number for session
HC_U=20         # HTTP connection number for source
HTTP_PORT=80    # HTTP port number
HTTP_LIST=/root/http.list
HTTP_LIST_TMP=${HTTP_LIST}.tmp
LIMIT_LIST=${HTTP_LIST}.limit; touch ${HTTP_LIST}.limit
DROP_LIST=${HTTP_LIST}.drop; touch ${HTTP_LIST}.drop
EXCP_LIST=${HTTP_LIST}.excp; touch ${HTTP_LIST}.excp
#-- create source list --#
touch $HTTP_LIST_TMP
netstat -na | grep ":$HTTP_PORT" | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
cpuload=$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $3":"$5}')
cpuusr=$(echo ${cpuload%:*} | sed 's/\..*$//')
cpusys=$(echo ${cpuload#*:} | sed 's/\..*$//')
http_cn=$(/bin/netstat -na | grep ":$HTTP_PORT" | wc -l | awk '{print $1}')
http_un=$(cat $HTTP_LIST_TMP | uniq | wc -l | awk '{print $1}')
echo    "       limit   current"
echo    "CL_U:  $CL_U   $cpuusr"
echo    "CL_S:  $CL_S   $cpusys"
echo    "HC_N:  $HC_N   $http_cn"
echo    "HC_U:  $HC_U   $http_un"

#-- remove old limit rules --#
for i in $(cat $LIMIT_LIST); do
        /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT -s $i \
                -m limit --limit 1/s -j ACCEPT
done
#-- remove old drop rules --#
for i in $(cat $DROP_LIST); do
        /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
done
cat /dev/null > $DROP_LIST
#-- update lists --#
for i in $HTTP_LIST $LIMIT_LIST; do
        touch ${i}.1 ${i}.2 ${i}.3 ${i}.4
        mv ${i}.4 ${i}.5
        mv ${i}.3 ${i}.4
        mv ${i}.2 ${i}.3
        mv ${i}.1 ${i}.2
        mv ${i} ${i}.1
        cat ${i}.[1-5] > ${i}.new
        touch $i
done

#-- limiting http connection --#
if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o \
        "$http_cn" -gt "$HC_N" -o "$http_un" -gt "$HC_U" ]
then

        #-- function: create list --#
        cr_list () {
                for i in $(cat $1 | sort | uniq); do
                  if [ "$(cat $1 | grep $i | wc -l)" -gt "$2" ]; then
                        echo $i >> $3
                  fi
                done
        }

        #-- collect high rate connection --#
        cr_list $HTTP_LIST_TMP $LIMIT_CNU $HTTP_LIST
        #-- create limit list --#
        cr_list ${HTTP_LIST}.new $LIMIT_NU $LIMIT_LIST
        #-- make exception --#
        if [ -s $EXCP_LIST ]; then
                cat /dev/null > $HTTP_LIST_TMP
                for i in $(cat $EXCP_LIST); do
                  grep -v $i $LIMIT_LIST >> $HTTP_LIST_TMP
                  mv $HTTP_LIST_TMP $LIMIT_LIST
                done
        fi
        #-- create drop list --#
        cr_list ${LIMIT_LIST}.new $DROP_NU $DROP_LIST
        #-- start limit --#
        for i in $(cat $LIMIT_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i \
                        -m limit --limit 1/s -j ACCEPT
        done
        #-- start blocking --#
        for i in $(cat $DROP_LIST); do
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
        done
fi
exit 0

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #25 於: 2002-12-18 16:32 »
我將 v0.95 版包好,有需要的來這抓吧:

http://study-area.ks.edu.tw/linux/src/block.http.sh.tgz

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #26 於: 2002-12-22 17:45 »
今天再度與砍站者奮站,也再次改良了 script ,
除了將限制調得更嚴之外,還增加了一個 "永久 block list" :
    之前是被 limit 3 次就被 drop ,
    但每次都會從 drop 規則中移除 ,
    現再再加一個:被 drop 3 次後,將不再移除其 drop 規則。


然則,砍站者將永久被 drop ,但我還是建議另寫一個  crontab ,
定期(每天、或每星期)清一次規則。
tips:若您有安裝 portsentry 的話,請留意 /etc/cron.d/portsentry 的設定,
因為它 "預設" 每 6 小時就清一次 iptables 。

關於本 script 的最新版本,為 v0.97,可從下面下載:
http://study-area.ks.edu.tw/linux/src/block.http.sh.tgz
(註:下午發表的 v0.96 有個 bug,若已下載請更新。)

v0.97 的 code 如下(請幫忙 debug):

代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/22
# Version: 0.97

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
# Version 0.92
#       1) separate cpu loading test into system and user
#       2) add test for httpd connection number
# Version 0.93
#       1) change to block frequently existed list
#       2) add excepted list
# Version 0.94
#       1) remove list-file size testing which was added in v0.91
#       2) change iptables' rule from DROP to limit
#       3) create drop list for most limited connections
# Version 0.95
#       1) remove IPT_LTD variable and hardcode the limit rule to 1/s
# Version 0.96
#       1) change based dir to /root/BLOCK
#       2) create PERM_LIST for permanent drop
# Version 0.97
#       1) bug fix: clean PERM_LIST at every running

HTTP_NU=16      # connection number to be added to list
LIMIT_NU=3      # number to be limited
DROP_NU=3       # number to be dropped
PERM_NU=4       # number to be dropped permanently
CL_S=8          # CPU loading for system
CL_U=65         # CPU loading for user
HC_N=200        # HTTP connection number for session
HC_U=20         # HTTP connection number for source
HTTP_PORT=80    # HTTP port number
BASED_DIR=/root/BLOCK
HTTP_LIST=${BASED_DIR}/http.list
HTTP_LIST_TMP=${HTTP_LIST}.tmp
LIMIT_LIST=${HTTP_LIST}.limit; touch ${HTTP_LIST}.limit
DROP_LIST=${HTTP_LIST}.drop; touch ${HTTP_LIST}.drop
PERM_LIST=${HTTP_LIST}.perm; touch ${HTTP_LIST}.perm
EXCP_LIST=${HTTP_LIST}.excp; touch ${HTTP_LIST}.excp

#-- create based dir --#
if [ ! -d $BASED_DIR ]; then
        mkdir $BASED_DIR || {
                echo "$0: ERROR: can NOT create directory $BASED_DIR."
                exit 1
        }
fi

#-- create source list --#
touch $HTTP_LIST_TMP
netstat -na | grep ":$HTTP_PORT" | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
cpuload=$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $3":"$5}')
cpuusr=$(echo ${cpuload%:*} | sed 's/\..*$//')
cpusys=$(echo ${cpuload#*:} | sed 's/\..*$//')
http_cn=$(/bin/netstat -na | grep ":$HTTP_PORT" | wc -l | awk '{print $1}')
http_un=$(cat $HTTP_LIST_TMP | uniq | wc -l | awk '{print $1}')
echo    "       limit   current"
echo    "CL_U:  $CL_U   $cpuusr"
echo    "CL_S:  $CL_S   $cpusys"
echo    "HC_N:  $HC_N   $http_cn"
echo    "HC_U:  $HC_U   $http_un"

#-- remove old limit rules --#
for i in $(cat $LIMIT_LIST); do
        echo remove $i from LIMIT
        /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT -s $i \
                -m limit --limit 1/s -j ACCEPT
done
#-- remove old drop rules --#
for i in $(cat $DROP_LIST); do
        echo remove $i from DROP
        /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
done

#-- clean up PERM_LIST --#
cat /dev/null > $PERM_LIST
#-- update lists --#
for i in $HTTP_LIST $LIMIT_LIST $DROP_LIST; do
        if [ -s $i -o "$i" != "$DROP_LIST" ]; then
                touch ${i}.1 ${i}.2 ${i}.3 ${i}.4
                mv ${i}.4 ${i}.5
                mv ${i}.3 ${i}.4
                mv ${i}.2 ${i}.3
                mv ${i}.1 ${i}.2
                mv ${i} ${i}.1
                cat ${i}.[1-5] > ${i}.new
                touch $i
        fi
done

#-- limiting http connection --#
if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o \
        "$http_cn" -gt "$HC_N" -o "$http_un" -gt "$HC_U" ]
then

        #-- function: create list --#
        cr_list () {
                for i in $(cat $1 | sort | uniq); do
                  if [ "$(cat $1 | grep $i | wc -l)" -ge "$2" ]; then
                        echo $i >> $3
                  fi
                done
        }

        #-- collect high rate connection --#
        cr_list $HTTP_LIST_TMP $HTTP_NU $HTTP_LIST
        #-- create limit list --#
        cr_list ${HTTP_LIST}.new $LIMIT_NU $LIMIT_LIST
        #-- make exception --#
        if [ -s $EXCP_LIST ]; then
                cat /dev/null > $HTTP_LIST_TMP
                for i in $(cat $EXCP_LIST); do
                  grep -v $i $LIMIT_LIST >> $HTTP_LIST_TMP
                  mv $HTTP_LIST_TMP $LIMIT_LIST
                done
        fi
        #-- create drop list --#
        cr_list ${LIMIT_LIST}.new $DROP_NU $DROP_LIST
        #-- create permanent drop list --#
        cr_list ${DROP_LIST}.new $PERM_NU $PERM_LIST


        #-- start limit --#
        for i in $(cat $LIMIT_LIST); do
                echo LIMIT $i
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i \
                        -m limit --limit 1/s -j ACCEPT
        done
        #-- start blocking --#
        for i in $(cat $DROP_LIST); do
                echo DROP $i
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
        done
        #-- start permanent blocking --#
        for i in $(cat $PERM_LIST); do
                echo permanently DROP $i
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i \
                        --sport 1024:65535 -j DROP
        done

fi
exit 0

wessley

  • 憂鬱的高中生
  • ***
  • 文章數: 185
    • 檢視個人資料
關於砍站
« 回覆 #27 於: 2002-12-22 18:33 »
我有兩個想法....
1. 把 www 移出來.......
2. 搜尋結果的文章能自動 tar 出來給人下載(當然要按我要下載,才 tar)???我想可能做不到吧?????

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #28 於: 2002-12-23 00:15 »
引述: "wessley"
我有兩個想法....
1. 把 www 移出來.......
2. 搜尋結果的文章能自動 tar 出來給人下載(當然要按我要下載,才 tar)???我想可能做不到吧?????


多謝建議!不過:
1) 到哪去?之後又如何防范?
2) 嗯... 逐篇抓如何?

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17292
    • 檢視個人資料
    • http://www.study-area.org
關於砍站
« 回覆 #29 於: 2002-12-23 00:20 »
還是有 BUG !!

這次重新設計了清單的更新規則,同時也修補了 perm drop 規則的疏忽。

最新版本已為 v0.98,可從下面下載:
http://study-area.ks.edu.tw/linux/src/block.http.sh.tgz

code 如下(唉,越來越長了... 請幫忙 debug):

代碼: [選擇]
#!/bin/bash
# Purpose: to block httpd connection
# Author: netman(netman@study-area.org)
# Lisence: GPL
# Date: 2002/12/23
# Version: 0.98

#-- change log --#
# Version 0.90
#       * Script created
# Version 0.91
#       1) add test for size of list file
#       2) add test for cpu loading
# Version 0.92
#       1) separate cpu loading test into system and user
#       2) add test for httpd connection number
# Version 0.93
#       1) change to block frequently existed list
#       2) add excepted list
# Version 0.94
#       1) remove list-file size testing which was added in v0.91
#       2) change iptables' rule from DROP to limit
#       3) create drop list for most limited connections
# Version 0.95
#       1) remove IPT_LTD variable and hardcode the limit rule to 1/s
# Version 0.96
#       1) change based dir to /root/BLOCK
#       2) create PERM_LIST for permanent drop
# Version 0.97
#       1) bug fix: clean PERM_LIST at every running
# Version 0.98
#       1) change to update list upon new source found or time base
#       2) bug fix: make PERM_IST clean properly


HTTP_NU=16      # connection number to be added to list
LIMIT_NU=3      # number to be limited
LIMIT_MIN=30    # number of limit minutes
DROP_NU=3       # number to be dropped
DROP_HR=3       # number of drop hours
PERM_NU=4       # number to be dropped permanently
PERM_DAY=1      # number of perm drop days
CL_S=8          # CPU loading for system
CL_U=65         # CPU loading for user
HC_N=200        # HTTP connection number for session
HC_U=20         # HTTP connection number for source
HTTP_PORT=80    # HTTP port number
BASED_DIR=/root/BLOCK
HTTP_LIST=${BASED_DIR}/http.list #; touch $HTTP_LIST $HTTP_LIST.new
HTTP_LIST_TMP=${HTTP_LIST}.tmp
LIMIT_LIST=${HTTP_LIST}.limit; touch --date="$LIMIT_MIN minutes ago" $LIMIT_LIST
DROP_LIST=${HTTP_LIST}.drop; touch --date="$DROP_HR hours ago" $DROP_LIST
PERM_LIST=${HTTP_LIST}.perm; touch --date="$PERM_DAY days ago" $PERM_LIST
EXCP_LIST=${HTTP_LIST}.excp; touch $EXCP_LIST

#-- create based dir --#
if [ ! -d $BASED_DIR ]; then
        mkdir $BASED_DIR || {
                echo "$0: ERROR: can NOT create directory $BASED_DIR."
                exit 1
        }
fi

#-- create source list --#
touch $HTTP_LIST_TMP
netstat -na | grep ":$HTTP_PORT" | awk '{print $5}' | cut -d: -f1 \
        | sort | sed '/0.0.0.0/d' > $HTTP_LIST_TMP
cpuload=$(/usr/bin/sar -u 1 3 | tail -1 | awk '{print $3":"$5}')
cpuusr=$(echo ${cpuload%:*} | sed 's/\..*$//')
cpusys=$(echo ${cpuload#*:} | sed 's/\..*$//')
http_cn=$(/bin/netstat -na | grep ":$HTTP_PORT" | wc -l | awk '{print $1}')
http_un=$(cat $HTTP_LIST_TMP | uniq | wc -l | awk '{print $1}')
echo    "       limit   current"
echo    "CL_U:  $CL_U   $cpuusr"
echo    "CL_S:  $CL_S   $cpusys"
echo    "HC_N:  $HC_N   $http_cn"
echo    "HC_U:  $HC_U   $http_un"

#-- function update lists --#
ud_list () {
        for i in $@; do
                touch ${1}.1 ${1}.2 ${1}.3 ${1}.4
                mv ${i}.4 ${i}.5
                mv ${i}.3 ${i}.4
                mv ${i}.2 ${i}.3
                mv ${i}.1 ${i}.2
                mv ${i} ${i}.1
                cat ${i}.[1-5] > ${i}.new
                touch $i
        done
}
if [ -s $HTTP_LIST -o $HTTP_LIST.new -ot $HTTP_LIST ]; then
        #-- remove old limit rules --#
        for i in $(cat $LIMIT_LIST); do
                echo remove $i from LIMIT
                /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT \
                        -s $i -m limit --limit 1/s -j ACCEPT
        done
        #-- update http list --#
        ud_list $HTTP_LIST
fi
if [ -s $LIMIT_LIST -o $LIMIT_LIST.new -ot $LIMIT_LIST ]; then
        #-- remove old drop rules --#
        for i in $(cat $DROP_LIST); do
                echo remove $i from DROP
                /sbin/iptables -D INPUT -p TCP --dport $HTTP_PORT \
                        -s $i -j DROP
        done
        #-- update limit list --#
        ud_list $LIMIT_LIST
fi
if [ -s $DROP_LIST -o $DROP_LIST.new -ot $DROP_LIST ]; then
        #-- update limit list --#
        ud_list $DROP_LIST
        #-- clean perm list --#
        cat /dev/null > $PERM_LIST
fi

#-- limiting http connection --#
if [ "$cpusys" -gt "$CL_S" -o "$cpuusr" -gt "$CL_U" -o \
        "$http_cn" -gt "$HC_N" -o "$http_un" -gt "$HC_U" ]
then

        #-- function: create list --#
        cr_list () {
                for i in $(cat $1 | sort | uniq); do
                  if [ "$(cat $1 | grep $i | wc -l)" -ge "$2" ]; then
                        echo $i >> $3
                  fi
                done
        }

        #-- collect high rate connection --#
        cr_list $HTTP_LIST_TMP $HTTP_NU $HTTP_LIST
        #-- create limit list --#
        if [ -s $HTTP_LIST ]; then
                cr_list ${HTTP_LIST}.new $LIMIT_NU $LIMIT_LIST
                #-- make exception --#
                if [ -s $EXCP_LIST ]; then
                        cat /dev/null > $HTTP_LIST_TMP
                        for i in $(cat $EXCP_LIST); do
                          grep -v $i $LIMIT_LIST >> $HTTP_LIST_TMP
                          mv $HTTP_LIST_TMP $LIMIT_LIST
                        done
                fi
        fi
        #-- create drop list --#
        if [ -s $LIMIT_LIST ]; then
                cr_list ${LIMIT_LIST}.new $DROP_NU $DROP_LIST
        fi
        #-- create perm list --#
        if [ -s $DROP_LIST ]; then
                cr_list ${DROP_LIST}.new $PERM_NU $PERM_LIST
        fi

        #-- start limit --#
        for i in $(cat $LIMIT_LIST); do
                echo LIMIT $i
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i \
                        -m limit --limit 1/s -j ACCEPT
        done
        #-- start blocking --#
        for i in $(cat $DROP_LIST); do
                echo DROP $i
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
        done
        #-- start permanent blocking --#
        for i in $(cat $PERM_LIST); do
                echo permanently DROP $i
                /sbin/iptables -I INPUT -p TCP --dport $HTTP_PORT \
                        -s $i --syn -j DROP
        done

fi
exit 0