zoukankan      html  css  js  c++  java
  • nginx 请求限制和访问控制

    请求限制

    限制主要有两种类型:

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

    HTTP协议的连接与请求

    HTTP协议是基于TCP的,如果要完成一次HTTP请求的时候,首先进行TCP的三次握手。当建立连接的时候就可以进行请求和响应。

    可以得到结论:
    HTTP请求建立在一次TCP连接基础上,一次TCP请求至少产生一次HTTP请求(可以有多个)

    对于 limit_conn_module模块

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

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

    对于连接限制的配置:

    • Syntax: limit_conn_zone key zone=name:size;
    • Default: —
    • Context: http
    • Syntax: limit_conn zone number;
    • Default: — Context: http, server, location

    对于第一部分可以理解在内存中开辟一个区域对于指定的nginx变量(key,例如:binary_remote_addr)进行限制。name表示申请的空间的名字,size表示申请空间的大小。

    对于第二部分zone就是第一部分设置的名字name,number表示进行并发的限制。例如设置为1,表示一个时间段只能有一个。

    对于ngx_http_limit_req_module模块:

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

    对于请求限制的配置:

    • Syntax: limit_req_zone key zone=name:size rate=rate;
    • Default: —
    • Context: http
    • Syntax: limit_req zone=name [burst=number] [nodelay];
    • Default: —
    • Context: http, server, location

    对于第一部分配置和连接配置相似,rate表示速率,以秒s为单位(rate=1r/s)
    对于第二部分zone就是第一部分设置的名字name,[]内为可配置选项。

    实例:
    首先编写配置文件 default.conf

        limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
        limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
    server {
        listen       80;
        server_name  localhost;
    
        #charset koi8-r;
        #access_log  /var/log/nginx/log/host.access.log  main;
    
    
        location / {
            root /opt/app/code;
            #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;
        }
    

      

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

    保存重新加载

    使用 ab 进行压力测试

    ab -n 40 -c 20 http://192.168.1.112/
    

    可以看到40 个都连接成功

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

     

    再次进行测试

    ab -n 40 -c 20 http://192.168.1.112/

    可以发现只成功了一次

    访问控制

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

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

    对于http_access_module模块:

    模块允许限制访问某些客户端地址。访问也可以通过密码子请求结果或JWT来限制满足控制地址和密码的同时访问限制。

    配置语法:

    • Syntax: allow address | CIDR | unix: | all;
    • Default: —
    • Context: http, server, location, limit_except
    • Syntax: deny address | CIDR | unix: | all;
    • Default: —
    • Context: http, server, location, limit_except

    语法中address表示地址,CIDR表示网段。unix:指定了特殊值,则允许访问所有UNIX域套接字。all表示所有的。

    实例:配置访问控制
    首先我们查看没有限制的时候进行的输出

    编辑配置文件

    location ~ ^/admin.html {
            root   /opt/app/code;
            deny 192.168.1.6;
            allow all;
            index  index.html index.htm;
        }
    

    其中 ~ 表示对请求路径URL模式匹配,表示跟目下以1.html开头的家目录设置在/opt/app/code。

    然后检查配置重启

    nginx -tc /etc/nginx/nginx.conf 
    systemctl reload nginx
    

    重新访问我们的页面  

     

    现在配置只有本机可以访问

        location ~ ^/admin.html {
            root   /opt/app/code;
            allow 192.168.1.0/24;
            deny all;
            index  index.html index.htm;
        }

    然后检查配置重启 

    nginx -tc /etc/nginx/nginx.conf 
    systemctl reload nginx
    

      

    重新访问我们的页面 

     

    http_access_module模块的局限性:

    nginx的访问控制限制是针对客户端的IP来进行限制的,但是nginx并不确定真正的客户端是哪个,凡是和nginx进行交互的都被当做是客户端。(remote_addr是直接和nginx通信的IP)如果我们访问不是直接访问到服务端而是由中间代理进行(如上图),访问控制这时就会失效。

    局限性解决方法总结:

    方法一: 采用http头信息控制访问,如HTTP_X_FORWARD_FOR
    方法二: 结合geo模块
    方法三: 通过HTTP自定义变量传递

    http_x_forwarded_for头信息控制访问 会更好的解决该问题,它要求访问时必须带上所有用到的ip的地址信息
    我们看一下http_x_forwarded_for记录过程:

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

    http_auth_basic_module模块

    配置语法

    • 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

    语法讲解:
    auth_basic 默认关闭,开启的话输入一段字符串即可。
    auth_basic_user_file 该文件存储用户账号密码。

    我们看一下官网的文件格式

    # comment
    name1:password1
    name2:password2:comment
    name3:password3
    

    详细官方链接

    密码加密方式有多中这里我们使用htpasswd  

    can be generated using the “htpasswd” utility from the Apache HTTP Server distribution or the “openssl passwd” command

    想要使用该方式,首先要装对应的包 

    yum -y install httpd-tools
    

    接下来创建对应的use_file文件  

    htpasswd -c ./auth_conf zhangbiao
    

    编辑配置文件
        location ~ ^/admin.html {
            root   /opt/app/code;
        auth_basic "Auth access test! input your password!";
        auth_basic_user_file /etc/nginx/auth_conf;
            index  index.html index.htm;
        }
    

      

    进行语法检查

    nginx -tc /etc/nginx/nginx.conf
    systemctl reload nginx
    

    现在我们再次访问页面的时候就需要输入用户名密码  

    输入刚才的账号密码就可以正常访问了。

    局限性:

    一: 用户信息依赖文件
    二: 操作管理机械,效率低

    解决方式:

    一: nginx结合LUA实现高效验证
    二: nginx配合LDAP打通,利用nginx-auth-ldap模块

  • 相关阅读:
    模-数(A/D)转换器
    数-模(D/A)转换器
    VIM 常用命令
    Linux常用命令
    一个开关电源传导、辐射处理案例-----Layout环路
    解决:PADS导入.DXF结构图出现坐标超出范围问题
    Python3-threading模块-多线程
    Python3-socketserver模块-网络服务器框架
    Python3-socket模块-低级网络接口
    Python3-面向对象
  • 原文地址:https://www.cnblogs.com/crazymagic/p/11012991.html
Copyright © 2011-2022 走看看