很多站长的第一反应是“上 CDN 缓存就稳了”,但 CC 攻击偏偏绕开缓存,专打登录、搜索、提交这些动态页面——CPU 飙高、数据库连接池打满,页面照样崩。本文用问答形式讲清 CC 攻击的选靶逻辑、动态页面被打时的典型症状,以及 Nginx 精确限流、缓存策略、数据库兜底的完整防法。
CC攻击为什么专挑动态页面打?
核心是攻击成本和消耗效果不对等:请求静态资源会被 CDN 缓存直接吃掉,打一万次 CDN 也就回源几次;而动态页面每次请求都要跑脚本、查数据库、写日志,攻击者发 1 个请求,服务器要付出上百倍的资源成本。CC 攻击的本质是“用最少的流量换取最大的资源消耗”,动态页面天然是性价比最高的靶子。
攻击者一般挑哪些动态入口?
- 登录/注册页:往往带验证码生成、密码加密,CPU 开销大;
- 搜索接口:每次请求都是一次模糊查询,数据库压力最大;
- 评论/表单提交:带写入操作和邮件通知;
- 内容详情页带翻页参数:?page=10000 这类请求缓存命中率低,还容易拖慢查询。
自查方法:翻自己的 access.log,看哪些带参数的 URL 请求量异常偏高——攻击者也在看同样的东西。
动态页面被CC时有什么典型症状?
- CPU 持续 90% 以上,且消耗集中在 php-fpm/应用进程而不是 Nginx;
- 数据库报 Too many connections,连接池打满;
- 正常用户反馈“网站转圈/超时”,但带宽曲线并不高——CC 是资源型攻击,不是带宽型;
- 日志里同一批 IP(或同一 UA)对某几个 URL 高频重复请求。
记住这个特征组合:低带宽 + 高 CPU + 慢查询 + URL 集中,基本可以断定是 CC。
Nginx怎么对动态路径单独限流?
不要全站一刀切,对动态入口精确加阀:
# http 块定义两个限流区
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=dynamic:10m rate=10r/s;
# 登录接口:每个 IP 每分钟最多 5 次
location = /wp-login.php {
limit_req zone=login burst=3 nodelay;
limit_req_status 429;
include fastcgi_params;
fastcgi_pass unix:/tmp/php-cgi.sock;
}
# 其他动态请求:每秒 10 次,容忍突发 20
location ~ \.php$ {
limit_req zone=dynamic burst=20 nodelay;
limit_req_status 429;
}
rate 和 burst 的取值要参考业务正常峰值:先从日志统计正常用户对登录页的真实频率,把阈值设在正常峰值的 2-3 倍,设太紧会误伤。再配合 limit_conn 限制单 IP 并发连接数效果更好。
缓存在这件事里能起什么作用?
缓存的战略价值是“减少必须回源的动态请求”:
- 列表页、详情页做页面缓存(如 WordPress 的页面缓存插件),被打时大部分请求命中缓存,数据库压力骤降;
- 搜索、登录、提交这类真动态接口不能缓存,重点靠限流保护;
- 给动态页面响应加短时微缓存(如 10-60 秒)也是折中方案,新内容晚几十秒可见,但抗 CC 能力明显提升。
注意缓存要设合理的失效策略,否则被攻击时攻击请求会把缓存刷穿,命中率反而归零。
数据库层怎么兜底?
就算前面没挡干净,也要保证数据库不被打死:
# MySQL:限制最大连接数和单查询超时
set global max_connections = 200;
set global max_execution_time = 3000; -- 毫秒,SELECT 超时
# php-fpm:限制进程数,防止请求堆积把内存吃光(www.conf)
pm.max_children = 30
pm.max_requests = 500
再加一层慢查询日志(long_query_time = 1),被 CC 期间盯一下哪些查询被反复触发,针对性加索引或改缓存。
验证码和JS挑战该什么时候用?
- 平时不建议全站开——影响收录和用户体验;
- 攻击发生时,在防护产品(WAF/CDN)上对被攻击的具体 URL 路径开启人机验证或五秒盾,精准打击;
- 登录、注册、提交接口可以长期挂验证码,这些页面本来就不服务搜索引擎。
还有什么补充建议?
- 接口限频按业务定:搜索每分钟几次、评论每分钟几次,写成明确的防护策略而不是用默认值;
- 别让源站裸奔:动态限流只能减缓,真正把 CC 流量在到达源站前洗掉,还得靠带 CC 防护的 WAF/CDN(如百度云防护),源站只接收回源流量;
- 留好监控:CPU、数据库连接数、php-fpm 队列三项设告警,攻击发生 1 分钟内知道,比事后翻日志强得多。