侧边栏壁纸
博主头像
buukle博主等级

布壳儿

  • 累计撰写 109 篇文章
  • 累计创建 17 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

记一次维持3天的cdn盗刷攻防

zhanglei001
2024-07-25 / 0 评论 / 0 点赞 / 151 阅读 / 4009 字

发现

7.24日,收到阿里云短信通知,可用额度欠费,登录阿里云控制台,发现确实额度低于预警线.
image-oqxl.png
感觉不应该余额用这么快,于是去查看明细,发现cdn账单异常.

查看cdn控制台,从2024-7-23 19:00 左右 ,到2024-7-24 23:55 左右,峰值带宽一直稳定在100M左右,总流量在100G左右,明显受到了异常请求:
image-bodn.png

检索后得知可能是cdn盗刷中招.看了几个类似的经验,一直没明白,盗刷我的cdn消耗网站的cdn费用,对盗刷者有什么好处,虽然不明白,但是不能让他一直这么搞下去,不然月底吃土了.

初次处理

去cdn控制台下载请求日志 , 不得不说阿里云的cdn日志是真的拉,24小时过去了,cdn日志卡在了受盗刷的时间段,只能下载到18:00~19:00 的日志,猜测是由于盗刷导致日志数据量上升,阿里云的任务跑批变慢或者异常了.

只能找人工要cdn日志,尝试看看前几位的ip能否封掉先止损.拿到日志后,使用awk进行去重排序,找到了被盗刷的静态资源 是一张平平无奇的照片
image-rcch.png
也定位到了前几位异常ip
image-yvzp.png
那就好办了,把ip加入cdn黑名单,睡觉!
image-acio.png

二度攻击

本来以为23号晚上处理完就ok了,结果第二天(24号) 19:30 又收到了欠费通知,我懵了.登录cdn控制台,果然流量又异常了

image-cles.png
由于日志有延后性,不能立即封禁恶意访问者ip,只能添加cdn流量封顶关闭
image-gzkw.png
这导致cdn被盗刷10分钟后,cdn直接关停,整个博客和小程序变得不可访问.
image-eans.png
本以为停服后对方脚本会放过请求失败的站点,于是手动又开启了cdn
不出意外的又出意外了 , 开启后立马被该嘎了的盗刷脚本打挂了..
image-ccyi.png

看来流量封顶只能作为最终兜底策略,盗刷者是有ip池的,在盗刷前就制定了轮换ip防封的方案,道高一尺魔高一丈,我们看来也不能简单的一封了之了.

最后处理

研究一番,决定使用阿里云cdn的远程鉴权,在鉴权服务中提供cdn鉴权接口,cdn接到资源请求时,请求我们的鉴权接口进行鉴权,我们趁机对访问者的ip和uri资源做限流.话不多说,上chatGPT

image-ertw.png
稍作调整后

public CommonResponse grantCdn(String ip, String uri) {

        // 总开关
        if (!rateLimitSwitch) {
            return new CommonResponse.Builder().buildSuccess();
        }

        if (uri.equals("/rpc/grantCdn")) {
            return new CommonResponse.Builder().buildSuccess();
        }

        // 检查是否在黑名单中
        if (this.isBlacklisted(ip)) {
            log.info("该ip已经被拉黑:{}",ip);
            throw new CDNException(SystemReturnEnum.FAILED, "该请求存在风险");
        }

        // 构建Redis的key
        String rateLimitKey = RATE_LIMIT_KEY_PREFIX + ip + ":" + uri;

        // 使用Redis的原子操作INCRBY来增加计数,并设置过期时间
        Long newCount = redisTemplate.opsForValue().increment(rateLimitKey, 1);
        if (newCount == 1) {
            // 如果是第一次请求,设置key的过期时间为 rateLimitCountWindow s
            redisTemplate.expire(rateLimitKey, rateLimitCountWindow, TimeUnit.SECONDS);
        } else if (newCount > rateLimitCount) {
            // 请求超过限制,将IP加入黑名单
            addToBlacklist(ip);
            log.info("该ip请求资源已经超限ip:{},uri:{}",ip,uri);
            throw new CDNException(SystemReturnEnum.FAILED, "该请求存在风险");
        }
        return new CommonResponse.Builder().buildSuccess();
    }

    private void addToBlacklist(String ip) {
        String blacklistKey = BLACKLIST_KEY + ip;
        redisTemplate.opsForValue().set(blacklistKey, "true", rateLimitBlackWindow, TimeUnit.SECONDS);
    }

    /**
     * 检查IP是否在黑名单中
     * @param ip IP地址
     * @return true 如果IP在黑名单中,false 否则
     */
    public boolean isBlacklisted(String ip) {
        // 检查IP是否在黑名单中
        String blacklistKey = BLACKLIST_KEY + ip;
        return redisTemplate.opsForValue().get(blacklistKey) != null;
    }

重新构建部署鉴权中心

image-rbdc.png

在cdn后台配置鉴权接口

image-bsmy.png

2024-7-25 19:00之后, 讲道理脚本小子又该来扫描了

登录cdn控制台,流量呈锯齿状,被限制在600k左右

image-daoy.png

查看鉴权中心日志
image-tddd.png
果不其然该噶的盗刷者今天又换ip了 ,不过一抬头就被按进小黑屋了,关一会又释放出来,然后又被关进去 ... 所以流量呈锯齿状

拿到小黑屋中的ip后,登录到cdn,将他加到cdn的大黑屋中 ,这样就能进一步节省鉴权中心的请求资源

image-acio.png

就这样吧 ,在这次盗刷行动中损失了一些元子 ,也对cdn的一些机制有点了解,算是花钱买教训吧~也希望有更好解决方案(买高防除外 ,没有元子..)的童鞋带带

0

评论区