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

获取客户端真实IP

  出于安全考虑,近期在处理一个记录用户真实IP的需求。本来以为很简单,后来发现没有本来以为的简单。这里主要备忘下,如果服务器处于端口回流(hairpin NAT),keepalived,nginx之后,如何取得客户端的外网IP。

  来自客户端PC的流量路径如上,在这样的拓扑中,在应用服务中取得,客户端PC的外网ip,可能会遇到哪些问题呢?(ip 编的随意,为便于说明,不考虑合理)。

  • 编程实现

  Java 为例,这个我会。

    public static String getClientIP(HttpServletRequest request) {String remoteAddr = request.getRemoteAddr();return remoteAddr;}

  运行一下,输出呢是 3.3.3.3 。 这是因为这个API所取得的是IP数据包的源地址。Nginx的反向代理时工作在应用层的,当他收到一个http请求时,会对应生成一个新的请求,发送给应用服务,这个请求的IP包的源地址是Nginx服务器的IP即3.3.3.3。

  • Nginx头部注入

  因为是应用层,那这个请求ip包的源地址肯定就是3.3.3.3了,但是在应用层我们可以附加一点信息,以便后面的应用服务,可以通过这个附加信息,了解这个请求对应的原始源地址。这个我也会。

  在Nginx 中配置。

server {...proxy_set_header X-Real-IP $remote_addr;

  在应用层http协议中,加一个http header。X-Real-IP:$remote_addr. $remote_addr 是一个预设变量,代表所代理转发请求的原始源ip地址。

  在Java 程序中,读取对应的附加信息

    public String getRealIp(HttpServletRequest request) {String realIp = request.getHeader("X-Real-IP");if (realIp != null && !realIp.isEmpty()) {return "Client's Real IP: " + realIp;} return "";}    

  运行一下,此时输出2.2.2.2。 显然我们向前推进了一步。

  • Keepalived负载均衡模式

  印象里这里keepalived的主要作用应该是解决nginx 代理服务器的单点问题的,似乎也被配置为负载均衡了?翻了下配置文件,实际的情况如下。

  运维大壮说他配置keepalived 时候多考虑了一步,如果机器活着,nginx 挂了怎么办,于是又做了一层负载均衡(这种情况虚拟IP不会漂移到右边的备机)。他说的也确实不是没有道理。keepalived 的负载均衡貌似是工作在第三层的,那肯定在负载均衡的时候,又对ip包的源地址进行了修改。这是网络层,向nginx 这样附加信息肯定是不行了。于是,翻了翻手册发现,keepalived 的负载均衡支持三种路由模式,NAT,Direct Routing 和 Tunneling。

  NAT 模式,会修改源IP,出入流量都会经过负载均衡器。而DR模式,会直接修改MAC地址,那回程流量就不再经过负载均衡器了,也就意味这种模式,源地址不会被修改,回程流量会直接发送给源ip地址。

  DR模式有个要求,就是负载均衡器需要能知道后端服务的MAC地址,这是依赖于ARP实现的,也就是,要求负载均衡器和后端服务器在同一广播域。恰好我门可以满足。于是。

virtual_server 192.168.11.242 80 {
……
lb_kind DR
……

  将负载均衡路由模式切换为DR模式。重新看一下这次,取得客户端地址变成了 1.1.1.1, 这一步一坑。为什么到达keepalived的ip包的源地址会变成,出口路由器的外网地址呢?

  • 路由器端口回流(Hairpin NAT)

  离胜利是不远了,此时见多识广的大壮说,这应该是跟端口回流有关,之前有个系统也是类似问题, 你的web端口配置了端口回流,如果关掉端口回流就可以取得外网地址了。什么是端口回流?

   首先,路由器做了端口映射,1.1.1.1:80->192.168.0.2:80

  服务器A,由于某些原因,不方便使用内网地址192.168.0.2访问B,而要通过外网IP或者域名访问服务器B,即访问1.1.1.1:80, 按端口转发规则,路由器会将这个来自于内网接口的流量再次转发回内网服务器B,形成了一个180度的急弯——发卡弯,这也就是Haripin NAT的名字由来,十分形象。

  如果不做设置,服务器A通过访问1.1.1.1:80 是无法正常访问服务器B的。原因是,hairpin会影响Tcp连接建立的握手过程。

  1. A发送握手请求给入口路由器,路由器修改目的ip为192.68.0.2 ,发送到服务器B。

  2.B收到握手请求后,回复握手确认应答给这个握手请求的源IP地址,此处是A的地址192.168.0.1

  3.因为A,B同一网络,握手确认会直接到达A。

  4.A发现这个握手确认回复的源ip(192.168.0.2)并不是我期望与之建立连接的握手请求目的地址(1.1.1.1),A并不认识B,只认识路由器,导致TCP连接无法建立。

  解决以上问题的关键,就是让握手确认应当同样经过路由器,发送给A。因此,需要在之前将握手请求转发给B时,同时修改源ip地址为(1.1.1.1),如此,B服务器作出确认回复时,自然也会发送给1.1.1.1。

  但是这个源地址转化(SNAT)的过程,实际上只对于来自内网的流量是有必要的。对于外网流量,其源IP本身就处于网络外部,必然会经过再次经过路由器返回。

  于是联系管路由器的小明,请他不要偷懒,规则配置的细致一点,不要做无差别的源地址转换。即

  1.对内网接口流量进行源地址和目标地址转换2.对外网流量只进行目标地址转化。

  重新测试。 终于输出实际了客户PC实际ip地址0.0.0.0

    

  OK,一波三折,跌宕起伏,写到这里~

相关文章:

获取客户端真实IP

出于安全考虑,近期在处理一个记录用户真实IP的需求。本来以为很简单,后来发现没有本来以为的简单。这里主要备忘下,如果服务器处于端口回流(hairpin NAT),keepalived,nginx之后,如何取得客户端的…...

韩式告白土味情话-柯桥生活韩语学习零基础入门教学

你们韩国人别太会告白了! 1、너 얼굴에 뭐가 조금 묻었어! 你的脸上有点5376东西! 뭐가 조금 묻었1585757는데? 有点什么? 이쁨이 조금 묻었네. 有点漂亮。 2、돌잡이 때 뭐 잡았어요? 你抓周的时候抓了什么? 쌀 잡았…...

Linux安全与高级应用(一)深入探讨Linux安全与高级应用

文章目录 深入探讨Linux安全与高级应用引言目录一、Linux安全与应用概述1.1 Linux的应用现状1.2 Linux的安全需求 二、构建LAMP企业网站平台2.1 LAMP平台简介2.2 安装和配置Apache服务器2.2.1 安装Apache2.2.2 配置Apache 2.3 安装和管理MySQL数据库2.3.1 安装MySQL2.3.2 配置M…...

【nginx 第二篇章】各个环境安装 nginx

一、Windows环境安装 1、下载 Nginx 访问Nginx官网(http://nginx.org/en/download.html)下载稳定版本的 Nginx 压缩包,如 nginx-1.xx.x.zip。下载后解压到指定的目录,例如 D:\nginx。 2、启动 Nginx 直接双击解压目录下的 ngi…...

在Spring Boot和MyBatis-Plus项目中,常见的错误及其解决方法2.0

1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name requestMappingHandlerMapping 现象 在创建bean时发生错误,通常是因为存在重复的URL映射。 解决方法 检查所有控制器方法上的URL映射注解,确保没有重复…...

招聘信息数据清洗

文章目录 前言代码示例如下 前言 相关知识 为了完成本关任务,你需要掌握: 1.Spark 清洗数据的相关方法, 2.空值列怎么删除; 3.怎么数据切分才能达到想要的数据。 Spark清洗数据相关方法 一、将含有空值的数据删除 1.将含有空值的数据删除&a…...

机器学习——支持向量机(SVM)(1)

目录 一、认识SVM 1. 基本介绍 2. 支持向量机分类器目标 二、线性SVM分类原理(求解损失) 三、重要参数 1. kernel(核函数) 2 .C(硬间隔与软间隔) 四、sklearn中的支持向量机(自查&#…...

Elastic Observability 8.15:AI 助手、OTel 和日志质量增强功能

作者:来自 Elastic Alex Fedotyev, Tom Grabowski, Vinay Chandrasekhar, Miguel Luna Elastic Observability 8.15 宣布了几个关键功能: 新的和增强的原生 OpenTelemetry 功能: OpenTelemetry Collector 的 Elastic 分发:此版本…...

Unity3D ECS架构的优缺点详解

前言 Unity3D作为一款强大的游戏开发引擎,近年来在性能优化和架构设计上不断进化,其中ECS(Entity-Component-System)架构的引入是其重要的里程碑之一。ECS架构通过重新定义游戏对象的组织和处理方式,为开发者带来了诸…...

理解Go语言中多种并发模式

Go 的同步原语使实现高效的并发程序成为可能,并且选择合适的同步原语和并发模式可以更加容易地实现并发的可能,减少错误的发生。这里谈论的并发模式是只在 Go 语言中常见的并发的“套路” ,一种可解决某一类通用场景和问题的惯用方法。 1. 并发模式概述 我们先来回顾下同步…...

C++ primer plus 第17 章 输入、输出和文件:文件输入和输出03:文件模式:二进制文件

系列文章目录 17.4.5 文件模式 程序清单17.18 append.cpp 程序清单17.19 binary.cpp 文章目录 系列文章目录17.4.5 文件模式程序清单17.18 append.cpp程序清单17.19 binary.cpp17.4.5 文件模式1.追加文件来看一个在文件尾追加数据的程序。程序清单17.18 append.cpp2.二进制文…...

网络安全之sql靶场(11-23)

sql靶场(11-23) 目录 第十一关(post注入) 第十二关 第十三关 第十四关 第十五关 第十六关 第十七关 第十八关 第十九关 第二十关 第二十一关 第二十二关 第二十三关 第十一关(post注入) 查看…...

WordPress网站被入侵,劫持收录事件分析

7.15,网站被入侵,但是直到7月17日,我才发现被入侵。 16日,17日正常更新文章,17日查询网站收录数据时,在站长资源平台【流量与关键词】查询上,我发现了比较奇怪的关键词。 乱码关键词排名 起初…...

原生js: 实现三个水平tab按钮, 默认第一个上面有class, 点击另外的实现class=‘cur‘的切换的效果

问: <ul><li class"cur">热门问题</li><li>订阅问题</li><li>使用问题</li></ul> 这是我的代码, 这是我的代码: // 遍历 helpInfoClass 数组helpInfoClass.forEach((item, index) > {var itemId item[0];var i…...

C#语言基础速成Day07

“知止而后有定&#xff0c;定而后能静&#xff0c;静而后能安&#xff0c;安而后能虑&#xff0c;虑而后能得。” 目录 前言文章有误敬请斧正 不胜感恩&#xff01;||Day07 C#常见数据结构&#xff1a;1. 集合&#xff08;Collection&#xff09;1.1 **List<T>**1.2 **H…...

jvm运行时常量池溢出的原因

Java虚拟机&#xff08;JVM&#xff09;的运行时常量池&#xff08;Runtime Constant Pool&#xff09;是方法区的一部分&#xff0c;用于存储类和接口的常量池表&#xff0c;包括字面量和对类型、字段和方法的符号引用。运行时常量池溢出通常指的是常量池的内存使用达到了JVM设…...

floyd算法详解

算法是一种用于求解所有顶点对之间的最短路径问题的算法&#xff0c;特别适用于稠密图。下面是一个使用C实现的算法示例&#xff1a; #include <iostream> #include <climits> // For INT_MAXusing namespace std;const int V 4; // 图的顶点数// 定义一个函数来…...

Web前端性能优化的方向

减少dom渲染复杂列表优化缓存优化首页背景图片加载慢&#xff0c;可以放在服务器上&#xff0c;读取绝对路径900k的图片大小有些大&#xff0c;可以对图片进行压缩&#xff0c;tinypng网站压缩、熊猫压缩、bing域名下的图片url后面带参数w、h、qlt剪裁下拉框数据较多进行懒加载…...

【面试题】设计模式-责任链模式

设计模式-责任链模式 前言责任链简历案例代码小结 前言 我们知道&#xff0c;设计模式是面试时经常被问到的问题之一&#xff0c;这是因为设计模式能够体现出代码设计的美感&#xff0c;且在很多框架的底层也都会使用到各种设计模式&#xff0c;所以对设计模式的考察&#xff…...

JavaEE 第8节 单例模式详解

目录 概念 饿汉模式 懒汉模式 懒汉模式在多线程环境下的优化 1.线程安全问题 2.效率问题 3.指令重排序导致的问题 1&#xff09;为什么要进行指令重排序&#xff1f; 2&#xff09;指令重排序在上述代码为什么会构成问题&#xff1f; 导读&#xff1a; 单例模式是一种…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...