You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache+PHP7.4环境下获取访问news.test.com的客户端真实IP问题

问题原因

你当前获取到父域IP的核心原因是news.test.com的访问流量经过了父域所在的123.100.1.10服务器反向代理后才到达你的Apache服务器,默认情况下Apache的REMOTE_ADDR会记录最后一跳的代理IP,也就是父域的IP。
该问题大概率是两个环节的配置问题导致:要么是父域的反向代理服务没有将客户端真实IP写入请求头转发给下游,要么是你本地Apache没有配置信任父域代理的请求头、无法从转发的头中提取真实IP。

解决方案

步骤1:配置父域反向代理转发真实IP头

父域服务器如果用Nginx做反向代理,需要在站点配置中添加以下参数,将客户端真实IP写入请求头转发给你的news.test.com服务器:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

如果父域服务器用Apache做反向代理,需要先启用mod_proxy和mod_headers模块,再添加以下配置:

RequestHeader set X-Real-IP %{REMOTE_ADDR}s
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s

步骤2:配置本地Apache提取真实IP

你192.168.1.11的服务器需要启用mod_remoteip模块,自动将代理转发的真实IP替换为REMOTE_ADDR的值,无需额外修改PHP代码即可直接拿到真实IP,安全性更高。
操作流程:

  1. 执行命令启用remoteip模块:a2enmod remoteip
  2. 编辑Apache站点配置文件或全局配置文件,添加以下配置:
# 信任父域代理服务器的IP,仅该IP传递的请求头会被识别
RemoteIPInternalProxy 123.100.1.10
# 指定从X-Forwarded-For头提取真实IP
RemoteIPHeader X-Forwarded-For
  1. 如需Apache访问日志也显示真实IP,将日志格式中的%h替换为%a,示例:
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
  1. 重启Apache生效:systemctl restart apache2

步骤3:优化PHP获取IP的代码

你当前的代码没有处理X-Forwarded-For多IP的场景,也未做IP合法性校验,容易出现取值错误或IP伪造问题,优化后代码参考:

public static function get_ip() {
    // 优先读取Apache替换后的REMOTE_ADDR(配置mod_remoteip后这里直接返回真实IP)
    $ip = getenv('REMOTE_ADDR');
    // 校验是否为合法公网IP
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
        return $ip;
    }
    // 兼容未配置mod_remoteip的场景,依次读取代理转发头
    $forwardHeaders = [
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_REAL_IP',
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED'
    ];
    foreach ($forwardHeaders as $header) {
        $headerValue = getenv($header);
        if (empty($headerValue)) {
            continue;
        }
        // 处理多级代理的多IP场景,取第一个公网IP
        $ipList = explode(',', $headerValue);
        foreach ($ipList as $currIp) {
            $currIp = trim($currIp);
            if (filter_var($currIp, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                return $currIp;
            }
        }
    }
    return 'UNKNOWN';
}

内容的提问来源于stack exchange,提问作者Ilham Riski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:51:00