阅读 129

关于服务端反爬虫的限制及告警方案

前言

        当前对于一些大型网站的开放式服务,有相当一部分流量都是爬虫程序导致,大概占比在20%左右,爬虫程序会增加服务端数据及流量开销、内部资料外泄等很多问题。

        反爬虫也成了当前服务端需要关注的一些问题,其中笔者所在的组内就遇到了被爬虫程序恶意爬取免费资源的问题,因此开始研究关于反爬虫的限流方案及对应类似爬虫程序的告警方案。

正文

        本反爬虫方案主要包括封禁告警两部分。

爬虫限制方案

        对于爬虫程序的限制方案,当前有以下的识别方式。

1. 通过User-Agent限制

        无论是客户端、浏览器还是爬虫程序,在进行http请求时都会在header中附带一个user-agent字段,类似于表明身份的意思,如Taobao/7.7.1 (iPad; iOS 12.1; Scale/2.00),rest-client/2.1.0 (darwin18.6.0 x86_64) ruby/2.6.3p62等,因此可以通过对请求中header进行过滤,如果不是正常的设备ua,则返回异常。

优点:简单,且误伤率很低,可在nginx配置。

缺点:非常容易绕过,user-agent字段可以进行抓包后伪造。

2. ip封禁

        在nginx网关层或者服务端自身对ip访问频次做监控,如果高于某个阈值则进行ip暂时封禁策略。

优点:简单。

缺点:稍微高级爬虫会有一系列的公网ip池做代理,这种情况无法预防;误伤率较高,由于封禁的是公网ip,有可能会使某个区域都访问不到;阈值难控制。

3. 用户封禁

        针对用户id及用户手机号做封禁措施。

优点:简单,且相对封禁公网ip影响范围更小。

缺点:基于用户id的监控维度比较难定义;阈值难控制。

4. 验证码限制

        多见于web端的验证码限制,在某个用户频繁访问服务时,再次进行服务调用会跳转至相应的手动输入验证码页面。

优点:误伤率极低,可以很有效的遏制脚本。

缺点:需要客户端配合进行改造,且技术方案较复杂。

具体采用方案

        根据上述现有的反脚本爬虫的技术方案及自身业务情况,准备采用ua+ip+用户id多个维度的反爬虫技术方案,同时减少token的失效时间。

       我们可以在每个请求的filter过滤器或者直接在网关层引入这个方案,由于需要维护多个维度的黑名单池,显然需要持久化到数据库中,同时引入web后台对于黑名单池进行手动维护。但不能每次都查库,因此需要每隔5秒或者更长的时间从数据库中同步相应的黑名单内容到服务器本地缓存中,之后再根据请求信息决定是否放行。

image

告警技术方案

        上述为服务端的限制方案,除了直接限制之外,也应该有适当的告警方案,通过设置阈值,如果超过了阈值就进行告警。其中方案流程如下:

image

关于滑动时间内阈值限制方案

        上面的对于每个维度中指定时间内的阈值限制,需要详细的实现方案,有以下三种

  1. 直接通过redis key-value过期时间限制

        拿对ip限流告警的方案来做示范,这样的方式不属于标准的限流方式,因为在使用阈值时间限制作为rediskey过期时间是不准确的,如在0分1秒时有1个请求,0分59秒时有8个请求,但在1分01秒时又有9个请求,在0分59秒——1分01秒之间有17个请求,但却无法触发1分钟10个请求的告警,如下:

image

时间消耗:较低

空间消耗:较低,每个维度为n

准确度:一般

  1. 使用redis,毫秒级key更新

        将redis key设置为ip_{时间戳},过期时间设置为设定阈值对应时间,判断是否超过阈值时,scan所有ip key前缀,个数如果超过阈值限定,则进行告警,如下:

image
时间消耗:中等,主要消耗在非阻塞请求scan中

空间消耗:较高,每个维度为n*n

准确度:较高,类似滑动窗口的方案

  1. redis funnel限流

        redis扩展模块有对应令牌桶扩展模块,命令如下,分别对应key,漏斗容量15,每60秒放出30个,命令:cl.throttle ip_127.0.0.1 15 30 60,需要自行扩展redis-cell模块,感兴趣的同学可以自行搜索。

时间消耗:中等

空间消耗:低,每个维度为n

准确度:高

结语

        如上针对反爬虫的方案包括限制禁止、阈值告警两个方面,其中两个地方都有不太完美的地方,比如在进行限制时,虽说只是在每次请求中的filter里新增了一些内存级别的逻辑判断,但是如果限制的维度或者单个维度(如ip)黑名单中的数据过多,也会给服务器带来挺大的压力;在阈值告警方面,对于指定时间内的访问频次限制还是不太完美。如果你们有更合适的解决方案,可以提出来一起讨论。

        并且本次的反爬虫的技术方案中并没有涉及到相应的限流方案,而限流方案可以将限制与告警两个方案相结合即可完成。

关注下面的标签,发现更多相似文章
评论