【Java开发】之获取客户端真实 IP 地址
一、应用场景
- 在投票系统开发中,为了防止刷票,我们需要限制每个 IP 地址只能投票一次;
- 当网站受到诸如 DDoS(Distributed Denial of Service,分布式拒绝服务攻击)等攻击时,我们需要快速定位攻击者 IP;
- 在渗透测试过程中,经常会碰到网站有 CDN(Content Distribution Network,内容交付网络),这时我们需要绕过 CDN 查找真实 IP;
二、获取客户端的 IP 地址
服务端获取客户端请求IP地址,常见的包括:remote_addr、x-forwarded-for、client-ip 等请求头参数:
remote_addr:指的是当前直接请求的客户端IP地址,它存在于tcp请求体中,是http协议传输的时候自动添加,不受请求头header的控制。因此,当客户端与服务器之间不存在任何代理的时候,通过remote_addr获取客户端IP地址是最准确,也是最安全。remote_addr无法伪造x-forwarded-for,即XFF,是很多代理服务器在请求转发时添加上去的。如果客户端和服务器之间存在代理服务器,那么通过remote_addr获取的IP就是代理服务器的地址,并不是客户端真实的IP地址。因此,需要代理服务器(通常是反向代理服务器)将真实客户端的IP地址转发给服务器,转发时客户端的真实IP地址通常就存在于XFF请求头中。client-ip:同XFF,也是代理服务器添加的用于转发客户端请求的真实IP地址,同样保存与请求头中。
在 Java 中,获取客户端 IP 最直接的方式就是使用 request.getRemoteAddr()。这种方式在中间没有代理的情况下,获取连接到服务器的客户端 IP 的最简单有效的方式。
但是目前互联网 Web 应用很少会将应用服务器直接对外提供服务,一般都会有一层 Nginx 做反向代理和负载均衡,有的甚至可能有多层代理。所以,在有反向代理的情况下,直接使用 request.getRemoteAddr() 获取到的IP地址是Nginx所在服务器的IP地址,而不是客户端的 IP。
为了解决上面的问题,很多 HTTP 代理会在 HTTP 协议头中添加 X-Forwarded-For 头,用来追踪请求的来源,X-Forwarded-For 的格式如下:
X-Forwarded-For: client1, proxy1, proxy2
X-Forwarded-For 包含多个 IP 地址,每个值通过逗号+空格分开,最左边(client1)是最原始客户端的IP地址,中间如果有多层代理,每一层代理会将连接它的客户端IP追加在 X-Forwarded-For 右边。
下面就是一种常用的获取客户端真实IP的方法:
public static String getRealIP(HttpServletRequest request) {String ip = request.getHeader("X-Forwarded-For");if (ip != null) {ip = ip.contains(",") ? ip.split(",")[0] : ip;} else {if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}}return ip;
}
注意,要让 Nginx 支持 X-Forwarded-For 头,需要配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$proxy_add_x_forwarded_for 会将和 Nginx 直接连接的客户端 IP 追加在请求原有 X-Forwarded-Fo r值的右边。
三、IP 伪造及解决方案
1、客户端可以伪造 X-Forwarded-For
一般的客户端(例如浏览器)发送HTTP请求是没有 X-Forwarded-For 头的,当请求到达第一个代理服务器时,代理服务器会加上 X-Forwarded-For 请求头,并将值设为客户端的IP地址(也就是最左边第一个值),后面如果还有多个代理,会依次将IP追加到 X-Forwarded-For 头最右边,最终请求到达Web应用服务器,应用通过获取 X-Forwarded-For 头取左边第一个IP即为客户端真实IP。
但是如果客户端在发起请求时,请求头上带上一个伪造的 X-Forwarded-For,由于后续每层代理只会追加而不会覆盖,那么最终到达应用服务器时,获取的左边第一个IP地址将会是客户端伪造的 IP。
2、解决方案:配置 Nginx 反向代理
在直接对外的Nginx反向代理服务器上配置:
proxy_set_header X-Forwarded-For $remote_addr;
如果有多层Nginx代理,内层的Nginx配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
在最外层 Nginx(即直接对外提供服务的Nginx)使用 $remote_addrb代替上面的 $proxy_add_x_forwarded_for,可以防止伪造 X-Forwarded-For。$proxy_add_x_forwarded_forb会在原有 X-Forwarded-For 上追加IP,这就相当于给了伪造 X-Forwarded-Fo r的机会。而 $remote_addr 是获取的是直接 TCP 连接的客户端 IP,这个是无法伪造的,即使客户端伪造也会被覆盖掉,而不是追加。
需要注意的是:如果有多层代理,只在直接对外访问的 Nginx 上配置 X-Forwarded-For 为 $remote_addr,内层的 Nginx 还是要配置为 $proxy_add_x_forwarded_for,不然内层的 Nginx 又会覆盖掉客户端的真实IP。
完成以上配置后,获取X-Forwarded-For最左边的IP地址即为真实的客户端地址,且客户端也无法伪造。
相关文章:
【Java开发】之获取客户端真实 IP 地址
一、应用场景 在投票系统开发中,为了防止刷票,我们需要限制每个 IP 地址只能投票一次;当网站受到诸如 DDoS(Distributed Denial of Service,分布式拒绝服务攻击)等攻击时,我们需要快速定位攻击者…...
Linux RPM包安装、卸载和升级
我们以安装 apache 程序为例。因为后续章节还会介绍使用源码包的方式安装 apache 程序,读者可以直观地感受到源码包和 RPM 包的区别。 RPM包默认安装路径 通常情况下,RPM 包采用系统默认的安装路径,所有安装文件会按照类别分散安装到表 1 所…...
ROS 多级tf坐标转换
题目 现有一移动机器人,该机器人的基坐标系为“base_link”,机器人包含3个子坐标系分别为“joint1”,“joint2”,“joint3”。 要求:利用多坐标转换,实现joint1下的坐标向joint2下的坐标转换,…...
ceph rados对象存储索引残留问题排查与处理
问题现象 对象存储存储桶无法删除,检查发现生命周期过期后存储桶中有文件残留,未完全删除,但实际访问文件时为404,通过s3cmd无法删除对象,且无报错。 问题定位 检查bucket当前状态,发现桶内有大量object…...
十年测试工龄,揭露软件测试痛点以及分析
做软件测试的同学们,你在平时的测试工作中有哪些困惑或困扰呢?你可以自行简单思考一下。下面我梳理一下,大家可以看看自己是不是也有如此的感受。 从测试整体角度分析: 第一个痛点是入门容易深入难。 很多人认为软件测试也就那么…...
【星海出品】flask(三) 组件
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架 wsgiref 因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python编写Web业务。 这个…...
关于卷积神经网络的池化层(pooling)
了解池化层 池化层又称“下采样层”或“子采样层”,池化层可以大大降低特征的维度,减少计算量,同时可以避免过拟合问题。 顾名思义,最大池化层就是从输入的矩阵中某一范围内,选择最大的元素进行保留;平均池…...
GNU链接脚本详解
0. 前言 每一个链接都是由链接脚本控制的,链接脚本是用链接命令语言编写的脚本。链接都会用到一个链接脚本,如果你没有指定自己的脚本,就会使用默认的链接脚本。可以用 "--verbose" 命令行选项显示默认的连接脚本。指定命令行参数…...
酷柚易汛ERP-账户管理操作指南
1、应用场景 对账户进行管理,可设置账户当前余额、期初余额和设置是否为默认账户。 2、主要操作 2.1 新增支付账户 打开【资料】-【账款管理】,点击【新增】添加账户类别,输入相关信息并保存,账户编号和名称为必录项。&#x…...
函数的连续性
函数在某一点极限存在,不一定连续 函数的左极限 函数的右极限 函数在某点连续需要满足三个条件 1、左右极限存在 2、左右极限相等 3、函数在该点的极限值等于在该点的函数值 满足1、2两个条件函数在该点极限存在。...
Pandas groupby方法中的group_keys属性
pandas版本1.5.3中groupby方法,当设置group_keysTrue时,会以groupby的字段为第一级索引,如下述代码中time_id作为第一级索引,同时保留了原dataframe(df)中的索引作为第二级索引。 >>> df.groupby…...
win 命令替代鼠标的操作
操作方式都是在 winR 输入框输入或者终端输入 1、快速打开 控制面板 运行control 2、快速打开 电源选项 运行powercfg.cpl 3、快速打开 网络连接 运行ncpa.cpl 4、快速打开 程序和功能 运行appwiz.cpl 5、快速打开 Windows Defender防火墙 运行Firewall.cpl 6、快速打开 鼠标 …...
Shopee活动取消规则是什么?shopee官方促销活动怎么取消?
作为一家知名的电商平台,shopee官方对于消费者取消促销活动的请求给予了相应的规定和处理流程。 shopee活动取消规则是什么? 首先,消费者应该明确了解虾皮的促销活动取消规则。根据虾皮的官方规定,消费者在参与促销活动之前&…...
安卓常见设计模式2------构建者模式(Kotlin版)
1. W1 是什么,什么是构建者模式? 构建者模式(Builder Pattern)是一种创建复杂对象的设计模式。它通过使用链式调用的方式,逐步构建对象,使得代码更易读、可维护,并且可以处理许多可选参数的情况…...
redis主从复制+哨兵
1.主从复制 redis配置文件redis.conf master机器:IP 192.168.1.5 ,端口 6379 设置配置参数 daemonize yes #bind 127.0.0.1 -::1 protected-mode no port 6379 dbfilename "dump.rdb" dir "/root/redis/my_redis_conf/dumpdir" l…...
html动态爱心超文本标记代码,丝滑流畅有特效,附源码
没想到现在看个剧(点燃我,温暖你)要的同款居然是代码,李峋 这盛世如你所愿啊!李峋的同款爱心代码来啦,拿走试试吧~ <!DOCTYPE html> <html><head><title></title&g…...
力扣:162. 寻找峰值(Python3)
题目: 峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时…...
【Python】20大报告生成词云
这个我其实写过一篇类似的博客,但是那个的文件对象是.csv,对应到.docx文件的话,就不太适用了。如下: Python生成词云-CSDN博客 代码: import jieba import os import wordcloud import numpy as np from PIL import…...
目标检测YOLO实战应用案例100讲-基于无人机的轻量化目标检测系统设计
目录 前言 国内外研究现状 国外研究现状 国内研究现状...
ansible-第二天
ansible 第二天 以上学习了ping、command、shell、script模块,但一般不建议使用以上三个,因为这三个模块没有幂等性。举例如下: [rootcontrol ansible]# ansible test -a "mkdir /tmp/1234"[WARNING]: Consider using the file …...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
