Apache中应通过%{X-Forwarded-For}i记录完整XFF头供审计,再用mod_remoteip模块自动解析并置入%h——该模块依据RemoteIPHeader和RemoteIPInternalProxy配置,跳过私有IP,取XFF中最左可信客户端IP。

要在 Apache 中通过 mod_log_config 记录 X-Forwarded-For 中的原始客户端 IP(即最左边、第一个非伪造的 IP),不能只依赖 %{X-Forwarded-For}i 简单记录——因为该头可能含多个 IP(如 203.0.113.1, 198.51.100.2, 10.0.1.10),而真正用户 IP 是最前面那个,且需排除内部代理 IP 和伪造值。
确保 X-Forwarded-For 来源可信
Apache 日志里记录的 X-Forwarded-For 必须来自你可控的上游代理(如 Nginx、CDN 或负载均衡器),而非客户端直接提交。否则攻击者可伪造该头,导致日志污染或安全误判。
- 在 Apache 配置中清除客户端可能携带的原始头:
RequestHeader unset X-Forwarded-For early - 再由你信任的代理(如 Nginx)统一添加:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 若使用多级代理(如 CDN → Nginx → Apache),确保只有最后一层代理(Nginx)添加该头,前端 CDN 应配置为“透传”或“重置”X-Forwarded-For。
用 %{X-Forwarded-For}i 记录完整头值
这是最基础也最常用的做法,适合后续用日志分析工具(如 Logstash、awk、ELK)提取首 IP。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 在
httpd.conf或虚拟主机配置中定义日志格式:LogFormat "%h %{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_xff - 启用该格式:
CustomLog logs/access_log combined_xff - 效果示例日志行:
127.0.0.1 203.0.113.1, 198.51.100.2 - - [27/Apr/2026:17:30:45 +0800] "GET /api/user HTTP/1.1" 200 124 "-" "curl/7.68.0"
用 mod_remoteip 替换 %h 并自动解析首 IP
如果你希望 Apache 自动识别并把真实客户端 IP 填入 %h(同时仍保留原始 XFF 头供审计),应启用 mod_remoteip 模块。
- 确认模块已加载:
LoadModule remoteip_module modules/mod_remoteip.so - 指定可信代理 IP 段(例如 Nginx 所在内网段):
RemoteIPInternalProxy 10.0.0.0/8RemoteIPInternalProxy 172.16.0.0/12RemoteIPInternalProxy 192.168.0.0/16 - 声明要解析的请求头:
RemoteIPHeader X-Forwarded-For - 此时
%h将自动显示 X-Forwarded-For 中最左的有效 IP(跳过内部代理地址),而%a仍表示原始 socket 连接 IP(即代理 IP)。
进阶:仅记录首个有效 IP(需外部处理)
Apache 原生不支持正则截取 X-Forwarded-For 的第一段 IP,但可通过以下方式间接实现:
- 用
%{X-Forwarded-For}i记录完整字段,再在日志采集阶段用 Grok 或自定义脚本提取:%{IP:client_ip}((,\s%{IP})*)? - 或配合
SetEnvIf做简单判断(适用于单 IP 场景):SetEnvIf X-Forwarded-For "^([0-9]{1,3}\.[0-9]{1,3}\.[0-Forwarded-For-First" env=xff_first
再用%{X-Forwarded-For}i配合条件日志,但可靠性低,不推荐生产环境使用。










