那阵子给七亿批量远程管理工具做防爆破,前后改了三版,越改越明白一件事:自动封 IP 这东西,最容易被它封住的不是攻击者,是自己人。

背景先说清楚。我们有一台放在公网上的跳板机,SSH 端口天天被人扫,纯爆破,一天几百次。标准做法,fail2ban 那套——同一个来源 IP,10 分钟里失败满 5 次,直接封。跑了一阵,榜单前排全是自己人。

头一回是同事跑批量任务。七亿批量远程管理工具一次连十台,密码那栏手滑多打了一个字符。脚本不会跟你商量,连着失败十几次,我们办公室出口那个固定 IP 当场进了黑名单。他人还在工位上,过了十来分钟才反应过来:不是连不上机器,是自己把出口 IP 给交了。

这个好办,出口 IP 拉白就完了。真正难缠的是用移动宽带的几个同事。他们的公网 IP 在省内到处飘,今天 112.90 那一段,明天就变成 120.232 开头。你今天把昨天封的段拉白,明天人家换了新段进来,接着被封。加白名单的速度,追不上 IP 漂移的速度。

后来有个同事索性把防爆破关了——等于把门锁拆了求个心安。

IP 白名单这层我们其实也写过,最土的那版:列一串 IP 或者 IP 段,封禁判定之前先比一遍,命中就跳过。问题是它太死。家宽的 IP 会变,出差、开手机热点、临时借别人机器上,全都不在名单里。维护到十几条的时候我就有点放弃了,隔段时间还得清理失效的,维护成本比它挡下的还高。这块当时也不是没栽过跟头,翻计数逻辑那次就是——单位时间里同一个来源的连接,正常的也算进去了,白白封了一批,写在这篇里:防爆破把自己人也算进攻击里了。

换思路是后来某个下午的事。干脆不认 IP,认归属地。

道理不复杂,你人在哪,就信哪一片。我们主力都在广东,那就把「广东」整个放进白名单。封禁判定之前先拿这个 IP 查一下归属地,命中就放行,压根不进封禁流程。粒度是比单个 IP 粗,但刚好卡在一个能用的位置上:家宽 IP 在省内怎么飘,归属地不变,照放行;出差去了外省,提前把常去的那几个省加上,实在不行借另一台机器解个封。至于「攻击者刚好也用广东 IP」这个概率,认了——真碰上盯着你打的,后面还有 IP 黑名单兜底,那层是精确打击。

实现不复杂,就在原来的封禁 hook 里插一步:查归属地,命中白名单关键词就跳过;查不到、接口挂了,就照封。这里我特意让它 fail-safe——白名单失效,绝不能连防护一起失效,查不到就按没白名单处理,该封还得封。这套东西都做在七亿批量远程管理工具里,Windows 和 Linux 端都有,教程在 rdp.7ehl.com/tutorials。

两个细节,现在回头看比功能本身还重要。

一个是缓存。我一开始图省事,每次封禁判定都实时去查接口。封禁 hook 是高频路径,一个 IP 在那儿反复试错,你就在那儿反复查,结果又慢又容易被接口限流。后来改成按 IP 缓存,查过的直接用;接口失败的做个负缓存,十分钟,别让一个半死不活的接口把整条封禁流程拖住。

另一个是留痕。归属地放行的,日志里单独记一类,我打的标记是 GEO-SKIP,跟正常封禁分开。这步我差点偷懒跳过——后来想想,哪天真有攻击者从白名单省份摸进来,我翻日志连他为什么没被封都说不清。日志还按每个 IP 每天一条去重,不然同一个人反复触发,能把日志刷满。

移动宽带那位同事,我给他解完封第二天,他专门过来问我是不是把防爆破关了。我说没有,只是变成先看你从哪来的。

现在我给防爆破排的层次大概是这样:IP 白名单(精确信任)> 归属地白名单(区域信任)> 自动封禁(默认防护)> IP 黑名单(针对兜底)。一层管一层,各管各的场景。算下来不到一百行,把最烦人的那类误封消掉了一大半。

软件免费,搜「七亿批量远程管理工具」,或者直接上 rdp.7ehl.com 看。

防火墙.png