2010 10 13日网站受到攻击
服务器都是centos5.4 , lsb_release –a可以查看release
公司购买的服务
发现网站打不开 46秒,会自动报警
The following monitor has failed:
Monitor Name: (15383175) Test Profile: Homepage (18039181) Time Since Failure Detected: 46 sec Last Test Time: 10/12/2010 5:31:24 PM
Detected Errors:
- Connect Attempt Error (117700) a connection attempt to the IP/Host address failed
- Host/IP Not Responding (114700) The IP/Host address did not respond to any connection attempts and is completely unavailable
For more detailed Test Results, see the AlertBot Manager Reports section
像这种情况,nagios没有报警,估计是爬虫或者网络攻击
1 打开一个真实服务器
发现大部分的连接来自192.168.10.146
这说明了真实服务器的连接都是来自负载均衡器,他并不知道对外的ip信息
因此要检测外部ip,只有打开负载均衡器192.168.10.146
2 打开负载均衡器192.168.10.146使用netstat –tun
必须使用n才能将外部连接的域名检测为ip
不用l ,因为这是listen
不用p这是要检测端口,也就是将端口转换为字符,比如80转换为http,所以不需要这个参数,会很慢的
也不是netstat –an 因为这样打印出listen 的和unix的没有必要
最终输出,大概是这样的:
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 192.168.10.100:443 98.154.206.160:1843 ESTABLISHED
tcp 0 0 192.168.10.100:443 98.154.206.160:1842 ESTABLISHED
tcp 0 0 192.168.10.100:443 76.201.177.249:53319 ESTABLISHED
tcp 0 0 192.168.10.100:443 71.139.174.196:51236 ESTABLISHED
tcp 0 0 192.168.10.100:80 192.55.55.37:51424 ESTABLISHED
tcp 0 0 192.168.10.100:80 69.120.200.34:1616 ESTABLISHED
tcp 0 0 192.168.10.100:80 75.22.38.252:20751 ESTABLISHED
tcp 0 0 192.168.10.100:443 128.107.239.233:22447 TIME_WAIT
如果有 :fff:之类的字样,是因为开启了ipv6,需要关闭
在vi /etc/modprobe.conf 加上2句
alias net-pf-10 off
alias ipv6 off
重启系统即可
不这样做怕影响很后面的脚本,当然服务器一般都是关闭了ipv6的
3 如何查看并发连接数 记得抓取established和:80端口 ,避免误杀
目前是1398
[jasony@lb1 ~]$ netstat -tun |grep ESTABLISHED|grep ":80" |wc
1398 8388 124422
4如何看哪个ip的并发连接最多呢?
netstat -tun |grep ":80"|grep ESTABLISH |awk -F "[ :]+" '{a[$6]++}END{for(i in a){if(a[i]>=2)print i,a[i]}}'|sort -nk2
解释一下 -F[ :]+是多个空格或者 : 都可以当做分隔符,这样成功将ip:端口 中的ip提炼出来,也就是$6
a[$6]++}是典型的awk数组统计,将$6也就是ip作为下标放入数组统计,最终a[$6]的值就对应的是并发连接数
{if(a[i]>=2)是打印并发数量大于2的 数字可以改变
最下面的就是最多连接数量的了
比如
96.30.231.86 12
72.173.192.59 13
75.107.64.57 13
124.43.6.52 14
76.15.174.71 18
12.189.32.37 39
70.41.96.39 54
其中最下面ip多达54个连接,就有问题了 因为一般先是几个并发链接
如果超过40个很可能是异常的接入了
5 如何将并发连接数大于某个值的ip封禁呢
直接用/etc/hosts.deny 最简单 但是缺点是无法禁用httpd的服务
而且不会立即杀掉禁止的ip 目前的session
因此 最好使用linux下的iptables或者freebsd下的ipFW防火墙
写为脚本自动检测 封禁
例子:
我的服务器CentOS5.4目前被人攻击了,假设我现在将大于连接数40的封禁掉
写一个脚本
#!/bin/bashi
PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin:/usr/local/sbin
WORKPATH=/root/bashshell
#如果大于多少连接,会被封禁,默认40
if [ -z "$1" ]
then
n=40
else
n=$1
fi
cd $WORKPATH
#被封禁的ip列表
IP=$(netstat -tun |grep ":80"|grep ESTABLISH |awk -v n=$n -F "[ :]+" '{a[$6]++}END{for(i in a){if(a[i]>=n)print i,a[i]}}'|sort -nk2 )
#加入黑名单备查
echo "---------------------------------------------" >>black_list.txt
echo `date` >> black_list.txt
echo -e "been banned ip || the connection counts" >>black_list.txt
echo "$IP"|awk '{print $1 " || " $2}' >> black_list.txt
#开始踢人
for i in `echo "$IP"|awk '{print $1}'`
do
echo $i
iptables -A INPUT -s $i -j DROP
done
一旦服务器异常,将这个脚本用cron执行 ,每分钟一次,即可封杀出现连接数大于40的任何ip
并且被封杀ip 信息都将出现在黑名单 black_list.txt下
它的位置根据变量 工作路径WORKPATH而定
有可能出现重复封杀同一ip 的情况,这是因为 apache的KeepAliveTimeout 设置太大了
KeepAliveTimeout 5是建立连接以后,也就是成了ESTABLISHED那么不做任何动作,5秒以后终止连接
这个值如果设计大了,那么将会很多连接established存在,哪怕你把ip禁用了,established一样存在,所以最好把这个值给的很小
如果给大了这个值,可能导致封ip脚本的时候,established很久不消失,那么一般封ip脚本一分钟运行一次,会反复封这个ip的
默认5秒即可