简单的Nginx防CC攻击方式
2019-07-03 10:02:23 【

简单的Nginx防CC方式

实验

Nginx配置


http {    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;    server {        #限制每ip每秒不超过20个请求,漏桶数burst为5        #brust的意思就是,如果第1秒、2,3,4秒请求为19个,        #第5秒的请求为25个是被允许的。        #但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。        #nodelay,如果不设置该选项,严格使用平均速率限制请求数,        #第1秒25个请求时,5个请求放到第2秒执行,        #设置nodelay,25个请求将在第1秒执行。        limit_req   zone=one  burst=1 nodelay;    }}

上面样本的配置是什么意思呢?

  • $binary_remote_addr 表示:客户端IP地址

  • zone 表示漏桶的名字

  • rate 表示nginx处理请求的速度有多快

  • burst 表示峰值

  • nodelay 表示是否延迟处理请求,还是直接503返回给客户端,如果超出rate设置的情况下。

详细的可以参考官方说明文档:Module ngx_http_limit_req_module(http://nginx.org/en/docs/http/ngx_http_limit_req_module.html)

模拟请求

这里我们需要Apache Benchmark这个小工具来生成请求

//1个用户持续100s的时间向服务器发送请求
ab -t 100 -c 1 -vvv http://example.com/

Nginx配置样本一


http {    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;    server {        limit_req   zone=one  burst=1 nodelay;    }}

ab测试结果如下所示:

数据成功的请求数失败的请求数请求时间每秒成功的请求数
110019438101.1950.98
210017651100.6550.99
39725735100.4240.96
410126791100.0001.01
59819051100.5140.98
平均9921733.2100.5570.98

以上失败的请求在Nginx上生成的错误日志如下显示


2015/05/0912:48:57 [error] 6564#0: *2219 limiting requests, excess: 1.273 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"2015/05/0912:48:57 [error] 6564#0: *2220 limiting requests, excess: 1.272 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"2015/05/0912:48:57 [error] 6564#0: *2221 limiting requests, excess: 1.271 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"2015/05/0912:48:57 [error] 6564#0: *2222 limiting requests, excess: 1.270 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"2015/05/0912:48:57 [error] 6564#0: *2223 limiting requests, excess: 1.269 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"2015/05/0912:48:57 [error] 6564#0: *2224 limiting requests, excess: 1.268 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"

如上ab测试中如果是失败的请求,nginx的limit_req模块会统一返回503给客户端,浏览器上面显示的是这个样子的。

Nginx配置样本二

在配置二里面,我把burst(峰值)提高到了10


http {    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;    server {        limit_req   zone=one  burst=10 nodelay;    }}

数据成功的请求数失败的请求数请求时间每秒成功的请求数
111019042100.1441.09
211122271101.7141.09
311118466100.5041.10
411116468101.2851.09
511112770100.5961.10
平均11017803100.788

1.09

从数据来看,提高了burst值,明显nginx成功的请求数上去了。

Nginx配置样本三

在样本二的基础上,我们把nodelay去除掉


http {    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;    server {        limit_req   zone=one  burst=10;    }}

数据成功的请求数失败的请求数请求时间每秒成功的请求数
1960100.2231.09
2980100.2380.97
31000100.7610.99
4960100.0740.95
5970100.0210.96
平均97.40100.2630.97

从这里的数据可以看到将nodelay的参数去掉的话,成功的请求数在100左右而失败的请求数变成0了,为什么呢?

  • 有nodelay参数的时候,nginx正常是及时处理当前的请求的并响应数据给客户端,但是如果超过limit_req_module的限制,那么会统一返回503给客户端。

  • 无nodelay参数的时候,nginx正常是及时处理当前的请求的并响应数据给客户端,但是如果超过limit_req_module的限制,那么会将此此请求缓存「就先这么理解」起来稍后再处理,所以也就不会出现大量的失败请求数了。

存在的问题

虽然用limit_req_module可以一定上的防止CC攻击,但是有误杀概率;国内宽带用户的IP地址已经大量内网化,几百人共享一个IP的可能性是很大的。


】【打印关闭】 【返回顶部
上一篇应用层DDoS的防御理论 下一篇CC攻击的变异品种-慢速攻击,如何..