ip_hash仅实现客户端IP路由,不防Header伪造;需结合real_ip_module还原真实IP、proxy_set_header透传X-Real-IP、后端校验Session中IP一致性三重机制。

配置 ip_hash 本身不防 Header 伪造,它只做请求路由;真正防止伪造需配合真实 IP 还原 + 请求头校验 + 服务端验证三重机制。单纯开 ip_hash 反而可能掩盖伪造问题,让攻击更隐蔽。
确保 $remote_addr 是真实客户端 IP
这是整个链条的起点。若 Nginx 收到的 $remote_addr 是 CDN、WAF 或上一级代理的内网地址(如 10.0.1.5),ip_hash 就会把所有用户哈希到同一台后端,既失效又放大风险。
- 启用
real_ip_module,在http块中明确声明可信代理段:
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
real_ip_header X-Forwarded-For; - 在
location中透传真实 IP:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 验证是否生效:临时加一条日志格式,检查 access.log 中
$remote_addr是否已变为公网 IP
禁用不可信请求头参与路由或鉴权
攻击者可轻易伪造 X-Forwarded-For、X-Real-IP 等 Header。Nginx 默认不校验,必须主动切断其被滥用路径。
-
禁止后端直接信任
X-Forwarded-For:该字段易被客户端篡改,仅可用于日志记录,不可用于登录态绑定、风控限流等关键逻辑 -
后端服务应只认
X-Real-IP,且该值必须由 Nginx 写入——通过proxy_set_header X-Real-IP $remote_addr;固定写死,不拼接、不转发原始请求头 - 在 Nginx 中清除恶意注入头:
proxy_set_header X-Forwarded-For "";
proxy_hide_header X-Forwarded-For;(若后端完全不需要)
服务端做二次 IP 校验(严格模式核心)
ip_hash 解决的是“请求发给谁”,但无法保证“谁发的请求是真的”。服务端必须独立验证 IP 一致性,尤其在登录、支付、敏感操作环节。
- 登录成功后,在 Session 或 Token 中记录客户端真实 IP(即 Nginx 传来的
X-Real-IP) - 后续每次关键请求,比对当前请求的
X-Real-IP与 Session 中存储的 IP 是否一致 - 不一致时,拒绝操作并记录告警(如返回 403 + “IP 异常变动”提示),而非仅刷新 Session
- 对内网访问(如运维跳板机)可配置白名单 IP 段,避免误拦
规避 ip_hash 自身的安全盲区
它不是万能锁,几个固有特性反而可能引入新风险:
- IPv4 仅取前 3 段哈希(
192.168.1.x全视为同一 IP),NAT 环境下大量用户被绑死单台后端,一旦该节点异常或被攻陷,影响面集中 - 不支持
weight,无法做灰度或故障隔离;加了会直接导致 Nginx 启动失败 - 增删 upstream 节点会重哈希,引发批量会话丢失——这不仅是可用性问题,更是安全窗口:用户重登时若无二次验证,可能被劫持会话
- 若后端用 Redis 共享 Session,
ip_hash实际冗余,应改用least_conn或轮询,降低单点依赖










