十一那天扒 nginx 日志写了篇 25 万发扫描的文章,结尾还很嘴硬,说静态站玩家用 return 444 就够了,fail2ban 那套复杂的就不用了。结果没过几天就真香了,fail2ban 现在在我这台 1 核小鸡上跑得欢实。今天把这事交代一下,顺便聊聊为什么封禁数是 0 我还挺高兴。
先看现状。装完之后我上去盘了一眼 lastb,btmp 里失败登录记录从 10 月 1 号到现在就两条,干净得像刚装完系统。不是攻击变少了,是我这台机器对扫描器来说基本隐形了:SSH 端口老早改成 2825,全网瞎扫 22 端口的机器人连门朝哪开都摸不到;HTTP 那边 nginx 的 444 规则天天在掐垃圾流量。所以 fail2ban 上岗半个月,一次出手的机会都没有。
那为什么还要装?这就要说到我之前想法里偷懒的地方了。444 和改端口这两招,本质都是"让扫描器看不见我",属于隐身流。但隐身有个前提,就是你真的没被盯上。哪天我的域名被谁挂到什么字典里了,或者来了个专门对着 IP 扫全端口的,nmap 跑一圈 2825 照样现形。隐身流最怕的就是隐身失败的那一刻没有任何兜底,被人从发现一路平推到沦陷。
fail2ban 补的就是这个位置。它不管你看没看见我,只要你在 SSH 上连续输错 5 次密码,或者对着 nginx 打了 3 次可疑路径,防火墙直接拉黑,SSH 那个 jail 一关就是一整天。我现在的配置很保守:sshd jail maxretry 5、bantime 86400,nginx-botsearch jail maxretry 3、bantime 3600。放着不动,让它自己看门。
资源这块也交代下,毕竟 1.9G 内存每一兆都是抠出来的。fail2ban 是 Python 写的,跑起来十几兆,相比它能兜底的场景,这价格我出得起。而且它是 systemd 服务,重启机器自己拉起来,完全不用管,这种装完就能忘的东西在我的运维哲学里是加分项。
顺便说下实际效果怎么验证。fail2ban-client status sshd 一敲,能看到 Currently banned 和 Total banned。我这里俩都是 0。第一反应是这玩意是不是白装了,后来想明白了:各层防线都在干活,扫描器根本活不到出现在 fail2ban 面前的那一步,它当然没业绩。这跟打 DOTA 买眼一个道理,眼位放了一整局没被排、也没抓到人,不代表眼是白买的,只是威胁在更外圈就被处理掉了。真等到眼位开始抓人,说明局势已经有点不对劲了。
所以现在这台机器的防线是这样的:改端口负责让瞎扫的滚,444 规则负责把 HTTP 层的垃圾掐了,fail2ban 在最后面蹲着,等一个万一。三层各司其职,任何一层失守都还有下一层。半个月 0 封禁不是它闲着,是前面几层干得太好了。
哪天你要是看到我这台机器的封禁列表里有 IP 了,别替我紧张,那说明兜底在工作,反而是好事。真正该慌的是哪天 btmp 突然多出几千条失败记录,那才是防线被打穿的信号。
就这样,希望 Total banned 永远是 0。