apache日志记录真实ip需配置logformat含%{x-forwarded-for}i,如logformat "%t %{x-forwarded-for}i %h \"%r\" %>s %b" combined-xff,并用customlog启用;进阶可启用mod_remoteip模块,设remoteipheader和remoteipinternalproxy,使%a输出真实ip。

Apache 本身不运行 Java,但常作为反向代理部署在 Java Web 应用(如 Spring Boot 内嵌 Tomcat、独立 Tomcat 或 Jetty)前端。此时客户端真实 IP 会被 Apache 接收并写入 X-Forwarded-For 请求头,再转发给后端 Java 服务。要让 Apache 日志准确记录这个真实 IP,关键不是改 Java 代码,而是配置 Apache 的日志格式和可信代理链。
确保 Apache 正确接收并传递 X-Forwarded-For
如果上游是 Nginx、CDN 或负载均衡器,它必须已设置 X-Forwarded-For 头(例如:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;)。Apache 需原样转发该头,不覆盖、不清空——默认行为即可,无需额外配置 RequestHeader,除非你要做头重写或补充协议信息。
修改 LogFormat 记录真实 IP(推荐方式)
在 Apache 主配置(httpd.conf)或虚拟主机配置中,定义一个包含 %{X-Forwarded-For}i 的日志格式:
LogFormat "%t %{X-Forwarded-For}i %h \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined-xff
说明:
-
%{X-Forwarded-For}i表示记录请求头中X-Forwarded-For的值; -
%h仍保留原始代理 IP(如 127.0.0.1 或 Nginx 内网地址),用于交叉验证; - 若头为空,Apache 自动记为
-,无需条件判断; - 该方式不依赖模块,兼容所有 Apache 版本(2.2+)。
然后启用该格式:
CustomLog "logs/access_log" combined-xff
使用 mod_remoteip 替换 REMOTE_ADDR(更安全的进阶方案)
当需要后端 Java 应用也能直接读取 REMOTE_ADDR(而非手动解析头)时,启用 mod_remoteip 模块:
- 确认模块已加载:
LoadModule remoteip_module modules/mod_remoteip.so; - 指定可信代理 IP 或网段(必须精确,漏一个中间节点会导致回退):
RemoteIPInternalProxy 127.0.0.1 192.168.10.5 10.0.0.0/8 - 声明头字段:
RemoteIPHeader X-Forwarded-For - 日志中改用
%a替代%h:
LogFormat "%t %a %h \"%r\" %>s %b" remoteip-format
因为启用后%a就是解析后的客户端真实 IP,%h则仍是代理地址。
Java 后端配合建议(避免常见错误)
即使 Apache 日志已记录真实 IP,Java 应用仍需安全获取:
- 不要直接用
request.getRemoteAddr()—— 它返回的是 Apache 的连接 IP; - 优先从
request.getHeader("X-Forwarded-For")取值,并只取逗号分隔后的第一个非私有 IP(如过滤掉 127.0.0.1、10.0.0.0/8 等); - 若已启用
mod_remoteip,可信任request.getRemoteAddr(),但前提是代理链完全可信且配置无误; - Spring Boot 用户可配置
server.forward-headers-strategy=framework并启用RemoteIpFilter,自动处理 XFF 和 X-Real-IP。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











