apache日志中需用%{x-forwarded-for}i引用该头以记录真实ip,但仅原样写入、不校验不解析;须确保前端(nginx/cdn/slb)正确传递且未覆盖,且不可用于安全控制。

直接在 Apache 的日志格式中引用 X-Forwarded-For 头部即可记录真实客户端 IP,但要注意:它只是把原始头内容原样写入日志,不自动校验、不自动提取首个可信 IP,也不替换 %h。要让日志里显示的是“用户真实 IP”而非“代理 IP”,关键不是加字段,而是加对字段、并理解它的行为。
确认 X-Forwarded-For 已由前端正确传递
这是前提。如果 Nginx、CDN 或负载均衡器没传这个头,Apache 日志里就永远看不到真实 IP。
- Nginx 前端需配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 腾讯云 CDN、阿里云 SLB、七牛等主流服务默认会携带
X-Forwarded-For,且把用户真实 IP 放在最左边(如X-Forwarded-For: 203.12.45.67, 118.89.171.94) - 确保该头部未被中间层覆盖或清空(例如某些安全网关会重写或删除)
修改 LogFormat,用 %{X-Forwarded-For}i 替代或补充 %h
%{X-Forwarded-For}i 表示请求头中名为 X-Forwarded-For 的值(i 表示 input header)。它不会做任何解析,只取原始字符串。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 推荐写法(保留代理 IP + 真实 IP):
LogFormat "%h %{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - 若只想看真实 IP(且信任前端只传一个有效 IP),可单独用:
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common - 注意大小写:
X-Forwarded-For是标准写法,Apache 不区分大小写,但建议保持一致
注意日志字段的含义和局限性
%{X-Forwarded-For}i 写进日志后,你看到的是完整字符串(如 "203.12.45.67, 118.89.171.94"),不是单个 IP。
- 它可能为空、为
unknown、或含多个逗号分隔的 IP —— 这取决于前端如何构造 - 它可被客户端伪造(如 curl -H "X-Forwarded-For: 1.2.3.4"),所以**不能用于权限控制或限流**,仅适合日志审计、地域统计等低敏感场景
- 如果需要在应用层(如 PHP/Java)可靠获取真实 IP,必须配合
mod_remoteip模块或手动解析逻辑,而不是只靠日志字段
验证与调试技巧
别只信配置,要亲眼看到请求头和日志是否匹配。
- 临时加一段 PHP 脚本输出所有头:
<?php print_r(apache_request_headers()); ?> - 检查 Apache 访问日志是否已生效:
tail -f /var/log/httpd/access_log,发起一次带真实 IP 的请求(比如用手机开飞行模式再连 WiFi 测试) - 对比
%h(总是代理 IP)和%{X-Forwarded-For}i(应含你本地公网 IP)是否不同










