GCP Cloud Run下Go如何获取传入HTTP请求的NAT静态IP
问题根因
你遇到的问题由GCP Cloud Run的原生流量路由机制导致,和你获取IP的代码逻辑无直接关联:
- 你配置的Cloud NAT静态IP仅对发送端服务访问公网目的地的流量生效:当你调用公网站点时,流量会从Cloud Run实例经无服务器VPC连接器转发到配置了NAT的VPC网络,再通过NAT网关做源地址转换后访问公网,因此公网站点能识别到你配置的静态IP。
- 当你调用另一个Cloud Run服务时,如果使用默认的
.run.app域名,GCP会自动通过内部私有网络路由流量,完全不经过公网、也不经过你配置的Cloud NAT网关:- 内部路由的流量不会做源NAT转换,自然不会带上你配置的静态公网IP
- Cloud Run服务前端部署了Google全球前端负载均衡(GFE),你的服务实例收到的请求都是GFE转发而来的,因此
r.RemoteAddr永远是GFE的内部转发地址,你看到的0.0.0.0是Cloud Run环境下的正常表现。真实的接入端IP默认会由GFE追加到X-Forwarded-For请求头中,但内部路由场景下这个IP是Google内部服务地址,不是你的静态NATIP。
可行解决方案
方案1:强制流量走公网路径(保留静态IP源地址逻辑)
如果必须通过静态IP做来源识别,你需要强制发送端到接收端的流量走公网链路,触发NAT转换:
- 不要让发送端通过默认
.run.app域名的内部路由访问接收端,可以给接收端绑定自定义域名,确保发送端解析域名得到公网IP,走公网链路发起请求 - 确认发送端的无服务器VPC连接器配置为将所有出站流量路由到VPC(路由范围选择
all-traffic,而非仅私有IP段流量),确保公网请求会经过VPC的Cloud NAT网关 - 注意:该方案会增加公网绕路带来的网络延迟,同时产生额外的公网流量费用,且
X-Forwarded-For头存在被伪造的风险,需要做可信代理校验才能拿到真实源IP。
方案2:使用GCP原生身份认证替代IP识别(推荐)
Cloud Run作为Serverless服务,不推荐使用IP白名单/源IP识别做服务间鉴权,更稳定可靠的方式是用GCP内置的服务账号身份认证:
- 给发送端Cloud Run服务绑定专属的服务账号
- 发送端发起请求时,为接收端服务生成对应受众的OIDC ID Token,放在
Authorization: Bearer <token>请求头中 - 接收端服务开启内置的IAM身份验证,或者在代码中校验请求携带的ID Token的签发方、受众、绑定的服务账号标识,确认请求来自受信任的发送端
该方案完全不依赖网络路由路径,没有额外的流量开销,也不存在IP伪造、NAT配置失效的风险,是GCP官方推荐的Cloud Run服务间调用鉴权方式。
补充:现有IP获取代码的风险
你当前的IP解析逻辑存在安全漏洞:X-Forwarded-For头可被客户端任意伪造,你直接取逗号分割的第一个IP,很容易拿到伪造的虚假地址。Cloud Run场景下,只有GFE追加到X-Forwarded-For最末尾的、和GFE直接建立连接的源IP是可信的,取IP时应该从右向左遍历IP列表,跳过已知的可信代理地址后拿到真实客户端IP。
内容的提问来源于stack exchange,提问作者rams
相关产品推荐
相关产品推荐

