背景
从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了
观察nginx error日志可以看到请求受限
优化返回
云服务器会统计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