一. POST_READ阶段
1. 用户ip在http请求中的传递?
前提:Tcp连接四元组(src ip,src port,dst ip,dst port)
HTTP头部 X-Formarded-For 用于传递Ip
HTTP头部X-Real-IP用于传递IP
网络中存在许多反向代理
客户端的请求往往不会直接到达客户端,而是会经过多个代理服务器 比如CDN、Nginx等。如果一个客户端请求经由Nginx与上游服务器通讯,建立Tcp连接,那么Tcp连接四元组中保存的src ip和src port都是Nginx代理服务器的。而我们要想做限流,就必须拿到用户的IP地址。在Http协议中,提供了两个请求头可以实现这个功能:X-Formarded-For、X-Real-IP。
a)X-Formarded-For:保存每个节点的ip地址,形成一个链表
b)X-Real-IP:保存第一个节点的ip地址
2. Nginx如何拿到用户IP地址?realip模块。
realip模块默认不会编译进Nginx,通过--with-http-realip-module启用功能
realip模块提供了两个变量来获取ip地址:binary_remote_addr(二进制数据,size较小)、remote_addr
指令:
a)set_real_ip_from address|CIDR|unix:定义什么样的连接才替换变量
b)real_ip_header field | X-Real-IP | X-Forward-For | proxy_protocol:定义变量从哪个header中取值
c)real_ip_recursive on | off:定义是否使用环回地址。默认不启用。开启时,如果X-Forward-For的最后一个地址与客户端地址相同,会删去最后一个地址。
二. SERVER_REWRITE和REWRITE阶段
这两个阶段所作的事情差不多,都是定制请求的后继行为,只不过配置的块不一样,作用域不一样。
Rewrite模块
提供了指令return、rewrite来改变客户端的行为,重定向或者直接返回状态码等。
rewrite模块不可删除。
1. return指令:向客户端返回信息
a)return code [text]
b)return code URL
c)return URL
思考:server与location下的return指令关系?
return与error_page指令的关系?
2. rewrite指令:重写客户端请求
a) rewrite regex replacement [flag]
1. 将regex指定的这个url替换成replacement这个新的url,可以使用正则表达式及变量提取
2. 当replacement以http://或者https://或者$schema开头,则直接返回302重定向
3. 替换后的url根据flag指定的方式进行处理
- last:用replacement这个URI进行新的location匹配
- break:break指令停止当前脚本指令的执行
- redirct:返回302重定向
- permanent:返回301重定向
开启rewrite行为记入日志:rewrite_log on | off; 默认为off,所属块:http、server、location、if
b)if(condition){ ... }:基于变量做重定向
1. 检查变量为空或者值是否为0,直接使用
2. 将变量与字符串做匹配,使用=或者!=
3. 将变量与正则表达式做匹配
大小写敏感,~或者!~
大小写不敏感,~*或者!~*
4. 检查文件是否存在,-f或者!-f
5. 检查目录是否存在,-d或者!-f
6. 检查是否为可执行文件,-x或者!-x
7. 检查文件、目录、软连接是否存在,使用-e或者!-e
三. FIND-CONFIG阶段
寻找处理请求的location指令块。
指令:location、merge_slashes
location [ = | ~ | ~* | ^~] uri { ... }
location指令规则:仅匹配URI,忽略参数
-
合并连续的符号:merge_slashes on
-
前缀字符串:
常规匹配
=:精准匹配
^~:匹配上后则不再进行正则表达式匹配
-
用于内部跳转的命令:location
-
正则表达式:
~:大小写敏感的正则匹配
~*:忽略大小写敏感的正则匹配
location匹配顺序
-
遍历匹配全部前缀字符串location
-
匹配上=字符串,使用匹配上的=精准匹配location,否则进入下一步
-
匹配上^~字符串,使用匹配上的^~字符串location,否则进入下一步
-
记住最长匹配的前缀字符串location,进入正则表达式匹配
-
按nginx.conf中的顺序依次匹配正则表达式location
-
匹配上,使用匹配上的正则表达式
-
未匹配上,使用最长匹配的前缀字符串location
总结优先级:=精准匹配前缀>^~停止正则匹配前缀>按位置顺序正则匹配>最长前缀匹配
注:前缀匹配符号:无符号、=符号、^~符号
正则匹配符号:~大小写敏感正则、~*大小写不敏感正则
四. preaccess阶段
1. 限制客户端的并发连接数
模块:http_limit_conn_moudule
默认编译进nginx,通过--without-http_limit_conn_module禁用
生效范围:全部worker进程(基于共享内存)
进入proaccess阶段前不生效
限制的有效性取决于key的设计:依赖postread阶段的realip模块的真实ip
limit_conn命令:
-
定义共享内存(包括名字和大小),以及key关键字
limit_conn_zone key zone=name:size;
context:http
-
限制并发连接数
limit_conn zone number;
context:http,server,location
-
限制发生时的日志级别
limit_conn_log_level info | notice | warn | error;
default:limit_conn_log_level error;
context:http,server,location
-
显示发生时向客户端返回的错误码
default:limit_conn_status code;
default:limit_conn_status 503;
context:http,server,location
2. 限制每个客户端的每秒处理请求数
模块:http_limit_req_module
默认编译进nginx,通过--without-http_limit_req_module禁用功能
生效算法:leaky bucket 算法
生效范围:全部worker进程(基于共享内存)
进入proaccess前不会生效
限制的有效性取决于key的设计:依赖postread阶段的realip模块的真实ip
limit_req在limit_conn之前生效
limit_req命令:
-
定义共享内存(包括名字和大小),以及key关键字
limit_req_zone key zone=name:size rate=rate;
context:http
-
限制并发连接数
limit_req zone =name [burst=number] [nodelay];
context:http,server,location
-
限制发生时的日志级别
limit_req_log_level info | notice | warn | error;
default:limit_req_log_level error;
context:http,server,location
-
显示发生时向客户端返回的错误码
default:limit_req_status code;
default:limit_req_status 503;
context:http,server,location
五. access阶段
1. 限制某些Ip地址的访问权限
模块:http_access_moudule
默认编译进nginx,通过--without-http_access_moudule禁用
生效范围:进入access阶段前不会生效
命令
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
示例
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}
2. 限制客户端登陆验证
RFC2617 HTTP Basic Authentication
auth_basic模块的指令
基于HTTP Basic Authutication 协议进行用户名密码的认证
默认编译进Nginx: --without-http_auth_basic_module disable ngx_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
3. 使用第三方做权限验证
模块:auth_request
默认未编译进nginx:--with-http_auth_request_module
功能:向上游的服务转发请求,若上游服务返回的响应码是2xx,则继续执行,若上游服务器返回的是401或者403,则将响应返回给客户端
原理:收到请求后,生成子请求,通过反向代理技术把请求参数传递给上游服务
Syntax: auth_request uri | off;
Default: auth_request off;
Context: http, server, location
Syntax: auth_request_set $variable value;
Default: —
Context: http, server, location
4. 限制所有access阶段模块的satisfy指令
Syntax: satisfy all | any;
Default: satisfy all;
Context: http, server, location
设置为all:所有access模块都允许访问才能访问
设置为any:有一个access模块允许访问就能访问
六. procontent阶段
1. try_files指令
默认编译进nginx中,并且不能取消
功能:依次试图访问多个url对应的文件(由root或者alias指令指定),当文件存在时直接返回文件内容,如果所有文件都不存在,则按最后一个URL结果或者code返回
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
2. mirror模块
实现零拷贝流量,将本次请求拷贝一份发送给指定的uri。比如将请求拷贝一份发送到测试服务器上。
默认编译进nginx中,通过--without-http_mirror_module移除模块
功能:处理请求时,生成子请求访问其他服务,对子请求的返回值不做处理
Syntax: mirror uri | off;
Default: mirror off;
Context: http, server, location
Syntax: mirror_request_body on | off;
Default: mirror_request_body on;
Context: http, server, location
七. content阶段
static模块,访问静态资源文件
1. root和alias指令
功能:将url映射为文件路径,以返回静态文件内容
差别:root会将完整的location的url映射进文件路径中
alias只会将location后边的url映射到文件路径中
Syntax: alias path;
Default: —
Context: location
Syntax: root path;
Default: root html;
Context: http, server, location, if in location
2. static模块提供的三个变量
request_name(待访问文件的完整路径)
document_root(由URL和root/alias规则生成的文件夹路径)
realpath_root(将document_root中的软链接等换成真实路径)
3. static模块对url不以斜杠结尾却访问目录的做法
static模块实现了root/alias功能时,发现访问目录是目录,但URL结尾未加/时,会返回301重定向
指令:
absolute_redirect on | off; 是否使用绝对路径,on(会填写域名等),off(不会加域名)
Defalut:absolute_redirect on;
Context:http,server,location
server_name_in_redirect on | off;
port_in_redirect on | off;
3. index模块于auto_index模块
index模块
功能:对处理/时的处理,指定/访问时返回index文件内容
默认编译进nginx,不可取消
Syntax: index file ...;
Default: index index.html;
Context: http, server, location
auto_index模块
功能:当url以/结尾时,尝试以html/xml/json/jsonp等格式返回root、alias中指向目录的目录结构
默认编译进nginx,--without-http_autoindex_module取消
Syntax: autoindex on | off;
Default: autoindex off;
Context: http, server, location
Syntax: autoindex_exact_size on | off;
Default: autoindex_exact_size on;
Context: http, server, location
Syntax: autoindex_format html | xml | json | jsonp;
Default: autoindex_format html;
Context: http, server, location
Syntax: autoindex_localtime on | off;
Default: autoindex_localtime off;
Context: http, server, location
4. 提升多个小文件访问的concat模块
功能:当页面需要访问多个小文件时,把它们的内容合并到一次http响应中返回,提升性能
使用:在uri后加上??,后通过多个,逗号隔开文件。如果还有参数,则在最后通过?
concat :on | off
default :concat off
Context :http, server, location
concat_types :MIME types
Default :concat_types: text/css application/x-javascript
Context :http, server, location
concat_unique :on | off
Default : concat_unique on
Context : http, server, location
concat_max_files :numberp
Default :concat_max_files 10
Context : http, server, location
concat_delimiter :string
Default :NONE
Context : http, server, locatione
concat_ignore_file_error :on | off
Default :off
Context :http, server, location
八. log阶段
记录请求日志的log模块
功能:将Http请求相关信息记录到日志
模块:ngx_http_log_module 无法禁用
命令:
1. 设置access日志格式
Syntax: log_format name [escape=default|json|none] string ...;
Default: log_format combined "...";
Context: http
2. 配置access日志文件路径
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default: access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except
3. 优化不用每次写日志都打开关闭日志文件
Syntax: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
Default: open_log_file_cache off;
Context: http, server, location
说明:max 缓存内的最大文件句柄数,超出后使用LRU算法淘汰
inactive 文件访问完后在这段时间内不会被关闭。默认10秒
min_uses 在inactive时间内使用次数超过min_uses才会继续存在内存中。默认是1
vaild 超出vaild时间后,将对缓存的日志文件检查是否存在。默认是60秒
off 关闭缓存功能
九. 过滤模块
1. 替换响应中的字符串:sub模块
功能:将响应中的指定的字符串,替换成新的字符串
模块:ngx_http_sub_filiter_modulem模块
默认未编译进nginx,通过--with-http_sub_module启用
指令:
Syntax: sub_filter string replacement;
Default: —
Context: http, server, location
Syntax: sub_filter_last_modified on | off;
Default: sub_filter_last_modified off;
Context: http, server, location
Syntax: sub_filter_once on | off;
Default: sub_filter_once on;
Context: http, server, location
Syntax: sub_filter_types mime-type ...;
Default: sub_filter_types text/html;
Context: http, server, location
2. 在响应的前后添加内容:addition模块
功能:在响应前后增加内容,而增加内容的方式是通过新增子请求的响应完成
模块:ngx_http_addition_filter_module
默认未编译进nginx,通过--with-http_addtion_filter_module启用
Syntax: add_before_body uri;
Default: —
Context: http, server, location
Syntax: add_after_body uri;
Default: —
Context: http, server, location
Syntax: addition_types mime-type ...;
Default: addition_types text/html;
Context: http, server, location
浙公网安备 33010602011771号