Nginx 如何限流和访问控制(详解)

前言

一、Nginx限流

1、简介

主要是当访问量达到一个限制量的时候可以选择以服务器为主要,而选择对用户访问请求的量做限制,对于超出限制的用户请求会采取丢弃或者延迟处理等方式处理,来保证更多用户来访问处理。

比如:某一服务器正常在高峰期上能支持的访问量是1w,但是突然某一时刻在访问量上突然暴增一下子超过3w,5w则可能会导致服务器宕机,这个时候我们 就可以通过设置最大的访问如1分钟访问8000次。

也可以防止攻击(对同一个ip每秒访问多少次)如:30min/次。

对应模块

  • limit_conn_module 限制连接数
  • limit_req_module 限制请求频率

2、关于 limit_req 和 limit_conn 的区别

limit_reqlimit_conn两个模块都是为了来限流的,但是两者不在一个层面,为了搞清楚这个,必须先要弄清楚requestconnection的区别,因为在很多情况下,我们把他们混淆了。

  • connection是连接,即常说的tcp连接,通过三次握手而建立的一个完整状态机。建立一个连接,必须得要三次握手。

  • request是指请求,即http请求,(注意,tcp连接是有状态的,而构建在tcp之上的http却是无状态的协议)。

通过打开一个网页,然后通过wireshark可以看到,一个连接建立后(即三次握手后),在这个连接断开之前(即四次挥手之前),会有很多的 http request,

这就是它们的区别:即一个连接的生命周期中,会存在一个或者多个请求,这是为了加快效率,避免每次请求都要三次握手建立连接,现在的HTTP/1.1协议都支持这种特性,称为长连接(keepalive)。

3、limit_conn 模块

通过 limit_zone 模块来达到限制用户的连接数的目的,即限制同一用户 IP 地址的并发连接数。
在这里插入图片描述
对于提供下载的网站,肯定是要进行流量控制的。Nginx 通过 core模块的 limit_rate 等指令可以做到限流的目的。

在这里插入图片描述

(1)limit_conn_zone
语法:limit_conn_zone key zone=name:size;
默认:no
区域:http
功能:该指令定义一个 zone,该 zone 存储会话的状态。

说明:

  • key 是 Nginx 中的变量,通常为 binaryremoteaddr|server_name;
  • name 为共享内存的名称,size 为该共享内存的大小;此配置会申请一块共享内存空间 name,并且保存 key 的访问情况。
(2)limit_conn
语法:limit_conn zone_name number
配置上下文:http,server,location

说明:

  • 使用 zone_name 进行访问并发控制,当超过 number 时返回对应的错误码
(3)limit_conn_log_level
语法:limit_conn_log_level info|notice|warn|error
默认值:error
配置上下文:http,server,location

说明:

  • 当访问达到最大限制之后,会将访问情况记录在日志中
(4)limit_conn_status code
语法:limit_conn_status code
默认值:503
配置上下文:http,server,location

说明:

  • 当访问超过限制 number 时,给客户端返回的错误码,此错误码可以配合 error_page 等参数,在访问超量时给客户返回友好的错误页面
(5)limit_rate
语法:limit_rate speed;
默认值:no
使用环境:http、server、location
示例: limit_rate 512k;

说明:

  • 对每个链接的速率进行限制,rate 表示每秒的下载速度;
(6)limit_rate_after
语法:limit_rate_after size;
默认值:limit_rate_after 1m;
使用环境:http、server、location
示例:limit_rate_after 3m;

说明:

  • 此命令和 limit_rate 配合,当流量超过 size 之后,limit_rate 才开始生效
(7)实例
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
  listen    80;
  server_name www.domain.com;
  root  /path/;
  index index.html index.htm;
  location /ip {
   limit_conn_status 503; # 超限制后返回的状态码;
   limit_conn_log_level warn; # 日志记录级别
   limit_rate 50; # 带宽限制
   limit_conn addr 1; # 控制并发访问
  }
  # 当超过并发访问限制时,返回503错误页面
  error_page 503 /503.html;
}

4、limit_req 模块

使用 ngx_http_limit_req_module 模块可以 限制某一 IP 在一段时间内对服务器发起请求的连接数,该模块为用来做流量控制

(1)流量控制的概念

流量限制 (rate-limiting),它可以用来限制客户端在指定时间内 HTTP 请求的数量。请求可以是GET 请求,也可以是登录表单的 POST 请求。

流量限制可以用作安全目的,如减慢暴力密码破解速率等。通过将传入请求的速率限制为真实用户的典型值,并标识目标 URL 地址(通过日志),还可以用来抵御 DDOS 攻击,该功能可以用来保护上游应用服务器不被同时太多用户请求所压垮。

Nginx 流量限制使用漏桶算法(leaky bucket algorithm),漏桶算法在通讯和分组交换计算机网络中广泛使用,用于处理带宽有限时的突发情况。
在这里插入图片描述

  • limit_req_zone指令定义了流量限制相关的参数
  • limit_req指令在出现的上下文中启用流量限制。

在这里插入图片描述

该模块主要控制单位时间内的请求数。使用 “leaky bucket” (漏斗)算法进行过滤,在设置好限制 rate 之后,当单位时间内请求数超过 rate 时,模块会检测 burst 值,如果值为0,则请求会依据 delay|nodelay 配置返回错误或者进行等待;如果 burst 大于0时,当请求数大于 rate 但小于 burst 时,请求进入等待队列进行处理。

(1)limit_req_zone
语法:limit_req_zone key zone=name:size rate=rate
配置上下文:http

说明:

  • key 是 Nginx 中的变量,通常为 binary_remote_addr | server_name
  • name 为共享内存的名称,size 为该共享内存的大小;
  • rate 为访问频率,单位为 r/s 、r/m 。此配置会申请一块共享内存空间 name,并且保存 $key 的访问情况;
(2)limit_req
语法: limit_rate zone=name [burst=number] [nodelay|delay=number]
配置上下文:http,server,location

说明:

  • 开启限制,burst设置最多容量,nodelay决定当请求超量时,是等待处理还是返回错误码;
(3)实例
limit_req_zone $binary_remote_addr zone=req:10m rate=2r/m;
server {
  listen    80;
  server_name www.domain.com;
  root  /path/;
  index index.html index.htm;
  location /limit {
   limit_req zone=req burst=3 nodelay;
  }
  # 当超过并发访问限制时,返回503错误页面
  error_page 503 /503.html;
}

注意

这两种访问控制都需要申请内存空间,既然有内存空间,当然会存在内存耗尽的情况,这时新的请求都会被返回错误,所以当开启访问量限制时,需要通过监控防止此类情况发生。

5、处理突发

(1)为什么要使用burst

如果我们在1000毫秒内接收到2个请求,怎么办?对于第二个请求,Nginx将给客户端返回错误。这可能并不是我们想要的结果,因为应用本质上趋向于突发性。

相反地,我们希望缓冲任何超额的请求,然后及时地处理它们。我们更新下配置,在limit_req中使用burst参数。

(2)实例

在这里插入图片描述

burst参数定义了超出zone指定速率的情况下(示例中的addr区域,速率限制在每秒1个请求),客户端还能发起多少请求。上一个请求1000毫秒内到达的请求将会被放入队列,我们将队列大小设置为5。

这意味着,如果从一个给定IP地址发送6个请求,Nginx会立即将第一个请求发送到上游服务器群,然后将余下5个请求放在队列中。然后每1000毫秒转发一个排队的请求,只有当传入请求使队列中排队的请求数超过5时,Nginx才会向客户端返回错误。

6、配置流量控制相关功能

(1)配置日志记录

默认情况下,Nginx会在日志中记录由于流量限制而延迟或丢弃的请求,如下所示:

2019/02/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, request: "GET / HTTP/1.0", host: "nginx.com"

日志条目中包含的字段:

  • limiting requests - 表明日志条目记录的是被“流量限制”请求
  • excess - 每毫秒超过对应“流量限制”配置的请求数量
  • zone - 定义实施“流量限制”的区域
  • client - 发起请求的客户端IP地址
  • server - 服务器IP地址或主机名
  • request - 客户端发起的实际HTTP请求
  • host - HTTP报头中host的值

默认情况下,Nginx以error级别来记录被拒绝的请求,如上面示例中的[error]所示(Nginx以较低级别记录延时请求,一般是info级别)。如要更改Nginx的日志记录级别,需要使用limit_req_log_level指令。这里,我们将被拒绝请求的日志记录级别设置为warn一定要定义日志位置和级别才可以

  • 错误日志级别设置为warn
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x230pEwh-1628934608040)(assets/1583466862249.png)]

  • limit_req_log_level日志级别设置为warn
    在这里插入图片描述

  • 继续访问测试,看error.log日志
    在这里插入图片描述

(2)发送到客户端的错误代码

一般情况下,客户端超过配置的流量限制时,Nginx响应状态码为503(Service Temporarily Unavailable)。可以使用limit_req_status指令来设置为其它状态码(例如下面的404状态码):

  • 修改配置文件
    在这里插入图片描述

  • 修改前
    在这里插入图片描述

  • 修改后
    在这里插入图片描述

二、访问控制

1、Nginx访问控制模块类型

  • 基于IP的访问控制:http_access_module
  • 基于用户的信任登录:http_auth_basic_module

2、基于IP模块

配置语法:

Syntax:allow address | CIDR | unix: | all;
default:默认无
Context:http,server,location

Syntax:deny address | CIDR | unix: | all;
default:默认无
Context:http,server,location

配置设置:

#vim /etc/nginx/conf.d/access_mod.conf  //修改配置文件

  server {
           listen 80;
           server_name localhost;
           location ~ ^/admin {
                  root /home/www/html;
                  index index.html index.hml;
                  deny 192.168.239.128;      //拒绝192.168.239.128访问
                  allow all;
           }
  }
 #如果先允许访问,在定义拒绝访问,那么拒绝访问不生效。

3、location拒绝所有请求

server {
        listen 80;
        server_name localhost;
        location /foo.html {
             root /home/www/html;
             deny all;
        }
}

4、用户的信任登录

Syntax:auth_basic string | off;
default:auth_basic off;
Context:http,server,location,limit_except

Syntax:auth_basic_user_file file;
default:默认无
Context:http,server,location,limit_except
file:存储用户名密码信息的文件。

配置实例

#mv access_mod.conf auth_mod.conf   //修改配置文件
server {
        listen 80;
        server_name localhost;
        location ~ ^/admin {
           root /home/www/html;
           index index.html index.hml;
           auth_basic "Auth access test!";
           auth_basic_user_file /etc/nginx/auth_conf;
        }
}
#auth_basic不为off,开启登录验证功能,auth_basic_user-file加载账号密码文件

建立口令文件

$ mkdir /home/www/html/admin -p
$ vim /home/www/html/admin/index.html
hello boy
$ yum -y install httpd-tools    //htpasswd使开源http服务器apache httpd的一个命令工具,用于生成http基本认证的密码文件
$ htpasswd -cm /etc/nginx/auth_conf user1   //第一次创建用户
$ htpasswd -m  /etc/nginx/auth_conf user2   //第二次创建用户
$ cat /etc/nginx/auth_conf    //查看创建的用户的密码
user1:$apr1$MOa9UVqF$RlYRMk7eprViEpNtDV0n40
user2:$apr1$biHJhW03$xboNUJgHME6yDd17gkQNb0

5、访问测试

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值