ip hash策略需配合realip模块和严格x-forwarded-for透传才能正确识别真实客户端ip;配置set_real_ip_from、real_ip_header及proxy_set_header x-real-ip后,后端应读取x-real-ip而非自行解析xff。

IP Hash 策略本身不处理多级代理问题,它只对 $remote_addr 做哈希。真正起作用的是让 $remote_addr 变成真实客户端 IP —— 这必须靠 realip 模块和严格透传规则配合完成。
确保 ip_hash 作用在修正后的客户端 IP 上
默认情况下,Nginx 的 $remote_addr 是上一跳代理的出口 IP(比如 CDN 或 LB 的内网地址),所有请求哈希结果都一样,导致流量全打到同一台后端。修复的关键是:先用 realip 把 $remote_addr 替换为用户真实 IP,再启用 ip_hash。
- 在
http或server块中配置可信代理段:set_real_ip_from 192.168.100.0/24;set_real_ip_from 173.245.48.0/20;(Cloudflare)set_real_ip_from 203.208.60.0/24;(Google CDN) - 指定头字段和递归模式:
real_ip_header X-Forwarded-For;real_ip_recursive on; - 验证是否生效:查看 access log 中
$remote_addr是否已变成公网 IP(如203.0.113.45),再写 upstream:
upstream backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
全链路 X-Forwarded-For 必须干净且可信
realip 能正确提取真实 IP,前提是 X-Forwarded-For(XFF)头没被污染或截断。中间任何一层清空、覆盖或错误追加 XFF,都会导致解析失败。
- 首层 Nginx(直连 CDN/WAF)必须用
$remote_addr初始化:proxy_set_header X-Forwarded-For $remote_addr; - 后续每一层(如中间网关)只能追加,不能覆盖:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 禁止出现
proxy_set_header X-Forwarded-For ""或硬编码固定值
避免 upstream 动态变更破坏哈希映射
即使 IP 识别准确,以下操作仍会导致会话漂移:
- 在
upstream中混用weight、backup、max_fails等参数 ——ip_hash不兼容这些,新版本 Nginx 会直接报错 - 扩容或缩容节点(如从 3 台变 4 台)—— 哈希环重算,所有用户路由关系改变,登录态丢失
- 后端应用自行解析
X-Forwarded-For而非读取$remote_addr—— 容易取错段(比如拿到 CDN 出口 IP 而非用户真实 IP)
后端应读取 realip 修正后的 IP,而非原始头
很多问题其实出在后端代码里。它不该自己拆解 X-Forwarded-For,而应信任 Nginx 注入的 X-Real-IP 或直接使用已修正的 $remote_addr(可通过日志确认)。
- Nginx 最后一层(直连后端)建议显式注入:
proxy_set_header X-Real-IP $remote_addr; - 后端语言(如 Java/Spring Boot)应读取
X-Real-IP头,或配置反向代理信任策略(如RemoteIpValve) - 禁用后端对
X-Forwarded-For的“第一段即真实 IP”逻辑 —— 这在多级代理下极不可靠











