我们访问互联网上的服务时,大多数时,客户端并不是直接访问到服务端的,而是客户端首先请求到反向代理,反向代理再转发到服务端实现服务访问,通过反向代理实现路由/负载均衡等策略。这样在服务端拿到的客户端IP将是反向代理IP,而不是真实客户端IP,因此需要想办法来获取到真实客户端IP

web服务器获得真正的用户和真实的ip ?
客户端访问服务端的数据流走向

可以看出,服务端根本获取不到真实的客户端ip,只能获取到上一层服务的ip,那么nginx怎样才能获取到真实的ip呢?

反向代理:获取上一节的ip,一层一层会找到真实client的ip;

问题背景:
在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆的判断,或者统计ip访问次数等,通常情况下我们使用request.getRemoteAddr()就可以获取到客户端ip,但是当我们使用了nginx作为反向代理后,使用request.getRemoteAddr()获取到的就一直是nginx服务器的ip的地址,那这时应该怎么办?
part1:解决方案

proxy_set_header X-real-ip $remote_addr;

其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:

request.getAttribute(“X-real-ip”)

part2:原理介绍:
关于nginx反向代理的原理的介绍
proxy_set_header原理

用一台服务器server1模拟实现获取本机ip

在server1上:

[root@server1 ~]# tar zxf nginx-1.17.0.tar.gz
[root@server1 ~]# cd nginx-1.17.0
[root@server1 nginx-1.17.0]# yum install -y zlib-devel# 这是编译nginx的依赖包
[root@server1 nginx-1.17.0]# yum install -y openssl-devel  # 这是编译nginx的依赖
[root@server1 ~]# cd /usr/local/nginx/[root@server1 conf]# vim nginx.conf
#当访问域名server1.example.com,实际访问的是直接返回client real ip: $remote_addr\n
配置文件-->虚拟主机server {listen 80;   #监听80端口server_name server1.example.com;  #定义域名set_real_ip_from 172.25.70.1;   #真正的ip地址;real_ip_header  X-Forwarded-For;real_ip_recursive on;location / {return 200 "client real ip: $remote_addr\n";}
}
[root@server1 conf]#/usr/local/nginx/sbin/nginx -t #启动失败;
[root@server1 conf]#  systemctl stop nginx

添加一个模块:-with-http_realip_module选项(后台Nginx服务器记录原始客户端的IP地址 )

[root@server1 nginx-1.17.0]# ./configure --prefix=/usr/local/nginx  --with-file-aio  --with-http_realip_module
************************
--with-file-aio 启用file aio支持(一种APL文件传输格式)
--with-http_realip_module:它的意义在于能够使得后台服务器记录原始客户端的IP地址。
*************************[root@server1 nginx-1.17.0]#  make && make install[root@server1 nginx-1.17.0]# vim /usr/local/nginx/conf/nginx.conf

参数解释:

1.使用realip模块后,$remote_addr输出结果为真实客户端IP,可以使用$realip_remote_addr获取最后一个反向代理的IP;
3.real_ip_headerX-Forwarded-For:告知Nginx真实客户端IP从哪个请求头获取;
4.set_real_ip_from 172.25.78.0/24:告知Nginx哪些是反向代理IP,即排除后剩下的就是真实客户端IP
5.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。

添加虚拟机从X-Forwarded-For中获取到真实客户端IP(最后一行):

132   server {
133         listen 80;
134         server_name server1.example.com;
135         set_real_ip_from 172.25.70.1; ###set_real_ip_from:  功能:通过该指令指定信任的地址,将会被替代为精确的IP地址。从0.8.22版本后也可以使用信任的Unix套接字。这里设置的IP就是指前端Nginx 、Varnish或者 Squid 的 IP地址。
136         real_ip_header  X-Forwarded-For;  # real_ip_header::这个指令用于设置使用哪个头来替换IP地址。如果使用了X-Forwarded-For,那么该模块将会使用X-Forwarded-For头中的最后一个IP地址来替换前端代理的IP地址。
137         real_ip_recursive on;  # 是否递归解析,off表示默认从最后一个地址开始解析; # on表示从前往后依次递归获取ip
138         location / {
139                 return 200 "client real ip: $remote_addr\n"; # $remote_addr 代表客户端真实IP
140         }
141
142
143 }

[root@server1 nginx-1.17.0]# cd /usr/local/nginx/conf/
[root@server1 conf]#  systemctl restart nginx.service
[root@server1 conf]# vim /etc/hosts
172.25.70.1     server1  server1.example.com
[root@server1 conf]# curl -H 'X-Forwarded-For:1.1.1.1,172.25.70.1' server1.example.com
client real ip: 1.1.1.1     #虚拟主机添加成功

[root@server1 conf]# scp -r /usr/local/nginx/ server2: #将其nginx的安装路径发过去

以上操作仅仅实现了获取本机ip和使用X-Forwarded-For的功能,现在我们来模拟实际生产中在有反向代理的阻碍下获取真实客户端ip,这里我们用一个反向代理来模拟

配置server2(nginx反向代理服务器):

[root@server2 nginx]# cd /usr/local/nginx/
[root@server2 nginx]# ls
[root@server2 nginx]# id nginx  #查看是否有nginx用户,没有重新建立;
uid=1000(nginx) gid=1000(nginx) groups=1000(nginx)
[root@server2 nginx]# cd conf/
[root@server2 conf]# vim nginx.conf19         upstream westos{20                 server 172.25.70.1:80;21         }135   server {
136         listen 80;
137         server_name server1.example.com;
138         set_real_ip_from 172.25.70.1;
139         real_ip_header  X-Forwarded-For;
140         real_ip_recursive on;
141         location / {
142
143                 proxy_pass http://westos;
144         }
145 }

[root@server2 conf]# ../sbin/nginx
[root@server2 conf]# netstat -tnlp
[root@server2 conf]# curl localhost
server2.example.com

#客户端(70)测试: 

[root@foundation70 ~]# curl 172.25.70.2
server2.example.com

在server2上:

[root@server2 conf]# vim nginx.conf
135 server {undefined
136 listen 80;
137 server_name server2.example.com;
138 # set_real_ip_from 172.25.70.1;
139 # real_ip_header X-Forwarded-For;
140 # real_ip_recursive on;
141 location / {undefined
142
143 proxy_pass http://westos;
144 }
145 }


[root@server2 conf]# curl 172.25.70.1
server1.example.com
[root@server2 conf]# ../sbin/nginx -s reload

在客户端测试

[root@foundation70 ~]# vim /etc/hosts
172.25.70.2     server2 server2.example.com
[root@foundation70 ~]# curl server2.example.com
server2.example.com
[root@foundation70 ~]# curl server2.example.com
server1.example.com

获取真正的客户端ip

在server1上:

[root@server1 conf]# vim nginx.conf
注释掉131-140行44         set_real_ip_from 172.25.70.2;45         real_ip_header  X-Forwarded-For;46         real_ip_recursive on;

 在server2上:

[root@server2 conf]# vim nginx.conf19         upstream westos{20                 server 172.25.70.1:80;21         }135   server {
136         listen 80;
137         server_name server2.example.com;
138 #       set_real_ip_from 172.25.70.1;
139 #       real_ip_header  X-Forwarded-For;
140 #       real_ip_recursive on;
141         location / {
142                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     #添加该变量是为了真正的获得用户的IP
143                 proxy_pass http://westos;
144         }
145 }
[root@server2 conf]# ../sbin/nginx -t
[root@server2 conf]# ../sbin/nginx -s reload

测试:


[root@foundation70 ~]# curl server2.example.com(172.25.70.2)
server1.example.com在server1上的日志:
[root@server1 logs]# cat access.log     #是真正访问的是客户端
172.25.70.250 - - [26/Sep/2019:22:05:25 +0800] "GET / HTTP/1.0" 200 20 "-" "curl/7.29.0"  #获得ip是客户端的

获得是server1的获得了server2(反向代理)的ip

在server1上:

[root@server1 conf]# vim nginx.conf44 #       set_real_ip_from 172.25.70.2;45 #        real_ip_header  X-Forwarded-For;46 #        real_ip_recursive on;
再次测试:
[root@foundation70 ~]# curl server2.example.com
server1.example.com在server1上的日志:
[root@server1 logs]# cat access.log
172.25.70.2 - - [26/Sep/2019:22:14:09 +0800] "GET / HTTP/1.0" 200 20 "-" "curl/7.29.0"

原文链接:https://blog.csdn.net/qq_38548994/article/details/101491890

nginx利用反向代理实现获取用户真实ip相关推荐

  1. nginx反向代理获取用户真实ip

    nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...

  2. 使用nginx代理的情况下获取用户真实IP

    ##1.背景知识 1.1. 前提知识点: 还有nginx中的几个变量: remote_addr 代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站 ...

  3. nginx 如何配置来获取用户真实IP

    ##1.背景知识 1.1. 前提知识点: 还有nginx中的几个变量: remote_addr 代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站 ...

  4. CDN下nginx获取用户真实IP地址

    为什么80%的码农都做不了架构师?>>>    随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能 ...

  5. nginx做负载CDN加速获取端真实ip

    nginx做负载CDN加速获取端真实ip在不用cdn的情况下,nginx做负载获取真实ip时,nginx配置如下:Java代码 proxy_set_header Host $host; proxy_s ...

  6. 查找“CDN、负载均衡、反向代理”等大型网络真实IP地址的方法

    查找"CDN.负载均衡.反向代理"等大型网络真实IP地址的方法     首先,CDN.负载均衡.反向代理还分为很多层,有时查出来的是最外层的 CDN 服务器群,真实的机器是不对外开 ...

  7. java获取用户真实IP地址

    /*** 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址.* 可是,如果通过了多级反向代理的话,X-Forwarded ...

  8. QQ空间迁移_【群晖NAS+FRP_并获取用户真实IP 支持群辉6.0和群辉7.0】

    群晖NAS+FRP 并获取用户真实IP 2020-11-12 13:57:54 事情的起因是这样的, 我的NAS没有公网IP,通过FRP端口映射到云主机对外提供访问,但是互联网不怀好意的人太多了,经常 ...

  9. php获取用户真实ip_开启CDN后,PHP获取用户真实IP的方法

    因为近日需要几个小项目上CDN,但上CDN的同时,要获取到用户的真实IP地址.虽然网上有很多关于网站在CDN加速的情况下,PHP获取用户真实IP地址的方法,但总觉的不可靠,还是自己测试一下最好. PH ...

最新文章

  1. 有什么好用的SaaS软件推荐?
  2. VS出现异常?!和十进制转二进制比是小事
  3. myeclipse文件目录自动定位(右编辑界面点击 左边Package Explorer导航自动定位)...
  4. Linux 进程状态详解
  5. java千万用户实现实时排名_想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜...
  6. db2 v9.7 tablespace_state -“表空间状态”监视器元素 0x0400
  7. 1人30天44587行代码,分享舍得网开发经验【修订版】
  8. oracle里xdb用户,修改Oracle XDB默认监听端口
  9. jpg格式电脑怎么弄_jpg图片格式如何操作
  10. python王者荣耀刷金币
  11. Android Hook框架adbi的分析(1)---注入工具hijack
  12. Wavesurfer.js 生成音频波形图
  13. 致远oa读取服务器信息失败,致远OA A8V5常见问题集
  14. Python数据采集分析告诉你为何上海二手房你都买不起
  15. 计算机法语怎么翻译软件,中法互译,好用的法语翻译软件
  16. 高并发和大流量解决方案
  17. MySQL基础测试题(今日作业)
  18. Android Studio主题设置
  19. 视觉残差函数及雅可比公式推导
  20. 苹果CEO库克怒怼媒体:Ive离职与我无关,华尔街不懂苹果

热门文章

  1. 安卓App太能乱来了!被曝一天扫你后台1.3万次:小米系统更新,一不小心扯出惊人真相...
  2. WordPress 使用 CDN 后获取访客真实 IP
  3. 备份android分区,安卓手机手动【备份+还原】分区
  4. 博客园样式(仿简书)
  5. ORA-03135: Connection Lost Contact 数据库丢失联系
  6. 游戏服务器到底是什么?
  7. 蓝桥杯省赛 走方格(多种方法)
  8. matlab 微分符号,Matlab 符号微积分
  9. The following tasks did not complete: first,Did you forget to signal async completion?问题
  10. Nvidia Tesla P100 性能评测