本文约 2,711 字,预计阅读 7 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:攻击持续了六小时,第二天收录掉了
CC 攻击的特点是请求量巨大但单请求成本低,很多小站点根本没有高防,结果是带宽被打满、PHP-FPM 进程耗尽,站点时好时坏。站长忙着救火,等第二天有空看后台,发现抓取频次暴跌、快照日期停在了昨天。这时候最关心的问题是:这次事故会不会导致降权?需要多久恢复?
原理分析:百度区分”临时抖动”与”长期不可用”
百度的抓取系统对失败是有容忍度的,它统计的是一段时间内的成功率与响应速度,而不是单次失败。
| 事故形态 | 持续时间 | 百度侧表现 | 恢复难度 |
|---|---|---|---|
| 短暂抖动 | 分钟级 | 自动重试,几乎无感知 | 无需处理 |
| 半天到一天不可用 | 小时级 | 抓取频次下调,快照停滞 | 数天恢复 |
| 持续数天时好时坏 | 天级 | 抓取异常增多,收录增长停滞 | 一两周恢复 |
| 持续一周以上 | 周级 | 索引量下滑,部分页面被判失效 | 一个月以上 |
| 长期打不开 | 月级 | 大幅降权至接近新站 | 极难 |
关键在于响应的一致性。最糟糕的情况不是”彻底打不开”,而是”有时候能开有时候不能”——爬虫每次得到的结果不同,无法形成稳定判断,抓取频次会被压得更低。所以如果确认要维护或限流,宁可统一返回 503,也不要让一部分请求成功、一部分超时。
保姆级实操
步骤 1:限流时给百度蜘蛛留白名单。 这是最容易出错的一步。很多防 CC 规则无差别拦截,把 Baiduspider 也挡在外面,百度侧看到的是站点彻底不可达:
# 在 http 块定义限流区
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=perconn:10m;
# 识别搜索引擎蜘蛛:命中则不做限流
map $http_user_agent $is_spider {
default 0;
"~*Baiduspider" 1;
"~*Sogou web spider" 1;
"~*360Spider" 1;
"~*Bytespider" 1;
"~*Googlebot" 1;
"~*bingbot" 1;
}
server {
location / {
# 蜘蛛与正常用户分流:蜘蛛走无限制路径
if ($is_spider) {
break;
}
limit_req zone=perip burst=20 nodelay;
limit_conn perconn 20;
try_files $uri $uri/ /index.php?$args;
}
}
注意:if 在 location 中的用法有诸多限制,生产环境更稳妥的做法是用 map 生成变量后交给 limit_req_zone 的 key,把蜘蛛的 key 设为空字符串(key 为空时限流不生效)。上线前务必在测试环境验证。
步骤 2:无法区分时统一返回 503。 如果攻击流量伪装了 UA,无法可靠区分,就统一返回 503 并带 Retry-After,让百度明确知道这是临时状态。
步骤 3:用日志判断事故影响面。 事故结束后立刻统计百度蜘蛛的实际抓取情况:
# 统计事故当天百度蜘蛛的请求量与状态码分布
grep "Baiduspider" /var/log/nginx/access.log | \
awk '{print $9}' | sort | uniq -c | sort -rn
# 对比事故前后的每日抓取量,确认是否下滑
for d in 09 10 11; do
n=$(grep "Baiduspider" /var/log/nginx/access.log | grep "10/$d/" | wc -l)
echo "10-$d 百度蜘蛛请求数: $n"
done
步骤 4:恢复后主动触发抓取。 站点恢复后,用百度搜索资源平台的「抓取诊断」抓首页与几个核心页面,确认返回 200 且内容完整。随后用 API 推送把近期更新页面推一遍。
步骤 5:检查抓取异常报告。 平台里查看「抓取异常」相关模块,看是否存在大量 5xx 或超时记录。如果异常比例高且持续,说明限流规则仍在误伤蜘蛛,需要调整。
步骤 6:加可用性监控。 装一个简单的外部定时探测(每分钟 curl 首页,非 200 就告警),具体做法见 WordPress 站点可用性监控,避免下次事故靠用户告知才发现。平均发现时间越短,SEO 损失越小。
步骤 7:一周内每天记录抓取频次。 恢复后连续七天记录抓取频次与收录量,形成曲线。若七天后仍未回到事故前水平,说明需要更主动的推送与内容更新。
常见踩坑
- 防 CC 规则无差别拦截 UA,百度蜘蛛被当成攻击者挡在外面。
- 用了 CDN 的”挑战页”(JS 挑战/验证码),爬虫拿不到真实内容,被判为页面异常。
- 站点时好时坏,爬虫得到不一致结果,抓取频次被压得比完全打不开更低。
- 攻击结束后不做任何主动推送,被动等待抓取恢复,多花两周。
- 只看总流量,不看百度蜘蛛的请求量,误以为影响不大。
- 案例: 某 WordPress 站被 CC 攻击期间,运维开启了 CDN 的 JS 挑战模式。攻击挡住了,但百度蜘蛛每次抓到的都是挑战页,两周内索引量下降约 15%,且抓取诊断一直显示内容为空白。关闭挑战、改为 IP 限速加蜘蛛白名单后,第三周抓取频次才恢复正常。
- 事故期间把站点整个 302 到静态公告页,导致所有 URL 都指向同一个页面。
- 恢复后立刻大量发文章想”补回来”,反而分散了恢复期的抓取预算。
总结
判断事故影响看三个数:持续时长、百度蜘蛛实际抓取量、抓取异常比例。小时级的规范 503 基本无伤;天级以上的不可用才需要认真做恢复。防 CC 的第一原则是「别把蜘蛛一起防了」,第二是「不确定就统一 503」。恢复期动作与 网站临时关闭 503 设置 基本一致:主动推送、每日记录、耐心等待。
