流量控制:是Nginx中一个很实用的功能,我们可以用来限制用户在给定时间内http请求数量,可用作安全目的,比如减慢暴力破解速率,主要是为了保护上游服务器不被同时太多用户请求压垮。
nginx如何限流:Nginx的流量限制使用漏桶算法,该算法在通讯和分组交换计算机网络中广泛使用,用以处理带宽有限时的突发情况。就好比,向一个桶底漏水的水桶里倒水一样。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水将会溢出;同样,在请求处理方面,水代表来自客户端的请求,水桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列,桶底漏出的水代表离开缓冲区被服务器处理的请求,桶口溢出的水代表被丢弃和不被处理的请求。
流量限制通过ngx_http_limit_req_module模块实现
两个主要指令是 limit_req_zone和limit_req
limit_req_zone 定义流量限制相关的参数,通常在http块中定义,使其可以在多个上下文中使用。
limit_req 启用流量限制
limit_req_zone需要以下三个参数:
Key——定义应用限制的请求特征,$binary_remote_addr,以二进制的形式保存客户端IP地址。
Zone——定义用于存储每个IP地址状态以及被限制请求URL访问频率的共享内存区域。定义分为两个部分:通过zone=keyword标识区域的名字,以及冒号后面跟区域大小。
Rate——定义最大请求速率。
示例:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
这定义了流量限制,意思是定义了一个名字为mylimit大小为10M的区域,每个IP地址被限制为每秒只能请求10次,更准确地说,在前一个请求的100毫秒内不能请求该URL,$binary_remote_addr,以二进制的形式保存客户端IP地址。
环境:
两台虚拟机:
虚拟机1:服务端,安装nginx,完成流量限制配置。
虚拟机2:充当客户端,访问服务端,验证流量限制。
操作:
虚拟机1
1)安装并启动nginx
2)修改主配置文件nginx.conf,在http块中添加流量限制功能
[root@localhost ~]# vim /etc/nginx/nginx.conf
每个IP地址被限制为每秒只能请求1次,若一秒内请求多次将进行流量限制。
3)编写子配置文件limit.conf
4)重新加载nginx的配置文件
[root@localhost ~]# nginx -s reload
5)创建默认发布目录以及网页内容,需与配置相对应
[root@localhost ~]# mkdir /limit
[root@localhost ~]# echo "limit,limit,limit" > /limit/index.html
虚拟机2
快速多次访问虚拟机1,验证流量限制
环境:
三台虚拟机:
虚拟机1:服务端,安装nginx,充当真正的web服务。
虚拟机2:代理服务器,安装nginx,配置代理功能和流量限制功能。
虚拟机3:充当客户端,访问代理服务器,验证流量限制。
操作:
虚拟机1
1)安装并启动nginx
2)主配置文件内容,默认的就好
3)编写子配置文件limit.conf
4)重新加载nginx的配置文件
[root@localhost ~]# nginx -s reload
5)创建默认发布目录以及网页内容,需与配置相对应
[root@localhost ~]# mkdir /limit
[root@localhost ~]# echo "limit,limit,limit" > /limit/index.html
虚拟机2
1)安装并启动nginx
2)修改主配置文件nginx.conf
3)编写子配置文件
4)重新加载nginx的配置文件
[root@localhost ~]# nginx -s reload
虚拟机3
快速多次访问虚拟机2,验证基于代理的流量限制
当快速访问代理服务器时,第一次正常,后面的访问速率超出了速率1r/sd的设置,显示503,说明基于代理的流量限制配置成功
通过将基本的“流量限制”与Nginx的白名单功能配合使用,从而可以实现更细粒度的流量限制。
通过使用白名单功能,对任何不在白名单内的ip请求强制执行流量限制。
环境:
四台虚拟机:
虚拟机1:服务器端。安装nginx充当真正的web服务。
虚拟机2:代理服务器。安装nginx,配置代理功能,流量限制功能和白名单功能。
虚拟机3:充当白名单里允许的客户端,访问代理服务器,验证白名单流量限制。
虚拟机3:充当白名单以外的客户端,访问代理服务器,验证白名单流量限制。
虚拟机1
与上文的基于代理的流量限制一样,这里不再赘述。
虚拟机2
与上文的基于代理的流量限制一样,只需修改主配合文件nginx.conf
这个例子同时使用了geo和map指令。geo块将给在白名单中的IP地址对应的 $ limit变量分配一个值0,给其它不在白名单中的分配一个值1。然后我们使用一个map映射将这些值转为key,如下:
如果$ limit变量的值是0,$ limit_key变量将被赋值为空字符串
如果$ limit变量的值是1,$ limit_key变量将被赋值为客户端二进制形式的IP地址
两个指令配合使用,白名单内IP地址的$limit_key变量被赋值为空字符串,不在白名单内的被赋值为客户端的IP地址。当limit_req_zone后的第一个参数是空字符串时,不会启用“流量限制”功能,所以虚拟机3:192.168.58.155不会被限制。其它所有IP地址都会被限制到每秒只能有1个请求。
重新加载nginx的配置文件
[root@localhost ~]# nginx -s reload
虚拟机3
快速多次访问代理服务器虚拟机2,验证基于白名单的流量限制
虚拟机4
快速多次访问代理服务器虚拟机2,验证基于白名单的流量限制