Nginx CloudFlare 客户端真实IP

博客围绕Nginx配置展开,因tomcat被Nginx反向代理只能获取本地回环地址,Nginx可通过变量设置头信息向上游tomcat提供远端客户端IP。但使用CDN后地址会改变,CDN通常在Header中提供真实IP,还提到一个电信反代的CF IP的特殊情况,并给出获取Real - IP的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题再现

由于 tomcat 被 Nginx 反向代理, 因此request.getRemoteAddr()只能获取到本地回环地址,
Nginx 提供了变量 $remote_addr, 可用于使用 proxy_set_header 设置头信息, 实现向上游的 tomcat 服务器提供远端客户端IP地址

proxy_set_header X-Real-IP $remote_addr;

但是, 一旦使用了 CDN 的话, 这个地址就变成了 CDN 节点的地址, 并且同一个用户不同时间发出的IP都不一样.
CDN 通常会在 Header 中提供客户端真实IP, 如 CloudFlare 在 x-forwarded-for, cf-connecting-ip 中设置了此数据.

Nginx 提供了变量 $http_x_forwarded_for 用于获取 x-forwarded-for 的值, 因此可以在 Nginx 配置文件中为 X-Real-IP 设置以下两个值:

remote_addr
http_x_forwarded_for

它们分别代表了未使用 CDN 和使用了 CDN 的客户端真实IP.



Nginx 配置实现

                #CloudFlare
                set $CDN "CloudFlare";
                #set $CDN "NO"; # 如果未使用 CloudFlare, 则取消该行代码的注释

                set $Real_IP $remote_addr;
                if ($CDN = "CloudFlare") {
                        set $Real_IP $http_x_forwarded_for;
                }

                #设置代理 Header
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $Real_IP;
                ......


民间传说, 一个电信反代的 CF IP

104.25.183.205

这个IP的电信延迟非常低, 而且速度非常不错, 你懂的!

当自选该IP后, x-real-ip 也就是 x-forwarded-for 变成了 59.174.137.107,140.206.61.106
cf-connecting-ip 更是变成了被反代的 140.206.61.106

这种特殊情况应当被考虑.

所以我写了一个 static 方法, 用来从 HttpServlet 中获取 Real-IP:

package common;

import javax.servlet.http.HttpServletRequest;

/**
 * 系统工具 & 配置
 */

public class Sys {
    private static final CDN cdn;

    private enum CDN {
        Nginx, CloudFlare,

    }

    static {
        cdn = CDN.Nginx;
    }

    public static String getRemoteIP(HttpServletRequest thiz) {
        switch (cdn) {
        case Nginx:
            return thiz.getHeader("X-Real-IP");
        case CloudFlare:
            return thiz.getHeader("CF-Connecting-IP");
        default:
            return thiz.getRemoteAddr();
        }
    }
}

转载于:https://www.cnblogs.com/develon/p/10816068.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值