本帖最后由 Moziyu 于 2019-4-29 18:01 编辑


前言


发这个贴本来只是为了介绍一次自己动手反压测的实战经验,后来发现这个版块有很多在热心学习Java的同学。作为一名工作多年的老Java,深知学习开发之初实战的重要性。如果能得到一些较为简单的例子进行反向研究,对能力提升是非常有帮助的,能快速掌握Java多种应用方法也对更深层的理解有所帮助。
本次的实战中,整套反压测组件的四个组件皆源于不同的应用场景中。如果你对特别的思路和解决方案感兴趣,就请仅带着好奇的心态继续浏览这个帖子吧。关于本人的代码风格、其他更优秀的解决方案,仅需简单提一下就好,请勿争论。





事件介绍


服务器从4月7日中午12点半左右开始受到压测攻击(攻击者使用攻击脚本,使大量账号通过代理进服并注册,同时跑图或放置拆除方块卡服)。据群内玩家推测,是由于我的服务器权限价格和游戏体验等等优于某个想赚钱想疯了的商业服,导致对方玩家大量流入我服,致使对方服主进行的报复行为。
由于我刚好在外地旅游,没有带电脑,时间安排较紧没法现去网吧搭建开发环境写应对工具,攻击者可能也是抓住了这一时机来的,一直到4月9号晚我回家才开始解决,两天内玩家忍受了许久巨卡的煎熬。
(期间我们可爱的管理员还用屏障和岩浆堵住出生点烫机器人,哈哈哈超级可爱)





解决方案


4月9号晚是我给出的第一轮解决方案,从设计到开发使用了不到两小时的时间,执行效果良好,简单说一下这第一部分:
大致的思路是通过让玩家在线注册用户名,然后用插件来过滤用户。这和白名单的功能基本一致,只是无需在服务器内输入指令即可添加,要灵活、方便许多。首先为了方便玩家注册,我选择用酷Q搭建了一个群机器人,玩家只需在群内发送【注册玩家:名字】这段文字后,机器人就自动将名字记录下来。记录的文件路径配置到服务器的插件目录中,然后就只需写一个简单的插件,读取记录文件中的列表,过滤进服的玩家即可。
然而第二天这个方案就出现了问题。因为攻击者发现了我的更新,他去除了脚本中跑图或放置拆除方块的部分,加倍增加了账号进服的频率,峰值达到了每秒30个账号进服,这样使服务端大量执行PlayerLoginEvent,而我的插件、Authme和LuckPerm插件都会处理这个事件,我的插件会重新访问记录文件,另两款插件也会高频访问数据库,导致CPU负载巨大。
针对这样的攻击,使用服务端插件反攻击的方案显然是无法解决的。我便开始考虑在服务端更前一层的位置解决,第一个想法就想到了TCP端口转发。因为在这一层,我可以主动过滤连接来源的IP。首先获取玩家IP是一个问题,我使用SpringBoot搭建了一个只有一个Mapping的简单Web应用,并在这之中获取客户端IP,并将客户端IP记录到文件中。然后使用JavaSocket搭建一个TCP代理,将原本服务端的端口切换为其他端口,将代理接入原端口,在收到请求时,取出记录下的IP列表进行匹配后放行。玩家只需要在进服前访问一次Web接口,即可在更换电脑前持续正常进服。





事件总结


全套解决方案共4个模块,完美解决了压测攻击、恶意注册的问题,同时群机器人还附带记录了玩家QQ,推进玩家加群的同时也方便在群中找到玩家。
TCP代理模块经过升级后,实现了定期统计连接次数,根据所设置的阈值自动开启或关闭防御的功能。并可以在拒绝连接时模拟服务端发送MOTD,由此该组件即可作为长期使用的反黑加固组件。
这次的攻击是个非常不错的挑战,能够完美解决也彰显了我们服务器的实力,感谢Hacker的出现,你让我玩的很开心。这番经历过后,我们服务器的各个方面一定会更上一层楼。





组件截图



反黑组件被攻击到飞起,服内玩家安然若素





组件源码






关于更多反黑加固的知识和支持,欢迎与我联系