專業施工團隊
專營室內裝潢、辦公室裝潢、店面裝潢
油漆快清辦公桌吧
辦公室細菌量比廁所高400倍!

首頁  •  j2h 論壇 • 程式設計討論     • 

防止砍站行為的 Shell Script

房東:小妹
發表時間:2007-02-12


不用多說,這個軟體就是要防止別人砍站軟體用的,
http://www.ossacc.org/Members/song/Docs/about_block.http.sh
為何要擋勒 ?,
有些軟體在強力抓網頁時,或是沒有設定好參數,
在某個時間點內,大量發出連線命令,造成 server 為了要應付這個多連線,
勢必,瞬間的 cpu 使用量大增, memory 使用量大增, 耗光整個硬體資源,
在這段時間, server 反應時間拉長, 讓人誤以為 server 掛點了,
使得 server 無法正常運作, 所以要擋掉這些不規矩的使用者.





--------------------------------------------------------------------------------

以下是全文

#!/bin/bash
# Purpose: to block httpd connection
# Author: netman([email protected])
# Lisence: GPL
# Date: 2004/05/28
# Version: 1.22

#-- 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
# Version 0.99
# 1) add detection for running process of script
# 2) add limit rule to OUTPUT
# 3) remove SYN factor from permanent drop rule
# Version 1.00
# 1) add detection for httpd daemon, restart while missing.
# Version 1.01
# 1) change httpd daemon detection from netstat to ps
# 2) add detection for DROP rules before permanet drop
# Version 1.02
# 1) add removal of Semaphore Arrays of apache
# 2) add -i interface elements in permanet drop rule
# 3) bug fix: change --dport to --sport in OUTPUT limit
# Version 1.03
# 1) change process detection from PID file to ps command
# 2) bug fix: add path to iptables-save command
# Version 1.04
# 1) bug fix: correct detection method of script process
# Version 1.05
# 1) bug fix: correct time stamp assignment for list files
# 2) bug fix: correct touch command in up_list function
# Version 1.06
# 1) improve removal of Semaphore Arrays of apache
# Version 1.07
# 1) add decection for TIME_WAIT peer
# 2) improve exeception list determination
# Version 1.08
# 1) BugFix: using lock file to determine running process.
# Version 1.09
# 1) BugFix: keep permanent list from flushing out
# Version 1.10
# 1) BugFix: fixed pid path.
# Version 1.11
# 1) imporve pid dedection method.
# Version 1.12
# 1) set up HTTP_SCRIPT & HTTP_CMD variables
# 2) create PERM_LIST by using touch command
# 3) remove touch command for HTTP_LIST_TMP
# 4) remove all LIMIT rules, dump to DROP directly.
# Version 1.13
# 1) put back the LIMIT rules
# 2) BugFix: add DROM rules to each limit host.
# 3) remvoe OUTPUT limit
# Version 1.14
# 1) add program checking for certain packages.
# 2) fix line order for first running.
# Version 1.15
# 1) BugFix: get rid off the softquote(") from program check
# 2) new define IPCS_CMD & HTTP_USER variable for ipcs detection
# 3) improve performance by patching some text filtering pipe line
# Version 1.16
# 1) replace cat by sort in ud_list function
# 2) rewrite cr_list function
# Version 1.17
# 1) BugFix: change --sport to --dport for limit rules
# 2) improve performance by patching some text filtering pipe line
# Version 1.18
# 1) BugFIx: add PATH for crontab running
# Version 1.19
# 1) re-sort PERM_LIST
# Version 1.20
# 1) BugFix: correct syntac in pipe line of ipcs detection
# Version 1.21
# 1) BugFix: improve PID determination method
# 2) BugFix: correct TIME_WAIT number teermination
# Version 1.22
# 1) BugFix: correct PERM_LIST sorting method
# 2) BugFix: correct cr_list function, which was having one ip only.


PATH=$PATH:/sbin:/usr/sbin

EXT_IF=eth0 # extenal interface
HTTP_NU=8 # connection number to be added to list
LIMIT_NU=2 # 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=55 # CPU loading for user
HC_N=200 # HTTP connection number for session
HC_U=20 # HTTP connection number for source
TW_N=20 # TIME_WAIT number for session
HTTP_PORT=80 # HTTP port number
UD_HTTP=30 # minutes to update http list
UD_LIMIT=2 # hours to update limit list
UD_DROP=1 # days to update drop list

HTTP_SCRIPT=/etc/rc.d/init.d/httpd
HTTP_USER=apache
HTTP_CMD=httpd
IPCRM_CMD=ipcrm
IPCS_CMD=ipcs
SAR_CMD=sar
NETSTAT_CMD=netstat
MAIL_CMD=mail
AWK_CMD=awk
IPT_CMD=iptables
IPT_SAVE_CMD=iptables-save

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



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

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

#-- create file and set timestampt --#
touch --date="$UD_HTTP minutes ago" $HTTP_LIST
touch --date="$UD_LIMIT hours ago" $LIMIT_LIST
touch --date="$UD_DROP days ago" $DROP_LIST
touch $EXCP_LIST
touch $PERM_LIST

#-- detect process --#
LPID=$(cat $PID_FILE 2>/dev/null)
PID=$(ps aux | awk '($2 == '${LPID:=0}'){print $2}')
if [ "$PID" ]; then
echo "${0##*/}: WARNING: There is a running copy of script."
echo " exiting..."
exit 3
else
echo "$$" > $PID_FILE
fi

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

#-- create source list --#
touch $HTTP_LIST_TMP
touch $HTTP_TW_TMP
$NETSTAT_CMD -na | grep ":$HTTP_PORT " | awk '{print $5}' | cut -d: -f1 | sort \
| grep -v '0.0.0.0' > $HTTP_LIST_TMP
$NETSTAT_CMD -na | grep ":$HTTP_PORT " | grep "TIME_WAIT" | awk '{print $5}' \
| cut -d: -f1 | sort | grep -v '0.0.0.0' > $HTTP_TW_TMP

#-- check loading --#
cpuload=$($SAR_CMD -u 1 3 | tail -1 | awk '{printf("%i:%i",$3,$5)}')
cpuusr=${cpuload%:*}
cpusys=${cpuload#*:}
http_cn=$(cat $HTTP_LIST_TMP | wc -l)
http_un=$(uniq $HTTP_LIST_TMP | wc -l)
http_tw=$(cat $HTTP_TW_TMP | 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##* }"
echo "TW_N: $TW_N ${http_tw##* }"

#-- function update lists --#
ud_list () {
for i in $@; 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
sort ${i}.[1-5] > ${i}.new
touch $i
done
}

#-- list is added? or nothing change in the period? --#
if [ -s $HTTP_LIST -o $HTTP_LIST.new -ot $HTTP_LIST ]; then
#-- remove old limit rules --#
for i in $(cat $LIMIT_LIST | grep -v '0.0.0.0'); do
echo remove $i from LIMIT
$IPT_CMD -D INPUT -p TCP --dport $HTTP_PORT \
-s $i -m limit --limit 1/s -j ACCEPT
$IPT_CMD -D INPUT -p TCP --dport $HTTP_PORT \
-s $i -j DROP
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
$IPT_CMD -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 drop list --#
ud_list $DROP_LIST
#-- sort perm list --#
sort -u $PERM_LIST > $HTTP_LIST_TMP
cat $HTTP_LIST_TMP > $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" -o "$http_tw" -gt "$TW_N" ]
then

#-- function: create list --#
cr_list () {
all_list="$(sort $1)"
for i in $(echo "$all_list" | sort -u); do
if [ $(echo "$all_list" | grep -c $i) -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
grep -v -E -f $EXCP_LIST $LIMIT_LIST \
> $HTTP_LIST_TMP
mv $HTTP_LIST_TMP $LIMIT_LIST
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
$IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT -s $i \
-j DROP
$IPT_CMD -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
$IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT -s $i -j DROP
done
#-- start permanent blocking --#
ipt_save="$($IPT_SAVE_CMD)"
for i in $(cat $PERM_LIST); do
echo "$ipt_save" | grep $i | grep $EXT_IF &>/dev/null || {
host $i | $MAIL_CMD -s "drop $i" root
echo permanently DROP $i
$IPT_CMD -I INPUT -p TCP --dport $HTTP_PORT \
-s $i -i $EXT_IF -j DROP
}
done

fi

#-- clean PID file --#
rm -f $PID_FILE
exit 0





  • 贊助網站       

    廣利不動產-新板特區指名度最高、值得您信賴的好房仲
    您的托付,廣利用心為您服務
    廣利不動產-板橋在地生根最實在--新板特區指名度最高、值得您信賴的好房仲
    完整房訊,房屋、店面熱門精選物件,廣利不動產 優質仲介,房屋租賃、買賣資訊透明,交易真安心!



  •  共 0 人回應

    姓名:
    佈告內容:
    其他選項: