广告位联系
返回顶部
分享到

Nginx allow/deny诡异问题:同一浏览器页面正常接口403问题分析与解决

linux 来源:互联网 作者:佚名 发布时间:2026-09-09 22:23:14 人浏览
摘要

1、背景 1.1 nginx配置 线上 Nginx 配置 IP 白名单,使用allow + deny all做访问控制,仅允许内网 IP196.16.0.2访问服务。 1 2 allow 196.16.0.2; deny all; 1.2 发起请求 同一台 Windows 浏览器发起两类请求: 访问首

1、背景

1.1 nginx配置

线上 Nginx 配置 IP 白名单,使用allow + deny all做访问控制,仅允许内网 IP196.16.0.2访问服务。

1

2

allow 196.16.0.2;

deny all;

1.2 发起请求

同一台 Windows 浏览器发起两类请求:

  1. 访问首页GET /:请求正常返回 304,页面成功加载;Nginx 访问日志客户端 IP 记录为196.16.0.2。
  2. 页面 JS 发起后端接口GET /test/get:直接返回 403 拒绝访问;Nginx 日志客户端 IP 记录为公网 IP1.80.211.195。

1.3 nginx日志

现象:同一个浏览器,页面请求放行,接口请求被拦截,Nginx 日志记录两个完全不同的客户端 IP,业务人员第一反应怀疑浏览器或者 Nginx 缓存异常。

1

2

196.16.0.2 - - [07/Aug/2026:15:01:25 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36"

1.80.211.195 - - [07/Aug/2026:15:01:26 +0800] "GET /test/get HTTP/1.1" 403 555 "http://196.16.0.37/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36"

Referer 字段http://196.16.0.37/,说明前端页面部署在196.16.0.37这台 Nginx 服务器。

2、根因分析

2.1 核心原理:allow/deny 的判断对象

allow、deny属于 Nginx 的access访问控制模块,读取的是 TCP 四层连接的源 IP 变量$remote_addr,完全忽略 HTTP 请求头,包括X?Forwarded?For。 即使 HTTP 头部携带真实客户端内网 IP,allow/deny也不会读取,仅以 TCP 连接对端 IP 作为判断依据。

这是绝大多数开发容易踩坑的知识点:经过代理转发的请求,$remote_addr是代理服务器出口 IP,而不是浏览器真实 IP。真实客户端 IP 被放在 HTTP 请求头X?Forwarded?For中。

2.2 两条请求链路完全不一样

  1. 首页请求链路(正常) 浏览器访问内网地址http://196.16.0.37/,直接在内网访问 Nginx 服务。 TCP 连接来源 IP 就是浏览器机器196.16.0.2,命中白名单allow 196.16.0.2,请求放行,页面正常返回。
  2. AJAX 接口请求链路(403 拒绝) 前端 JS 代码硬编码写死公网域名调用后端接口,没有使用相对路径。 浏览器发起接口请求不再走内网,流量走到公网,经过上层负载均衡 / 代理网关,再转发到同一套 Nginx。 此时 Nginx 收到 TCP 连接的源 IP 变成代理出口公网 IP1.80.211.195;虽然 HTTP 头X?Forwarded?For携带真实客户端196.16.0.2,但是allow/deny不识别 HTTP 头,匹配不到白名单,执行deny all,返回 403。

关键点:同一个浏览器,不同请求可以走完全独立的网络链路,Nginx 看到的客户端 IP 可以完全不同,不是浏览器故障。

2.3 现象总结

页面在内网访问,接口走公网代理;四层 TCP 源 IP 发生改变,HTTP 头里的真实 IP 没有被 Nginx 访问控制模块识别,最终出现页面正常,接口 403 的诡异现象。

2.4 故障流程图说明

3、改变 Nginx 看到的 $remote_addr的各类方式

说明:$remote_addr是 Nginx 拿到的TCP 连接对端 IP,allow/deny 直接读取这个值。 下面全部是会改变服务端看到 IP 的场景,也就是:浏览器真实 IP 不变,但 Nginx 日志里面记录的 IP 变成别的 IP。

代理转发类(最常见,业务系统高频踩坑)

Nginx 反向代理

客户端→代理 Nginx→后端 Nginx / 服务。后端 Nginx 看到的 IP 是代理服务器 IP。 需要配置proxy_set_header X?Forwarded?For $remote_addr传递真实 IP;但allow/deny仍然看 TCP 源 IP,不读该 header。

HAProxy / LVS (DR 模式除外) / 负载均衡 SLB(云厂商)

云 SLB、硬件负载均衡,流量经过负载均衡转发,后端服务 TCP 对端 IP 变成 LB 节点 IP。

本次故障就是该场景:页面直连内网,接口走公网 SLB,IP 发生变化。

CDN 加速

域名接入 CDN 后,用户请求全部打到 CDN 节点,源站 Nginx 看到的 IP 是 CDN 节点 IP,不是用户真实 IP。

内网正向代理(公司代理服务器)

公司内网配置 HTTP 代理,浏览器所有请求经过代理服务器出去,服务端看到代理服务器 IP。

VPN、隧道类

远程 VPN(SSL?VPN、IPsec VPN)

  • 客户端接入 VPN:访问内网资源时,TCP 源 IP 变为 VPN 分配给本机的虚拟内网 IP;访问公网资源时,出口为 VPN 网关公网 IP。

现象:本机真实网卡 IP 不变,但是服务端看到的 IP 已经切换。

代理隧道工具(socks5 代理)

浏览器配置 Socks5 代理,全部流量经由代理节点转发,服务端记录代理节点 IP。

ZeroTier / Tailscale 虚拟组网

组建虚拟局域网,访问虚拟网络地址,TCP 源 IP 为虚拟网卡分配 IP,和物理网卡 IP 不一样。

域名 / DNS 带来的 IP 变化(本次故障根源)

同一个浏览器,不同域名,会走完全不同网络路径,服务端拿到不同源 IP

  1. 域名 A 记录指向内网 IP:浏览器直接内网 TCP 直连,Nginx 看到浏览器真实内网 IP。
  2. 同一个业务,另外一个域名解析到公网 IP(经过 SLB/CDN):DNS 解析出来公网 IP,浏览器向外网发起 TCP 连接,经过公网代理,Nginx 看到代理节点 IP。

典型坑:页面用内网域名http://196.16.0.37访问,JS 接口写死公网域名,虽然是同一台浏览器,两套请求 TCP 链路完全不一样,服务端拿到的源 IP 完全不同,就是我们故障案例。

关键点:域名 / DNS 本身不会修改 IP,但是 DNS 解析结果决定流量走哪条网络链路,最终导致服务端看到的 $remote_addr 改变。

网关 / NAT 网络环境

SNAT 源地址转换(路由器、防火墙做源 NAT)

大量企业内网出口防火墙做 SNAT,内网机器访问服务器,源 IP 被转换成防火墙网关 IP。

  • 如果客户端和服务器同网段:不经过 SNAT,服务端看到真实客户端 IP。
  • 如果客户端访问跨网段,经过防火墙 SNAT:服务端看到网关 IP。

极易出现:同个浏览器,访问同服务器,不同访问路径,日志 IP 不一样。

容器环境 NAT(Docker、K8s)

容器内部访问外部服务,经过 docker0 网桥 SNAT,外部服务看到宿主机 IP,不是容器内部 IP。

客户端侧网络切换

1. 电脑多网卡:机器同时有内网网卡、Wi?Fi、4G 上网卡。访问不同目标 IP,系统路由选择不同网卡出口,TCP 源 IP 随之改变。

例如:访问内网服务走内网网卡;访问公网域名走 Wi?Fi 网卡,服务端看到不同 IP。

2. 双栈网络 IPv4/IPv6:服务器支持 IPv6,客户端优先 IPv6 连接,Nginx 日志记录客户端 IPv6 地址,和 IPv4 内网 IP 完全不同。

总结

  • allow/deny是四层 TCP 访问控制,只要中间任意设备做了代理、NAT、VPN 转发,$remote_addr 就会被替换,哪怕 HTTP 头携带真实 IP,allow/deny 完全无视。
  • 有代理 / NAT 环境,不要使用allow/deny做业务客户端 IP 白名单,需要读取X?Forwarded?For做应用层 IP 校验,同时做好防请求头伪造。
方式 是否改变 TCP 源 IP ($remote_addr) 是否使用 X?Forwarded?For 传递真实 IP allow/deny 能否拿到真实客户端 IP
反向代理 / SLB/CDN ?改变(变成代理 IP) ?可以带上真实 IP ?不能,allow/deny 只看 TCP 源 IP,忽略 header
VPN、Socks 代理 ?改变(网关 / 代理节点 IP) ?一般不带 X?Forwarded?For ?
DNS 域名切换链路 ?间接改变(路由链路变化) 看链路中间设备 ?
SNAT 防火墙 NAT ?改变(网关 IP) ? ?

版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计