remote_addr 在负载均衡后显示为 lb ip,因 apache 默认只读取 tcp 源地址,不解析 x-forwarded-for 等 http 头;需启用 mod_remoteip 并配置 remoteipheader、remoteiptrustedproxy 等参数,使 remote_addr 正确映射真实客户端 ip。

为什么 REMOTE_ADDR 在负载均衡后总是显示为 LB 的 IP
因为 Apache 默认只读取 TCP 连接的源地址,而负载均衡器(如 Nginx、AWS ALB、SLB)转发请求时,真实客户端 IP 会被“藏”在 HTTP 头里(通常是 X-Forwarded-For)。Apache 不会自动解析这个头并覆盖 REMOTE_ADDR,所以 PHP 的 $_SERVER['REMOTE_ADDR']、日志里的 client IP、甚至某些限流逻辑拿到的都是 LB 的内网地址。
启用 mod_remoteip 并配置可信代理
必须显式告诉 Apache 哪些 IP 是可信的代理,否则它会拒绝信任任何 X-Forwarded-For 值(防伪造)。关键配置如下:
LoadModule remoteip_module modules/mod_remoteip.so RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 10.0.0.0/8 RemoteIPTrustedProxy 172.16.0.0/12 RemoteIPTrustedProxy 192.168.0.0/16 RemoteIPTrustedProxy 127.0.0.1 RemoteIPInternalProxy 10.0.0.0/8
-
RemoteIPHeader指定从哪个 header 提取原始 IP;多数 LB 用X-Forwarded-For,Cloudflare 用Cf-Connecting-IP,需按实际改 -
RemoteIPTrustedProxy列出所有 LB 的真实出口 IP 或网段(不是 VIP,是后端真实发包的 IP) -
RemoteIPInternalProxy可选,用于标记“内部跳转代理”,影响X-Forwarded-For解析方向(默认取最左非可信 IP) - 如果 LB 是单层,且只加一次
X-Forwarded-For,RemoteIPTrustedProxy足够;若有多层代理(如 CDN → LB → Apache),必须把每一层代理 IP 都加进去,否则中间某层的 IP 会被误认为客户端
验证 mod_remoteip 是否生效
重启 Apache 后,检查访问日志是否已更新为真实 IP。若仍不对,常见原因有:
- LB 没有正确设置
X-Forwarded-For:比如 Nginx 配置漏了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - Apache 配置未加载:确认
mod_remoteip.so已LoadModule,且配置放在全局或对应<virtualhost></virtualhost>内(不能只放 .htaccess) - header 名不匹配:有些 LB 用
X-Real-IP,此时要设RemoteIPHeader X-Real-IP - 日志格式未更新:默认
%h记录的是原始 socket 地址,应改用%a(remoteip 模块提供的修正后地址)——日志配置示例:LogFormat "%a %l %u %t \"%r\" %>s %O" combined
PHP 中获取真实 IP 的注意事项
启用 mod_remoteip 后,$_SERVER['REMOTE_ADDR'] 会自动变成真实客户端 IP,但仍有陷阱:
- 不要手动解析
$_SERVER['HTTP_X_FORWARDED_FOR']—— 这会绕过mod_remoteip的校验逻辑,带来安全风险 - 确保 PHP 运行在 Apache 模块模式(
mod_php),而非 FPM:FPM 是独立进程,不直接受 Apache 的REMOTE_ADDR修改影响;若用 FPM,需额外配置fastcgi_param REMOTE_ADDR $remote_addr;并确保$remote_addr是 mod_remoteip 设置后的值(Nginx 下需用$upstream_http_x_forwarded_for等配合) - 部分框架(如 Laravel)自带 IP 获取逻辑,可能默认读
HTTP_X_FORWARDED_FOR,需检查其信任代理配置是否与 Apache 一致
真实 IP 的来源链很脆弱:LB 头字段、Apache 代理白名单、日志变量、PHP 运行模式,任意一环没对齐,拿到的就还是内网地址。









