apch能否实现:当用户访问超过xx后自动屏蔽ip?详细见内

apch能否实现:当用户访问超过xx后自动屏蔽ip?详细见内

linux +apache 如何实现
当访问某站点的某个ip 超过x个连接后自动屏蔽掉这个ip ?
必须手工?还是可以自动执行?
手工开发代码来进行关闭
呵呵. 这样不就可以在一定程度上防止了dos攻击了. 偶也很需要. 谁可以提供?
#!/bin/sh
# this program is used to check tcp/ip connections
# and block those ip with excessive connections

# my version
myver="1.0RC1"

# wake up every 120s if last check found abuse client
wakeup_time_min=120

# wake up every 300s if last check found no abuse client
wakeup_time_max=300

# rule timeout 3600s
rule_timeout=3600

# check port list
portlist="80"

# max established connection per ip
max_active_conn=8

# iptables chain name
iptables_chain_name="RH-Lokkit-0-50-INPUT"

# log facility
log_facility="local0"

# Block policy
ipchains_block_policy="DENY"
iptables_block_policy="REJECT"

# myself
myself=`basename $0`

mylogger_info()
{
logger -p $log_facility.info -t $myself $@ 2>/dev/null
}

mylogger_debug()
{
logger -p $log_facility.debug -t $myself $@ 2>/dev/null
}

mylogger_notice()
{
logger -p $log_facility.notice -t $myself $@ 2>/dev/null
}

dotimeout()
{
mylogger_info "reset firewall when timeout arrives"
case "$firewall" in
  ipchains)
    /etc/init.d/ipchains restart 1>/dev/null 2>/dev/null
    if [ $? = 0 ] ; then
       mylogger_info "ipchains restarted"
    else
       mylogger_notice "ipchains restart failed"
    fi
    ;;
  iptables)
    /etc/init.d/iptables restart 1>/dev/null 2>/dev/null
    if [ $? = 0 ] ; then
       mylogger_info "iptables restarted"
    else
       mylogger_notice "iptables restart failed"
    fi
    ;;
  *)
    mylogger_notice "neither ipchains nor iptables"
    ;;
esac
   
}

blockclient()
{
if [ -z "$1" ] || [ -z "$2" ]; then
   mylogger_notice "blockclient() missing client or port to block"
   return
fi
local ip port

ip=$1
port=$2

case "$firewall" in
  ipchains)
    mylogger_notice "blocking $1 to $2 via ipchains"
found=`ipchains -nL | egrep "^$ipchains_block_policy.*[[:space:]]+$ip[[:space:]]+.*[[:space:]]+\->[[:space:]]+$port"`
if [ -z "$found" ] ; then
cmd="ipchains -I input 1 -p tcp -s $ip -d 0/0 $port -j $ipchains_block_policy 1>/dev/null 2>/dev/null"
mylogger_debug "cmd: $cmd"
`ipchains -I input 1 -p tcp -s $ip -d 0/0 $port -j $ipchains_block_policy 1>/dev/null 2>/dev/null`
if [ $? != 0 ] ; then
  mylogger_notice "$cmd call failed"
  return
fi
new_block=1
ever_block=1
else
mylogger_info "$ip already blocked to $port"
fi
    ;;
  iptables)
    mylogger_notice "blocking $1 to $2 via iptables"
found=`iptables -nL | egrep "^$iptables_block_policy.*[[:space:]]+$ip[[:space:]]+.*[[:space:]]+dptport[[:space:]]+"`
if [ -z "$found" ] ; then
cmd="iptables -I $iptables_chain_name 1 -p tcp -m tcp -s $ip --dport $port -j $iptables_block_policy 1>/dev/null 2>/dev/null"
mylogger_debug "cmd: $cmd"
`iptables -I $iptables_chain_name 1 -p tcp -m tcp -s $ip --dport $port -j $iptables_block_policy 1>/dev/null 2>/dev/null`
if [ $? != 0 ] ; then
  mylogger_notice "$cmd call failed"
  return
fi
new_block=1
ever_block=1
else
mylogger_info "$ip already blocked to $port"
fi
    ;;
  *)
    mylogger_notice "neither ipchains nor iptables"
    ;;
esac
}

restartservice()
{
local service
if [ -z "$1" ] ; then
  mylogger_notice "no port given to see which service to be restart"
  return
fi

case "$1" in
  80)
    service="httpd"
    ;;
  25)
    service="postfix"
    ;;
  110)
    service="courier-pop3d"
    ;;
  21)
    service="muddleftpd"
    ;;
  53)
    service="named"
    ;;
  3306)
    service="mysqld"
    ;;
esac
if [ ! -z "$service" ] ; then
  /etc/init.d/$service restart 1>/dev/null 2>/dev/null
  if [ $? = 0 ] ; then
    mylogger_notice "$service restarted"
  else
    mylogger_notice "$service restart failed"
  fi
fi
}

docheckport()
{
mylogger_info "do check port $1"
local port last_client count client total_count

if [ -z "$1" ] ; then
  mylogger_notice "docheckport() port not given"
  return
fi

port=$1

clientlist=`netstat -an --tcp| grep ESTABLISHED | awk "{ if ( index(\\$4,\"port\" ) print \\$5}" | awk -F ':' '{print $1}'|sort`
if [ $? != 0 ] ; then
  mylogger_notice "netstat call failed"
  return
fi
#echo $clientlist
# reset new_block
new_block=0
count=0
total_count=0
last_client=""
for client in $clientlist
do
  #echo "client is $client"
  if [ -z "$last_client" ] ; then
    count=$((count+1))
    total_count=$((total_count+1))
    last_client=$client
  else
    if [ "$client" = "$last_client" ] ; then
      count=$((count+1))
      total_count=$((total_count+1))
    else
      mylogger_debug "$last_client $count connections"
      if [ $count -ge $max_active_conn ] ; then
         mylogger_notice "client $last_client connection $count >= $max_active_conn"
         blockclient $last_client $port
      fi
      count=1
      total_count=$((total_count+1))
      last_client=$client
    fi
  fi
done
# check the last client
if [ ! -z "$client" ] ; then
  count=$((count+1))
  total_count=$((total_count+1))
  mylogger_debug "$client $count connections"
  if [ $count -ge $max_active_conn ] ; then
    mylogger_notice "client $client connection $count >= $max_active_conn"
    blockclient $client $port
  fi
fi
mylogger_info "total connections on port $port: $total_count"

if [ $new_block = 1 ] ; then
  restartservice $port
fi
}

docheckall()
{
# reset wakeup_time
wakeup_time=$wakeup_time_max
for port in $portlist
do
  docheckport $port
  if [ $new_block = 1 ] ; then
    # set wakeup_time shorter cause we found some abuse client
    wakeup_time=$wakeup_time_min
  fi
done
}

if [ -z "$firewall" ] && [ -f /etc/sysconfig/ipchains ] ; then
  firewall="ipchains"
fi

if [ -z "$firewall" ] && [ -f /etc/sysconfig/iptables ] ; then
  firewall="iptables"
fi

if [ -z "$firewall" ] ; then
  echo "Error: This machine does not have ipchains or iptables firewall support"
  exit 1
fi

mylogger_info "firewall.sh v$myver ValueOf.com starting"
mylogger_info "Firewall is:           $firewall"
mylogger_info "ort protected:        $portlist"
mylogger_info "Max connection per ip: $max_active_conn"
mylogger_info "Min time to check:     $wakeup_time_min""s"
mylogger_info "Max time to check:     $wakeup_time_max""s"
mylogger_info "Timeout circle:        $rule_timeout""s"
mylogger_info "Output is logged to:   $log_facility"

# if new ip blocked at this check run?
new_block=0
# if new ip blocked at this timeout run?
ever_block=0
# reset wakeup_time
wakeup_time=$wakeup_time_max

lasttime=`date +%s`

while [ 1 ]
do
curtime=`date +%s`
timediff=$((curtime-lasttime))
#echo "timediff: $timediff"
if [ $timediff -ge $rule_timeout ] && [ $ever_block = 1 ] ; then
  lasttime=$curtime
  ever_block=0
  dotimeout
fi
docheckall
mylogger_info "sleep for $wakeup_time""s"
sleep $wakeup_time
done

http://www.hzbase.cn/thread-62-1-1.html
pf防火墙可以把超过规定连接数的IP地址block掉(BSD系统)。使用LINUX的用户,IPTABLE可以限制单IP的连接数(但不能自动block这个IP)