注意:这篇文章上次更新于1556天前,文章内容可能已经过时。
This article was last updated1556 days ago, the content may be outdated.
起因
4 月 13 号早上八点多,我还在睡梦中,被 Telegram 的一条推送吵醒了。

很奇怪,我一个根本没人访问的 WebServer 小项目竟然会自己就宕机了😕。
上午十点睡醒了,起来看一眼日志吧。
好家伙,有人拿我 抄来 的小项目在练手?








等等…很多很多
我也看不到他这些操作是在干什么,但我知道正常在网页上点来点去是不会有这样的请求数据的。这一系列花里胡哨的操作持续了 10 多分钟我就宕机了。
为了应对这种情况,只能再加一个 IP 黑名单模块了。
基本功能
我的想法是这样的,如果在短时间内同一个 IP 连续多次获得了 404 ,那就把它放在 IP 黑名单里封禁一段时间。
实现逻辑如下:
- IP 黑名单类中需要维护以下数据成员
- 404计数阈值(404次数超过这个阈值,将有可能屏蔽这个IP的连接)
- 已经在黑名单中的 IP 过期时间(对 IP 不进行永久封禁,超过这个时间将被移除黑名单)
- 404计数时间范围(在功能描述中提到,只对短时间内的404进行计数,这个变量规定了这个短时间是多长时间)
- 一个IP到该IP目前状态的映射(也就是说,键是 IP,值包含两部分,第一部分是目前被记录的404次数,第二部分是第一次被记录404的时间点)
- 主要维护以下公有函数
- void set_member(int cnt404,int expire ,int countTime); // 设置成员变量
- bool in_list(u_int32_t IP); // 判断当前 IP 是否在黑名单内
- void add_404(u_int32_t IP); // 增加当前 IP 的 404 计数
由于我们既需要在主线程中使用黑名单对象检查当前 IP 是否在黑名单内,也需要在子线程中使用该对象为 IP 增加 404 计数。所以采用单例模式实现 IP 黑名单类。
代码实现
头文件
1 | /* |
源文件
1 | /* |
效果测试
我在两分钟内请求了几次不存在的页面
就直接这样了

并且服务器记录下相关日志

我换了一个新的 IP 可以正常访问服务器。我设置的封禁时间是 3 个小时,应该三小时后就解封了吧。
最后还是欢迎路过的大佬指出错误。


