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

使用Apache2作为Tomcat8代理时如何保留客户端IP?

解决Apache反向代理后Spring Boot无法获取真实客户端IP的问题

我完全懂你碰到的这个困扰——当Apache作为反向代理把HTTPS请求转成HTTP发给Tomcat后,后端Spring Boot拿到的全是127.0.0.1,根本看不到真实的客户端IP。这是因为代理转发时没把原始IP传递给后端,下面是一套亲测有效的解决步骤:

第一步:修改Apache虚拟主机配置,传递真实IP与请求协议

在你sites-available目录下的目标配置文件里,除了已有的ProxyPass和ProxyPassReverse,补充以下配置,让Apache把真实客户端IP和原始请求协议(HTTPS)传递给Tomcat:

# 将真实客户端IP写入X-Forwarded-For请求头
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
# 告诉后端原始请求是HTTPS(因为Apache转成了HTTP发给Tomcat)
RequestHeader set X-Forwarded-Proto "https"
# 可选:传递原始请求的HTTPS端口
RequestHeader set X-Forwarded-Port "443"

另外,确保你已经启用了mod_headers模块,没启用的话执行这条命令:

a2enmod headers

修改完配置后,重启Apache让设置生效:

systemctl restart apache2

第二步:配置独立Tomcat(用嵌入式Tomcat直接看第三步)

如果你用的是独立部署的Tomcat,需要修改server.xml里的Connector节点,让Tomcat信任Apache的代理并解析X-Forwarded-For头:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443">
    <!-- 添加RemoteIpValve来解析代理传递的IP和协议头 -->
    <Valve className="org.apache.catalina.valves.RemoteIpValve"
           remoteIpHeader="X-Forwarded-For"
           protocolHeader="X-Forwarded-Proto"
           protocolHeaderHttpsValue="https"/>
</Connector>

这个Valve会自动把X-Forwarded-For里的真实IP替换成Tomcat记录的客户端IP,同时识别原始的HTTPS协议。修改后重启Tomcat即可。

第三步:Spring Boot嵌入式Tomcat配置

如果你的Spring Boot用的是自带的嵌入式Tomcat,不用改独立Tomcat的配置,直接在application.properties或application.yml里添加以下配置:

application.properties写法:

# 告诉Spring Boot信任代理传递的请求头
server.forward-headers-strategy=framework
# 注:Spring Boot 2.2版本前用下面两行替代:
# server.tomcat.remote-ip-header=x-forwarded-for
# server.tomcat.protocol-header=x-forwarded-proto

application.yml写法:

server:
  forward-headers-strategy: framework
  # 旧版本兼容写法:
  # tomcat:
  #   remote-ip-header: x-forwarded-for
  #   protocol-header: x-forwarded-proto

第四步:在Spring Boot中获取真实IP

配置完成后,你就可以通过HttpServletRequest直接拿到真实客户端IP了,代码示例:

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IpController {

    @GetMapping("/get-client-ip")
    public String getRealClientIp(HttpServletRequest request) {
        // 经过前面的配置,getRemoteAddr()已经返回真实客户端IP
        String realIp = request.getRemoteAddr();
        return "客户端真实IP:" + realIp;
    }
}

这样操作后,你的Spring Boot应用就能正确获取到客户端的真实IP,再也不会只拿到127.0.0.1啦。

内容的提问来源于stack exchange,提问作者Jamil Farooq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:15:26