Linux Nginx服务器 连接限制 访问控制

一、Nginx的请求限制

1.1 请求限制

限制主要有两种类型:

  • 连接限制: limit_conn_module
  • 请求限制: limit_req_module

对于连接限制 limit_conn_module模块

该ngx_http_limit_conn_module模块用于限制每个定义的密钥的连接数量,特别是来自单个IP地址的连接数量。

并非所有连接都被计算在内 ,只有在服务器处理请求并且已经读取了整个请求头时才计算连接。

  • 连接频率限制的配置:
Syntax: limit_conn_zone key zone=name:size;
Default: 
Context: http
	#可理解在内存中开辟一个区域对于指定的nginx变量(key,例如:binary_remote_addr)进行限制。name表示申请的空间的名字,size表示申请空间的大小。
Syntax: limit_conn zone number;
Default:  
Context: http, server, location
	#第二部分zone就是第一部分设置的名字name,number表示进行并发的限制。例如设置为1,表示一个时间段只能有一个。

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 用法
http {
  # ...其它代码省略...
  # 开辟一个10m的连接空间,命名为addr
  limit_conn_zone $binary_remote_addr zone=addr:10m;
  server {
    ...
    location /download/ {
      # 服务器每次只允许一个IP地址连接
      limit_conn addr 1;
    }
  }
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

请求限制 ngx_http_limit_req_module模块

用于限制每一个定义的密钥的请求的处理速率,特别是从一个单一的IP地址的请求的处理速率。限制是使用“泄漏桶”方法完成的

  • 请求限制的配置:
    Syntax: limit_req_zone key zone=name:size rate=rate;
    Default: 
    Context: http
 #第一部分配置和连接配置相似,rate表示速率,以秒s为单位(rate=1r/s)   
    Syntax: limit_req zone=name [burst=number] [nodelay];
    Default: 
    Context: http, server, location
 #第二部分zone就是第一部分设置的名字name,[]内为可配置选项。   

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 用法
http { 
  # ...其它代码省略...  
  limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
  	#开辟一个10m的请求空间,命名为one。同一个IP发送的请求,平均每秒只处理一次
  	#$binary_remote_addr :表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址
	#zone=one:10m:表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
	#rate=1r/s:表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,即每秒只处理一个请求;比如30r/m的,即限制每2秒访问一次,即每2秒才处理一个请求。
  server {
      ... 
    location /search/ {
    	# 1s同一个客户端只允许连接一次
      limit_req zone=one;
      	# 当客户端请求超过指定次数,最多宽限3次请求,并延迟处理,11个请求
      # limit_req zone=one burst=3;
      	# 当客户端请求超过指定次数,最多宽限3次请求,并立即处理。
      # limit_req zone=one burst=3 nodelay;
    }
  }
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

1.2 连接限制的配置

1、vim /usr/local/nginx/conf/nginx.conf
在这里插入图片描述

2、添加

limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
	#  rate=1r/s每秒只能执行1次请求, 多的直接返回503错误。			
    server {
        listen       80;
        server_name  localhost;
		#charset koi8-r;
		#access_log  logs/host.access.log  main;
        location / {
            root   html;
            #limit_conn conn_zone 1;
            #limit_req zone=req_zone burst=3 nodelay;
            #limit_req zone=req_zone burst=3;
            #limit_req zone=req_zone; 
            index  index.html index.htm;
        }

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

我们看到上面为定义zone,第二行是请求定义,表示对远程请求进行每秒一次的请求限制。这里的binary_remote_addr和remote_addr代表的含义是一样的(远程主机的IP)只是使用binary_remote_addr存储一个IP会比remote_addr省10个字节。burst 参数往后延迟3个请求 nodelay 立即返回

3、进行语法检测 nginx -t, 重新加载 nginx -s reload

在这里插入图片描述
4、客户端测试:ab -n 40 -c 20 http://172.25.2.2/,共访问页面40次,一次产生请求的并发数为20.

在这里插入图片描述此时,我们可以看到40个访问都成功。

1)打开请求限制limit_req zone=req_zone,1s同一个客户端只允许连接一次

在这里插入图片描述再次在客户端测试,ab -n 40 -c 20 http://172.25.2.2/,我们可以看到只成功了1次,且1.015s就完成了压测。

在这里插入图片描述我们查看/usr/local/nginx/logs/access.log日志,看到只有一个请求成功,其他的都是直接返回503,即服务器拒绝了请求。

在这里插入图片描述

2)打开请求限制limit_req zone=req_zone burst=3,

burst=3:burst爆发,这个配置是设置一个大小为3的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,但是这个等待区里的位置只有3个,超过的请求会直接报503的错误然后返回。 在完成峰值请求之后,缓冲队列不能再放入请求。如果rate=1r/s,且这段时间内没有请求再到来,则每1s 缓冲队列就能恢复一个缓冲请求的能力,直到恢复到能缓冲3个请求位置。
在这里插入图片描述

再次在客户端测试,ab -n 40 -c 20 http://172.25.2.2/,我们可以看到请求只成功了4次,且3.003s才完成压测。

在这里插入图片描述我们查看/usr/local/nginx/logs/access.log日志,看到只有4个请求成功,其他的都是直接返回503,即服务器拒绝了请求。

  • 我们可观察到17分8秒时,即压测第1秒时,成功处理了1个请求,另外有36个请求瞬间返回了503,剩余的3个请求每隔1秒处理一次。这是因为设置了burst=3,在服务器接收到40个并发请求后,先处理1个请求,同时将3个请求放入burst缓冲队列中,等待处理。而超过burst等待区的数量的请求就被直接抛弃了,报错503然后直接返回。

在这里插入图片描述
此时,查看 /var/log/nginx/error.log日志,可以看到36个limiting request

在这里插入图片描述
3)打开请求限制limit_req zone=req_zone burst=3 nodelay,

nodelay: 如果设置,会在瞬时提供处理(burst + rate)个请求的能力,请求超过(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况。(这里的rate的单位是:r/s);如果没有设置,则所有请求会依次等待排队。

加brust=3和nodelay的情况下, 有一个容量为3的缓冲区, rate=1r/s每秒能执行4次请求, 4=1+3,多的直接返回503错误。
在这里插入图片描述

再次在客户端测试,ab -n 40 -c 20 http://172.25.2.2/,我们可以看到压测在0.031秒内就完成了。

在这里插入图片描述
我们查看/usr/local/nginx/logs/access.log日志,看到只有4个请求成功,其他的都是直接返回503。

  • 可以发现在1s内,服务器端处理了4个请求(峰值速度:burst+原来的处理速度)。对于剩下的36个请求,直接返回503,在下一秒如果继续向服务端发送40个请求,服务端会直接拒绝这40个请求并返回503。因为设定了每1s处理1个请求,所以直到3s 之后,才可以再处理一个请求,即如果此时向服务端发送40个请求,会返回39个503,一个200

在这里插入图片描述

二、Nginx的访问控制

nginx的访问控制主要分为两类:

  • 基于IP的访问控制 http_access_module
  • 基于用户的登录认证 http_auth_basic_module,此种方法我们不多解释。

对于http_access_module模块

  • 配置
Syntax:    allow address | CIDR | unix: | all;
Default:  
Context:  http, server, location, limit_except 
Syntax:    deny address | CIDR | unix: | all;
	# address:IP地址,例如:192.168.1.1
	# CIDR:例如:192.168.1.0/24;
	# unix:Socket方式
	# all:所有
Default:  
Context:  http, server, location, limit_except

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 用法
server {
  # ...其它代码省略...
  location ~ ^/index_1.html {
    root  /usr/share/nginx/html;
    deny 172.25.2.250; # 拒绝这个IP访问
    allow all; # 允许其他所有IP访问
  } 
  location ~ ^/index_2.html {
    root  /usr/share/nginx/html;
    allow 172.25.3.0/24; # 允许IP172.25.3.*访问
    deny all; # 拒绝其他所有IP访问
  }
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

编辑配置文件/usr/local/nginx/conf/nginx.conf
allow和deny会按照顺序, 从上往下, 找到第一个匹配规则, 判断是否允许访问, 所以一般把all放最后。
在这里插入图片描述此时,从物理机(172.25.2.250)访问,可以看到没有权限。
在这里插入图片描述
从另一台虚拟机(172.25.2.4)访问,可以访问。
在这里插入图片描述
http_access_module模块的局限性:
nginx的访问控制限制是针对客户端的IP来进行限制的,但是nginx并不确定真正的客户端是哪个,凡是和nginx进行交互的都被当做是客户端。(remote_addr是直接和nginx通信的IP)如果我们访问不是直接访问到服务端而是由中间代理进行(如nginx,CDN等),访问控制这时就会失效。

  • 局限性解决方法总结:

方法一: 采用http头信息控制访问,如HTTP_X_FORWARD_FOR。http_x_forwarded_for头信息控制访问 会更好的解决该问题,它要求访问时必须带上所有用到的ip的地址信息
http_x_forwarded_for记录过程:

http_x_forwarded_for = Client IP, Proxy(1)IP, Proxy(2)IP,...

  
  
  • 1

在这里插入图片描述

方法二: 结合geo模块
方法三: 通过HTTP自定义变量传递

发布了107 篇原创文章 · 获赞 0 · 访问量 1427

猜你喜欢

转载自blog.csdn.net/weixin_45029822/article/details/104655132