DDoS (distributed denial-of-service) 及 DoS (denial-of-service) 在网络上十分常见,而 DoS 攻击所传送的请求跟正常的请求一样,分别在于每秒钟发出大量请求到服务器,使服务器的负载增加,最常见的情况是服务器暂停服务。
而 mod_evasive 则是一个预防 Apache 遭受 DDos 攻击的模块,可以防止同一个 IP 对相同 URI 发出的大量请求,可设定的选项有:
– 限制同一个 IP 在一定秒数内请求一个页面或档案的次数。
– 限制同一个 IP 一秒内只可发出 50 个请求。
– 设定被禁止的 IP 封锁时间。
以下是 mod_evasive 的安装方法:
1. 先将原来的 httpd.conf 备份起来。
2. 到http://www.sfr-fresh.com/unix/privat/mod_evasive_1.10.1.tar.gz下载 mod_evasive。
3. 在指令模式解压及编译 mod_evasive:
tar zxvf mod_evasive_1.10.1.tar.gz
cd mod_evasive/
apxs -cia mod_evasive20.c
以上的 apxs 会放在 Apache 的 bin 目录内;假设 Apache 版本是 1.3 的话,指令要改为:
apxs -cia mod_evasive.c
安装好 mod_evasive 后,便要修改 httpd.conf .
假设执行失败的话,需要安装httpd-devel,可直接通过yum安装.
4. 开启 httpd.conf,加入以内容:
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
</IfModule>
DOSHashTableSize — 这是占用内存的大小,假设服务器比较繁忙,这个数值要设定大一点。
DOSPageCount — 同一 IP 在一个时段内可以存取同一页面的次数,超过会被禁止。
DOSSiteCount — 同一 IP 在一个网站内可以占用多少 Object,超过会禁止。
DOSPageInterval — DOSPageCount 内的时段设定。
DOSSiteInterval — DOSSiteCount 的时间设定,以秒为单位。
DOSBlockingPeriod — 当发现疑似攻击后,使用者会收到 403 Forbidden,这是设定封锁的时间,以秒为单位。
5. 最后重新启动 Apache 即可。
配合iptables防止DDOS攻击的脚本
#!/bin/sh
## define some vars
MAX_TOTAL_SYN_RECV="1000"
MAX_PER_IP_SYN_RECV="20"
MARK="SYN_RECV"
PORT="80"
LOGFILE="/var/log/netstat_$MARK-$PORT"
LOGFILE_IP="/var/log/netstat_connect_ip.log"
DROP_IP_LOG="/var/log/netstat_syn_drop_ip.log"
## iptables default rules: accept normailly packages and drop baleful SYN* packages
iptables -F -t filter
iptables -A INPUT -p TCP ! --syn -m state --state NEW -j DROP
iptables -A INPUT -p ALL -m state --state INVALID -j DROP
iptables -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT
## initialize
if [ -z $MARK ];then
MARK="LISTEN"
fi
if [ -z $PORT ];then
SPORT="tcp"
else
SPORT="PORT"
fi
######################## end
## save the results of command netstat to specifal file
netstat -atun|grep $MARK|grep $SPORT 2>/dev/null >$LOGFILE
REPEAT_CONNECT_IP=`less $LOGFILE|awk '{print $5}'|cut -f1 -d ':'|sort|uniq -d |tee > $LOGFILE_IP`
if [ -f $DROP_IP_LOG ];then
for i in `less $DROP_IP_LOG`;do
iptables -A INPUT -p ALL -s $i -j DROP
done
fi
for i in `less $LOGFILE_IP`;do
REPEAT_CONNECT_NUM=`grep $i $LOGFILE|wc -l`
## count repeat connections ,if the accout is large than default number,then drop packages
if [ $REPEAT_CONNECT_NUM -gt $MAX_PER_IP_SYN_RECV ];then
echo "$i####$REPEAT_CONNECT_NUM" >> $DROP_IP_LOG
iptables -A INPUT -p ALL -s $i -j DROP
fi
done
ALL_CONNECT=`uniq -u $LOGFILE|wc -l`
#echo $ALL_CONNECT
## count repeat connections ,if the accout is large than default number,then drop packages
if [ $ALL_CONNECT -gt $MAX_TOTAL_SYN_RECV ];then
#echo $ALL_CONNECT
exit
fi