You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HAProxy TCP模式下如何让Tomcat获取真实客户端IP?

解决HAProxy TCP模式下Tomcat无法记录真实客户端IP的问题

核心原因

HAProxy工作在TCP四层模式时仅做数据包透传,不会修改HTTP请求头,因此Tomcat无法通过X-Forwarded-For获取真实客户端IP,只能记录HAProxy的IP地址。需要通过修改HAProxy配置添加转发头或使用PROXY协议,配合Tomcat配置实现真实IP的传递。

解决方案

方案1:将HAProxy切换为HTTP模式(推荐,支持HTTPS终止)

此方案适合让HAProxy处理SSL解密,将明文HTTP转发给Tomcat,同时添加转发头。

修改HAProxy配置(haproxy.cfg)

  • 80端口监听块调整:
listen WebServer-80
     bind    *:80
     mode    http  # 从tcp改为http模式
     option  httplog  # 替换tcplog为httplog
     log /dev/log local0 debug
     balance leastconn
     option forwardfor  # 自动添加X-Forwarded-For请求头
     http-request set-header X-Forwarded-Proto http  # 设置转发协议头
     server  portal2-w2  172.16.1.95:80 check inter 5s rise 2 fall 3
     server  portal2-w3  172.16.1.96:80 check inter 5s rise 2 fall 3
     server  portal2-w4  172.16.1.97:80 check inter 5s rise 2 fall 3
  • 443端口监听块调整(需提前准备SSL证书文件,示例路径为/etc/haproxy/certs/mycert.pem):
listen WebServer-443
     bind    *:443 ssl crt /etc/haproxy/certs/mycert.pem  # 添加SSL终止配置
     mode    http  # 从tcp改为http模式
     option  httplog  # 替换tcplog为httplog
     log /dev/log local0 debug
     balance leastconn
     option forwardfor  # 自动添加X-Forwarded-For请求头
     http-request set-header X-Forwarded-Proto https  # 设置转发协议头
     server  portal2-w1  172.16.1.95:80 check inter 5s rise 2 fall 3  # 转发到Tomcat明文80端口
     server  portal2-w2  172.16.1.96:80 check inter 5s rise 2 fall 3
     server  portal2-w3  172.16.1.97:80 check inter 5s rise 2 fall 3

调整Tomcat配置(server.xml)

保持已有的RemoteIpValve配置,确保internalProxies指向HAProxy的IP(172.16.1.45),此时日志中的%a会自动替换为真实客户端IP:

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
       remoteIpHeader="x-forwarded-for" 
       protocolHeader="x-forwarded-proto" 
       internalProxies="172.16.1.45" />

<Valve className="org.apache.catalina.valves.AccessLogValve" 
       directory="logs" 
       prefix="tomcat_access_log" 
       suffix=".log" 
       pattern="%t %{X-AUSERNAME}o %{User-Agent}i %a %m %r %b %s %D %I %{x-forwarded-for}i" />

方案2:使用PROXY协议(适合TCP透传场景,如Tomcat自行处理SSL)

若必须保持HAProxy的TCP模式(例如Tomcat直接处理HTTPS证书),可使用PROXY协议传递客户端IP信息。

修改HAProxy配置(haproxy.cfg)

在每个server行末尾添加send-proxy,启用PROXY协议:

listen WebServer-80
     bind    *:80
     mode    tcp
     option  tcplog
     log /dev/log local0 debug
     balance leastconn
     server  portal2-w2  172.16.1.95:80 check inter 5s rise 2 fall 3 send-proxy
     server  portal2-w3  172.16.1.96:80 check inter 5s rise 2 fall 3 send-proxy
     server  portal2-w4  172.16.1.97:80 check inter 5s rise 2 fall 3 send-proxy

listen WebServer-443
     bind    *:443
     mode    tcp
     option  tcplog
     log /dev/log local0 debug
     balance leastconn
     server  portal2-w1  172.16.1.95:443 check inter 5s rise 2 fall 3 send-proxy
     server  portal2-w2  172.16.1.96:443 check inter 5s rise 2 fall 3 send-proxy
     server  portal2-w3  172.16.1.97:443 check inter 5s rise 2 fall 3 send-proxy

调整Tomcat配置(server.xml)

在对应Connector标签中添加proxyProtocol="true",并保留RemoteIpValve配置:

<!-- 80端口Connector -->
<Connector port="80" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="443"
           proxyProtocol="true" />

<!-- 443端口Connector(Tomcat处理SSL时) -->
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true"
           proxyProtocol="true">
    <SSLHostConfig>
        <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                     type="RSA" />
    </SSLHostConfig>
</Connector>

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
       remoteIpHeader="x-forwarded-for" 
       protocolHeader="x-forwarded-proto" 
       internalProxies="172.16.1.45" />

<Valve className="org.apache.catalina.valves.AccessLogValve" 
       directory="logs" 
       prefix="tomcat_access_log" 
       suffix=".log" 
       pattern="%t %{X-AUSERNAME}o %{User-Agent}i %a %m %r %b %s %D %I %{x-forwarded-for}i" />

验证方法

  1. 重启HAProxy和Tomcat服务
  2. 用外部客户端访问Web服务,查看Tomcat的tomcat_access_log日志,确认%a字段显示真实客户端IP而非HAProxy的IP

内容的提问来源于stack exchange,提问作者a.sadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:25:23