当前位置: 代码网 > 服务器>服务器>Linux > Nginx allow/deny诡异问题:同一浏览器页面正常接口403问题分析与解决

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

2026年09月09日 Linux 我要评论
1、背景1.1 nginx配置线上 nginx 配置 ip 白名单,使用allow + deny all做访问控制,仅允许内网 ip196.16.0.2访问服务。allow 196.16.0.2;de

1、背景

1.1 nginx配置

线上 nginx 配置 ip 白名单,使用allow + deny all做访问控制,仅允许内网 ip196.16.0.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 缓存异常。

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 的判断对象

allowdeny属于 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 传递真实 ipallow/deny 能否拿到真实客户端 ip
反向代理 / slb/cdn✅改变(变成代理 ip)✅可以带上真实 ip❌不能,allow/deny 只看 tcp 源 ip,忽略 header
vpn、socks 代理✅改变(网关 / 代理节点 ip)❌一般不带 x‑forwarded‑for
dns 域名切换链路✅间接改变(路由链路变化)看链路中间设备
snat 防火墙 nat✅改变(网关 ip)

以上就是nginx allow/deny诡异问题:同一浏览器页面正常接口403问题分析与解决的详细内容,更多关于nginx allow/deny页面正常接口403的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com