Nginx 获取客户端真实IP $remote_addr与X-Forwarded-For的实现

 更新时间:2024年03月19日 10:20:02   作者:富士康质检员张全蛋  
我们大多数情况下访问服务时,客户端并不是直接访问到服务器的,本文主要介绍了Nginx 获取客户端真实IP $remote_addr与X-Forwarded-For的实现,具有一定的参考价值,感兴趣的可以了解一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

nginx配置

首先,一个请求肯定是可以分为请求头和请求体的,而我们客户端的IP地址信息一般都是存储在请求头里的。如果你的服务器有用Nginx做负载均衡的话,你需要在你的location里面配置X-Real-IPX-Forwarded-For请求头:

        location ^~ /your-service/ {
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:60000/your-service/;
        }

X-Real-IP

在《实战nginx》中,有这么一句话:

经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址。

这句话的意思是说,当你使用了nginx反向服务器后,在web端使用request.getRemoteAddr()(本质上就是获取$remote_addr),取得的是nginx的地址,即$remote_addr变量中封装的是nginx的地址,当然是没法获得用户的真实ip的。但是,nginx是可以获得用户的真实ip的,也就是说nginx使用$remote_addr变量时获得的是用户的真实ip,如果我们想要在web端获得用户的真实ip,就必须在nginx里作一个赋值操作,即我在上面的配置:

proxy_set_header X-Real-IP $remote_addr;

$remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr一般都是设置第一个代理上面;但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip,那么这个时候就要用到X-Forwarded-For 了,这个变量的意思,其实就像是链路反追踪,从客户的真实ip为起点,穿过多层级的proxy ,最终到达web 服务器,都会记录下来,所以在获取用户真实ip的时候,一般就可以设置成,proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这样就能获取所有的代理ip 客户ip。 

X-Forwarded-For

X-Forwarded-For变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做X-Forwarded-For设置的话,每次经过proxy转发都会有记录,格式就是client1,proxy1,proxy2以逗号隔开各个地址,由于它是非rfc标准,所以默认是没有的,需要强制添加。在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.getAttribute("X-Forwarded-For")获取不到用户的ip,如果我们想要通过这个变量获得用户的ip,我们需要自己在nginx添加配置:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

意思是增加一个$proxy_add_x_forwarded_forX-Forwarded-For里去,注意是增加,而不是覆盖,当然由于默认的X-Forwarded-For值是空的,所以我们总感觉X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,实际上当你搭建两台nginx在不同的ip上,并且都使用了这段配置,那你会发现在web服务器端通过request.getAttribute("X-Forwarded-For")获得的将会是客户端ip和第一台nginx的ip。

那么$proxy_add_x_forwarded_for又是什么?

$proxy_add_x_forwarded_for变量包含客户端请求头中的X-Forwarded-For$remote_addr两部分,他们之间用逗号分开。

举个例子,有一个web应用,在它之前通过了两个nginx转发,www.linuxidc.com即用户访问该web通过两台nginx。

在第一台nginx中,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

现在的$proxy_add_x_forwarded_for变量的X-Forwarded-For部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。

到了第二台nginx,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

现在的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”,这样就清楚了吧。

举个例子说明 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

192.168.179.99->192.168.179.100->192.168.179.101->192.168.179.102(102为最后的服务端)

192.168.179.99配置
      location /{
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://192.168.179.100;
     }


192.168.179.100配置
      location /{
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://192.168.179.101;
     }


192.168.179.101配置
      location /{
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://192.168.179.102;
     }


192.168.179.102配置
在日志中设置打印$http_x_forwarded_for,进行观察
 log_format  main  '$http_x_forwarded_for|$http_x_real_ip|$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

(1)客户端使用浏览器去访问192.168.179.99服务端192.168.179.102日志如下,可以看到获取到客户端的IP为192.168.179.4
192.168.179.4, 192.168.179.99, 192.168.179.100|-|192.168.179.101 - - [26/Apr/2020:10:57:22 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36" "192.168.179.4, 192.168.179.99, 192.168.179.100"

(2)客户端192.168.179.103去访问192.168.179.99服务端192.168.179.102日志如下,可以看到获取到客户端的IP为192.168.179.103
192.168.179.103, 192.168.179.99, 192.168.179.100|-|192.168.179.101 - - [26/Apr/2020:10:57:32 +0800] "GET / HTTP/1.0" 200 4833 "-" "curl/7.29.0" "192.168.179.103, 192.168.179.99, 192.168.179.100" 

到此这篇关于Nginx 获取客户端真实IP $remote_addr与X-Forwarded-For的实现的文章就介绍到这了,更多相关Nginx IP $remote_addr X-Forwarded-For内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • windows下nginx的安装使用及解决80端口被占用nginx不能启动的问题

    windows下nginx的安装使用及解决80端口被占用nginx不能启动的问题

    这篇文章主要给大家介绍了关于windows下nginx的安装使用,以及如何解决80端口被占用导致nginx不能启动的问题,文中介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-04-04
  • 安装OpenResty(Nginx仓库)

    安装OpenResty(Nginx仓库)

    这篇文章主要介绍了安装OpenResty(Nginx仓库),需要的朋友可以参考下
    2023-06-06
  • Nginx常用技巧使用实例汇总

    Nginx常用技巧使用实例汇总

    这篇文章主要介绍了Nginx常用技巧使用实例汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • 本地通过nginx配置反向代理的全过程记录

    本地通过nginx配置反向代理的全过程记录

    这篇文章主要给大家介绍了关于本地通过nginx配置反向代理的全过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • nginx 配置静态缓存及静态缓存文件没有生成的问题及解决方案

    nginx 配置静态缓存及静态缓存文件没有生成的问题及解决方案

    这篇文章主要介绍了nginx 配置静态缓存及静态缓存文件没有生成的问题及解决方案,本文分步骤结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • nginx使用nginx-rtmp-module模块实现直播间功能

    nginx使用nginx-rtmp-module模块实现直播间功能

    做的过程出现很多问题,环境其实就需要nginx就可以,然后就是在播放的问题,m3u8的格式,mac直接访问就支持,苹果系统原生H5支持m3u8,还有就是手机直接访问也支持!但是其他其他系统PC端不支持,尝试了好多都不行,最后终于找到了一个支持m3u8格式H5播放
    2017-10-10
  • nginx配置解决跨域访问的方法详解

    nginx配置解决跨域访问的方法详解

    这篇文章主要为大家详细介绍了nginx如何配置解决跨域访问的方法,文中的示例代码讲解详细,具有一定的参考价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • nginx?rtmp模块编译?arm版本的问题

    nginx?rtmp模块编译?arm版本的问题

    这篇文章主要介绍了nginx?rtmp模块编译?arm版本的问题,pcre库和libz库都不用单独编译,在编译nginx时添加模块时一起编译,需要的朋友可以参考下
    2021-12-12
  • Nginx的try_files指令使用实例

    Nginx的try_files指令使用实例

    这篇文章主要介绍了Nginx的try_files指令使用实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • nginx正向代理的配置和使用教程

    nginx正向代理的配置和使用教程

    本文主要介绍了nginx正向代理的配置和使用教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07

最新评论

?


http://www.vxiaotou.com