服务器遭遇高CC攻击导致CPU 100%应急排查与防护

当服务器CPU突然飙升至100%,网站响应缓慢甚至瘫痪,大概率是遭遇了CC攻击。本文从现象识别、应急排查到长效防护,提供一套可直接落地的操作步骤,帮助运维人员快速恢复业务并加固防御。

服务器遭遇高CC攻击导致CPU 100%应急排查与防护
封面图:ZuCDN · ZuCDN 原创

一、现象确认:不只是负载高

CPU 100%可能由多种原因引起,但CC攻击(Challenge Collapsar)的特征非常明显:大量看似正常的HTTP请求(GET/POST)短时间涌入,占用PHP-FPM或Web服务器进程,导致CPU耗尽。此时你会观察到:

  • top命令显示php-fpm或nginx进程数量暴增,每个进程CPU占用高
  • netstat -anp | grep ‘:80’ 或 :443 显示大量TIME_WAIT或ESTABLISHED连接来自分散的IP
  • access.log中同一URL(如首页、登录接口)被反复请求,间隔极短
  • 系统load average远高于CPU核心数,但磁盘I/O正常

先不要急着重启——盲目重启进程只会加剧问题。你需要在几分钟内定位攻击源,并采取屏蔽措施。

二、应急排查三步走

1. 快速定位攻击特征

登录服务器后执行:

top -c   # 按P查看CPU占用最高的进程,记录PID
netstat -anp | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20

如果前几个IP的请求数远超正常数值(比如每分钟数百次以上),基本可以判定是攻击IP。进一步查看请求路径:

tail -n 1000 /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -10

观察是否集中在少数几个URI上。如果是动态页面(如php页面),说明攻击者试图耗尽PHP-FPM进程;如果是静态资源(如jpg),可能只是耗尽带宽或连接数。

2. 临时阻断:iptables限速与封禁

不要直接封禁大量IP,手动操作低效且容易误伤。推荐使用iptables+connlimit模块限制单个IP并发连接数:

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 32 -j DROP
iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 20 -j DROP

若攻击IP已经明确,可直接添加DROP规则:

iptables -A INPUT -s 攻击IP/24 -j DROP

但CC攻击通常使用代理池或僵尸网络,IP变化快。更高效的做法是限制同一IP的请求速率

iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 10 --hitcount 30 -j DROP

以上规则允许每个IP每10秒最多30个新连接,超过则丢弃。可根据实际情况调整数值。

3. 应用层应急:降级与切换

如果攻击绕过了网络层限制(比如直接攻击PHP逻辑),你需要快速减少PHP进程消耗:

  • 调整PHP-FPM进程数:编辑php-fpm.conf,降低pm.max_children和pm.start_servers,避免瞬间创建过多进程。
  • 启用静态页面缓存:临时开启Nginx的FastCGI Cache或使用LiteSpeed Cache插件,对攻击URL直接返回缓存页。
  • 暂停耗资源的接口:在Nginx配置中return 403针对攻击URI(如 /api/getdata)。

这些操作可在1-2分钟内生效,大幅降低CPU压力,为你争取配置WAF的时间。

三、长期防护策略

1. 部署Web应用防火墙(WAF)

无论是云WAF(如阿里云WAF、CloudFlare)还是自建ModSecurity,都能有效识别和拦截CC攻击。云WAF的优势在于大流量清洗和智能CC防护,建议开启人机验证功能:当请求频率异常时,弹出验证码或JS挑战,自动拦截脚本攻击。

2. Nginx层限流与连接限制

在Nginx配置中加入:

limit_req_zone $binary_remote_addr zone=cc:10m rate=30r/m;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
    location / {
        limit_req zone=cc burst=5 nodelay;
        limit_conn addr 10;
    }
}

该配置对每个IP每分钟最多30个请求,突发允许5个;同时限制同一IP最多10个并发连接。配合连接超时设置,可有效抑制低慢速CC。

3. 业务层面优化

  • 动态转静态:对不常更新的页面(如新闻详情)生成静态HTML,减少PHP执行。
  • CDN缓存:将静态资源全量推送到CDN,动态内容开启智能缓存。
  • API层鉴权:对敏感接口增加Token、签名验证或频率限制。

4. 监控与告警

部署Prometheus + Grafana或Zabbix,监控CPU使用率、Nginx活跃连接数、PHP-FPM进程状态。当CPU超过80%持续5分钟,自动触发告警,并执行预设脚本(如启用限流规则)。提前写好回滚脚本,避免误封导致业务中断。

四、实战中容易踩的坑

  • 误封搜索引擎CDN IP:在添加iptables规则时,记得先排除已知的搜索引擎IP段(如百度、谷歌),否则影响SEO。
  • 杀进程导致服务雪崩:不要kill -9所有PHP-FPM进程,应逐步调整pm.max_children。
  • 忽略HTTPS:443端口的CC攻击更容易被忽略,务必同样配置限流。
  • 日志不滚动:攻击期间日志会飞速增长,务必提前配置logrotate,否则磁盘写满加速崩溃。

五、总结

应对CC攻击的核心在于快速定位、临时降级、长期加固。先用iptables和Nginx限流止血,再用WAF和业务优化固化防线。事后分析日志保留攻击特征,更新黑名单库。没有一劳永逸的防护,但有一套可复用的应急流程,能让运维团队在攻击中从容不迫。

延伸阅读