小微企业站点遭遇CC攻击时,最常见的困境不是找不到防护产品,而是预算撑不起那些动辄数千元一年的云防护套餐,或者技术团队根本没人能啃下复杂的WAF规则配置。低成本CC防护的核心思路其实很明确:把攻击流量挡在业务服务器之前,用最少的资源消耗识别并丢弃恶意请求,同时保证正常用户访问不受影响。下面直接讲几套经过验证的可行方案,从网络层到应用层都有覆盖,按实施难度和成本从低到高排列。

利用Nginx限速与连接数控制

绝大多数小微企业站点都跑在Nginx上,而Nginx自带的两个模块就能挡掉相当一部分CC攻击。第一个是limit_conn_module,用来限制单个IP的并发连接数。攻击工具通常会瞬间发起几十甚至上百个TCP连接,正常浏览器一般只维持2到6个。配置思路是在http块里定义一个共享内存区域,然后在server或location里引用。具体配置如下:

http {
    limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
    server {
        location / {
            limit_conn conn_per_ip 10;
            limit_conn_status 503;
        }
    }
}

第二个是limit_req_module,基于漏桶算法限制请求速率。CC攻击的典型特征是请求频率远超人类点击速度,限制每秒请求数能有效过滤。配置时要注意突发容量的设置,太严格会误伤正常用户,太宽松又拦不住攻击。下面这个例子允许正常突发20个请求,但平均速率限制在每秒5个:

http {
    limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=5r/s;
    server {
        location / {
            limit_req zone=req_per_ip burst=20 nodelay;
            limit_req_status 503;
        }
    }
}

这两个模块完全免费,性能开销极小,单台1核2G的服务器就能扛住每秒数千请求的过滤。但局限也很明显:只针对单IP限速,遇到分布式僵尸网络发起的CC攻击,每个IP只发几个请求,这种方案就失效了。所以它适合作为第一层基础防线,不能当作唯一手段。

利用Redis构建动态IP黑名单

当攻击源IP数量较多但并非海量时,可以在应用层做动态封禁。思路是:在Nginx的access阶段通过Lua脚本检查请求IP是否在黑名单中,同时将可疑IP的访问行为记录到Redis,超过阈值自动拉黑。这套方案需要OpenResty或者Nginx搭配lua-nginx-module,Redis作为共享存储,成本几乎为零。

具体实现逻辑分三步。第一步,每个请求进来时,用Lua对IP做计数,比如以分钟为窗口记录访问次数。第二步,当某个IP在一分钟内请求超过200次,就将其加入Redis的blacklist集合,设置过期时间比如10分钟。第三步,Nginx在请求处理早期检查该IP是否在黑名单,命中则直接返回444或503,不再转发到后端。代码片段大致如下:

access_by_lua_block {
    local redis = require "resty.redis"
    local red = redis:new()
    red:set_timeout(1000)
    local ok, err = red:connect("127.0.0.1", 6379)
    if not ok then return end
    local ip = ngx.var.binary_remote_addr
    local is_blocked = red:sismember("cc_blacklist", ip)
    if is_blocked == 1 then
        ngx.exit(503)
    end
    local key = "cc_count:" .. ip .. ":" .. ngx.today()
    local count = red:incr(key)
    if count == 1 then
        red:expire(key, 60)
    end
    if count > 200 then
        red:sadd("cc_blacklist", ip)
        red:expire("cc_blacklist", 600)
        ngx.exit(503)
    end
}

这套方案的优点是灵活,阈值和封禁时长都可以按业务实际情况调整。缺点是需要一定的技术能力来维护Lua脚本和Redis,而且对分布式慢速CC攻击的识别能力有限。如果攻击者控制了几千个肉鸡IP,每个IP每分钟只发几十个请求,阈值就很难设得恰到好处。

前端JavaScript挑战与Cookie校验

很多CC攻击工具是脚本化的,不会执行JavaScript,也不维护Cookie。利用这个特性,可以在Nginx层加一道JS挑战:首次访问的请求返回一个包含JavaScript的页面,脚本执行后设置一个特定Cookie并自动刷新,Nginx验证Cookie有效后才放行到后端。这套逻辑同样可以用Lua实现,不需要引入额外的商业产品。

具体做法是:当请求到达时,检查Cookie中是否存在一个经过签名的token。如果没有,返回一个HTML页面,里面包含一段简单的JS代码,计算一个值(比如时间戳加固定盐的哈希)写入Cookie,然后location.reload。Nginx收到带Cookie的请求后,用同样的算法验证token是否正确且未过期。攻击脚本通常不会执行JS,也就拿不到有效Cookie,请求在到达业务服务器之前就被拦截。

这种方案对自动化CC工具效果显著,而且几乎零成本。但要注意两个问题:一是搜索引擎爬虫也不执行JS,需要给已知爬虫IP加白名单,否则会影响收录;二是用户体验会多一次跳转,首次访问延迟增加几百毫秒。对于以API接口为主的小微企业站点,这种方案可能不适用,因为API调用方往往不是浏览器。

利用云服务商的免费或低成本防护资源

国内主流云服务商都提供基础DDoS防护,部分也涵盖CC防护能力,而且很多基础版是随服务器附赠的。例如阿里云的基础安全防护、腾讯云的基础防护、华为云的Anti-DDoS基础版,都能在一定程度上缓解CC攻击。小微企业在选购云服务器时,应该优先选择自带基础CC防护的套餐,而不是购买裸机再自己从零搭建。

如果攻击流量超过了基础防护的阈值,可以考虑按量付费的高防IP或者CDN加速产品。很多CDN服务商提供的边缘节点本身就具备CC防护功能,把站点接入CDN后,攻击流量会被分散到各个节点,源站压力大幅降低。CDN的按流量计费模式对于小微企业来说成本可控,平时正常业务流量不大的情况下,一个月几十元就够用。选择CDN时要注意确认其CC防护策略是否默认开启,以及是否支持自定义防护规则。

应用层代码级防护策略

如果攻击已经穿透了前面几层,到达了应用代码,还可以在业务逻辑里做最后一道防线。常见做法包括:对登录、搜索、提交等敏感接口做独立的频率限制,用内存缓存或Redis记录每个用户或IP的调用次数,超限后返回友好提示并短暂拒绝服务。对于不需要登录的公开接口,可以要求客户端携带动态token,token由服务端下发并绑定会话,攻击脚本难以伪造。

另外,静态资源分离也是一个容易被忽视的CC缓解手段。把图片、CSS、JS等静态文件放到对象存储或独立的静态服务器上,业务服务器只处理动态请求。这样即使动态请求被打满,静态资源仍然可以正常访问,用户感知到的站点可用性会好很多。对象存储的静态托管成本极低,按量计费,小微企业完全负担得起。

低成本防护的边界与取舍

必须坦诚地说,低成本方案有明确的防护上限。如果攻击者投入的资源远超你的防护能力,比如每秒几万甚至几十万请求的混合CC攻击,单靠Nginx限速和Redis黑名单是扛不住的,这时候需要更高规格的云防护或者专业安全设备。小微企业在做防护规划时,应该先评估自己站点的业务价值和可能面临的攻击强度,把有限的预算花在性价比最高的环节。

日常运维中,建议保持对访问日志的监控,设置简单的告警规则,比如每分钟请求数突增超过日常峰值三倍就触发通知。很多CC攻击在发起前会有试探性扫描,提前发现异常能争取到响应时间。同时,定期备份站点数据和配置,确保在极端情况下可以快速切换到备用环境,这也是一种成本极低的容灾手段。

综合来看,小微企业站点应对CC攻击,最务实的做法是分层设防:Nginx基础限速作为第一层,Redis动态黑名单作为第二层,JS挑战或CDN边缘防护作为第三层,应用代码限流作为兜底。每一层都只解决一部分问题,叠加起来就能应对大多数中小规模的CC攻击,而总成本可能每月不到百元。