因为movieinfogen源站的原因,导致我原来公开的PT-Help工具的moveinfo/gen遭到了大量的使用,此外因为原先设计理念上的问题(ps. 不是因为我懒(事实就是,前面都是借口)),没有对相关请求做相关的身份验证。
导致部分人使用脚本批量请求该接口生成对应简介信息,以至于经常被豆瓣封请求,使得正常用户不可用。
(滥用公开服务可耻!!!!为什么不自建!!!源代码都是公开的!!!

那么就来做些限制吧。(想不到我一个写爬虫开始学编程的人如今也要开始做反爬了23333
使用Nginx对User-Agent限制
这是最开始想到的办法,因为很早之前我就使用了 mitchellkrogza/nginx-ultimate-bad-bot-blocker 的相关规则以及自动更新模块,来对一些Bad Bot基于UA头进行限制。
关于这一系列规则的安装还请见其项目的README就行,挺简单的,唯一有些不便的就是它所有的配置都是围绕使用包管理器安装的Nginx来进行的,每次使用都需要夹带相关参数来覆盖默认配置。
所以记得用-h多看对应说明,没确认前千万不要用-x执行。
因为当初的安装记录找不到了,这里就贴一下crontab升级时候使用的吧,希望对同样使用lnmp.org提供的lnmp一件包的朋友有帮助。
1 | 00 22 * * * sudo /usr/local/sbin/update-ngxblocker -c /usr/local/nginx/conf/ -b /usr/local/nginx/conf/bot.d/ -n Y |
**注意:**安装后,可能会通不过Nginx的检验。。记得注释掉没过的就ok。。
该规则自带空白模块,允许用户在bot.d目录下的blacklist-user-agents.conf中添加基于UA的屏蔽,因为原滥用者都是使用脚本调用curl来进行的,所以直接屏蔽UA头为curl的。故在文件中添加
1 | "~*\bcurl\b" 3; |
然而好景不长,毕竟UA头都是可以伪造的,简单的一个IE就直接破解了2333

Nginx自带的 rate_limit
通过对访问频率来限制,相关的教程可见官方的文档:
考虑到使用的方便,毕竟这个/tools下不止挂了本人的movieinfogen服务,所以简单设置如下:
1 | limit_req_zone $binary_remote_addr zone=pthelp:10m rate=5r/m; |
相对较为宽松,仅限制了每分钟5个请求,而且还补充了burst和nodelay项。对超过限制的直接返回503就行~
这个破起来多简单,我当初自己爬豆瓣的时候都知道time.sleep(),滥用者会想不到吗?
503的话就休息一段时间。或者可以都不用这么这样,反正Nginx最后一定会放行的,疯狂请求不就ok了吗?

ps. 这个IP的同学在我一天的Nginx记录中疯狂刷出了近2000条记录,其中返回503的就有近1700条。。。。
使用 CF-Firewall 基于IP自动限制
根据对之前的访问频率的判断,我们可以知道,正常用户一天的请求量不会超过50次。(不,是我瞎讲的,不是基于统计的结果)
大体只有爬虫会疯狂的进行请求,所以我们不如根据总访问次数来对爬虫IP进行限制。
但是由于网站在Cloudflare的CDN之后,所以直接在系统层面使用iptables以及配套日志分析脚本对单一IP进行限制是不可能的,如果在Nginx上使用deny则每次修改都要重新reload较为麻烦,所以不如直接使用CF-Firewall进行限制较为方便。
手动添加可以直接在网页上使用Firewall面板,并设置规则为Block即可。
通过日志可以看到确实被有效的屏蔽了~~~
通过试验,以CF-Firewall屏蔽会返回404状态码。

但是毕竟我们不可能时时刻刻都查看日志吧,所以需要用脚本自动分析日志并通过CF-API来自动禁用对应IP。
CF的Global API Key在profile面板获取。
示例脚本如下
1 | import re |
然后放到crontab中每隔几分钟运行一次不久ok了吗?
后续注意点
- Nginx使用
set_real_ip_from模块从Cloudflare中获取用户真实IP地址,并记录到access_log中。相关方法将之前Blog: Cloudflare 下 Nginx 获取用户真实 IP 地址 - R 酱小窝 - 上述示例脚本真的仅作示意,临时现写的。
所以为什么宁愿多写一个脚本也不修改原有架构呀
