最近在分析nginx日志发现,有很多可以ip访问网站根目录,如下:
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
GET / - - 58.60.170.219 HTTP/1.1 [Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)]
从00:00--6:00这个ip的记录已经达到10万条左右,如何解决此问题呢?
本来nginx上有相关模块limit_conn 100 及limit_req 12 burst 10做了一层限制,但是效果不是很明显。因为之前日志也有过类似ip,导致503错误很多,但这个ip并没有产生503错误很多,这说明limit模块配置不太合适。
limit具体参数的调整就不说了,但是对于limit_conn 100这个模块有些疑问:(1)同一时间有100个ip在访问(2)产生100个连接;请明白的具体说下,不胜感激!!
既然nginx无法完全限制,我们就换个思路,结合iptables限制特定时间内ip的连接数来实现。
iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --name httpuser --rcheck --seconds 60 --hitcount 20 -j DROP iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --name httpuser --set -j ACCEPT
测试过程:
当我把--hitcount设置为8时:
[[email protected] webbench-1.5]# ab -c 10 -n 20
-t 60 http://192.168.3.124/1.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.3.124 (be patient)
apr_socket_recv: Connection timed out (110)
Total of 8 requests completed
20个请求只有8个是成功的。
紧接着在60s内再发送请求:
[[email protected] webbench-1.5]# ab -c 10 -n 20 -t 60 http://192.168.3.124/1.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.3.124 (be patient)
apr_socket_recv: Connection timed out (110)
已经无法建立连接了,但过了60s后就可以正常测试了。
用netstat -ant |grep ESTABLISHED |grep 192.168.3.124:80|wc -l ,发现ESTABLISHED状态的个数在8个以内。
当将当--hitcount设置为20时,发现ESTABLISHED状态的个数在20以内,大致10个左右,而且网页访问速度也有提高。
还有一种写法是:
#iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --name httpuser --set #iptables -A INPUT -m recent --update --name httpuser --seconds 60 --hitcount 20 -j LOG --log-prefix 'HTTP attack:' #iptables -A INPUT -m recent --update --name httpuser --seconds 60 --hitcount 20 -j DROP
1.先插入INPUT链的最前面,对于80端口的新建连接,创建一个名为httpuser的清单( /proc/net/xt_recent/httpuser ),并且将记录加1
2.在INPUT链最后插入后,匹配第二条,在60s内新建的连接叨叨20,会开始记录日志(默认iptables日志写在/var/log/message下,我们可以设置将其分离,下面讲到),并有HTTP attack标识
3.在INPUT链最后插入后,继续匹配第三条,连接达到20后,后续新建的连接会被iptables drop掉。
但是这种写法适用于INPUT链默认规则为ACCEPT的,否则都会DROP,这点需要注意,建议用第一种方法。
另日志配置:
在/etc/rsyslog.conf中加入:
kern.=warn /var/log/kern-warn-log
防止日志过大,需要截断日志:
vim /etc/logrotate.d/syslog
/var/log/kern-warn-log
{
rotate 50
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
ps:1.--rcheck --update --set 参数的区别,这里不多说了。
2.iptables和nginx配合使用,可以减少大量可疑ip的访问,不仅增加了安全性,也增加了nginx的抗并发数,一举两得啊
3.本次实验用ab和webbench测试发现,它们的每次request应该都是建立一个连接,这样才会符合我们iptables的设置,也符合测试中的request 成功数。这让我对ab和
webbench这两个工具又加深了认知。