CC攻击的本质不是拼带宽,而是拼资源。攻击者用大量看似正常的请求占满服务器的连接数、CPU、内存和I/O,导致正常用户无法访问。很多运维人员一遇到CC攻击就想着扩带宽,但带宽加到1Gbps甚至10Gbps,攻击流量可能只有100Mbps,服务器照样被打挂。问题出在链路没满,但服务器先撑不住了。所以“防止链路占满”这个目标,首先要纠正一个认知:链路占满只是表象,真正的战场在带宽资源、连接资源和计算资源的综合监控与调度上。

要防住CC攻击并防止链路被占满,第一件事是把“带宽资源监控”从粗放式变成细粒度。传统的流量监控只看总进出流量,比如交换机端口流量、网卡流量。但CC攻击往往不是把总带宽打满,而是把某个服务端口、某个域名、某个URL的请求通道塞满。比如攻击者只打你的登录接口,总带宽可能只用了30%,但登录接口背后的数据库连接池已经耗尽。所以监控必须细化到“每IP连接数”“每URL请求速率”“每域名并发连接数”“TCP连接状态分布”这几个维度。只看总带宽,等你发现链路满的时候,业务已经中断很久了。

监控带宽资源需要同时看三个层面:物理链路层、传输层和应用层

物理链路层就是网卡和交换机的实际吞吐量,这个数据用来判断是否真的发生了大流量拥塞。传输层要看TCP连接数、SYN包速率、连接建立成功率、连接超时数量。CC攻击很多时候是慢速连接攻击,每个连接只发很少的数据,但连接数能堆到几万甚至几十万,这时候物理带宽没满,但服务器的连接表满了,新连接根本进不来。应用层要看每个URI的请求频率、响应时间、错误率,尤其是动态请求和数据库查询的耗时。这三个层面的数据要同时采集,交叉分析,才能判断当前链路资源到底是被什么消耗掉的。

一个实用的做法是在服务器上部署轻量级监控脚本,实时采集连接状态。下面这段脚本可以统计当前TCP连接状态分布,帮助快速判断是否遭遇CC攻击:

#!/bin/bash
# 统计TCP连接状态,每2秒刷新一次
while true; do
    clear
    echo "===== TCP连接状态统计 $(date '+%Y-%m-%d %H:%M:%S') ====="
    netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
    echo ""
    echo "===== 当前连接数最高的10个IP ====="
    netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10
    sleep 2
done

这个脚本的意义在于,当SYN_RECV或ESTABLISHED状态的连接数异常升高,并且某个IP的连接数远超正常水平时,基本可以判定是CC攻击。但监控只是第一步,接下来要做的是在链路被占满之前主动干预。

防止链路占满的核心策略是分层限速和主动丢弃

很多人在服务器上配置防火墙规则,比如限制单个IP的连接数,但这只能应对小规模攻击。真正的CC攻击会动用大量代理IP,每个IP只建立几十个连接,单IP限速很难触发。这时候需要在更上层做聚合限速,比如按C段限速、按地域限速、按UA特征限速。更有效的方式是在服务器前面部署反向代理或专门的抗CC设备,在请求到达业务服务器之前就完成过滤。

Nginx和OpenResty是目前使用最广的软件层防御方案。通过limit_conn和limit_req模块,可以针对连接数和请求速率做精细控制。下面是一段Nginx配置示例,限制每个IP的并发连接数为20,每个IP每秒最多处理10个请求,超过就返回503:

http {
    # 定义限速规则:每个IP最多20个并发连接
    limit_conn_zone $binary_remote_addr zone=conn_perip:10m;
    # 定义请求速率:每个IP每秒最多10个请求,突发允许20个
    limit_req_zone $binary_remote_addr zone=req_perip:10m rate=10r/s;

    server {
        listen 80;
        server_name example.com;

        # 应用连接数限制
        limit_conn conn_perip 20;
        # 应用请求速率限制
        limit_req zone=req_perip burst=20 nodelay;

        location / {
            proxy_pass http://backend;
        }
    }
}

这个配置能挡住一部分简单的CC攻击,但它的局限性也很明显:如果攻击者用大量IP轮换,每个IP只发几个请求,limit_req和limit_conn就形同虚设。所以更进一步的方案是引入行为分析,把正常用户和攻击流量区分开。正常用户的请求往往有完整的浏览器行为,比如会加载CSS、JS、图片,请求之间有合理的间隔,Cookie和Referer正常。而CC攻击工具发出的请求往往缺少这些特征,或者请求频率极其规律。

链路资源监控要和自动防御联动,不能只靠人工处理

很多运维团队的问题在于,监控报警了,但人工响应需要几分钟甚至更久,而CC攻击在几十秒内就能把连接池打满。所以必须建立自动化的防御触发机制。当监控系统发现某个指标超过阈值时,自动执行预设的防御策略。比如当单IP的TCP连接数超过100时,自动将该IP加入防火墙黑名单;当某个域名的总连接数超过5000时,自动启用全局限速;当某个URL的请求速率超过正常值的10倍时,自动对该URL启用验证码或JS挑战。

实现自动联动可以用脚本配合crontab定时执行,也可以用更专业的工具。下面是一个简单的自动封禁脚本,当某个IP的连接数超过100时,自动用iptables封禁该IP:

#!/bin/bash
# 自动封禁连接数超过100的IP
LIMIT=100
FIREWALL_CMD="iptables"

# 获取当前连接数超过阈值的IP列表
BAD_IPS=$(netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | awk -v limit=$LIMIT '$1 > limit {print $2}')

for ip in $BAD_IPS; do
    # 检查是否已经封禁
    if ! $FIREWALL_CMD -L INPUT -n | grep -q "$ip"; then
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 封禁IP: $ip (连接数超过$LIMIT)"
        $FIREWALL_CMD -A INPUT -s $ip -j DROP
    fi
done

这个脚本可以每30秒执行一次,但要注意白名单机制,避免误封正常用户。更稳妥的做法是只封禁明显异常的行为,比如连接数超过正常值几十倍的IP,并且封禁时间设置一个上限,比如1小时后自动解封。

带宽资源监控不能只看服务器,还要看上游设备和CDN

如果你的业务部署在云上,或者前面有CDN,那么链路资源的监控要延伸到CDN节点和负载均衡器。很多CC攻击的目标是源站,但攻击流量会先经过CDN。如果CDN的回源策略配置不当,攻击请求会被大量回源到服务器,导致源站链路被占满。所以要监控CDN的回源带宽、回源请求数、缓存命中率。正常情况下,CDN的缓存命中率应该在90%以上,如果突然下降到50%以下,说明有大量请求绕过了缓存直接回源,这很可能是CC攻击的特征。

在CDN层面可以做的防御包括:开启CC防护模式、设置回源限速、配置区域封禁、启用智能调度。很多CDN服务商提供自动化的CC攻击检测和清洗,但默认配置往往不够激进,需要根据业务特点手动调整。比如对于API服务,可以设置更严格的速率限制;对于静态资源,可以设置更长的缓存时间,减少回源压力。

链路占满的另一个隐蔽原因是攻击者利用了协议层漏洞

除了应用层的CC攻击,还有一类攻击专门消耗链路资源,比如SYN Flood、UDP Flood、ICMP Flood。这类攻击的特点是流量大、包小、速度快,很容易把物理链路带宽占满。防御这类攻击不能只靠服务器上的软件,因为流量到达服务器之前链路就已经拥塞了。需要在网络入口处部署专业的抗DDoS设备,或者使用运营商提供的流量清洗服务。对于自建机房的用户,可以在核心交换机上配置ACL和速率限制,丢弃明显的攻击流量。

一个常被忽视的细节是DNS解析。CC攻击有时会针对DNS服务器发起查询洪水,导致DNS响应缓慢,进而影响整个链路的访问。所以监控DNS查询速率和响应时间也很重要。如果DNS服务器被打挂,即使业务服务器正常,用户也无法解析域名,效果等同于链路中断。

综合防御思路:把链路资源当成一个可弹性伸缩的池子

防止链路占满的最终方案不是硬扛,而是让链路资源具备弹性。当攻击流量涌来时,自动扩容带宽、增加前端节点、分散流量到多个入口。这需要架构上支持水平扩展,比如使用负载均衡器把流量分发到多个后端服务器,使用Anycast技术把流量分散到多个机房。对于大多数企业来说,完全自建弹性架构成本太高,更实际的做法是混合使用云防护服务和本地防御,攻击流量先经过云清洗,干净的流量再回源到服务器。

监控体系要形成闭环:采集数据、分析异常、触发防御、验证效果、调整策略。每一步都要自动化,减少人工干预的时间窗口。同时要定期做压力测试和攻防演练,验证监控和防御策略是否真的有效。很多配置在平时看起来没问题,一旦遇到真实攻击就暴露出各种漏洞,比如阈值设置不合理、白名单过于宽松、自动封禁脚本有bug等。

最后要强调的是,防止链路占满不是一次性配置就能解决的事。攻击者的手法在不断变化,从简单的HTTP Flood到慢速攻击、混合攻击、分布式僵尸网络,防御策略也要持续迭代。带宽资源监控的数据要长期留存,分析攻击趋势,提前调整容量规划。只有把监控、防御、弹性扩展结合起来,才能在CC攻击面前保持链路畅通,保障业务连续运行。