服务器负载突然飙高,CPU占用率持续90%以上,网站响应从几百毫秒变成十几秒甚至直接拒绝服务,这种情况绝大多数不是正常流量增长,而是遭遇了CC攻击。CC攻击的本质是攻击者控制大量代理或肉鸡,对目标URL发起海量的、看似正常的HTTP请求,耗尽服务器的CPU、内存、带宽或连接数资源。和SYN Flood这类网络层攻击不同,CC攻击发生在应用层,单个请求包可能完全合法,所以很难靠简单的防火墙规则拦截。排查的第一步不是盲目重启服务器,而是先确认攻击特征,再针对性做流量清洗和规则限制。
先看连接状态。登录服务器后执行
netstat -an | awk '/^tcp/ {print $6}' | sort | uniq -c | sort -rn 这条命令会统计当前TCP连接的状态分布。如果TIME_WAIT数量异常高,比如几万甚至十几万,说明有大量短连接在快速建立和关闭,这是CC攻击的典型特征。如果ESTABLISHED数量极高且持续不降,说明攻击者维持了大量长连接,可能是慢速攻击或连接耗尽型CC。正常情况下,一台中等配置的Web服务器ESTABLISHED连接数在几百到两三千之间,超过这个量级就要警惕。
接着看请求来源IP的分布。执行
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -20 这条命令会列出连接数最多的前20个IP。如果某个或某几个IP的连接数明显异常,比如单个IP有上千个并发连接,基本可以判定是攻击源。但更常见的情况是攻击源非常分散,每个IP只有几十个连接,这时候就要结合访问日志进一步分析。
访问日志是判断CC攻击最直接的证据。先确认Web服务器日志路径,Nginx一般在/var/log/nginx/access.log,Apache在/var/log/httpd/access_log。执行
tail -10000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -20 统计最近一万条日志中访问最频繁的IP。CC攻击期间,攻击IP的请求频率会远高于正常用户,可能达到每秒几十甚至上百次。同时要关注请求的URL是否集中在某个特定页面,比如搜索接口、登录接口、数据库查询页面,攻击者往往会选择消耗服务器资源最大的页面作为攻击目标。
如果发现某个URL被大量请求,进一步分析请求特征。执行
grep "目标URL" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -20 查看是哪些IP在集中访问这个URL。同时观察User-Agent字段,很多CC攻击工具使用默认的UA,比如python-requests、ApacheBench、curl等,或者使用明显伪造的UA字符串。执行 tail -10000 /var/log/nginx/access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -nr | head -20 可以统计最近日志中的UA分布,异常的UA占比过高就是攻击信号。
确认攻击后,第一时间的应急处理是限制攻击IP的访问。如果攻击源IP数量不多,可以直接用iptables封禁。执行
iptables -I INPUT -s 攻击IP -j DROP但CC攻击往往有大量攻击源,手动封禁效率太低。更有效的做法是针对攻击特征做规则限制。比如攻击请求都集中在某个URL,可以在Nginx配置中对这个URL做访问频率限制。在Nginx的http块中添加limit_req_zone,然后在server或location块中应用限制规则:
http {
limit_req_zone $binary_remote_addr zone=cc_limit:10m rate=5r/s;
server {
location /目标URL {
limit_req zone=cc_limit burst=10 nodelay;
}
}
}
这个配置的意思是每个IP每秒最多允许5个请求,突发最多10个,超过的请求直接返回503。rate参数要根据正常业务情况调整,设置过低会误伤正常用户,设置过高又起不到防护效果。对于动态页面或API接口,5r/s通常是比较合理的阈值。如果攻击请求的UA特征明显,可以直接在Nginx层拦截:
if ($http_user_agent ~* "python-requests|curl|ApacheBench|wget") {
return 444;
}
但要注意,UA可以伪造,攻击者很容易绕过这种基于UA的拦截。更可靠的方式是结合多个维度做判断,比如同时满足高频访问和异常UA才拦截。Nginx的map模块可以实现多条件组合判断:
map $http_user_agent $is_bad_ua {
default 0;
~*python-requests 1;
~*ApacheBench 1;
~*curl 1;
}
map $is_bad_ua $limit_key {
1 $binary_remote_addr;
0 "";
}
limit_req_zone $limit_key zone=cc_ua:10m rate=1r/s;
这样配置后,只有使用异常UA的请求才会被限制到每秒1个请求,正常用户的UA不受影响。这种方案在攻击初期可以快速止血,但攻击者如果更换UA,规则就会失效。所以长期方案还是要靠更智能的流量分析。
如果服务器前面有负载均衡或CDN,排查思路要调整。因为经过CDN后,服务器看到的源IP是CDN节点的IP,而不是真实客户端IP。这时候直接统计来源IP会发现所有请求都来自少数几个CDN节点,无法定位攻击源。需要从CDN传递的X-Forwarded-For或X-Real-IP头中提取真实客户端IP。Nginx日志格式需要配置为记录这些头信息:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
然后用awk提取X-Forwarded-For字段做统计。如果攻击者伪造了X-Forwarded-For,还要结合CDN的防护能力,比如开启CDN的CC防护策略,或者配置CDN回源限速。
对于高强度的CC攻击,单靠服务器端的Nginx规则可能不够,因为攻击流量已经打到了服务器,即使被拒绝,也消耗了服务器的网络带宽和CPU资源。这时候需要在网络层做清洗。如果服务器托管在IDC,可以联系机房启用流量清洗设备。如果是云服务器,可以购买云服务商的DDoS高防服务,把攻击流量牵引到清洗中心过滤后再回源。高防服务通常能处理几十Gbps到几百Gbps的攻击流量,是目前应对大规模CC攻击最有效的手段。
除了被动防御,还可以从架构层面提升抗CC能力。把静态资源全部走CDN缓存,源站只处理动态请求,减少源站压力。动态接口做缓存,比如使用Redis缓存热点数据,减少数据库查询。数据库查询优化,避免慢查询被攻击者利用。使用独立的图片服务器或对象存储,把图片、视频等大文件请求从主站分离出去。这些措施虽然不能直接阻止CC攻击,但能提高服务器的抗压能力,让攻击者需要投入更多资源才能打垮服务器。
还有一个容易被忽视的点是PHP-FPM或Tomcat等应用容器的配置。CC攻击大量请求到达应用层后,如果应用容器的工作进程数配置过低,请求会堆积在队列中,导致正常请求也无法被处理。检查PHP-FPM的pm.max_children配置,如果当前值已经达到上限,可以适当调高,但不要超过服务器内存承受范围。同时检查pm.max_requests,避免进程内存泄漏导致资源耗尽。对于Java应用,检查Tomcat的maxThreads和acceptCount参数,确保有足够的线程处理并发请求。
排查CC攻击时还要注意区分攻击类型。有些CC攻击不是高频请求,而是慢速攻击,比如Slowloris,攻击者建立大量连接后,以极慢的速度发送请求头,占用服务器的连接资源。这种攻击的特征是连接数很高,但每个连接的请求频率很低,用常规的频率限制无法拦截。对于慢速攻击,需要设置连接超时时间和请求头超时时间。Nginx中可以配置client_header_timeout和client_body_timeout为较小的值,比如5秒,超过时间未完成请求头的连接直接断开。同时限制每个IP的最大并发连接数:
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
limit_conn conn_limit 20;
client_header_timeout 5s;
client_body_timeout 5s;
}
这样每个IP最多同时保持20个连接,超时的慢速连接会被强制关闭,有效缓解慢速CC攻击。
日志分析工具可以大幅提高排查效率。如果服务器日志量很大,手动用awk统计效率太低,可以借助GoAccess、ngxtop等实时日志分析工具。GoAccess可以实时展示访问来源、请求URL、状态码分布、UA分布等信息,在攻击发生时能快速定位异常。安装GoAccess后执行
goaccess /var/log/nginx/access.log -c即可进入交互式界面。ngxtop类似top命令,可以实时显示请求频率最高的IP、URL和状态码,执行
ngxtop -t 10查看最近10秒的请求统计。
对于长期遭受CC攻击的站点,建议部署WAF(Web应用防火墙)。开源方案有ModSecurity,可以配合Nginx或Apache使用,配置规则后能自动识别和拦截常见的CC攻击模式。商业WAF如云服务商提供的WAF产品,通常集成了更智能的CC防护算法,能基于请求频率、行为特征、IP信誉库等多维度做综合判断,误杀率更低。WAF的缺点是会增加请求延迟,对性能有一定影响,需要根据业务情况权衡。
最后要强调的是,CC攻击的排查和处理是一个持续的过程,不是封几个IP就结束了。攻击者会不断更换攻击源和攻击方式,需要持续监控服务器状态和日志。建议部署监控告警系统,比如Zabbix、Prometheus配合Grafana,设置CPU、内存、连接数、请求延迟等指标的告警阈值,一旦指标异常立即通知运维人员。同时定期分析访问日志,建立正常流量的基线模型,这样在攻击发生时能快速识别出偏离基线的异常流量。只有把被动应急和主动监控结合起来,才能有效应对CC攻击。
