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两部分用逗号分隔后赋值给X−Forwarded−For请求头,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算法的基础上,将每个点分成若干层,从而使得每个点之间的转移只在同一层次或上下两个相邻层次之间进行,减少了每轮的迭代次数,优化了算法的效率。 #include <iostream> #include <cstdio> #inc…...
Python bs4 BeautifulSoup库使用记录
目录 介绍 安装 初始化 解析器 使用方法 优势 Python标准库 lxml HTML lxml XML html5lib 格式化输出 对象 tag Name 多值属性 其他方法 NavigableString BeautifulSoup Comment 遍历 子节点 父节点 兄弟节点 回退和前进 搜索 过滤器 字符串 正则表达…...
Jmeter系列-插件安装(5)
前言 jmeter4.0以上,如现在最新的5.2.1版本是有集成插件的只需要在官网下载 plugins-manager.jar 包,放在jmeter安装路径的lib/ext目录下即可使用:https://jmeter-plugins.org/install/Install/但并不能满足所有需求,仍然需要安装…...
spring aop源码解析
spring知识回顾 spring的两个重要功能:IOC、AOP,在ioc容器的初始化过程中,会触发2种处理器的调用, 前置处理器(BeanFactoryPostProcessor)后置处理器(BeanPostProcessor)。 前置处理器的调用时机是在容器基本创建完成时ÿ…...
使用Unity的Input.GetAxis(““)控制物体移动、旋转
使用Unity的Input.GetAxis("")控制物体移动、旋转 Input.GetAxis("") 是 Unity 引擎中的一个方法,用于获取游戏玩家在键盘或游戏手柄上输入的某个轴(Axis)的值。这里的 "" 是一个字符串参数,表示要…...
【CSS】画个三角形或圆形或环
首先通过调整边框,我们可以发现一些端倪 <!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
若该文为原创文章,转载请注明原文出处。 一、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驱动包交叉编译时出现的一点问题
由于一不小心把交叉编译的系统根目录破坏了,所以一股脑将交叉编译系统根目录全删了重新安装,安装后,交叉编译发现ydlidar的ros包驱动出现了库无法链接的错误(刚刚还是好好的),但是又想不起来之前是怎么解决的了,所以还…...
嵌入式学习笔记(32)S5PV210的向量中断控制器
6.6.1异常处理的2个阶段 可以将异常处理分为2个阶段来理解。第一个阶段是异常向量表跳转;第二个阶段是进入了真正的异常处理程序irq_handler之后的部分。 6.6.2回顾:中断处理的第一个阶段(异常向量表跳转阶段)处理 (…...
linux下安装qt、qt触摸屏校准tslib
linux下安装qt 在 Linux 系统下安装 Qt,可以通过以下步骤进行操作:1. 下载 Qt 安装包:首先,你需要从 Qt 官方网站(https://www.qt.io/)下载适用于 Linux 的 Qt 安装包。选择与你的系统和需求相匹配的版本&…...
C++之unordered_map,unordered_set模拟实现
unordered_map,unordered_set模拟实现 哈希表源代码哈希表模板参数的控制仿函数增加正向迭代器实现*运算符重载->运算符重载运算符重载! 和 运算符重载begin()与end()实现 unordered_set实现unordered_map实现map/set 与 unordered_map/unordered_set对比哈希表…...
React Router,常用API有哪些?
react-router React Router是一个用于构建单页面应用程序(SPA)的库,它是用于管理React应用中页面导航和路由的工具。SPA是一种Web应用程序类型,它在加载初始页面后,通过JavaScript来动态加载并更新页面内容࿰…...
JVM类加载和双亲委派机制
当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把类加载到JVM,本文主要说明类加载机制和其具体实现双亲委派模式。 一、类加载机制 类加载过程: 类加载的过程是将类的字节码加载到内存中的过程,主要包括…...
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定位元素,现在实例讲解。 页面上有一个下拉框,里面内容有三个,用F12看一下 一、使用xpath定位这个下拉框select eldocument.evaluate(//select[name"shoppingPreference"], document).iterateNext()二、为下拉框…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
