广州总部电话:020-85564311
广州总部电话:020-85564311

广州网站建设-小程序商城开发-广州小程序开发-企业微信开发公司-网站建设高端品牌-优网科技

20年
互联网应用服务商
请输入搜索关键词
知识库 知识库

优网知识库

探索行业前沿,共享知识宝库

nginx反向代理之获取客户端IP(二)
发布日期:2025-04-15 18:23:19 浏览次数: 826 来源:重生之运维


前言

之前我们分享了nginx反向代理的X-Real-IPX-Forwarded-For的作用和实现原理,现在我们就根据之前的实验结果,继续分享nginx反向代理如何获取客户端的真实IP

Realip模块

该模块的作用是帮助我们在使用了代理的情况下获取客户真实ip。该模块默认不编译进nginx二进制文件中,需要在编译时指定 --with-http_realip_module 参数才会安装该模块(yum安装的nginx默认编译该模块)

参数说明

  • set_real_ip_from
    指定可信地址,这里的可信地址是上一级代理,也就是直接访问上游服务的代理的ip;可以指定多行该指令;如果不使用该指令,就无法获取到起始客户端IP

  • real_ip_header
    告知Nginx真实客户端IP从哪个请求头获取。默认是X-Real-IP。但我们一般设置为X-Forwarded-For。

  • real_ip_recursive off
    是否递归解析,off表示默认从最后一个地址开始解析。例如 X-Forwarded-For 是 1.1.1.1,2.2.2.2,3.3.3.3,那么off取的是3.3.3.3,我们一般设置为on。如果只有一层代理,on和off都无所谓。

以上参数,一般配置在后端服务中,中间代理层不做配置

实验解析

网络环境还是上篇文档中的相关配置,下面直接开始实验过程。

角色ip软件及版本
客户端192.168.124.101nginx1.22.1
反向代理A192.168.124.170nginx1.22.1
反向代理B192.168.124.171nginx1.22.1
反向代理C192.168.124.172nginx1.22.1
后端web服务器192.168.124.173nginx1.22.1

客户端配置域名解析文件C:\Windows\System32\drivers\etc\hosts

192.168.124.170   www.ywnm.com

real_ip_recursive

开启

在反向代理节点A/B/C中开启proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;,A节点开启proxy_set_header X-Real-IP $remote_addr;, 后端web服务器,配置Realip模块参数real_ip_recursive on;set_real_ip_from添加3个代理地址为可信地址,具体配置如下

后端web服务
http{
...
    log_format  main  '$remote_addr + "$http_host" + "$http_x_forwarded_for" + "$http_x_real_ip"';
    access_log    logs/access.log main;

    server {
        listen       80;
        server_name  192.168.124.173;
        set_real_ip_from 192.168.124.170;
        set_real_ip_from 192.168.124.171;
        set_real_ip_from 192.168.124.172;
        real_ip_header   X-Forwarded-For;
        real_ip_recursive on;

        location / {
            root   html/;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html/;
        }
    }
}

访问www.ywnm.com,后端web服务日志:

192.168.124.101 + "www.ywnm.com" + "192.168.124.101, 192.168.124.170, 192.168.124.171" + "-"

关闭

后端web服务器,设置real_ip_recursive off;,访问www.ywnm.com,后端web服务日志:

192.168.124.171 + "www.ywnm.com" + "192.168.124.101, 192.168.124.170, 192.168.124.171" + "-"

注意
这里的remote_addr值变成了192.168.124.171。上一篇中的实验结果,该值都是192.168.124.172,即后端web服务的上层代理节点C的ip。

set_real_ip_from

设置不同可信地址set_real_ip_from时,后端web服务日志中remote_addr的变化

  • set_real_ip_from可信地址设置为192.168.124.170/171,去掉192.168.124.172,后端web服务日志
192.168.124.172 + "www.ywnm.com" + "192.168.124.101, 192.168.124.170, 192.168.124.171" + "-"
  • set_real_ip_from可信地址设置为192.168.124.170/172,去掉192.168.124.171,后端web服务日志
192.168.124.171 + "www.ywnm.com" + "192.168.124.101, 192.168.124.170, 192.168.124.171" + "-"
  • set_real_ip_from可信地址设置为192.168.124.171/172,去掉192.168.124.170,后端web服务日志
192.168.124.170 + "www.ywnm.com" + "192.168.124.101, 192.168.124.170, 192.168.124.171" + "-"

通过启用Realip模块配置,与上篇《nginx反向代理之获取客户端IP(一)》实验结果对比,可知:

  1. 不使用realip模块,$remote_addr是上一级代理的ip。使用了realip模块,$remote_addr是real_ip_header指令指定的起始客户端ip.
  2. 当real_ip_recursive为off时,nginx会把real_ip_header指定的HTTP头中的最后一个IP当成真实IP
  3. 当real_ip_recursive为on时,nginx会把real_ip_header指定的HTTP头中的最后一个不是信任服务器的IP当成真实IP

IP地址伪装

从之前的实验结果, 我们一共得到得到了2种获取客户端真实IP的方式:

  1. 从首层代理(或者是互联网中的CDN)自定义header头
    即设置proxy_set_header X-Real-IP $remote_addr;,然后在应用端解析$http_x_real_ip
  2. 获取forwarded-for信息,设置realip
    即每层代理都设置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;,在后端web服务通知设置可信地址,并开启real_ip_recursive来获取真实客户端ip。

以上的2种方案都能获取到真实的客户端ip,但是当你的后端服务不是nginx作为web服务(不能设置可信地址,并且从右往左遍历ip串),或者是后端代码通过获取远程客户端ip,如以下代码:

public String getClientIp(HttpServletRequest request) {
    String xff = request.getHeader("X-Forwarded-For");
    if (xff == null) {
        return request.getRemoteAddr();
    } else {
        return xff.contains(",") ? xff.split(",")[0] : xff;
    }
}

这个时候,通过X-Forwarded-For来获取heade头作为客户端真实ip就会出现问题。我们通过apipost伪装X-Forwarded-For并发送请求来模拟

此时后端web中获取到的日志信息:

192.168.124.101 + "www.ywnm.com" + "2.2.2.2, 192.168.124.101, 192.168.124.170, 192.168.124.171" + "-"

此时X-Forwarded-For为2.2.2.2, 192.168.124.101, 192.168.124.170, 192.168.124.171,如果取字符串的最左侧ip,客户端为2.2.2.2

总结

  1. 小型架构(单一代理)
    直接使用 X-Real-IP,简单高效,日志中获取到的 IP 就是客户端的真实 IP。或者使用remote_addr,因为remote_addr无法伪造
  2. 多层代理架构(Nginx + CDN / WAF / 反向代理链)
    建议使用 X-Forwarded-For,配合 real_ip_recursive 来递归解析最原始的 IP 地址。。并且首层代理配置proxy_set_header X-Forwarded-For $remote_addr;代替proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;,这样X-Forwarded-For将无法伪造客户端ip。


优网科技,优秀企业首选的互联网供应服务商

优网科技秉承"专业团队、品质服务" 的经营理念,诚信务实的服务了近万家客户,成为众多世界500强、集团和上市公司的长期合作伙伴!

优网科技成立于2001年,擅长网站建设、网站与各类业务系统深度整合,致力于提供完善的企业互联网解决方案。优网科技提供PC端网站建设(品牌展示型、官方门户型、营销商务型、电子商务型、信息门户型、DIY体验、720全景展厅及3D虚拟仿真)、移动端应用(手机站APP开发)、微信定制开发(微信官网、微信商城、企业微信)、微信小程序定制开发等一系列互联网应用服务。


我要投稿

姓名

文章链接

提交即表示你已阅读并同意《个人信息保护声明》

专属顾问 专属顾问
扫码咨询您的优网专属顾问!
专属顾问
马上咨询
扫一扫马上咨询
扫一扫马上咨询

扫一扫马上咨询