开发者社区> 问答> 正文

使用nginx负载之后无法获取客户端真实IP?

我在web.xml中配置的DruidStatView添加限制IP参数

allow 192.168.1.1/24,10.0.0.1/24

使用nginx负载后,无法拦截客户端的访问,查看代码发现:

com.alibaba.druid.support.http。ResourceServlet

protected String getRemoteAddress(HttpServletRequest request) { String remoteAddress = null;

    if (remoteAddressHeader != null) {
        remoteAddress = request.getHeader(remoteAddressHeader);
    }

    if (remoteAddress == null) {
        remoteAddress = request.getRemoteAddr();
    }

    return remoteAddress;
}

这里是无法获取客户端真实的IP实现,但是我发现:

com.alibaba.druid.util.DruidWebUtils public static String getRemoteAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); 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;
}

通过这个函数是能正常获取的,不清楚为什么上面的位置没有更调用这个函数?

原提问者GitHub用户denghp

展开
收起
山海行 2023-07-05 22:05:00 1595 0
4 条回答
写回答
取消 提交回答
  • 当使用 Nginx 作为负载均衡器后,可能会出现无法获取客户端真实 IP 的问题。这是因为默认情况下,Nginx 会将请求的来源 IP 修改为负载均衡器的 IP。

    要解决这个问题,您可以在 Nginx 配置中添加一些配置项来传递客户端真实 IP。以下是一种常见的设置方法:

    http 配置块中添加以下配置项:

    http {
        # ...
        set_real_ip_from <load-balancer-ip>;  # 指定负载均衡器的 IP 地址
        real_ip_header X-Forwarded-For;  # 设置用于传递客户端真实 IP 的请求头
        real_ip_recursive on;  # 如果有多级代理,开启递归模式以处理 X-Forwarded-For 请求头
        # ...
    }
    

    在以上配置中,需要将 <load-balancer-ip> 替换为实际使用的负载均衡器的 IP 地址。该配置指定了从哪个 IP 地址接收客户端真实 IP。

    然后,在您的应用程序中,可以通过读取请求头 X-Forwarded-For 来获取客户端真实 IP。

    请注意,以上配置假设您的负载均衡器已正确地将客户端的真实 IP 添加到 X-Forwarded-For 请求头中。如果您使用的负载均衡器不是 Nginx,或者负载均衡器没有正确配置 X-Forwarded-For 请求头,您可能需要进行适当的调整。

    此外,还要确保您的应用程序能够安全地处理传递的客户端 IP,并采取必要的安全措施来防止 IP 欺骗和其他安全问题。

    2023-07-30 23:24:33
    赞同 展开评论 打赏
  • 北京阿里云ACE会长

    在使用Nginx做反向代理和负载均衡时,如果应用程序需要获取客户端的真实IP地址,可能会遇到获取到的IP地址为Nginx服务器IP地址的问题。这是因为在默认情况下,Nginx会将请求的HTTP头中的客户端地址(即X-Forwarded-For)替换为Nginx服务器的IP地址。

    为了解决这个问题,可以在Nginx的配置文件中添加以下配置:

    basic
    Copy
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    其中,X-Real-IP是自定义的HTTP头,用于存储客户端真实IP地址,$remote_addr表示客户端IP地址,X-Forwarded-For是标准的HTTP头,用于存储客户端IP地址和代理服务器IP地址,$proxy_add_x_forwarded_for表示将客户端IP地址和代理服务器IP地址添加到X-Forwarded-For头中

    2023-07-29 23:09:30
    赞同 展开评论 打赏
  • 在 location 中加入下类配置: proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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; 在Java代码中通过 `public static String getRemoteAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); 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;
    

    }`

    原回答者GitHub用户shi1991

    2023-07-06 12:58:35
    赞同 展开评论 打赏
  • 在您的情况下,当使用Nginx作为负载均衡器时,Druid无法获取到客户端的真实IP地址。这是因为Nginx在代理请求时会将客户端的IP地址存储在X-Forwarded-For或其他类似的头部中,而不是直接传递给后端应用程序。

    在Druid的ResourceServlet类中,获取远程地址的方法只尝试从请求的头部remoteAddressHeader中获取IP地址,并且如果没有设置该头部,则使用getRemoteAddr()方法获取IP地址。默认情况下,remoteAddressHeader为空,因此Druid无法获取到被Nginx代理之后的真实客户端IP地址。

    另一方面,在DruidWebUtils类中,提供了一个工具方法getRemoteAddr(),它会检查常见的代理头部,如X-Forwarded-ForProxy-Client-IPWL-Proxy-Client-IP,以获取真实的客户端IP地址。

    如果您希望Druid能够正确获取到客户端的真实IP地址,可以自定义ResourceServlet类,并重写getRemoteAddress(HttpServletRequest request)方法,使其调用DruidWebUtils.getRemoteAddr(request)方法来获取IP地址。例如:

    public class CustomResourceServlet extends ResourceServlet { @Override protected String getRemoteAddress(HttpServletRequest request) { return DruidWebUtils.getRemoteAddr(request); } } 然后,将web.xml中的ResourceServlet替换为自定义的CustomResourceServlet,以确保Druid使用正确的方法获取客户端真实IP地址。

    2023-07-06 08:51:49
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
《Nginx 代理系统常用手册》 立即下载
CentOS Nginx PHP JAVA 多语言镜像使用手 立即下载
CentOS Nginx PHP JAVA多语言镜像使用手册 立即下载