Nginx应用与运维——Nginx HTTP模块详解(访问控制功能模块)

Nginx HTTP模块详解

2、访问控制功能模块

2.1、访问镜像模块

模块名称:ngx_http_mirror_module

该模块的功能是将用户的访问请求镜像复制到指定的URI,通过location的URI匹配将流量发送到指定的服务器。用户请求的实际请求响应通过Nginx返回客户端,镜像服务器的请求响应则会被Nginx服务器丢弃。镜像请求与实际请求是异步处理的,对实际请求无影响。该模块的内置配置指令如表所示。

2.1.1、访问镜像指令------mirror

配置样例如下:

bash 复制代码
server {
    listen 8080;
    root /opt/nginx-web/www;
    location / {
        mirror /benchmark;
        index index.html;
    }

    location = /benchmark {
        internal;
        proxy_pass http://192.168.2.145$request_uri;
    }
}
2.1.2、镜像请求体指令------mirror_request_body

配置样例如下:

bash 复制代码
server {
    listen 8080;
    server_name localhost;
    root /opt/nginx-web/www;
    mirror_request_body off;
    location / {
        index index.html;
        mirror /accesslog;
    }

    location = /accesslog {
        internal;
        proxy_pass http://192.168.2.145/accesslog/${server_name}_$server_port$request_uri;
    }
}
  • 如果该指令值为off则不同步请求体。

配置样例如下:

bash 复制代码
server {
    listen 8080;
    root /opt/nginx-web/www;
    location / {
        mirror /benchmark; # 镜像用户请求
        mirror /benchmark; # 镜像用户请求
        mirror /benchmark; # 镜像用户请求
        index index.html;
    }

    location = /benchmark {
        internal;
        proxy_pass http://192.168.2.145$request_uri;
    }
}
  • 访问镜像模块可以将用户请求同步镜像到指定的服务器,同时还可以对用户的流量进行放大,通常可以在镜像线上流量后进行压力测试或预生产环境验证。

2.2、referer请求头控制模块

模块名称:ngx_http_referer_module

referer请求头控制模块可以通过设置请求头中的属性字段Referer的值控制访问的拒绝与允许。Referer字段用来表示当前请求的跳转来源,由于该字段可能会涉及隐私权问题,部分浏览器允许用户不发送该属性字段,因此也会存在浏览器正常的请求头中无Referer字段的情况。另外,有些代理服务器或防火墙也会把Referer字段过滤掉。通常情况下,伪造Referer字段的内容是很容易的,因此该模块主要用于浏览器正常发送请求中Referer值的过滤。虽然通过Referer字段进行来源控制并不十分可靠,但用在防盗链的场景中还是基本可以满足需求的。该模块的内置配置指令如表所示。

  • referer哈希表大小指令
  • referer哈希桶大小指令
  • 有效referer值指令

referer指令值参数如表所示。

配置样例如下:

bash 复制代码
server{
    listen 8080;
    server_name nginxtest.org;
    root /opt/nginx-web/www;
    valid_referers none blocked *.nginxtest.org; 
         # 当Referer为空或内容不包含"http://"或以"https://"开头的主机名为"*.nginxtest.
        # org"时允许访问
    if ($invalid_referer) {
        return 403;
    }
}
  • 指令值为字符串时,既可以是包含前缀或后缀的主机名,也可以是包含主机名的URI。
  • 指令值为正则表达式时,必须以~开头,Nginx将从"http://"或"https://"之后的字符串开始匹配。
  • 默认变量$invalid_referer的值为1,当Referer的值与指令值的内容匹配时,$invalid_referer的值为空。

2.3、连接校验模块

模块名称:ngx_http_secure_link_module

该模块的功能是与实际HTTP应用程序(PHP或Java等动态应用程序)相结合,实现对用户的访问连接做校验和过期验证的功能。常用于访问及文件下载的防盗链的实现。该模块的内置配置指令如表所示。

  • 连接校验参数指令
  • 连接校验MD5指令

该模块功能的实现原理如下:

  • HTTP应用程序计算出唯一的MD5字符串和过期时间。
  • HTTP应用程序把计算出的MD5字符串和过期时间以参数的形式与被限制的真实连接组成新的访问连接。
  • 用户单击有MD5字符串和过期时间参数的连接后,请求Nginx服务器。
  • Nginx通过secure_link指令获取用户访问连接中的MD5字符串和过期时间的值。
  • Nginx校验过期时间是否过期,当被判断为过期时,设置模块内置参数$secure_link的值为0。
  • Nginx把MD5字符串与secure_link_md5指令指定格式生成的MD5值进行比对,在过期时间内,当MD5被判断为一致时,设置模块内置参数$secure_link的值为1。
  • 模块内置参数$secure_link的值默认为空。

HTTP服务器代码(PHP)配置样例如下:

php 复制代码
<?php
$secret = 'nginxtest';                                         // 定义密钥
$path   = "/download/test.zip";                                // 被保护的真实连接
$expire = time()+10;                                          // 访问超时时间是10s
$md5 = base64_encode(md5($secret . $path . $expire, true));  // 将访问密钥、访问路径、超时时
                                                             // 间加密
$md5 = strtr($md5, '+/', '-_');                               // 特殊字符"+"和"/"的处理
$md5 = str_replace('=', '', $md5);                            // 特殊字符"="的处理
$url = "http://".$_SERVER['HTTP_HOST']."$path?valid=$md5&time=$expire"; // 新的访问连接
echo '<a href="'.$url.'" >test.zip</a>';

?>

Nginx配置样例如下:

bash 复制代码
server{
    listen 8083;
    root /opt/nginx-web/phpweb;

    location ~ \.php(.*)$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;

        fastcgi_split_path_info       ^(.+\.php)(.*)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        include        fastcgi.conf;
    }    

    location /download/ {
        alias /opt/nginx-web/files/;
        secure_link $arg_valid,$arg_time;       # 设置MD5及过期时间的参数为valid和time
        secure_link_md5 nginxtest$uri$arg_time; # MD5计算格式
        if ( $secure_link = "" ) {
                return 403;
        }
        if ( $secure_link = "0" ) {
                return 405;
        }
    }
}

2.4、源IP访问控制模块

模块名称:ngx_http_access_module

该模块可以对客户端的源IP地址进行允许或拒绝访问控制。该模块的内置配置指令如表所示。

  • 允许访问指令
  • 拒绝访问指令

    配置样例如下:
bash 复制代码
location / {
    deny  192.168.1.1;          # 禁止192.168.1.1
    allow 192.168.0.0/24;       # 允许192.168.0.0/24的IP访问
    allow 10.1.1.0/16;          # 允许10.1.1.0/16的IP访问
    allow 2001:0db8::/32;
    deny  all;
}
  • Nginx按照自上而下的顺序进行匹配。

2.5、基本认证模块

模块名称:ngx_http_auth_basic_module

该模块允许使用基于"HTTP基本认证"协议的用户名和密码对客户端访问请求进行控制。该模块的内置配置指令如表所示。

  • 基本认证指令
  • 基本认证用户文件指令

密码文件格式如下:

bash 复制代码
# comment
name1:password1
name2:password2:comment
name3:password3

配置样例如下:

bash 复制代码
location / {
    auth_basic           "closed site";     # 认证提示
    auth_basic_user_file conf.d/htpasswd;   # 认证密码文件conf.d/htpasswd
}
  • 当auth_basic的指令值为off时,可以对当前指令域取消来自上一层指令域的auth_basic配置。
  • 用户密码可以用Apache中的htpasswd命令生成。

2.6、认证转发模块

模块名称:ngx_http_auth_request_module

认证转发模块允许将认证请求转发给指定的服务器进行处理。启用认证转发后,会将认证需求以子请求的方式转发给指定的服务器,并通过子请求的返回结果判断客户端的认证授权。如果子请求返回响应码2××,则允许授权访问;若返回响应码401或403,则拒绝访问。该模块的内置配置指令如表所示。

  • 认证转发指令

    auth_request启用时,需要指定一个内部子请求的URI。

  • 认证请求变量设置指令

    配置样例如下:

    bash 复制代码
    upstream member_server {
        server 172.16.1.13:8080;
    }
    
    server {
        listen       8080;
        server_name  localhost;
    
        location / {
            root   /opt/nginx-web;
            index  index.html index.htm;
        }
    
        location /member {
            auth_request /auth;                       # 启用认证转发到/auth
            error_page 401 = @error401;               # 认证若返回状态码401,则跳转到@error401
    
        #    auth_request_set $user $upstream_http_x_forwarded_user; # 将用户名赋予变量$user
        #    proxy_set_header X-Forwarded-User $user; # 将用户名传递给应用服务
            proxy_pass http://member_server;          # 代理转发到会员服务
        }
    
        location /auth {
            internal;
            proxy_set_header Host $host;
            proxy_pass_request_body off;
            proxy_set_header Content-Length "";
            proxy_pass http://172.16.10.14/auth;      # 将认证信息转发到http://172.16.10.14/auth
        }
    
        location @error401 {
                return 302 http://172.16.10.14/login; # 认证失败跳转到登录页
        }
    }

认证请求变量设置指令同样支持基本认证的转发。当客户端发起请求时,Nginx会将具有WWW-Authenticate的子请求头响应信息转发给客户端,提示用户输入账号、密码。用户的用户名和密码信息通过Base64编码后写在子请求的请求头中发送给认证请求的服务器,认证服务器解码后返回相应的响应状态码。配置样例如下:

bash 复制代码
server {
    listen 8083;
    server_name localhost;
    root /opt/nginx-web;
    auth_request /auth;

    location / {
        index  index.html index.htm;
    }

    location /auth {
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
        proxy_pass http://192.168.2.145:8080/HttpBasicAuth.php;
    }
}

HttpBasicAuth.php的配置样例如下:

php 复制代码
<?php

if(isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])){
    $user = $_SERVER['PHP_AUTH_USERv];
    $passwd = $_SERVER['PHP_AUTH_PW'];

    if ($user == 'admin' && $passwd == v111111'){
        return true;
    }
}

header('WWW-Authenticate: Basic realm="BasicAuth Test"');
header('HTTP/1.0 401 Unauthorized');

?>

2.7、用户cookie模块

模块名称:ngx_http_userid_module

用户cookie模块的作用是为客户端设置cookie以标识不同的访问用户。可以通过内部变量$uid_got和$uid_set记录已接收和设置的cookie。该模块的内置配置指令如表所示。

  • 用户cookie指令

    • 当指令值为off时,关闭用户cookie接收和记录功能。
    • 当指令值为on时,启用用户cookie接收和记录功能,默认为v2版本设置cookie。设置cookie的响应头标识为Set-Cookie2。
    • 当指令值为v1时,使用v1版本设置cookie,设置cookie的响应头标识为Set-Cookie。
    • 当指令值为log时,不设置用户cookie,但对接收到的cookie进行记录。
  • 用户cookie域指令
  • 用户cookie过期指令
  • 用户cookie标识指令
    • 用作标记的指令值可以是任意英文字母(区分大小写)、数字或"="。
    • userid_mark设置完成后,将与用户cookie中传送的Base64格式的标识的第一个字符进行比较,如果不匹配,则重新发送用户标识、userid_p3p及cookie的过期时间。
  • 用户cookie名称指令
  • 用户p3p指令

    P3P是W3C推荐的隐私保护标准,P3P头属性字段通常用于解决与支持P3P协议的浏览器的跨域访问问题。
  • 用户cookie路径指令
  • 用户cookie源服务器指令

配置样例如下:

bash 复制代码
server {
    listen 8083;
    server_name example.com;
    root /opt/nginx-web;

    auth_request /auth;

    userid         on;
    userid_name    uid;
    userid_domain  example.com;
    userid_path    /;
    userid_expires 1d;
    userid_p3p     'policyref="/w3c/p3p.xml", CP="CUR ADM OUR NOR STA NID"';

    location / {
        index  index.html index.htm;
        add_header    Set-Cookie "username=$remote_user";
    }
    location /auth {
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
        proxy_pass http://192.168.2.145:8080/HttpBasicAuth.php;
    }
}

2.8、并发连接数限制模块

模块名称:ngx_http_limit_conn_module

该模块对访问连接中含有指定变量且变量值相同的连接进行计数,指定的变量可以是客户端IP地址或请求的主机名等。当计数值达到limit_conn指令设定的值时,将会对超出并发连接数的连接请求返回指定的响应状态码(默认状态码为503)​。该模块只会对请求头已经完全读取完毕的请求进行计数统计。由于Nginx采用的是多进程的架构,该模块通过共享内存存储计数状态以实现多个进程间的计数状态共享。该模块的内置配置指令如表所示。

  • 计数存储区指令
  • 连接数设置指令
  • 连接数日志级别指令
  • 连接数状态指令

配置样例如下:

bash 复制代码
limit_conn_zone $binary_remote_addr zone=addr:10m;  # 对用户IP进行并发计数,将计数内存区命
                                                    # 名为addr,设置计数内存区大小为10MB
server {
    location /web1/ {
        limit_conn addr 1;                          # 限制用户的并发连接数为1
    }
}
  • limit_conn_zone的格式为limit_conn_zone keyzone=name:size。
  • limit_conn_zone的key可以是文本、变量或文本与变量的组合。
  • $binary_remote_addr为IPv4时占用4B,为IPv6时占用16B。
  • limit_conn_zone中1MB的内存空间可以存储32 000个32B或16 000个64B的变量计数状态。
  • 变量计数状态在32位系统平台占用32B或64B,在64位系统平台占用64B。
  • 并发连接数同样支持多个变量的同时统计,配置样例如下:
bash 复制代码
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}

2.9、请求频率限制模块

模块名称:ngx_http_limit_req_module

该模块会对指定变量的请求次数进行计数,当该变量在单位时间内的请求次数超过设定的数值时,后续请求会被延时处理,当被延时处理的请求数超过指定的队列数时,将返回指定的状态码(默认状态码为503)​。通常该模块被用于限定同一IP客户端单位时间内请求的次数。该模块通过共享内存存储计数状态以实现多个工作进程间的同一变量计数状态的共享。该模块的内置配置指令如表所示。

  • 计数存储区指令
  • 请求限制设置指令
  • 请求限制日志级别指令
  • 请求限制状态指令

配置样例如下:

bash 复制代码
http {
    limit_req_zone $server_name zone=addr:10m rate=1r/s; 
                # 限制访问当前站点的请求数,对站点请求计数,将计数内存区命名为addr,
                # 设置计数内存区大小为10MB,请求限制为1秒1次
    server {
        location /search/ {
            limit_req zone=one;        
                # 同一秒只接收一个请求,其余的立即返回状态码503,直到第2秒才接收新的请求
            limit_req zone=one burst=5; 
                # 同一秒接收6个请求,其余的返回状态码503,只处理一个请求,其余5个请求进入队
          # 列,每秒向Nginx释放一个请求进行处理,同时允许接收一个新的请求进入队列
            limit_req zone=one burst=5 nodelay;  
                # 同一秒接收6个请求,其余的返回状态码503,同时处理6个请求,6秒后再接收新的请求
        }
    }
}
  • limit_req_zone的rate参数的作用是对请求频率进行限制,有r/s(每秒的请求次数)和r/m(每分钟的请求次数)两个频率单位,也可根据每秒的次数换算成毫秒单位的次数。1MB内存大小大约可以存储16 000个IP地址的状态信息。
  • limit_req的burst参数相当于一个缓冲容器,该容器内可容纳burst所设置的数量的请求,没有nodelay参数时,将匀速向Nginx释放需要处理的请求。未进入burst容器队列的请求将被返回状态码503或由limit_req_status指令指定的状态码。
  • limit_req的nodelay参数是指对请求队列中的请求不进行延时等待,而是立即处理。
  • 请求频率同样支持多个变量的同时计数及叠加,配置样例如下:
bash 复制代码
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;   

server {
    ...
    limit_req zone=perip burst=5 nodelay;
    limit_req zone=perserver burst=10;
}
相关推荐
Ruiery2 小时前
Linux 6.6内核 CPU 深度解析(一):BSP 拉起 — 从实模式到 kernel_init 的完整旅程
linux·运维·服务器
赵民勇2 小时前
dconf命令详解
linux·运维
代码方舟2 小时前
零信任架构实战:基于天远学历信息高级版构建自动化智库入驻审查网关
运维·人工智能·架构·自动化
和裕2 小时前
年度框架直供 vs 零散按需采购:定制纸箱采购成本、交付与服务核心区别全对比
大数据·运维·网络·人工智能·算法
qeen873 小时前
【Linux】Linux环境下的进程终止与进程等待问题
linux·运维·服务器
机核研创社4 小时前
短裤自动化工序与设备清单:十个点位、三项技术要点与选型裁决顺序
运维·自动化
尹人入圣4 小时前
市面上IP驱动产业新场景新工具
运维·网络·python·tcp/ip
JieDavid6 小时前
奇智创达知识产权管理系统期限监控模块实操,告别人工期限疏漏,实现管理闭环!
大数据·运维·人工智能·经验分享·重构
wuyk5556 小时前
Python网络爬虫入门到实战 第02章:HTTP/HTTPS协议超通俗精讲(GET/POST、请求头、响应码、爬虫核心基础)
爬虫·python·http