基于Nginx实现限制某IP短时间访问次数


Posted in Servers onMarch 31, 2021

如何设置能限制某个IP某一时间段的访问次数是一个让人头疼的问题,特别面对恶意的ddos攻击的时候。其中CC攻击(Challenge Collapsar)是DDOS(分布式拒绝服务)的一种,也是一种常见的网站攻击方法,攻击者通过代理服务器或者肉鸡向向受害主机不停地发大量数据包,造成对方服务器资源耗尽,一直到宕机崩溃。

cc攻击一般就是使用有限的ip数对服务器频繁发送数据来达到攻击的目的,nginx可以通过HttpLimitReqModul和HttpLimitZoneModule配置来限制ip在同一时间段的访问次数来防cc攻击。

HttpLimitReqModul用来限制连单位时间内连接数的模块,使用limit_req_zone和limit_req指令配合使用来达到限制。一旦并发连接超过指定数量,就会返回503错误。

HttpLimitConnModul用来限制单个ip的并发连接数,使用limit_zone和limit_conn指令

这两个模块的区别HttpLimitReqModul是对一段时间内的连接数限制,HttpLimitConnModul是对同一时刻的连接数限制

HttpLimitReqModul 限制某一段时间内同一ip访问数实例

http{
  ...
  #定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
  #以$binary_remote_addr 为key,限制平均每秒的请求为20个,
  #1M能存储16000个状态,rete的值必须为整数,
  #如果限制两秒钟一个请求,可以设置成30r/m
  limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
  ...
  server{
    ...
    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;
      ...
    }
    ...
  }
  ...
}

HttpLimitZoneModule 限制并发连接数实例

limit_zone只能定义在http作用域,limit_conn可以定义在http server location作用域

http{
  ...
  #定义一个名为one的limit_zone,大小10M内存来存储session,
  #以$binary_remote_addr 为key
  #nginx 1.18以后用limit_conn_zone替换了limit_conn
  #且只能放在http作用域
  limit_conn_zone  one $binary_remote_addr 10m; 
  ...
  server{
    ...
    location {
      ...
      limit_conn one 20;     #连接数限制
      #带宽限制,对单个连接限数,如果一个ip两个连接,就是500x2k
      limit_rate 500k;      
      ...
    }
    ...
  }
  ...
}

nginx白名单设置

以上配置会对所有的ip都进行限制,有些时候我们不希望对搜索引擎的蜘蛛或者自己测试ip进行限制,
对于特定的白名单ip我们可以借助geo指令实现。

1.

http{
   geo $limited{
    default 1;
    #google
    64.233.160.0/19 0;
    65.52.0.0/14 0;
    66.102.0.0/20 0;
    66.249.64.0/19 0;
    72.14.192.0/18 0;
    74.125.0.0/16 0;
    209.85.128.0/17 0;
    216.239.32.0/19 0;
    #M$
    64.4.0.0/18 0;
    157.60.0.0/16 0;
    157.54.0.0/15 0;
    157.56.0.0/14 0;
    207.46.0.0/16 0;
    207.68.192.0/20 0;
    207.68.128.0/18 0;
    #yahoo
    8.12.144.0/24 0;
    66.196.64.0/18 0;
    66.228.160.0/19 0;
    67.195.0.0/16 0;
    74.6.0.0/16 0;
    68.142.192.0/18 0;
    72.30.0.0/16 0;
    209.191.64.0/18 0;
    #My IPs
    127.0.0.1/32 0;
    123.456.0.0/28 0; #example for your server CIDR
  }

geo指令定义了一个白名单$limited变量,默认值为1,如果客户端ip在上面的范围内,$limited的值为0

2.使用map指令映射搜索引擎客户端的ip为空串,如果不是搜索引擎就显示本身真是的ip,这样搜索引擎ip就不能存到limit_req_zone内存session中,所以不会限制搜索引擎的ip访问

map $limited $limit {
1 $binary_remote_addr;
0 "";
}

3.设置limit_req_zone和limit_req

limit_req_zone $limit zone=foo:1m rate=10r/m;

limit_req zone=foo burst=5;

最后我们使用ab压php-fpm的方式,对上面的方法效果实际测试下

例1:限制只允许一分钟内只允许一个ip访问60次配置,也就是平均每秒1次

首先我们准备一个php脚本放在根目录下$document_root

test.php

<?
for( $i=0; $i < 1000; $i++)
echo 'Hello World';
?>

nginx配置增加limit_req_zone 和 limit_req

http{
  ...
  limit_req_zone $binary_remote_addr zone=allips:10m rate=60r/m;
  ...
  server{
    ...
    location {
      ...
      limit_req zone=allips;
      ...
    }
    ...
  }
  ...
}
# ab -n 5 -c 1 http://blog.rekfan.com/test.php
127.0.0.1- - [22/Dec/2012:06:27:06 +0000] "GET /test.php HTTP/1.0" 200 11000 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:06:27:06 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:06:27:07 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:06:27:07 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:06:27:07 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"

未设置brust和nodelay可以看到该配置只允许每秒访问1次,超出的请求返回503错误

http{
  ...
  limit_req_zone $binary_remote_addr zone=allips:10m rate=60r/m;
  ...
  server{
    ...
    location {
      ...
      limit_req zone=allips burst=1 nodelay;
      ...
    }
    ...
  }
  ...
}

# ab -n 5 -c 1 http://blog.rekfan.com/test.php
127.0.0.1- - [22/Dec/2012:07:01:00 +0000] "GET /test.php HTTP/1.0" 200 11000 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:07:01:00 +0000] "GET /test.php HTTP/1.0" 200 11000 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:07:01:01 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:07:01:01 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [22/Dec/2012:07:01:01 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"

设置brust=1和nodelay后允许第1秒处理两个请求。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Servers 相关文章推荐
Nginx快速入门教程
Mar 31 Servers
nginx优化的六点方法
Mar 31 Servers
nginx中proxy_pass各种用法详解
Nov 07 Servers
使用 Apache Dubbo 实现远程通信(微服务架构)
Feb 12 Servers
Nginx+Windows搭建域名访问环境的操作方法
Mar 17 Servers
使用kubeadm命令行工具创建kubernetes集群
Mar 31 Servers
详解使用内网穿透工具Ngrok代理本地服务
Mar 31 Servers
Dashboard管理Kubernetes集群与API访问配置
Apr 01 Servers
Window server 2012 R2 AD域的组策略相关设置
Apr 28 Servers
使用 Docker Compose 构建复杂的多容器App
Apr 30 Servers
GPU服务器的多用户配置方法
Jul 07 Servers
Linux在两个服务器直接传文件的操作方法
Aug 05 Servers
Nginx tp3.2.3 404问题解决方案
Mar 31 #Servers
解决Nginx 配置 proxy_pass 后 返回404问题
nginx配置ssl实现https的方法示例
Mar 31 #Servers
Nginx解决前端访问资源跨域问题的方法详解
Mar 31 #Servers
nginx实现发布静态资源的方法
Nginx中break与last的区别详析
nginx网站服务如何配置防盗链(推荐)
You might like
如何在PHP中使用Oracle数据库(2)
2006/10/09 PHP
谨慎使用PHP的引用原因分析
2012/09/06 PHP
基于php下载文件的详解
2013/06/02 PHP
PHP统计nginx访问日志中的搜索引擎抓取404链接页面路径
2014/06/30 PHP
一张表搞清楚php is_null、empty、isset的区别
2015/07/07 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
2016/03/29 PHP
IE DOM实现存在的部分问题及解决方法
2009/07/25 Javascript
JQuery中如何传递参数如click(),change()等具体实现
2013/04/28 Javascript
Jquery原生态实现表格header头随滚动条滚动而滚动
2014/03/18 Javascript
js实现带缓冲效果的仿QQ面板折叠菜单代码
2015/09/06 Javascript
jquery实现定时自动轮播特效
2015/12/10 Javascript
JavaScript实现多种排序算法
2016/02/24 Javascript
详解js的延迟对象、跨域、模板引擎、弹出层、AJAX【附实例下载】
2016/12/19 Javascript
12306 刷票脚本及稳固刷票脚本(防挂)
2017/01/04 Javascript
JavaScript实现分页效果
2017/03/28 Javascript
JavaScript实现的反序列化json字符串操作示例
2018/07/18 Javascript
浅析JS中回调函数及用法
2018/07/25 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
webpack安装配置与常见使用过程详解(结合vue)
2020/06/01 Javascript
JSON 入门教程基础篇 json入门学习笔记
2020/09/22 Javascript
python访问sqlserver示例
2014/02/10 Python
详解Python中break语句的用法
2015/05/14 Python
Python使用wxPython实现计算器
2018/01/30 Python
python高级特性和高阶函数及使用详解
2018/10/17 Python
python并发爬虫实用工具tomorrow实用解析
2019/09/25 Python
浅谈python多线程和多线程变量共享问题介绍
2020/04/17 Python
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
台湾旅游网站:灿星旅游
2018/10/11 全球购物
泰国王权免税店官方网站:KingPower
2019/03/11 全球购物
幼儿园实习生辞职信
2014/01/20 职场文书
农民工讨薪标语
2014/06/26 职场文书
四风问题对照检查材料整改措施
2014/09/27 职场文书
详解Python生成器和基于生成器的协程
2021/06/03 Python
Nginx进程调度问题详解
2021/09/25 Servers
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript