docker:Java通过nginx获取客户端的真实ip地址

问题现象

  • 我们的平台使用Spring Cloud微服务架构,使用Spring Boot构建Java服务,使用google的jib插件打成docker镜像包
  • 我们使用docker虚拟化部署,使用docker-compose统一管理所有服务,包括Java服务和nginx等组件
  • 我们前后端分离,前端通过nginx访问我们的网关(Spring Cloud Gateway),再转发到对应的Java服务
  • 我们需要记录一些基础业务数据变动日志,于是在过滤器里拦截对应请求记录日志
  • 在记录操作的来源ip时,记录了一个172.18.0.x的地址,这个明显不是实际客户端来源的ip

排查解决

  • 我们使用getRemoteAddres(request)获取的ip地址,按理说是能获取到客户端的真实ip地址的
  • 地址不对,想着从request的header里直接获取,参考网上的方法,查看哪个header参数里有ip地址
    log.info("X-Real-IP={}", request.getHeader("X-Real-IP"));log.info("X-Original-Forwarded-For={}", request.getHeader("X-Original-Forwarded-For"));log.info("X-Forwarded-For={}", request.getHeader("X-Forwarded-For"));log.info("x-forwarded-for={}", request.getHeader("x-forwarded-for"));log.info("Proxy-Client-IP={}", request.getHeader("Proxy-Client-IP"));log.info("WL-Proxy-Client-IP={}", request.getHeader("WL-Proxy-Client-IP"));log.info("HTTP_CLIENT_IP={}", request.getHeader("HTTP_CLIENT_IP"));log.info("HTTP_X_FORWARDED_FOR={}", request.getHeader("HTTP_X_FORWARDED_FOR"));
  • 结果发现,只有X-Forwarded-For能获取到地址,还是那个错误的172.18.0.x的地址
    在这里插入图片描述

  • 地址不对,应该是哪里出了问题,可能是docker网络、nginx代理或者gateway网关

  • 进一步排查,这个地址之前看到过,172.1x.0.x,是docker网络生成的ip地址

  • 使用docker命令docker network ls,查看了docker网络后,发现我们确实用的是这个
    在这里插入图片描述

  • 继续查看各个docker服务的ip,确定下这个ip是哪个服务的,具体来说,是nginx的、gateway的,还是具体的这个Java应用的

  • 使用docker exec -it 服务名 /bin/bash进入docker容器内部,使用cat /etc/hosts查看网络配置

  • 对比发现这个ip是nginx服务的,说明获取客户端远程地址时,获取到了nginx的ip
    在这里插入图片描述

  • nginx是决定能获取到正确的客户端请求ip地址的,因为它的log日志输出里,是有来源ip的
    在这里插入图片描述

修改nginx配置

  • 查看了nginx的配置文件default.conf,发现里面没有其他配置,已有的X-Forwarded-For配置为proxy_set_header X-Forwarded-For $proxy_protocol_addr;,这里直接把nginx代理服务自己的地址赋给了X-Forwarded-For,所以我们获取到的是nginx的地址
  • 我们现在需要做的,主要是在主配置文件,添加一行proxy_set_header X-Real-IP $remote_addr;,将客户端的真实ip地址,赋给X-Real-IP
  • 执行命令docker restart nginx,重启nginx使其生效

Java代码

  • Java代码修改也很简单,对应nginx的配置,获取X-Real-IP即可
    public static String getIpAddress(HttpServletRequest request) {String ip = request.getHeader("X-Real-IP");if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}
  • 成功获取,结束
    在这里插入图片描述

nginx配置proxy_set_header介绍

在Nginx配置中,proxy_set_header 指令是用于定义向代理服务器传递的请求头字段。该指令专门用于location块中,并且通常配合 proxy_pass 指令一起工作,proxy_pass 指令定义了代理服务器的协议和地址。

基本上,当Nginx作为反向代理服务器时,客户端的请求首先到达Nginx,然后Nginx将这些请求转发到后端的上游服务器。在转发请求时,Nginx可以设置或修改请求头。proxy_set_header 指令正是用来进行这样的设置或修改。

下面是几个proxy_set_header 常见用例:

  • 传递主机名 - 将客户端请求的原主机头信息传递到上游服务器。

    proxy_set_header Host $host;
    
  • 传递真实IP地址 - 将客户端的真实IP地址传递给后端应用,这在后端应用需要记录真实的客户端地址时非常有用。

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
  • 传递HTTPS相关信息 - 当Nginx用作SSL终结时,它可以告诉后端应用请求是通过HTTPS或HTTP进行的。

    proxy_set_header X-Forwarded-Proto $scheme;
    
  • 用户的Worker处理状态: 有时,应用程序可能需要知道客户端连接的具体状态。

    proxy_set_header Connection $connection_upgrade;
    

标准的 proxy_set_header 指令使用方法如下:

proxy_set_header Header-Name Header-Value;
  • Header-Name 是你希望设置的HTTP请求头名称。
  • Header-Value 是对应的值,它可能是一个固定的字符串,也可以是Nginx提供的变量,如 $remote_addr$http_user_agent$http_cookie 等。

注意,默认情况下,Nginx会使用某些标准请求头,如HostConnection等,如果你没有明确使用proxy_set_header设置它们,Nginx会传递它的默认值。

在调整Nginx作为反向代理服务器时,正确配置proxy_set_header指令能确保后端服务器可以接收到所需的所有重要信息,提供正确和安全的服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/633828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏《泰坦陨落2》msvcr120.dll丢失的多种解决方法分享

在Windows 11操作系统环境下,众多玩家在体验《泰坦陨落2》这款备受瞩目的射击游戏时,遭遇了一个令人困扰的技术问题:系统提示缺失msvcr120.dll文件。这一关键的动态链接库文件对于游戏的正常运行至关重要,它的缺失直接导致了《泰坦…

如何用 ChatGPT生成生成元宇宙内容

ChatGPT 是一种强大的自然语言处理模型,可以生成高质量的文本内容,包括元宇宙相关内容。以下是一些建议,帮助您使用 ChatGPT 生成元宇宙相关内容: 明确需求:在开始生成内容之前,请明确您需要什么样的元宇宙…

ACEeditor使用手册(二)

文章目录 ACEeditor使用手册3. 代码高亮与语言支持3.1 语法高亮内置语言模式列表自定义语言模式动态切换语言模式 3.2 代码补全与提示启用代码补全功能自定义补全规则第三方补全库的集成 3.3 代码片段与模板插入代码片段自定义代码片段代码模板的使用 4. 编辑器配置与扩展4.1 编…

小白数学建模 Mathtype 7.7傻瓜式下载安装嵌入Word/WPS以及深度使用教程

数学建模Mathtype的下载安装嵌入Word/WPS以及深度使用教程 一 Mathtype 的下载安装1.1 安装前须知1.2 下载压缩包1.3 安装注册 二 嵌入Word/WPS2.1 嵌入Word2.1.1 加载项嵌入 Word2.1.2 宏录制嵌入 Word 2.2 嵌入 WPS2.2.1 加载项嵌入 WPS2.2.2 宏录制嵌入 WPS 2.3 嵌入时报错解…

【GNN报告】“青源Talk”-图可信学习与图大模型研究进展

北航王啸-图自监督学习 简介 介绍 浙大杨洋-探索大图模型预训练 总括 介绍 参考 Yang Yang - Zhejiang University dgraph-web DGraph: ALarge-Scale Financial Dataset for Graph Anomaly Detection All in One: Multi-task Prompting for Graph Neural Networks&#xf…

element-ui 打包流程源码解析(上)

目录 1,源码整体结构1.1,build 目录1.2,examples 目录1.3,packages 目录1.4,src 目录 2,打包整体流程2.1,npm run build:file2.1.1,build/bin/iconInit.js2.1.2,build/bi…

vue2 -- 截图工具html2canvas

文章目录 🍉需求描述🍉基础功能实现🍉下载另存为本地图片功能🍉需求描述 可以将网页中的指定元素或整个页面截取为图片,以便保存或分享。 🍉基础功能实现 在 Vue 中使用 html2canvas 实现 1:安装 html2canvas 库。你可以使用 npm 安装,命令如下: npm install …

K8S-YAML

一、Kubernetes对象的描述 kubernetes中资源可以使用YAML描述(如果您对YAML格式不了解,可以参考YAML语法),也可以使用JSON。其内容可以分为如下四个部分: typeMeta:对象类型的元信息,声明对象…

一款开源且不限制大小可以设置过期时间的支持分享的的开源文件共享系统picoshare 部署教程

1.拉取镜像 2.部署 创建目录 mkdir -p /opt/picoshare/data 部署 其中:"somesecretpass"是密码 docker run \--env "PORT4001" \--env "PS_SHARED_SECRETsomesecretpass" \--publish 10005:4001/tcp \--volume "/opt/picoshare/data:…

最优解-最长公共子序列

问题描述 最长公共子序列(Longest Common Subsequence,LCS)即求两个序列最长的公共子序列(可以不连续)。比如3 2 1 4 5和1 2 3 4 5两个序列,最长公共子序列为2 4 5 长度为3。解决这个问题必然要使用动态规划。既然要用到动态规划,就要知道状…

oracle11g的闪回技术-闪回表-时间戳

--数据库闪回表 --1创建表(登录模式system) CREATE table dept2 as select * from dept;--此语句如果加上where条件可用于工作中数据的临时备份 select * from dept2;--查询新建表信息 --进入sql>set time on 通过时间点闪回 记录弹出的时间点&#…

certificate-transparency-go用例

文章目录 证书的SCT列表验证SCT依赖包加载证书初始化log机构信息离线验证在线验证 证书的SCT列表 浏览器对证书链的合法性检查通过后,会再检查服务端证书附件里的SCT列表(Signed Certificate Timestamp); 浏览器内置了一批certif…

Tmux教程

会话(session)、窗口(window)、窗格(panel)的概念 参考资料:Tmux 使用教程 - 阮一峰的网络日志 (ruanyifeng.com) 命令行的典型使用方式是,打开一个终端窗口(terminal …

MySQL的安装和部署

2.0 描述 仅仅是一个产品,Oracle旗下的小型数据库。广泛应用在中小型项目中,特征体积小速度快整体成本低。尤其是开源,所以很多中小型项目为了降低成本纷纷选用MySql作为数控存储介质。 2.1 MySql的特征 底层语言使用C、C编写的。并且使用多…

Acrel-1000DP分布式光伏系统在某重工企业18MW分布式光伏中应用

摘 要:分布式光伏发电特指在用户场地附近建设,运行方式以用户侧自发自用、余电上网,且在配电系统平衡调节为特征的光伏发电设施,是一种新型的、具有广阔发展前景的发电和能源综合利用方式,它倡导就近发电,就…

一张图描述Http常用状态码(301、302、305、404、408等等)

301—永久移动。被请求的资源已被永久移动位置; 302—请求的资源现在临时从不同的 URI 响应请求; 305—使用代理。被请求的资源必须通过指定的代理才能被访问; 307—临时跳转。被请求的资源在临时从不同的URL响应请求; 40…

抖音VR直播新玩法,凸显各行业领域商业价值

抖音近期新推出了VR直播新玩法,用户不需要佩戴专业的显示头盔,只需要左右摇晃旋转手机,即可通过手机看到主播的全景直播。其实,VR直播并不是一个新东西,几年前,明星演唱会也用过VR直播拍摄技术,…

网站会遇到的几种攻击类型,及如何防御

随着互联网的普及和人们对网络使用的增加,网站安全问题变得越来越突出。无论是个人还是企业,都需要了解并采取措施来保护自己的网站和用户数据的安全。本文介绍了几种常见的网站安全攻击方式、潜在危害及其预防措施,帮助全面了解网站安全的各…

达梦数据库增删改查常用操作及-2723: 仅当指定列列表,且SET IDENTITY_INSERT为ON时,才能对自增列赋值问题修复

创建表 CREATE TABLE DICT ( "ID" INT IDENTITY(1, 1) NOT NULL, "TYPE" VARCHAR(30), "CODE" BIGINT, "NAME" VARCHAR(300), "VALUE" VARCHAR(200), "DESCRIPTION" VARCHAR(255), "OPERATOR"…

AI在检验数据方面的应用场景-九五小庞

AI在检验数据方面有广泛的应用前景,主要体现在以下几个方面: 自动化数据收集和分析:AI可以通过自动化技术,收集各种检验数据,如血液、尿液、生化指标等,并进行快速、准确的分析,提高检验效率。…