CC攻击最棘手的问题不是带宽被塞满,而是服务器资源正常、网络连接正常,但真实用户就是打不开网站。这是因为攻击者利用了Web服务器的并发连接限制,用大量看似合法的请求占满了连接池。当服务器前端防火墙或WAF介入清洗流量时,往往采用一刀切的速率限制策略,导致正常用户和攻击流量一起被拦截。恢复的核心在于精准解封被误伤的真实流量,同时保持对攻击源的压制。

快速确认用户被屏蔽的具体位置

用户访问链路通常经过多层防护:CDN层、云防火墙、主机软件防火墙、Web服务器(如Nginx)的limit_conn模块。当用户反馈无法访问时,第一时间要定位阻断点。让用户执行ping和telnet命令测试连通性。如果ping通但80/443端口不通,说明IP被云防火墙或主机iptables封禁。如果端口通但返回403/503,是WAF或Web服务器层面的拦截。如果浏览器直接显示连接重置,通常是触发了运营商的黑洞路由或云厂商的流量清洗阈值。很多运维人员直接去查Nginx日志,这是低效的,必须先通过用户的网络诊断结果反向排查。

建立临时白名单通道是应急首选

攻击持续期间,最有效的恢复手段是建立一条绕过流量清洗设备的白名单通道。在云防火墙或WAF上创建一个临时规则:对于带有特定Cookie或Header的请求,直接放行到源站,不经过CC防护策略的检测。具体操作是:让受影响的用户访问一个特定的静态验证页面,这个页面不经过WAF,直接部署在源站的另一个端口或子域名上。用户通过验证后,前端写入一个加密的Cookie,然后跳转回主站。WAF识别到这个Cookie后跳过速率限制。这个方案能在5分钟内让核心用户恢复访问,比调整全局策略风险小得多。

从WAF日志中提取误封IP并批量解封

如果你使用的是云WAF,登录控制台查看安全报表中的“误拦截”或“人机识别”记录。很多WAF会自动将高频访问的IP加入黑名单,解封操作不能全量清除,否则攻击流量会瞬间涌入。正确的做法是按时间段导出被封IP列表,与攻击发生前24小时的正常访问日志做交集比对。使用以下思路处理:先提取攻击前日志中访问次数超过10次的IP,这些大概率是真实用户或搜索引擎爬虫。再将这些IP与当前黑名单做匹配,匹配上的优先解封。这个过程可以写一个简单的脚本完成。

# 示例:从旧日志中提取高频访问IP
cat access_log_before_attack.log | awk '{print $1}' | sort | uniq -c | sort -nr | awk '$1 > 10 {print $2}' > normal_ips.txt

# 假设blacklist.txt是当前被封IP列表
grep -Fxf normal_ips.txt blacklist.txt > to_unblock.txt

解封后密切监控这些IP的请求频率,如果某个IP在解封后瞬间产生大量请求,立即重新封禁,因为这可能是攻击者伪装的长效IP。

调整速率限制策略,从“一刀切”转向“行为分级”

CC攻击期间最大的错误就是设置全局统一的访问频率阈值。正常用户的请求模式与攻击脚本有本质区别。攻击脚本通常只请求单一URL或少量几个URL,且请求间隔均匀。真实用户会请求HTML、CSS、JS、图片等多种资源,请求间隔呈现长尾分布。在Nginx或WAF上配置分级限速:对静态资源(jpg、png、css、js)设置较高的容忍阈值,因为这些资源本身就应该被频繁请求。对动态接口(如/api/、/login/)设置严格阈值,但对登录状态下的用户放宽限制。具体到Nginx配置,可以这样区分处理:

# 对静态资源不做连接数限制
location ~* \.(jpg|jpeg|png|gif|css|js|svg|woff|woff2)$ {
    limit_conn static_zone 0;
}

# 对API接口严格限制,但排除已登录用户
location /api/ {
    if ($http_cookie ~* "session_token=valid") {
        set $limit_rate 0;
    }
    limit_req zone=api_zone burst=20 nodelay;
    limit_req_status 429;
}

这种分级策略能在压制攻击的同时,让大部分真实用户无感知地访问。

利用JS挑战和浏览器指纹识别实现静默验证

现代CC攻击大多使用无头浏览器或脚本直接发包,这些工具通常无法执行完整的JavaScript或渲染DOM。在WAF上启用JS挑战模式,向请求注入一段JavaScript代码,要求客户端完成一个简单的计算任务后回传结果。真实用户的浏览器会在几百毫秒内自动完成这个过程,用户完全无感知。而攻击脚本如果没有完整的JS执行环境,就会被拦截。更进一步,可以结合浏览器指纹:收集客户端的Canvas指纹、WebGL指纹、屏幕分辨率、时区等信息,建立一个信任评分模型。如果某个IP的请求来自多种不同的浏览器指纹,很可能是代理出口或攻击工具,直接拒绝。这个方案对用户体验影响极小,但能有效区分人和机器。

源站层面的连接池优化与SYN Cookie防护

如果攻击已经穿透了前端防护到达源站,需要在内核层面进行加固。调整Linux内核参数,开启SYN Cookie保护,缩短TIME_WAIT状态的连接回收时间,增大半连接队列长度。这些参数能显著提升服务器在遭受CC攻击时的抗压能力:

# 开启SYN Cookie,防止SYN Flood
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# 快速回收TIME_WAIT连接
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

# 增大半连接队列
echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog

# 缩短孤儿连接超时
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

同时检查Nginx的worker_connections和worker_processes配置,确保连接池足够大。很多站点默认配置只有1024个连接,攻击时瞬间被占满。将worker_connections提升到4096或更高,并配合keepalive_timeout调低到15秒以内,让空闲连接快速释放。

利用CDN的智能调度分散攻击流量

如果你的站点接入了CDN,可以利用CDN的负载均衡能力将攻击流量分散到多个节点。CC攻击通常针对单一源站IP,通过CDN的Anycast网络,攻击请求会被分散到最近的边缘节点处理。更重要的是,主流CDN都提供“源站卸载”功能:在边缘节点缓存动态内容的静态版本。对于攻击者反复请求的动态URL,如果内容在短时间内不变,可以在CDN层缓存30秒到1分钟。这样99%的攻击请求在边缘就被响应了,根本不会到达源站。配置时注意设置正确的Cache-Control头,避免敏感数据被缓存。

反向代理层实现IP信誉库联动

在Nginx或HAProxy层面集成第三方IP信誉库,可以实时识别已知的恶意IP。通过geoip模块或自定义脚本,从威胁情报平台拉取最新的恶意IP列表,自动加入拒绝列表。更高效的做法是使用Nginx的ngx_http_geo_module模块,将IP信誉数据转换为geo变量,在配置中直接判断:

geo $threat_level {
    default 0;
    include /etc/nginx/conf.d/threat_ip_list.conf;
}

server {
    if ($threat_level = 1) {
        return 403;
    }
}

threat_ip_list.conf文件由定时任务从威胁情报API更新,格式为“IP地址 1;”。这样即使攻击IP不在当前WAF规则库中,只要它在全球范围内有过恶意行为记录,就会被自动拦截。

建立用户申诉与自动恢复机制

无论策略多精细,误封始终存在。在网站的503错误页面或拦截提示页上,提供一个自助解封入口。这个入口指向一个独立的、不经过WAF限速的验证服务。用户输入手机号或邮箱,系统发送验证码,验证通过后将该用户的公网IP加入白名单并设置有效期(如24小时)。这个流程必须完全自动化,因为攻击期间运维人员根本没时间处理单个解封请求。白名单有效期机制很重要,避免攻击者通过此通道获取永久豁免权。同时记录所有自助解封的IP和操作时间,事后分析是否存在被攻击者利用的情况。

事后复盘:从日志中提取攻击特征并固化为长期规则

攻击结束后,对全量日志进行分析,提取攻击流量的特征指纹。重点关注User-Agent的分布、请求URL的集中度、请求时间间隔的规律、HTTP协议版本(攻击脚本常用HTTP/1.0)、是否携带合法的Referer等。将这些特征固化为WAF的自定义规则。例如,如果发现攻击流量全部使用某个特定的User-Agent字符串,且不携带任何Referer,可以创建一条规则:当请求同时满足这两个条件时,触发人机验证或直接拒绝。这些基于实战提炼的规则比通用规则库有效得多,能在下一次攻击的初期就发挥作用。

恢复被屏蔽的正常用户不是简单的“解封IP”,而是一套组合策略:建立白名单通道应急、分级限速减少误伤、行为分析区分人机、内核调优提升抗压、事后复盘沉淀规则。每个环节都围绕一个核心目标:让真实用户畅通无阻,让攻击流量无处遁形。