Apache默认用%h记录代理IP,真实客户端IP需通过%{X-Forwarded-For}i获取最左IP;推荐启用mod_remoteip模块并配置RemoteIPInternalProxy,再用%a记录真实IP,确保日志与Java应用一致。

Apache 默认用 %h 记录的是直接连接它的客户端 IP(通常是上一级代理或负载均衡器的内网地址),不是用户真实 IP。当请求经过 CDN、WAF、Nginx 再到 Apache 时,X-Forwarded-For 头里会包含一串 IP,格式类似:X-Forwarded-For: 203.0.113.45, 198.51.100.22, 172.16.0.10 —— 最左边那个才是原始客户端 IP。
直接在 LogFormat 中引用 %{X-Forwarded-For}i 即可记录整串值
这是最基础也最常用的做法:
- 在
httpd.conf或虚拟主机配置中添加或修改 LogFormat:
LogFormat "%h %{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_with_xff
-
%h:记录代理层 IP(如 Nginx 或 CDN 回源 IP) -
%{X-Forwarded-For}i:记录请求头中完整的X-Forwarded-For字符串(含逗号分隔的多级 IP) - 后续配合
CustomLog /var/log/apache2/access.log combined_with_xff生效
这样日志每行开头就会是:172.16.0.10 203.0.113.45, 198.51.100.22, 172.16.0.10 ...
只提取并记录最左侧原始客户端 IP(推荐用于分析和限流)
如果只想保留真实用户 IP(即 X-Forwarded-For 中第一个),Apache 本身不支持正则截取,但可通过 mod_remoteip 模块实现“可信解析”后用 %a 输出:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 启用模块:
LoadModule remoteip_module modules/mod_remoteip.so - 指定可信代理 IP 段(必须准确!否则可能被伪造):
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 172.16.0.0/12
RemoteIPInternalProxy 192.168.0.0/16
RemoteIPInternalProxy 10.0.0.0/8
- 之后日志中可用
%a替代%h,它会自动取X-Forwarded-For最左有效 IP - 例如:
LogFormat "%a %l %u %t \"%r\" %>s %b ..." combined_realip
⚠️ 注意:RemoteIPInternalProxy 必须只填你完全可控的代理节点(如自建 Nginx、K8s Ingress、内部负载均衡器),不能写公网 CDN 或第三方 WAF 的 IP 段,否则有安全风险。
Java 后端协同:让 Apache 日志与业务日志 IP 对齐
光靠 Apache 日志还不够——Java 应用里 request.getRemoteAddr() 仍可能是 127.0.0.1 或代理内网 IP。要让日志、限流、白名单真正一致,需两端配合:
- Apache 层确保正确透传
X-Forwarded-For(第一跳设RequestHeader set X-Forwarded-For %{REMOTE_ADDR}e,后续跳用edit拼接) - Tomcat 需启用
RemoteIpValve,配置remoteIpHeader="X-Forwarded-For",使getRemoteAddr()返回真实 IP - Java 日志中可输出
MDC.get("X-Forwarded-For")或统一用getRemoteAddr(),与 Apache 的%a日志严格对齐
这样,运维查 Apache 日志、开发查应用日志、安全团队做 IP 统计,看到的都是同一个原始客户端 IP。

















