Karp 的技术博客

多层代理 获取真实IP 问题百度一搜 一堆. 但大多都是通过 X-Forwarded-For 获取真实IP
原理就是 负载 LVS /EOB /SLB 为了让下游正常获取 客户端IP 会将 客户端IP 填充到 X-Forwarded-For 中传递给下游服务

用户真实IP, 负载, 代理服务器1-IP代理服务器2-IP

我们原来获取真实IP 直接就 逗号炸开 取第一个IP

问题来了 客户端请求头 只需要添加 X-Forwarded-For 头信息 就可以伪造IP

解决方案:

  1. 根据自己服务代理层数决定 层数 != ip 数 就丢包
    /**
     * @desc 检测异常IP
     * @return string
     * @throws
     */
    public static function checkLimitIp()
    {
        $header_data = Http::getHeader();
        foreach (array('x-real-forwarded-for', 'x-forwarded-for', 'http_x_forwarded_for', 'x-real-ip', 'http_client_ip', 'remote_addr') as $v1) {
            if (isset($header_data[$v1])) {
                $ip_list = explode(',', $header_data[$v1]);
                // todo 注意 前端 slb + nginx IP
                $ip_num = count($ip_list);
                if ($ip_num > 2) {
                    throw new ErrorException(-114);
                }
            }
        }
    }
  1. 代理层除了第一层负载外 全部都是内网IP 所以只需要倒着数 找到最后一个外网IP 就可以定位到 负载IP , 负载IP 的前面就是真实客户端IP

真实深坑. 阿里云SLB 如果是覆盖 X-Forwarded-For , 不是 追加 X-Forwarded-For 就不会存在用户伪造问题. 也许阿里大佬有自己的想法吧 . 但在业务代码中 过滤真心麻烦....

ip

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2018年11月09日 03:22
1

目录

来自 《PHP 多层代理 获取真实IP 问题》