0%

nginx限制恶意请求

背景

从nginx配置上防止恶意请求

nginx处理方式

HttpLimitReqModule配置来限制ip在同一时间段的访问次数来防cc攻击。
HttpLimitConnModul用来限制单个ip的并发连接数
网友总结     nginx文档

实例(见上面网友总结)

https://www.nginx.com/blog/rate-limiting-nginx/

http://blog.nkhost.net/notes/nginx-limit-the-request-processing-rate/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
http{
...

#定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
#以$binary_remote_addr 为key,限制平均每秒的请求为20个,
#1M能存储16000个状态,rete的值必须为整数,
#如果限制2秒钟处理一个请求,可以设置成30r/m

limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
...
server{
...
location { #也可以不用放在location这一级
...

#限制每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=allips burst=5 nodelay; #也可以直接放在server这一级下面
...
}
...
}
...
}

测试

ab -n 1000 -c 50 http://testweb.com/index.html #1000个请求,50个并发测试

观察nginx访问日志可以看到,很快就限制返回503了
nginx503
观察nginx error日志可以看到请求受限
nginx_err

优化返回

云服务器会统计5xx错误,5xx错误可能引发报警。有时需要把这种错误自定义,例如把这种503自定义成403错误。http错误码

nginx配置 stackoverflow

1
2
limit_req zone=allips burst=2 nodelay;
limit_req_status 403;

自定义错误返回页 stackoverflow

1
2
3
4
error_page  403  /403.html;
location /403.html {
internal;
}

进一步优化

在webapi项目中,想用json返回错误提示,并且状态码设为200 github

1
2
3
4
5
6
7
limit_req zone=allips burst=2 nodelay;
limit_req_status 403;
error_page 403 =200 @403.json;
location @403.json {
default_type application/json;
return 200 '{"limit":"request is too fast"}';
}
测试效果

先用ab命令发起并发请求,引发连接限制。同时访问可以发现,服务器返回json格式数据,同时状态码200
自定义json测试