网站挂在代理后面,登录锁定和黑名单为什么会认错来源地址

📅 2026-10-12 👁️ 2

网站挂在反向代理后面时,登录锁定和 IP 黑名单为什么会认错来源地址,根子在于两层地址被当成了一层。直连的时候,程序从连接本身读到的就是访问者地址,两层重合,看不出问题。前面加了一层代理或网关之后,连接的对端变成代理,真实访问者的地址只能靠代理写进转发头里带过来。这两条线索一条是握手时确定的、由不得对方编,一条是文本形式传过来的、发请求的人想写什么就写什么,一旦代码把它们视作同一种信息,判定对象就开始错位。

两层地址本来就不是一回事

第一层是连接层来源。它由传输层确定,程序拿到的是「谁跟我建立了这条 TCP 连接」。挂上代理之后,这个值稳定地指向代理自身的地址,日志里成片的相同来源就是这么来的。第二层是声称层来源,常见形态是 X-Forwarded-For 这类头,内容由前置节点追加,用来转述「最初请求来自哪里」。它能用,但可用性取决于链路是否可信:如果请求先经过攻击者控制的节点再进入站点,那这条声称完全可以是伪造的。

判定逻辑要区分这两件事:连接层来源是证据,声称层来源是证词。把证词当证据用,等于让访问者自己填报身份。

无条件信任来源头会出什么事

出问题的写法很直白:程序取地址时先看转发头,头里有什么就用什么,既不检查这一跳是不是自己的代理,也不管头里已经串了几段。PbootCMS 在 V3.2.25 的更新记录里修过这类问题——取地址函数无条件信任 X-Forwarded-For,导致 IP 黑白名单与登录锁定可以被绕过,同一版本把可信代理配置项加了进来。

后果具体落在两处。登录锁定是按来源地址累计失败次数的,地址可自报,攻击者每次换一个值,计数就永远落不到同一个人身上,锁定形同虚设。黑名单反过来是封禁手段,封的是真实对端,判定用的却是可伪造的字段,于是真地址照打、假地址被误伤。两处共用的缺陷是同一个:拿可编辑的字段当身份标识。

只在可信链路里取最右可信值

通行的做法是先声明可信代理网段,再决定从哪一段取值。请求经过多级代理时,转发头里会串出多个地址,越靠左的越可能是访问者自填,越靠右的越接近自己掌控的那一跳,所以取值规则应当是从右往左走,第一个不属于可信代理网段的地址即为来源。不在可信名单里的跳,它写进来的内容一律不采信,退回连接层地址。

这套规则的前提是把「我的代理是谁」配置成显式事实,而不是靠推断。配置项在程序里、在网关里都可能出现,两处都改才算改完;只改一层时,另一层仍在按旧规则取值,日志与判定的分歧就会继续留着。

限速与锁定该用哪一层地址

按来源做惩罚的功能,用哪一层地址取决于惩罚要对谁生效。限制暴力尝试、封禁滥用来源,目标是真实发起方,因此要用经过可信链路还原后的地址;针对某个入口做整体限流,作用对象是进入本站的这条通道,用连接层地址反而更稳。把两类混在一个开关上,常见现象是锁定误伤一大片同源出口的正常用户,而真正的高频尝试却在换一个自报值之后就恢复。

同一份地址还要看写进日志的字段是哪一层。排查时只有连接层地址,判定用的是声称层地址,两边对不上,复现与统计都会失真。

常见问题

问:把转发头整个删掉是不是更省事? 答:删掉之后连接层地址只剩代理自己,判定会退化成「按代理地址集体处置」,误伤范围反而更大。正确做法是保留并配可信网段,而不是取消这一层信息。

问:只有一层自建代理,还需要配可信网段吗? 答:需要。可信网段的作用是确认这一跳值得采信,不取决于层数多少。配了之后取值规则才有依据,将来加一层缓存或网关时也不用重新推导。

问:程序改了,网关那边还要动吗? 答:要。地址由前置节点写入、由程序读取,两端的约定改了才生效。只改程序时,前置节点是否追加、追加格式如何,都还在旧状态。

相关文章

后台留言批量删除接口按参数拼接,删除范围该怎么校验

后台留言的批量删除如果直接把前端传来的编号列表拼进删除条件,一次请求就可能删掉范围外的内容。PbootCMS 在 V3.2.18 的更新记录里修过这一类参数注入,做法是严格校验要删除的 id 列表。本文说明批量接口为什么把影响面放大、编号该按类型和存在性怎么验、删除范围为什么要服务端重新算一遍,以及误删之后回收站能兜住什么。

2026-10-12

模板标签输出了脚本开标签,内容怎么会被当成代码执行

PbootCMS修复过站点标签输出脚本开标签的风险并增强了标签页参数过滤——当可编辑内容带着开标签进入模板引擎,数据就会被当成代码执行。本文解释数据变成代码的那一步发生在哪、标签输出位为什么要过滤、HTML、属性、脚本、URL四种上下文为什么要分别转义,以及越靠前的过滤越省事的分层收口。

2026-10-11

图片处理库被列为攻击面,站点上传环节该收哪几道门禁

图片处理库在服务端解码用户上传的二进制内容,远程代码执行往往发生在解码器层而不是业务代码。PbootCMS在V3.2.22版本记录里把危险coder门禁、输入格式白名单与资源上限一起加入安全硬化,并修复了合法图片误判。本文按这三道门禁讲清站点上传环节该收的口子,以及收得太紧为什么会误伤正常图片。

2026-10-11

公告把示例功能整段移除以修掉资源分配问题,生产站该留演示代码吗

Drupal公告SA-CONTRIB-2026-215的评级只是Less critical,处理方式却把邮件示例功能整个移除,因为示例存在没有上限的资源分配问题。生产站要不要保留演示代码,判断依据应是暴露面而不是风险评级。本文拆解示例代码带出的三类风险、部署阶段的清理清单,以及保留演示入口时的限制办法。

2026-10-11

页面里嵌第三方视频,iframe 的能力授权按什么放行

页面里嵌第三方视频涉及两层限制:来源域名按白名单放行,摄像头、定位、自动播放这些能力按最小集逐项授权。PbootCMS 在 V3.2.18 的更新记录里对可信视频域名保留默认来源策略,并对 allow 属性做了 token 白名单。本文解释内嵌框架为什么同时带着脚本与媒体能力、精确域与子域通配怎么分,以及放行与授权为什么要分开配。

2026-10-12

用户退出登录后浏览器里还留着旧数据,响应头怎么要求清除

退出登录时浏览器里留着的缓存和本地存储不会自动消失。Clear-Site-Data 响应头是给客户端的清除信号,可按项清缓存、凭据、存储与执行上下文,且只在加密连接里生效:凭据清到整个注册域,存储只清当前来源。站内登录态由 JWT 承载,客户端这一层本地数据要靠它配合收尾,公共设备上尤其值得加。

2026-10-12

浏览器会标出请求来自本站还是外站,服务端怎么据此挡住跨站请求

浏览器会给请求加上标明来源关系的几个 Sec-Fetch 请求头,前端脚本改不了它们。取值区分同源、同站、跨站与无发起方,服务端按这些关系决定放行还是拒绝,就能对跨站请求伪造做出一道与写操作确认互补的防线;这组头只在可信地址的请求里发送。本文讲四个取值的含义、按上下文放行的写法,以及它与回合级操作审批各自管什么。

2026-10-12

内容没变时服务器只回一个状态码,条件请求靠哪个标识判断

缓存过期不代表要重新下载整份内容。ETag 是某一版资源的标识,资源内容变了就必须生成新值;客户端回访时用 If-None-Match 把旧值带回,服务端比对一致就只回一个不带正文的状态码。本文讲这个标识代表什么、强校验与弱校验的差别、弱标识为什么会影响分段请求,以及内容频繁改动的站点怎么用它减少重复传输。

2026-10-12