req.RemoteAddr 不可靠,因它仅返回直连服务器的对端地址(如Nginx、CDN或SLB内网IP),而非用户真实IP;必须结合可信代理校验与X-Forwarded-For头解析,取其中最左非私有IP,否则限流、风控、日志将失效。
直接用 req.remoteaddr 拿到的几乎从来不是真实用户 ip,除非你的服务直接暴露在公网、中间零代理。 真实 ip 必须结合可信代理校验 + 请求头解析,否则限流、风控、日志全会出错。
为什么 req.RemoteAddr 不可靠
它只返回和你服务器**直连的对端地址**——通常是 Nginx、CDN 或云负载均衡(如 AWS ALB、阿里云 SLB)的内网 IP,不是用户本身。比如看到 10.0.1.5:42193,这其实是你集群内部某个反向代理节点的出口地址。
- CDN 场景下,
req.RemoteAddr是 CDN 边缘节点 IP - K8s Ingress 控制器(如 Nginx Ingress)后,它是 Ingress Pod 的 ClusterIP 或 NodePort 所在节点 IP
- 本地开发用
curl localhost:8080,它甚至可能是127.0.0.1
必须校验可信代理后再解析 X-Forwarded-For
攻击者可以随意伪造 X-Forwarded-For: 1.2.3.4,所以不能无条件信任该头。核心逻辑是:只有当 req.RemoteAddr 属于你**明确信任的代理网段**(如 Nginx 内网 IP 段 10.0.0.0/8、172.16.0.0/12),才去取 X-Forwarded-For 最左的非私有 IP。
-
X-Forwarded-For格式为"203.0.113.195, 203.0.113.196, 203.0.113.197",最左边是原始客户端,越往右越靠近服务端 - 需逐个
strings.TrimSpace后调用net.ParseIP(ip).IsPrivate()判断是否私有(127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16等) - 若所有项都是私有 IP,再 fallback 到
X-Real-IP(前提是 Nginx 配置了proxy_set_header X-Real-IP $remote_addr;)
net/http 标准方式比第三方库更轻量也更可控
别引入 github.com/mholt/xforwarded 或类似包——它们默认信任所有代理,或配置复杂。自己写一个 20 行内的函数反而更安全、更易审计:
func getClientIP(req *http.Request) string {
ip, _, _ := net.SplitHostPort(req.RemoteAddr)
if !isTrustedProxy(ip) {
return ip
}
if xff := req.Header.Get("X-Forwarded-For"); xff != "" {
for _, x := range strings.Split(xff, ",") {
x = strings.TrimSpace(x)
if ip := net.ParseIP(x); ip != nil && !ip.IsPrivate() {
return x
}
}
}
if realIP := req.Header.Get("X-Real-IP"); realIP != "" {
if ip := net.ParseIP(realIP); ip != nil && !ip.IsPrivate() {
return realIP
}
}
return ip
}
其中 isTrustedProxy(ip string) 应硬编码你自己的代理 CIDR 列表(如 "10.0.0.0/8"),或从配置加载。不要用 localhost 或 127.0.0.1 做判断依据——Docker/K8s 下 req.RemoteAddr 可能是 172.17.0.1 这类网桥地址。
HTTP 与 TCP 场景不能混用
上面逻辑只适用于 *http.Request。如果你写的是裸 TCP 服务(比如自定义协议服务器),conn.RemoteAddr().String() 就是真实客户端 IP:Port,无需解析任何 header——因为没 HTTP 头这回事。此时误套用 HTTP 的 X-Forwarded-For 解析逻辑,纯属南辕北辙。
最容易被忽略的一点:同一份代码,部署在不同网络拓扑下(直连 vs Nginx vs CDN vs K8s Service),可信代理列表、请求头存在性、甚至是否启用 TLS 终止,都会让 IP 提取结果完全不同。没有“一劳永逸”的函数,只有贴合你当前基础设施的判断逻辑。


















