部署在AWS App Mesh的服务如何获取远程/客户端IP地址或域名
问题原因确认
返回127.0.0.1的问题确实是与服务一同部署的Envoy代理导致的。
AWS App Mesh 架构下,Envoy sidecar 会和 Spring Boot 服务同实例部署在 Fargate 中,所有入站流量都会先经过 Envoy 代理转发到本地运行的 Spring Boot 进程,因此 Spring Boot 收到的 TCP 连接来源是本地的 Envoy 进程,调用getRemoteHost()和getRemoteAddr()自然会返回127.0.0.1。
正确获取调用方IP/服务信息的方案
1. 配置App Mesh虚拟节点开启请求头传递
首先需要调整对应服务的App Mesh虚拟节点入站监听器配置:
- 确保
X-Forwarded-For(XFF)头的追加与传递能力开启,Envoy默认会将真实调用方的IP追加到该请求头中 - 配置客户端IP检测方式为XFF,设置可信代理范围为本地网段,避免XFF头被恶意篡改
- 网格内部服务调用场景下,Envoy默认会自动携带
X-Envoy-Peer-Address(调用方IP)、X-Envoy-Peer-Metadata-Service-Name(调用方服务名)等头,无需额外配置即可直接读取
2. Spring Boot服务侧适配
你可以根据业务需求选择以下两种适配方式:
方式一:手动从请求头读取
直接在业务代码中从HttpServletRequest对象读取对应请求头即可:
import javax.servlet.http.HttpServletRequest; // 获取真实调用方IP public String getRealIp(HttpServletRequest request) { String xffHeader = request.getHeader("X-Forwarded-For"); if (xffHeader != null && !xffHeader.isEmpty()) { // XFF头为逗号分隔的IP列表,第一个为最原始的调用方IP return xffHeader.split(",")[0].trim(); } // 网格内部调用可直接读取Envoy自带的对等IP头 return request.getHeader("X-Envoy-Peer-Address"); } // 获取调用方服务名(仅网格内部调用场景可用) public String getCallerServiceName(HttpServletRequest request) { return request.getHeader("X-Envoy-Peer-Metadata-Service-Name"); }
方式二:配置框架自动识别,兼容原有代码
如果不想修改原有调用getRemoteAddr()的代码,可配置Spring Boot信任代理头,框架会自动从XFF头解析真实IP:
如果使用内置Tomcat容器,在application.yml中添加如下配置:
server: forward-headers-strategy: native tomcat: remoteip: trusted-proxies: "127.0.0.1" internal-proxies: "127.0.0.1" remote-ip-header: "X-Forwarded-For" protocol-header: "X-Forwarded-Proto"
配置完成后,原有getRemoteAddr()、getRemoteHost()方法无需修改即可返回真实调用方IP。
内容的提问来源于stack exchange,提问作者shwetap
相关产品推荐
相关产品推荐

