<p>HAProxy 可精细控制 Java 应用的请求与响应 Header:在 req 阶段用 set-header 补充 X-Forwarded-* 等转发头,在 rsp 阶段用 del-header 移除 Server 等敏感头,并通过 ACL 拦截非法请求头,需与 Spring Boot/Tomcat 的转发头配置协同对齐。</p>

HAProxy 可以在反向代理 Java 应用(如 Spring Boot、Tomcat)时,对请求和响应的 Header 进行精细控制,既可用于补充必要字段(如 X-Forwarded-For),也能实现安全过滤(如移除敏感响应头、限制危险请求头)。关键在于理解 HAProxy 的处理阶段(req / rsp)、匹配逻辑与执行顺序。
修改请求 Header:补充转发信息与标准化输入
Java 应用常依赖 X-Forwarded-For、X-Forwarded-Proto 等头判断客户端真实 IP 或协议。HAProxy 需在请求发往后端前主动添加或覆盖:
- 使用
http-request set-header设置标准转发头:http-request set-header X-Forwarded-For %[src]<br>http-request set-header X-Forwarded-Proto https if { ssl_fc }<br>http-request set-header X-Forwarded-Host %[hdr(host)] - 若后端已存在同名头,用
set-header会覆盖;需保留原始值时改用add-header(但注意避免重复) - 对 Java 应用特别建议设置
X-Real-IP并确保其唯一性,避免 Spring Cloud Gateway 或某些 Filter 因解析混乱导致 IP 判断错误
过滤/删除响应 Header:消除敏感信息泄露风险
Java 应用默认可能返回暴露技术栈的响应头(如 Server: Apache-Coyote/1.1、X-Powered-By: Servlet/4.0),HAProxy 可在响应返回客户端前统一剥离:
- 用
http-response del-header删除指定头:http-response del-header Server<br>http-response del-header X-Powered-By<br>http-response del-header X-AspNet-Version
- 若需彻底隐藏服务端标识,可结合
http-response set-header Server "nginx"(伪饰)或留空(set-header Server ""),但部分 HTTP/2 实现对空值支持有限,建议设为通用值 - 注意:Spring Boot Actuator 的
/actuator/env等端点可能返回含敏感信息的Content-Type或自定义头,应在 HAProxy 层通过 ACL 拦截或响应头清理双重防护
安全过滤请求 Header:拦截非法或危险输入
防止攻击者利用恶意 Header 绕过 Java 应用的安全校验(如伪造 X-Forwarded-For、注入 Authorization 头):
立即学习“Java免费学习笔记(深入)”;
- 用
http-request deny+ ACL 拦截非法头:acl has_x_forwarded_for hdr(X-Forwarded-For) -m found<br>http-request deny if has_x_forwarded_for
(适用于只允许 HAProxy 自己添加该头的严格场景) - 限制特定头长度防缓冲区溢出:
acl long_auth hdr_len(Authorization) gt 512<br>http-request deny if long_auth
- 重写可疑头值(如清除
Referer中的 XSS 载荷)可用regsub,但更推荐在 Java 层做语义校验;HAProxy 适合做初步格式清洗
与 Java 应用协同的关键注意事项
HAProxy 的 Header 操作需与 Java 应用配置对齐,否则可能引发认证失败、跳转异常或日志失真:
- Spring Boot 中启用
server.forward-headers-strategy=framework后,会自动信任X-Forwarded-*头 —— 此时必须确保 HAProxy 是唯一能写入这些头的组件,禁用应用自身生成 - Tomcat 需配置
RemoteIpValve并设置remoteIpHeader="x-forwarded-for",且 HAProxy 必须保证该头不被客户端篡改(即上文的拦截策略) - 所有 Header 修改操作应放在
frontend或backend块中,避免在listen全局块中误配;调试时开启option http-server-close和详细日志(capture request header/capture response header)验证实际传递效果










