一、实验环境(rhel7.3版本)
1、selinux和firewalld状态为disabled
2、各主机信息如下:
主机 | ip |
---|---|
server1(nginx服务端) | 172.25.8.1 |
server2(nginx反向代理服务器) | 172.25.8.2 |
二、安装带有模块http_realip_module的nginx1.14服务
前期准备:
- 停掉之前开启的nginx服务
- 清空缓存(删除之前安装nginx服务生成的Makefile文件和objs目录)
#我们可以看到之前安装的nginx1.14服务,并没有安装任何模块
安装带有模块http_realip_module的nginx1.14服务
#预编译
#可以看到生成了Makefile文件和objs目录
#在objs目录下的ngx_modules.c文件中可以查看安装好的模块
#可以看到有http_realip_module模块
#编译
#将生成的新的nginx二进制文件拷贝到/usr/local/nginx/sbin/目录下(覆盖之前该目录下的nginx文件)
#可以看到安装时添加的模块
至此,带有模块http_realip_module的nginx1.14服务也就安装完成了。
我们访问互联网上的服务时,大多数时,客户端并不是直接访问到服务端的,而是客户端首先请求到反向代理,反向代理再转发到服务端实现服务访问,通过反向代理实现路由/负载均衡等策略。这样在服务端拿到的客户端IP将是反向代理IP,而不是真实客户端IP,因此需要想办法来获取到真实客户端IP
客户端访问服务端的数据流走向 |
Client(172.25.0.1) --> ADSL( 192.168.0.1) --> cdn(10.0.0.1) --> SLB(反向代理)11.0.0.1 --> server(nginx)12.0.0.1 |
可以看出,服务端根本获取不到真实的客户端ip,只能获取到上一层服务的ip,那么nginx怎样才能获取到真实的ip呢?
三、用一台服务器模拟实现获取用户真实ip
1、nginx服务访问成功后返回200状态码(在nginx的服务端server1进行测试)
#在该配置文件的最后一个}(http模块中的})内编写如下128-135行的内容。136的}是http模块的}
#修改完配置文件之后,启动nginx服务
#编辑本地解析文件
#进行测试
2、获取nginx服务客户端对应的IP地址(在nginx的服务端server1进行测试)
#修改完配置文件之后,重启nginx服务
#在物理机编辑本地解析文件
#我们可以看到解析到了访问该域名的主机对应的ip地址
3、使用nginx自带模块realip获取用户IP地址(在nginx的服务端server1进行测试)
#测试
#我们可以看到取到的ip地址是从右往左数的第一个ip地址
#将上面编写内容的133行的off改为on
#测试
#获取到的是,除了配置文件中定义的172.25.8.1以外的地址
#获取到的是,除了配置文件中定义的172.25.8.1以外的从右往左数的第一个地址
参数解释:
1、
set_real_ip_from:真实服务器上一级代理的IP地址或者IP段,可以写多行
2、
real_ip_header:从哪个header头检索出要的IP地址
3、
real_ip_recursive:递归排除IP地址,ip串从右到左开始排除set_real_ip_from里面出现的IP,如果出现了未出现这些ip段的IP,那么这个IP将被认为是用户的IP。
例如我这边的例子(该例子的前提是:real_ip_header的值为X-Forwarded-For),真实服务器获取到的IP地址串如下:120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121
在real_ip_recursive on的情况下:如果61.22.22.22,121.207.33.33,192.168.50.121都出现在set_real_ip_from中,仅仅120.22.11.11没出现,那么它就被认为是用户的ip地址,并且赋值到remote_addr变量
在real_ip_recursive off或者不设置的情况下
从右往左数第一个ip地址即192.268.50.121就是用户的ip地址(不管该ip地址是否出现在set_real_ip_from中)
四、nginx反向代理实现获取用户真实ip
1、配置反向代理服务器
2、配置服务端
#在原先的server模块中添加42,43,44行的内容。下面其余的内容都是原先配置文件中自带的
客户端测试
#编辑本地解析文件
服务端查看日志
总结
1.使用realip模块后,$remote_addr输出结果为真实客户端IP,可以使用$realip_remote_addr获取最后一个反向代理的IP;
2.real_ip_header X-Forwarded-For:告知Nginx真实客户端IP从哪个请求头获取;
3.set_real_ip_from 172.25.8.0/24:告知Nginx哪些是反向代理IP,即排除后剩下的就是真实客户端IP
4.real_ip_recursive on:是否递归解析,当real_ip_recursive配置为off时,Nginx会把real_ip_header指定的请求头中的最后一个IP作为真实客户端IP;
当real_ip_recursive配置为on时,Nginx会递归解析real_ip_header指定的请求头,最后一个不匹配set_real_ip_from的IP作为真实客户端IP。