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

这篇具有很好参考价值的文章主要介绍了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:Java通过nginx获取客户端的真实ip地址,java,异常报错,工具使用,docker,java,nginx,真实ip

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

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

  • 使用docker命令docker network ls,查看了docker网络后,发现我们确实用的是这个
    docker:Java通过nginx获取客户端的真实ip地址,java,异常报错,工具使用,docker,java,nginx,真实ip

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

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

  • 对比发现这个ip是nginx服务的,说明获取客户端远程地址时,获取到了nginx的ip
    docker:Java通过nginx获取客户端的真实ip地址,java,异常报错,工具使用,docker,java,nginx,真实ip

  • nginx是决定能获取到正确的客户端请求ip地址的,因为它的log日志输出里,是有来源ip的
    docker:Java通过nginx获取客户端的真实ip地址,java,异常报错,工具使用,docker,java,nginx,真实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;
    }
  • 成功获取,结束
    docker:Java通过nginx获取客户端的真实ip地址,java,异常报错,工具使用,docker,java,nginx,真实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指令能确保后端服务器可以接收到所需的所有重要信息,提供正确和安全的服务。文章来源地址https://www.toymoban.com/news/detail-802169.html

到了这里,关于docker:Java通过nginx获取客户端的真实ip地址的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Java开发】之获取客户端真实 IP 地址

    在投票系统开发中,为了防止刷票,我们需要限制每个 IP 地址只能投票一次; 当网站受到诸如 DDoS(Distributed Denial of Service,分布式拒绝服务攻击)等攻击时,我们需要快速定位攻击者 IP; 在渗透测试过程中,经常会碰到网站有 CDN(Content Distribution Network,内容交付网络),

    2024年02月04日
    浏览(7)
  • Java-通过IP获取真实地址

    Java-通过IP获取真实地址

    最近写了一个日志系统,需要通过访问的 IP 地址来获取真实的地址,并且存到数据库中,我也是在网上看了一些文章,遂即整理了一下供大家参考。 这个是获取正确 IP 地址的方法,可以直接使用的。 通过以上方法你可以获取到访问者的 IP 地址,只有获取到了 IP 地址,才能

    2024年02月15日
    浏览(9)
  • Spring Boot获取客户端的IP地址

    前言 在Web应用程序中,获取客户端的IP地址是一项非常常见的需求,例如记录访问日志、过滤恶意IP等。在本文中,我们将介绍如何使用Spring Boot框架获取客户端的IP地址。 方法一:使用ServletRequest对象获取IP地址 Spring Boot应用程序可以使用HttpServletRequest对象获取客户端的IP地址

    2024年02月08日
    浏览(10)
  • nginx 获取客户端真实IP

    网站接入Web应用防火墙WAF(Web Application Firewall)后,访问请求在到达源站服务器之前,需要经过WAF的代理转发。这种情况下,源站服务器可以通过解析回源请求中的X-Forwarded-For记录,获取客户端的真实IP。 WAF在将客户端的访问请求转发到下一环节的服务器时,会在HTTP的请求头

    2023年04月09日
    浏览(14)
  • nginx获取客户端真实ip

    在nginx中获取客户端真实IP的方法有多种,以下是其中两种常用的方法: 使用nginx的access_log模块记录请求日志,并在日志中包含客户端的真实IP信息。例如: 在上述配置中,通过使用http_x_forwarded_for字段来获取客户端的真实IP地址。如果该字段不存在或不合法,则使用remote_ad

    2024年02月16日
    浏览(6)
  • 获取客户端真实 IP 地址的最佳实践

    1. 业务上云带来性能收益 公司从去年全面推动业务上云,而以往 IDC 架构部署上,接入层采用典型的 4 层 LVS 多机房容灾架构,在业务高峰时期,扩容困难(受限于物理机资源和 LVS 内网网段的网络规划),且抵挡不住 HTTPS 卸载引发的高 CPU 占用。 而经过压力测试发现,使用

    2024年02月05日
    浏览(12)
  • nginx代理后,nodejs如何获取用户真实ip地址(包括websocket获取用户真实IP地址)

    nginx代理后,nodejs如何获取用户真实ip地址(包括websocket获取用户真实IP地址)

    因为nginx代理的原因,我们在请求头中获取到的用户ip只是nginx代理的ip,并非用户真实ip,原因是经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,可以通过$remote_addr变量拿到的将是反向代理服务器的ip地址。 第一步,修改

    2024年02月13日
    浏览(35)
  • Nginx(二十) 获取真实客户端IP

            客户端在访问互联网应用服务器时,与真实的应用服务器之间会因为有多层反向代理,而导致真实应用服务器获取的仅是最近一层的反向代理服务器 IP。为使 Nginx 后端的上游服务器可以获得真实客户端 IP,Nginx 提供了 ngx_http_realip_module 模块用以实现真实客户端

    2024年01月16日
    浏览(3)
  • nginx如何获取真实客户端ip

    nginx作为反向代理服务器,即代理我们的服务端,下面介绍下如何配置nginx获取真实的客户端ip 1、配置nginx.con 2、在java程序中可以通过如下方式获取: 这样就可以打印出真实ip了!即request.getHeader(\\\"X-Real-IP\\\")的值 引用: 查看端口占用及释放所占用的端口_查询谷歌浏览器的端口

    2024年02月11日
    浏览(6)
  • nginx获取不到真实ip地址,注意这个细节

    1 一定要把proxy_pass语句放在最后面 location / {         proxy_set_header Host $host;         proxy_set_header X-Real-IP $remote_addr;         proxy_set_header REMOTE-HOST $remote_addr;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;         client_max_body_size 1024m;         # 一

    2024年02月13日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包