HAProxy 在 HTTP 模式下通过 option forwardfor 指令自动向请求头添加 X-Forwarded-For 字段,用于向后端服务器传递客户端真实 IP。该配置需写在 frontend 或 listen 段落中,且后端应用需配置信任该头部才能获取正确 IP。
先说结论:启用 option forwardfor 即可透传客户端 IP,但必须配合后端日志格式调整和安全信任配置。
- 适合:HTTP 七层负载均衡场景,后端需要记录真实访客 IP。
- 先准备:确认 HAProxy 运行在
mode http模式下,TCP 模式不支持此功能。 - 验收:检查后端访问日志是否显示客户端真实 IP 而非负载均衡器 IP。
命令速用版
在 HAProxy 配置文件的 frontend 或 listen 段中加入以下指令,无需额外脚本:
listen webserver
bind :80
mode http
option forwardfor
option forwardfor except 127.0.0.0/8
server web1 192.168.1.10:80 check若需自定义 header 名称,可使用 option forwardfor header Custom-Header-Name。
为什么会这样
负载均衡器默认会替换请求源 IP 为自身 IP,导致后端无法识别真实用户。
HAProxy 作为七层代理,在转发 HTTP 请求时可以通过插入标准非 RFC 头部 X-Forwarded-For 来保留原始客户端地址。该字段格式通常为 X-Forwarded-For: client_ip, proxy_ip,第一项为真实客户端 IP。后端服务器(如 Nginx、Apache、Tomcat)需要配置解析该头部才能将其作为远程地址记录。
分步处理
按以下顺序修改配置并重启服务,确保变更生效且不影响现有连接。
- 编辑配置文件:打开
/etc/haproxy/haproxy.cfg,找到对应的frontend或listen块。 - 添加透传指令:在块内插入
option forwardfor。若 HAProxy 自身也是客户端之一,建议添加option forwardfor except 127.0.0.0/8避免本地请求误加。 - 调整后端日志:修改后端 Web 服务器日志格式,添加
%{X-Forwarded-For}i字段,否则日志仍记录 HAProxy IP。 - 检查配置语法:执行
haproxy -c -f /etc/haproxy/haproxy.cfg确保无语法错误。 - 重载服务:执行
systemctl reload haproxy或service haproxy reload使配置生效。
怎么验证是否生效
通过后端服务器日志或抓包工具确认请求头中是否包含正确 IP。
- 查看后端日志:访问网站后,检查后端 access.log。若配置正确,日志末尾应显示客户端真实 IP,例如
192.168.23.36而非 HAProxy 内网 IP。 - 应用层读取:在后端代码中读取
HTTP_X_FORWARDED_FOR环境变量或请求头,确认值与客户端公网 IP 一致。 - 命令行测试:使用
curl -v http://your-domain配合后端日志观察,或在 HAProxy 上配置capture request header X-Forwarded-For len 15查看内部日志。
常见坑
配置过程中容易忽略模式限制和安全隐患,导致功能无效或安全风险。
- 模式限制:
option forwardfor仅在mode http下生效,mode tcp四层代理无法修改 HTTP 头部。 - 日志未改:HAProxy 已发送头部,但后端 Web 服务器(如 Nginx)未配置日志格式包含该字段,导致运维排查时仍看到负载均衡器 IP。
- 安全风险:
X-Forwarded-For可由客户端伪造,后端应用不应直接信任该字段进行身份验证或 ACL 控制,需结合可信代理列表。 - 重复添加:若链路中存在多层代理,未配置
if-none可能导致头部重复堆积,建议使用默认行为或明确指定追加策略。
常见问题
TCP 模式下能添加 X-Forwarded-For 吗
不能,TCP 模式无法解析 HTTP 协议头部。
HAProxy 的 option forwardfor 依赖 HTTP 协议解析,四层 TCP 代理只能透传流量,如需透传 IP 需使用 PROXY 协议。
后端仍然显示负载均衡器 IP 怎么办
后端应用未配置信任或读取该头部。
检查后端 Web 服务器配置,如 Nginx 需设置 real_ip_header X-Forwarded-For 并指定可信源 set_real_ip_from。
如何自定义 Header 名称
使用 option forwardfor header 参数指定。
例如 option forwardfor header X-Real-IP 可将客户端 IP 写入自定义字段,但需确保后端应用支持读取该字段。
参考来源
- CSDN 博客:HAProxy 配置详解
- 博客园:haproxy 关于 HTTP_X_FORWARDED_FOR 配置
- 企业级反向代理 HAProxy 高级功能之自定义日志格式与 IP 透传
- RHEL9.3 HAProxy 高级功能配置实战
- 负载或反向代理服务器如何配置 XFF 以获取终端真实 IP