Nginx HTTP模块详解
- 2、访问控制功能模块
- 2.1、访问镜像模块
- 2.1.1、访问镜像指令——mirror
- 2.1.2、镜像请求体指令——mirror_request_body
- 2.2、referer请求头控制模块
- 2.3、连接校验模块
- 2.4、源IP访问控制模块
- 2.5、基本认证模块
- 2.6、认证转发模块
- 2.7、用户cookie模块
- 2.8、并发连接数限制模块
- 2.9、请求频率限制模块
2、访问控制功能模块
2.1、访问镜像模块
模块名称:ngx_http_mirror_module
该模块的功能是将用户的访问请求镜像复制到指定的URI,通过location的URI匹配将流量发送到指定的服务器。用户请求的实际请求响应通过Nginx返回客户端,镜像服务器的请求响应则会被Nginx服务器丢弃。镜像请求与实际请求是异步处理的,对实际请求无影响。该模块的内置配置指令如表所示。
2.1.1、访问镜像指令——mirror
配置样例如下:
server{listen8080;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
配置样例如下:
server{listen8080;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则不同步请求体。
配置样例如下:
server{listen8080;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指令值参数如表所示。
配置样例如下:
server{listen8080;server_name nginxtest.org;root /opt/nginx-web/www;valid_referers none blocked *.nginxtest.org;# 当Referer为空或内容不包含“http://”或以“https://”开头的主机名为“*.nginxtest.# org”时允许访问if($invalid_referer){return403;}}- 指令值为字符串时,既可以是包含前缀或后缀的主机名,也可以是包含主机名的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$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配置样例如下:
server{listen8083;root /opt/nginx-web/phpweb;location ~\.php(.*)${fastcgi_pass127.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和timesecure_link_md5 nginxtest$uri$arg_time;# MD5计算格式if($secure_link=""){return403;}if($secure_link="0"){return405;}}}2.4、源IP访问控制模块
模块名称:ngx_http_access_module
该模块可以对客户端的源IP地址进行允许或拒绝访问控制。该模块的内置配置指令如表所示。
- 允许访问指令
- 拒绝访问指令
配置样例如下:
location /{deny192.168.1.1;# 禁止192.168.1.1allow192.168.0.0/24;# 允许192.168.0.0/24的IP访问allow10.1.1.0/16;# 允许10.1.1.0/16的IP访问allow2001:0db8::/32;deny all;}- Nginx按照自上而下的顺序进行匹配。
2.5、基本认证模块
模块名称:ngx_http_auth_basic_module
该模块允许使用基于“HTTP基本认证”协议的用户名和密码对客户端访问请求进行控制。该模块的内置配置指令如表所示。
- 基本认证指令
- 基本认证用户文件指令
密码文件格式如下:
# commentname1:password1 name2:password2:comment name3:password3配置样例如下:
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。 - 认证请求变量设置指令
配置样例如下:upstream member_server{server172.16.1.13:8080;}server{listen8080;server_name localhost;location /{root /opt/nginx-web;index index.html index.htm;}location /member{auth_request /auth;# 启用认证转发到/autherror_page401=@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{return302http://172.16.10.14/login;# 认证失败跳转到登录页}}
认证请求变量设置指令同样支持基本认证的转发。当客户端发起请求时,Nginx会将具有WWW-Authenticate的子请求头响应信息转发给客户端,提示用户输入账号、密码。用户的用户名和密码信息通过Base64编码后写在子请求的请求头中发送给认证请求的服务器,认证服务器解码后返回相应的响应状态码。配置样例如下:
server{listen8083;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的配置样例如下:
<?phpif(isset($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'])){$user=$_SERVER['PHP_AUTH_USERv]; $passwd = $_SERVER['PHP_AUTH_PW']; if ($user == 'admin' && $passwd == v111111'){returntrue;}}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源服务器指令
配置样例如下:
server{listen8083;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采用的是多进程的架构,该模块通过共享内存存储计数状态以实现多个进程间的计数状态共享。该模块的内置配置指令如表所示。
- 计数存储区指令
- 连接数设置指令
- 连接数日志级别指令
- 连接数状态指令
配置样例如下:
limit_conn_zone$binary_remote_addrzone=addr:10m;# 对用户IP进行并发计数,将计数内存区命# 名为addr,设置计数内存区大小为10MBserver{location /web1/{limit_conn addr1;# 限制用户的并发连接数为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。
- 并发连接数同样支持多个变量的同时统计,配置样例如下:
limit_conn_zone$binary_remote_addrzone=perip:10m;limit_conn_zone$server_namezone=perserver:10m;server{... limit_conn perip10;limit_conn perserver100;}2.9、请求频率限制模块
模块名称:ngx_http_limit_req_module
该模块会对指定变量的请求次数进行计数,当该变量在单位时间内的请求次数超过设定的数值时,后续请求会被延时处理,当被延时处理的请求数超过指定的队列数时,将返回指定的状态码(默认状态码为503)。通常该模块被用于限定同一IP客户端单位时间内请求的次数。该模块通过共享内存存储计数状态以实现多个工作进程间的同一变量计数状态的共享。该模块的内置配置指令如表所示。
- 计数存储区指令
- 请求限制设置指令
- 请求限制日志级别指令
- 请求限制状态指令
配置样例如下:
http{limit_req_zone$server_namezone=addr:10mrate=1r/s;# 限制访问当前站点的请求数,对站点请求计数,将计数内存区命名为addr,# 设置计数内存区大小为10MB,请求限制为1秒1次server{location /search/{limit_reqzone=one;# 同一秒只接收一个请求,其余的立即返回状态码503,直到第2秒才接收新的请求limit_reqzone=oneburst=5;# 同一秒接收6个请求,其余的返回状态码503,只处理一个请求,其余5个请求进入队# 列,每秒向Nginx释放一个请求进行处理,同时允许接收一个新的请求进入队列limit_reqzone=oneburst=5nodelay;# 同一秒接收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参数是指对请求队列中的请求不进行延时等待,而是立即处理。
- 请求频率同样支持多个变量的同时计数及叠加,配置样例如下:
limit_req_zone$binary_remote_addrzone=perip:10mrate=1r/s;limit_req_zone$server_namezone=perserver:10mrate=10r/s;server{... limit_reqzone=peripburst=5nodelay;limit_reqzone=perserverburst=10;}