目录
- 1. 引言
- 2. Real IP模块的使用
- 2.1 启用Real IP模块
- 2.2 配置Real IP模块
- 2.2.1 配置指令
- 2.2.2 举例
- 3. 变量的使用
1. 引言
nginx 的 Real IP 模块用于解决代理服务器转发请求到nginx上时可能出现的 IP 地址问题。因为当 PROXY收到客户端的请求时,它会通过自己的IP与nginx服务器连接并转发请求。这会导致在nginx应用程序中记录的 IP 地址是代理服务器的地址,而不是实际客户端的地址。
举例如下图:
当nginx收到来自客户端的HTTP请求,由于经过了中间的代理PROXY服务器,NGINX默认只能知道请求来自PROXY的内网IP 192.168.0.1,而不是客户端的真实IP 111.22.33.44。因此,需要一种机制能够让NGINX获取到客户端的真实IP,好在HTTP协议可以通过X-Forwarded-For头或者X-Real-IP头将客户端的真实IP透传到后端,在这个例子中,当PROXY收到请求后,它会在客户端的请求头中增加一个带有客户端IP的X-Forwarded-For头或者X-Real-IP头,然后转发给后端的NGINX服务器,NGINX服务器要根据约定从对应的HTTP请求头中获取客户端的真实IP。
Real IP 模块的使命就是将代理服务器传递的真实客户端 IP 地址还原为实际客户端的 IP 地址,以便nginx中的应用模块可以获取到真实的客户端IP。
本文首先介绍Real IP 模块的使用和配置,然后通过对Real IP 模块的源码分析来深入理解其实现的机理。
2. Real IP模块的使用
2.1 启用Real IP模块
ngx_http_realip_module默认是没有enable的,因此,需要在configure的时候将这个模块enable,如下:
./configure --with-http_realip_module
2.2 配置Real IP模块
2.2.1 配置指令
1. real_ip_header配置指令
语 法:
real_ip_header field | X-Real-IP | X-Forwarded-For | proxy_protocol;
默认值:
real_ip_header X-Real-IP;
上下文:
http, server, location
本指令用来定义从哪个地方获取客户端的真实IP,以便让NGINX能够获取到,并将获取到的客户端真实IP替换代理服务器的IP。
其中的选项包括 X-Real-IP 头, X-Forwarded-For 头,或者自定义HTTP 头都可以。另外,还支持通过proxy_protocol协议来获取客户端的真实IP,当然,要使用这个选项,首先需要在nginx上开启proxy_protocol的功能。
2. real_ip_recursive配置指令
语 法:
real_ip_recursive on | off;
默认值:
real_ip_recursive off;
上下文:
http, server, location
本指令用来开启或者关闭通过HTTP相关头获取客户端真实IP的时候是否允许多级代理的情况。
如果禁用递归搜索,与受信任地址之一匹配的原始客户端地址将被请求头字段中由 real_ip_header 指令定义的最后一个地址替换。如果启用递归搜索,与受信任地址之一匹配的原始客户端地址将被请求头字段中最后一个非受信任地址替换。
3. set_real_ip_from配置指令
定义一个或者多个受信任的PROXY服务器的地址,格式如下:
语 法:
set_real_ip_from address | CIDR | unix:;
默认值:
—
上下文:
http, server, location
set_real_ip_from指令可以定义多次,定义的PROXY服务器地址可以用ip/mask的方式指定(即CIDR),也可以用域名的方式指定,还可以指定为”unix:“用来表示信任所有以unix socket形式建立的连接。
举个例子,如下:
set_real_ip_from 192.168.0.0/24;
set_real_ip_from unix:
set_real_ip_from www.test_proxy.com;
2.2.2 举例
先举一个例子:
http {
# ...
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# ...
}
以上例子开启了Real IP功能,nginx将查找X-Forwarded-For头来获取客户端真实IP。
3. 变量的使用
本模块在获取到客户端的真实IP后,它会将与它连接的IP地址替换为客户端真实IP,当然有时候我们还是需要得到PROXY的IP和端口,那么nginx也提供相应的机制来获得,即通过变量的方式来提供这个信息。包括两个变量如下:
-
$realip_remote_addr: PROXY的IP地址
-
realip_remote_port: PROXY与nginx连接的PROXY本地端口号
<未完待续>
下文将以源代码的角度来分析real ip模块的实现原理。