网站被CC攻击怎么办?我凌晨三点爬起来处理的完整记录

3月17日,凌晨 2:47

手机震了。是一条网站监控告警:”你的网站响应超时。”

我迷迷糊糊摸手机,看了眼,没当回事。心想大概又是哪次瞬时访问突增,过几分钟就好了。翻个身接着睡。

3:12,第二条告警。

“网站宕机,连续 5 次探测失败。”

这回我坐起来了。打开电脑,访问自己的网站——白屏,转圈,转了半天冒出来一个”502″。再访问后台,一样。服务器 SSH 倒是能连上,CPU 显示正常,内存也正常,就是网站打不开。

我这下彻底清醒了。

3:30,我开始慌了。 第一反应是”又被黑了?”可我前几天刚做过一轮安全自查,不该这么快出问题。

冷静下来,先看 Nginx 日志。这一看,直接傻眼——

密密麻麻的请求,全指向同一个 URL,我的网站首页。每一秒几百条,来源 IP 成千上万,分布在全国各地,甚至还有很多境外的。请求头里 User-Agent 五花八门,看起来像真人浏览器,但点进去的路径完全相同。

这是 CC 攻击。 不是黑进服务器,而是用海量的”假访问”,把你的服务器资源活活耗死。

这就是我写这篇文章的起点。下面我把那天从凌晨三点到天亮,怎么一步步止住 CC 攻击、又怎么做了长期防护的整个过程,原原本本记下来。


先搞懂 CC 攻击:它不是”黑进来”,是”堵死你”

CC,全称 Challenge Collapsar,是一种拒绝服务型攻击。打个比方:

你的网站是一家小店,正常情况一天进几十个顾客,门庭清净。CC 攻击就是”雇”了成千上万个假扮顾客的人,同一时间涌进你的小店,把门口、柜台全部堵死。真顾客想进来,挤不进去。

它和”被黑”的最大区别是:服务器没坏,网站也没被篡改,纯粹是资源被耗光了。 CPU 可能没跑满,但连接数爆了,Nginx 处理不过来,表现出来就是 502、白屏、超时。

我那天就是这种情况。CPU 才 30%,但网站的连接数直接顶到了上限,所以什么都打不开。

CC 攻击的特点也很明显,回头看日志一目了然:

特征表现
海量请求同一时间每秒几百甚至几千条
目标单一往往只打一个或几个 URL,比如首页、搜索页
IP 分散来源 IP 成千上万,封一个没用
伪装强UA 都是正常的浏览器标识,不是那种明显爬虫

这也是 CC 攻击最难缠的地方——它模仿正常访客,你很难靠”过滤坏人”来挡住,因为你根本分不清谁是真人谁是假的。


当天晚上,我是怎么一步步止住的

第一步:先临时”保命”。 在宝塔面板里,我把网站的”并发连接数限制”调低,把 PHP 的超时时间缩短。这一步不是解决问题,是让服务器别那么快被打垮,给我争取操作时间。相当于先关掉小店的大门,把闹事的人隔在门外。

第二步:找出被打的 URL。 用命令统计日志里被请求最多的路径:

awk '{print $7}' /www/wwwlogs/你的域名.log | sort | uniq -c | sort -rn | head -10

跑出来一看,首页 / 被请求了几十万次,而其他页面的请求是正常的几百次。目标很明确——攻击者就盯着首页打。

第三步:临时封掉异常 IP。 CC 攻击的 IP 虽然多,但同一批攻击往往集中在某些 IP 段。我用命令把请求最频繁的前几十个 IP 先揪出来封掉:

awk '{print $1}' /www/wwwlogs/你的域名.log | sort | uniq -c | sort -rn | head -50

拿到这些 IP 后,在宝塔的”安全”里批量加入黑名单。封完一轮,网站的负载明显降下来了。

但我知道这只是暂时的——攻击者换了 IP 还会再来。 封 IP 是治标,得想治本的办法。

第四步:开启 CDN 的 CC 防护。 我的站当时还没接 CDN,攻击直接打到服务器上。于是我连夜把我的域名接上了 CDN(用的免费方案),把”CC 防护”功能打开。CDN 会在攻击流量到达服务器之前,先把可疑的、异常的请求拦掉一部分,服务器的压力就小多了。

关于 CDN 怎么选、怎么配,我在个人网站 CDN 那篇里写过完整教程,这里不重复。说句实在的,对个人站来说,套 CDN 是防 CC 攻击性价比最高的一招——你自己拦,远不如让 CDN 这种专业大厂帮你拦。

到这一步,网站基本恢复了。我看了眼时间——早上 6 点 10 分,天已经亮了。


天亮了之后,我又补的几件长期防护

临时止住还不算完。CC 攻击这玩意儿,一旦盯上你,极可能再来。我又做了几件事往下堵。

第一,限制单 IP 请求频率。 在 Nginx 里加了一段 limit_req 配置,限制单个 IP 在一秒内的请求次数。正常访客一秒钟点不了一百下,真攻击才会这么疯狂。超过频率的,直接拒绝。这段配置我贴在下面,照抄改改就能用:

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

第二,把搜索页、接口这类重负载页面保护起来。 CC 攻击最喜欢打那些”最耗资源”的页面,比如站内搜索、评论提交接口、登录页。我把这些位置的访问也做了限流,哪怕首页被绕过了,这些重灾区也不至于一打就崩。

第三,关掉 XML-RPC。 WordPress 的 xmlrpc.php 是个老被利用的入口,很多 CC 攻击会借着它放大流量。如果你用不到远程发布功能,直接禁掉最省心。

第四,加强监控。 那天要不是有告警,我可能第二天一早才发现网站挂了半天。后来我把监控告警的灵敏度调高了,响应超时、宕机,第一时间通知我。半夜被叫醒是难受,但总比白天才发现强。

第五,把域名解析到 CDN,隐藏真实服务器 IP。 这一步很多人忽略。如果攻击者知道你真服务器的 IP,他可以绕过 CDN 直接打你。所以套了 CDN 之后,要确保真实 IP 不暴露,这个 CDN 服务商一般都有说明。


后来我又被 CC 打过一次,但没那么慌了

第二次是五个月之后的事了。凌晨,同样的告警,同样的 502。但这次我熟练了:先看是哪个 URL 被打、限流、拉黑高频 IP、确认 CDN 防护开着。前后不到一个小时,完事。

说出来你可能觉得好笑——第一次被 CC 攻击时,我慌得手都在抖;第二次,我居然还有心情给自己倒了杯水。 不是因为攻击不凶,是因为我这些防护做在了前面,打过来的流量被 CDN 和限流挡掉了大半,剩下的已经不足以打垮服务器了。

CC 攻击防不住的,是你”裸奔”的时候。只要提前把 CDN、限流、监控这几件事做好,它从”致命”降级成了”烦人”。

如果你现在什么防护都还没做,我认真劝你:别等第一次被打。 挑一个周末,花半小时把 CDN 套上、限流配上、监控开上。这三件事做完,你就已经赢过了 90% 的个人站长。

来自 wujianzhan.com。