当前位置: 首页 > news >正文

nginx配置获取客户端的真实ip

场景描述:

访问路径: A机器 - > B机器的 ->C虚拟机 :

A机器为客户端用户,本地地址为 192.168.0.110

B机器为服务端反向代理服务器 本地地址为192.168.0.128 –>(192.168.56.1)

C机器为B主机安装的linux虚拟机,并安装了nginx ,本地ip为**(192.168.56.10)**

从侧面反映了反向代理的好处,直接从A是无法访问C的,但是在B中做了反向代理 ,就能访问了,保护了服务端的地址。而无法将C的ip暴露给客户端A

注意:在B和C直接由于使用了虚拟机,虚拟机的网关的ip为192.168.56.1 所以 在C端取到的上一层ip为192.168.56.1

目的: 在C机器取到 A的ip地址,并输出日志客户端的真实ip为192.168.0.110

B机器的nginx 配置:(首层代理)

 location /bb/ {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $remote_addr;proxy_pass http://192.168.56.10/cc/;}

在B中的nginx 中 给请求设置了 header 。 X-Real-IP 和 X-Forwarded-For

X-Real-IP 取得值是 r e m o t e a d d r ,而 remote_addr ,而 remoteaddr,而remote_addr为与主机B直连客户端A 的ip地址。

X-Forwarded-For 取得值是个用逗号分隔得多个值,主要包括客户端X-Forwarded-For的值 与 $remote_addr 的值,两部分用逗号分隔。

所以此时 X-Real-IP 为 192.168.0.110, X-Forwarded-For 为 ,192.168.0.110 此时客户端并未主动传 X-Forwarded-For 头。

  • proxy_set_header X-Real-IP $remote_addr; 这句的作用是将客户端的IP地址赋值给X-Real-IP请求头,$remote_addr变量表示与nginx服务器直接连接的客户端或代理服务器的IP地址。这句一般用于第一层代理服务器,以便后续的代理服务器能够获取到客户端的IP地址。
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这句的作用是将客户端请求头中的X-Forwarded-For和 r e m o t e a d d r 两部分用逗号分隔后赋值给 X − F o r w a r d e d − F o r 请求头, remote_addr两部分用逗号分隔后赋值给X-Forwarded-For请求头, remoteaddr两部分用逗号分隔后赋值给XForwardedFor请求头,proxy_add_x_forwarded_for变量表示客户端请求头中的X-Forwarded-For和$remote_addr两部分。这句一般用于非首层代理服务器,以便将客户端和所有经过的代理服务器的IP地址都记录下来。

C中nginx 输出的log-format

   log_format main '$http_x_forwarded_for|$realip_remote_addr|$http_x_real_ip|$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" ''$upstream_addr $request_time $upstream_response_time ';

C中nginx的配置

http {include       /etc/nginx/mime.types;default_type  application/octet-stream;proxy_set_header        X-Real-IP       $remote_addr; proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;#   real_ip_header X-Forwarded-For;#   set_real_ip_from 192.168.56.1;#   real_ip_recursive on;
}

在这一层中 X-Real-IP 取到的是上层代理的地址,也就是192.168.56.1

X-Forwarded-For 是上两层的地址?192.168.0.110,192.168.56.1 (这一层其实就一个值还是192.168.0.110,在下一层才是这两个值,这里有些歧义,原因是这一层接收到值之后 还没有拼接本层获取上一层的地址。这一层只是待发送状态。proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for 这个是将头拼接后发给下一层的。所以在下一层取到地址才是 192.168.0.110,192.168.56.1

所以在c中的输出日志中打印的值为

192.168.0.110|192.168.56.1|192.168.0.110|192.168.56.1 - - [15/Sep/2023:02:32:43 +0000] "GET /cc/ HTTP/1.0" 200 15539 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "192.168.0.110" 123.121.155.167:16002 0.326 0.326

如果我使用nginx自带的模块 realip 再固定一层,重点观察$remote_addr的值

http {include       /etc/nginx/mime.types;default_type  application/octet-stream;proxy_set_header        X-Real-IP       $remote_addr;proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;real_ip_header X-Forwarded-For;set_real_ip_from 192.168.56.1;real_ip_recursive on;
}

如果我将配置改成这样,我们再来观察一下日志输出

192.168.0.110|192.168.56.1|192.168.0.110|192.168.0.110 - - [15/Sep/2023:02:46:38 +0000] "GET /cc/ HTTP/1.0" 200 15539 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "192.168.0.110" 123.121.155.167:16002 0.796 0.796

上述描述只是两层代理,为了测试出 X-Forwarded-For 的值,我们设置了3层代理。

A -》B-》c-》d

A:192.168.0.110 B:192.168.0.104 C:192.168.0.128(192.168.56.1) D:192.168.56.10

B nginx 配置:

location /testIp/ {# set $current-X-Fowarded-for X-Forwarded-For proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $remote_addr;proxy_pass http://192.168.0.128:6666/testIp/;}

C nginx配置:

 location /testIp/ {# set $current-X-Fowarded-for X-Forwarded-For proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://192.168.56.10/testIp/;}

D nginx 配置:

http {include       /etc/nginx/mime.types;default_type  application/octet-stream;proxy_set_header        X-Real-IP       $remote_addr;proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;# real_ip_header X-Forwarded-For;#  set_real_ip_from 192.168.56.1;#  real_ip_recursive on;.....localtion /testIp/ {porxy_pass  http://666.com}}

D 中nginx的日志

192.168.0.110, 192.168.0.104|192.168.56.1|192.168.0.104|192.168.56.1 - - [15/Sep/2023:03:26:30 +0000] "GET /testIp/ HTTP/1.0" 200 15539 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "192.168.0.110, 192.168.0.104" 192.168.0.104:82 0.299 0.299

192.168.0.110, 192.168.0.104 是输出的X-forwarded-for 的值。

   real_ip_header X-Forwarded-For;set_real_ip_from 192.168.56.1;real_ip_recursive on;

这三个值一般是加到最后的D中,为了设置授信ip为上层的remot_addr的值,

  • set_real_ip_from:用于设置信任的 IP,即请求头中的 IP 中 nginx 认为可信的 IP。一般是前几层代理的 IP。
  • real_ip_header:用于告诉 nginx 从哪个请求头字段中获取客户端真实的 IP。一般是 X-Forwarded-For 或 X-Real-IP。
  • real_ip_recursive:用于控制 nginx 如何从请求头字段中获取多个 IP 中的一个。当值为 on 时,nginx 会从右往左排除信任的 IP,取最后一个非信任的 IP 作为客户端真实的 IP。

例如,如果您想从 X-Forwarded-For 字段中获取客户端真实的 IP,并且信任 192.168.56.1 这个 IP,您可以在 location 中添加以下代码:

location /test {proxy_pass http://backend;real_ip_header X-Forwarded-For;set_real_ip_from 192.168.56.1;real_ip_recursive on;
}

这样,nginx 就会把 X-Forwarded-For 字段中最后一个非 192.168.56.1 的 IP 赋值给 $remote_addr 变量,作为客户端真实的 IP。

对于nginx 获取客户端真实ip做个总结

  • 对于首层代理服务器,使用proxy_set_header X-Forwarded-For $remote_addr;来将客户端IP赋值给X-Forwarded-For请求头
  • 对于非首层代理服务器,使用proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;来将客户端请求头中的X-Forwarded-For和$remote_addr两部分用逗号分隔后赋值给X-Forwarded-For请求头
    ursive on;
    }
    这样,nginx 就会把 X-Forwarded-For 字段中最后一个非 192.168.56.1 的 IP 赋值给 $remote_addr 变量,作为客户端真实的 IP。

对于nginx 获取客户端真实ip做个总结

对于首层代理服务器,使用proxy_set_header X-Forwarded-For $remote_addr;来将客户端IP赋值给X-Forwarded-For请求头

  • 对于非首层代理服务器,使用proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;来将客户端请求头中的X-Forwarded-For和$remote_addr两部分用逗号分隔后赋值给X-Forwarded-For请求头
  • 如果有多层代理服务器,可以使用nginx的realip模块来从XFF中抛弃指定的可信IP,从而获取用户真实IP

相关文章:

nginx配置获取客户端的真实ip

场景描述: 访问路径: A机器 - > B机器的 ->C虚拟机 : A机器为客户端用户,本地地址为 192.168.0.110 B机器为服务端反向代理服务器 本地地址为192.168.0.128 –>(192.168.56.1) C机器为B主机安…...

1990-2022上市公司董监高学历工资特征信息数据/上市公司高管信息数据

1990-2022上市公司董监高学历工资特征信息数据/上市公司高管信息数据 1、时间:1990-2022年(统计截止日期为 2022年7月) 2、指标:证券代码、统计截止日期、姓名、国籍、籍贯、籍贯所在地区代码、出生地、出生地所在地区代码、性别…...

Java程序连接 Mysql 超时问题 - 数据包过大,导致超时,# 配置网络超时时间 socketTimeout: 1800000

问题 Java程序连接 Mysql 超时问题 解决方法 如果存在 yml 等类似的配置文件,那么可以配置一下 socket 连接超时的参数,例如 # 配置网络超时时间 半小时,计算公式 60秒*1000毫秒*30分钟 socketTimeout: 1800000...

c++分层最短路(洛谷飞行路线)acwing版

分层最短路算法是在SPFA算法的基础上&#xff0c;将每个点分成若干层&#xff0c;从而使得每个点之间的转移只在同一层次或上下两个相邻层次之间进行&#xff0c;减少了每轮的迭代次数&#xff0c;优化了算法的效率。 #include <iostream> #include <cstdio> #inc…...

Python bs4 BeautifulSoup库使用记录

目录 介绍 安装 初始化 解析器 使用方法 优势 Python标准库 lxml HTML lxml XML html5lib 格式化输出 对象 tag Name 多值属性 其他方法 NavigableString BeautifulSoup Comment 遍历 子节点 父节点 兄弟节点 回退和前进 搜索 过滤器 字符串 正则表达…...

Jmeter系列-插件安装(5)

前言 jmeter4.0以上&#xff0c;如现在最新的5.2.1版本是有集成插件的只需要在官网下载 plugins-manager.jar 包&#xff0c;放在jmeter安装路径的lib/ext目录下即可使用&#xff1a;https://jmeter-plugins.org/install/Install/但并不能满足所有需求&#xff0c;仍然需要安装…...

spring aop源码解析

spring知识回顾 spring的两个重要功能&#xff1a;IOC、AOP&#xff0c;在ioc容器的初始化过程中&#xff0c;会触发2种处理器的调用&#xff0c; 前置处理器(BeanFactoryPostProcessor)后置处理器(BeanPostProcessor)。 前置处理器的调用时机是在容器基本创建完成时&#xff…...

使用Unity的Input.GetAxis(““)控制物体移动、旋转

使用Unity的Input.GetAxis("")控制物体移动、旋转 Input.GetAxis("") 是 Unity 引擎中的一个方法&#xff0c;用于获取游戏玩家在键盘或游戏手柄上输入的某个轴&#xff08;Axis&#xff09;的值。这里的 "" 是一个字符串参数&#xff0c;表示要…...

【CSS】画个三角形或圆形或环

首先通过调整边框&#xff0c;我们可以发现一些端倪 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style>.box{width: 150px;height:150px;border: 50px solid black;}</style&g…...

AI项目六:基于YOLOV5的CPU版本部署openvino

若该文为原创文章&#xff0c;转载请注明原文出处。 一、CPU版本DEMO测试 1、创建一个新的虚拟环境 conda create -n course_torch_openvino python3.8 2、激活环境 conda activate course_torch_openvino 3、安装pytorch cpu版本 pip install torch torchvision torchau…...

记录YDLidar驱动包交叉编译时出现的一点问题

由于一不小心把交叉编译的系统根目录破坏了&#xff0c;所以一股脑将交叉编译系统根目录全删了重新安装&#xff0c;安装后&#xff0c;交叉编译发现ydlidar的ros包驱动出现了库无法链接的错误(刚刚还是好好的)&#xff0c;但是又想不起来之前是怎么解决的了&#xff0c;所以还…...

嵌入式学习笔记(32)S5PV210的向量中断控制器

6.6.1异常处理的2个阶段 可以将异常处理分为2个阶段来理解。第一个阶段是异常向量表跳转&#xff1b;第二个阶段是进入了真正的异常处理程序irq_handler之后的部分。 6.6.2回顾&#xff1a;中断处理的第一个阶段&#xff08;异常向量表跳转阶段&#xff09;处理 &#xff08;…...

linux下安装qt、qt触摸屏校准tslib

linux下安装qt 在 Linux 系统下安装 Qt&#xff0c;可以通过以下步骤进行操作&#xff1a;1. 下载 Qt 安装包&#xff1a;首先&#xff0c;你需要从 Qt 官方网站&#xff08;https://www.qt.io/&#xff09;下载适用于 Linux 的 Qt 安装包。选择与你的系统和需求相匹配的版本&…...

C++之unordered_map,unordered_set模拟实现

unordered_map&#xff0c;unordered_set模拟实现 哈希表源代码哈希表模板参数的控制仿函数增加正向迭代器实现*运算符重载->运算符重载运算符重载! 和 运算符重载begin()与end()实现 unordered_set实现unordered_map实现map/set 与 unordered_map/unordered_set对比哈希表…...

React Router,常用API有哪些?

react-router React Router是一个用于构建单页面应用程序&#xff08;SPA&#xff09;的库&#xff0c;它是用于管理React应用中页面导航和路由的工具。SPA是一种Web应用程序类型&#xff0c;它在加载初始页面后&#xff0c;通过JavaScript来动态加载并更新页面内容&#xff0…...

JVM类加载和双亲委派机制

当我们用java命令运行某个类的main函数启动程序时&#xff0c;首先需要通过类加载器把类加载到JVM&#xff0c;本文主要说明类加载机制和其具体实现双亲委派模式。 一、类加载机制 类加载过程&#xff1a; 类加载的过程是将类的字节码加载到内存中的过程&#xff0c;主要包括…...

P-MVSNet ICCV-2019 学习笔记总结 译文 深度学习三维重建

文章目录 5 P-MVSNet ICCV-20195.0 主要特点5.1 文章概述5.2 研究方法5.2.1 特征提取5.2.2 学习局域匹配置信5.2.3 深度图预测5.2.4 Loss方程MVSNet系列最新顶刊 对比总结5 P-MVSNet ICCV-2019 深度学习三维重建 P-MVSNet-ICCV-2019(原文、译文、批注) 下载 5.0 主要特点 …...

vueshowpdf 移动端pdf文件预览

1、安装 npm install vueshowpdf -S2、参数 属性说明类型默认值v-model是否显示pdf--pdfurlpdf的文件地址String- scale 默认放大倍数 Number1.2 minscale 最小放大倍数 Number0.8 maxscale 最大放大倍数 Number2 3、事件 名称说明回调参数closepdf pdf关闭事件-pdferr文…...

C#根据excel文件中的表头创建数据库表

C#根据excel文件中的表头创建数据库表 private void button1_Click(object sender, EventArgs e){string tableName tableNameTextBox.Text;string connectionString "";using (OpenFileDialog openFileDialog new OpenFileDialog()){openFileDialog.Filter &quo…...

js通过xpath定位元素并且操作元素以下拉框select为例

js也可以使用xpath定位元素&#xff0c;现在实例讲解。 页面上有一个下拉框&#xff0c;里面内容有三个&#xff0c;用F12看一下 一、使用xpath定位这个下拉框select eldocument.evaluate(//select[name"shoppingPreference"], document).iterateNext()二、为下拉框…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...