预防ip欺骗的关键是只信任nginx的$remote_addr,因其不可伪造;所有访问控制、限流、封禁必须基于它,而非x-forwarded-for等可伪造请求头,并在有代理时正确配置real_ip模块及清理不可信头。

预防基于 IP 欺骗的访问绕过,关键不是信任请求头,而是**只认 Nginx 自身拿到的真实客户端 IP**。很多绕过源于后端盲目信任 X-Forwarded-For 或类似字段,而攻击者可轻易伪造它们。
只用 $remote_addr 做真实判断
Nginx 的 $remote_addr 是 TCP 连接建立时内核记录的源 IP,无法被 HTTP 请求头篡改,是唯一可信来源。所有访问控制(如 allow/deny)、限流、封禁都应基于它,而非任何请求头变量。
- 在
http或server块中配置 IP 白名单/黑名单时,直接写allow 192.168.1.0/24;,不要依赖头信息做条件判断 - 若需将真实 IP 透传给后端,用
proxy_set_header X-Real-IP $remote_addr;,并在后端代码中只读取X-Real-IP(且不 fallback 到其他头) - 彻底禁用可能被伪造的头参与逻辑:比如删除或覆盖
X-Forwarded-For,避免后端误用
前端有代理时必须严格配置 real_ip 模块
当 Nginx 前面有 CDN、负载均衡或反向代理(如阿里云 SLB、AWS ALB),$remote_addr 会变成代理的 IP。此时必须启用 ngx_http_realip_module 并正确设置可信代理段。
- 确认上游代理会通过
X-Real-IP或X-Forwarded-For传递原始 IP - 在
http块中声明可信代理网段:set_real_ip_from 10.0.0.0/8;(按实际填写) - 指定哪个头携带真实 IP:
real_ip_header X-Real-IP;或real_ip_header X-Forwarded-For; - 启用
real_ip_recursive on;可处理多层代理嵌套,但前提是每层都可信
拒绝伪造头参与访问决策
即使启用了 real_ip,也要防止攻击者在请求中夹带恶意头干扰判断。Nginx 本身不校验头合法性,需主动清理或拦截。
- 用
map指令清空不可信头:map $http_x_forwarded_for $fake_xff { default ""; "~^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$" ""; },再在 proxy_pass 前设proxy_set_header X-Forwarded-For ""; - 对含多个 IP 的
X-Forwarded-For(如1.1.1.1, 2.2.2.2),只取第一个并验证格式,其余丢弃 - 禁止客户端自定义
X-Real-IP:在 server 块开头加underscores_in_headers off;,并用if ($http_x_real_ip) { return 400; }拦截非法设置
结合 location 和变量做细粒度控制
单纯靠 deny all 容易被路径编码、大小写、分号等绕过。应在关键路径上叠加 IP 校验与语义检查。
- 敏感接口(如
/admin、/actuator)用精确前缀匹配:location ^~ /admin/ { allow 192.168.10.0/24; deny all; } - 配合 URL 编码防护:拒绝含
%00、%2e%2e、%252e等高危编码的请求,避免 IP 检查被路径穿越绕过 - 使用
$binary_remote_addr配合limit_req或limit_conn,对异常高频 IP 主动限速限连,不依赖头信息











