CC攻击针对API接口,Nginx+iptables分层限流
当 API 接口遭遇针对 351.CC 节点的 CC 攻击时,表现通常是 QPS 飙升、响应延迟变大、CPU 跑满,而服务器并未被流量打崩。
此时需要在应用层和网络层分别做手脚:用 Nginx 的 limit_req 限制单 IP 请求频率,用 iptables 限制并发连接和封禁异常来源。
以下操作以 CentOS 7/8 和 Ubuntu 20.04 为例,其他发行版命令大同小异。
开始前请确认你有 root 权限,且已备份现有 Nginx 配置。
一、先判断攻击特征:API 和普通网页限流思路不同
普通网页被 CC 攻击,往往靠缓存和并发限制就能缓解;
但 API 接口通常不允许缓存,且请求路径带有业务参数,攻击特征更隐蔽。
判断方法很简单:执行 tail -f /var/log/nginx/access.log,观察同一 IP 是否在短时间内密集请求同一个 /api/xxx 路径,或者请求参数类似但 User-Agent 异常。
如果确认是这种模式,单纯调大 Nginx 并发参数无效,必须做分层限流。
二、Nginx 层:对 API 路径设置精确限流
先编辑 Nginx 配置文件(通常在 /etc/nginx/nginx.conf 的 http{} 块,
或 /etc/nginx/conf.d/ 下),
在 http{} 中定义限流区域:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
含义是:为每个客户端 IP 建立一个共享内存区 api_limit,大小 10MB,默认每秒最多处理 5 次请求。
然后在你对应的 server 或 location 中启用:
location /api/ {
limit_req zone=api_limit burst=10 nodelay;
limit_req_status 429;
proxy_pass http://你的后端服务;
}
burst=10 表示允许瞬间超出 5 次请求的缓冲区为 10 个,nodelay 让超出的请求直接返回 429 而不是排队等待。
配置后先执行 nginx -t 检查语法,再执行 systemctl reload nginx 生效。
到这一步,单 IP 的短时高频请求已经被拦住。
三、iptables 层:堵住连接洪峰和异常来源
Nginx 限流只针对已建立的 HTTP 请求,无法阻止攻击者不停发起新连接。
此时用 iptables 做第二层拦截。
先用下面命令限制单 IP 的 TCP 并发连接数:
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 50 -j REJECT --reject-with tcp-reset
这意味着每个 IP 对 80 和 443 端口的并发连接数超过 50 会直接重置连接。
同时启用 SYN 洪水简易防护:
iptables -A INPUT -p tcp --syn -m limit --limit 50/s --limit-burst 100 -j ACCEPT
注意执行顺序:在 iptables 中,规则按顺序匹配,所以要确保这两条规则在允许合法流量的放行规则之前。
如果你用的是宝塔面板,也可以在「安全」-「系统防火墙」中直接添加这些规则,但效果不如命令行即时。
四、避坑:限流参数太小会误伤正常用户
新手最容易把 rate 设得太低,比如 1r/s,结果大量正常用户被 429。
我建议按照你 API 的真实调用情况来调整:先跑一天看 access log,统计正常用户的单 IP 最大 QPS,再取 3-5 倍余量作为限流值。
另外 iptables 的 connlimit 不要设得过低,APP 和网页同时迭代时很容易超过 50。limit_req 的 burst 也不要太大,否则攻击高峰时积压请求会占满后端连接池。
还有一点:如果攻击源来自大量伪造 IP,Nginx 和 iptables 都无解,需要配合云服务商的 DDoS 清洗或 CDN 加速。
本方案适合攻击 IP 相对集中、且来源 IP 真实可控的 CC 攻击场景。
五、验证效果:用日志和命令确认是否生效
配置完成后,用以下方法验证限制是否真的在起作用。
先看 Nginx 错误日志:
grep "limit_req" /var/log/nginx/error.log | tail
如果出现 limiting requests, excess: 0.200 by zone "api_limit",说明限流生效。
再看返回状态码分布:
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
正常情况会看到一定量的 429。
iptables 的匹配次数可以用 iptables -L -n -v 查看,connlimit 那行 packets 数量在增长就代表拦截正在发生。
最后提醒一句:接口限流是长期防护手段,不是打一次就删。
建议把配置保存为独立文件,如 /etc/nginx/conf.d/api_limit.conf,方便后续按业务调整。
当你发现攻击频率进一步上升,再考虑增加多维度限流,比如按 $request_uri 或 $http_referer 区分。
如果你正在处理 351.CC 节点上的 API 被 CC 攻击的问题,建议先按本文步骤完整执行,再根据实际日志微调参数;
遇到异常时优先看避坑部分,不要盲目调大或取消限制。