Nginx 的限流模块是防御 CC 攻击最直接的手段之一,适合在攻击流量尚未打满带宽前进行应用层拦截。
先说结论:通过配置 limit_req_zone 限制单位时间内同一 IP 的请求次数,能有效缓解高频请求导致的服务器资源耗尽,但需避免误伤正常用户。
- 先判断:确认攻击特征是否为高频 HTTP 请求,而非带宽耗尽型 DDoS。
- 优先做:在 Nginx 配置中启用请求频率限制,并设置合理的爆发阈值。
- 再验证:观察错误日志和业务访问是否正常,确保未阻断合法流量。
命令速用版
http {
limit_req_zone $binary_remote_addr zone=forum_limit:10m rate=10r/s;
limit_req_log_level warn;
server {
location /login {
limit_req zone=forum_limit burst=20 nodelay;
limit_req_status 503;
}
}
}为什么会这样
CC 攻击的本质是攻击者模拟正常用户,向服务器发送大量看似合法的请求,耗尽服务器的 CPU、内存或数据库连接资源。Nginx 作为反向代理,位于用户和后端服务之间,可以在请求到达后端之前进行拦截。
limit_req 模块基于令牌桶算法工作。它允许请求以设定的速率通过,超出部分的请求会被延迟处理或直接拒绝。这样可以将突发的大流量平滑化,保护后端服务不被瞬间击垮。防御效果取决于服务器硬件资源和攻击规模,建议结合监控调整。
分步处理
1. 备份配置文件
修改前务必备份,防止配置错误导致 Nginx 无法启动。
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak2. 编辑配置
在 http 块中定义限流区域,在 server 或 location 块中启用限制。$binary_remote_addr 表示基于客户端 IP 进行限制,zone 定义共享内存大小,rate 设定速率。针对论坛场景,建议仅对动态接口限流。
http {
limit_req_zone $binary_remote_addr zone=forum_limit:10m rate=10r/s;
limit_req_log_level warn;
server {
# 静态资源不限流
location ~* \.(gif|jpg|png|css|js)$ {
expires 30d;
}
# 关键动态接口限流
location /login {
limit_req zone=forum_limit burst=20 nodelay;
limit_req_status 503;
}
location /post {
limit_req zone=forum_limit burst=10 nodelay;
limit_req_status 503;
}
}
}3. 检查配置语法
reload 之前必须测试语法,避免服务中断。
nginx -t4. 重载服务
语法无误后重载配置,使更改生效。
nginx -s reload怎么验证是否生效
1. 查看错误日志
当请求被限制时,Nginx 会在 error.log 中记录 limiting requests 相关信息。使用 warn 级别可减少正常日志噪音。
tail -f /var/log/nginx/error.log | grep "limiting"2. 模拟高频请求
使用 curl 循环请求测试接口,观察是否返回 503 状态码。
for i in {1..30}; do curl -o /dev/null -s -w "%{http_code}\n" http://yourdomain.com/login; done3. 监控后端负载
观察服务器 CPU 和内存使用率,确认限流后后端压力是否有所下降。
常见坑
1. 误伤正常用户
如果 rate 设置过低,正常用户快速刷新页面或加载多个资源时可能被限制。建议先设置较宽松的值,根据日志逐步调整。
2. 共享 IP 问题
多个用户可能通过同一出口 IP 访问(如公司网络、移动网络),限流可能导致该 IP 下所有用户受影响。需结合实际业务日志分析受影响比例。
3. 攻击者更换 IP
限流主要针对单一 IP 高频请求,如果攻击者使用大量代理 IP 分散请求,单纯限流效果有限,需结合防火墙或 WAF 使用。
4. 静态资源限制
不要对 css、js、图片等静态资源文件启用严格限流,否则会导致页面加载失败。配置中应排除静态文件路径,仅对动态请求路径进行限制。
参考来源
- Nginx 官方文档,ngx_http_limit_req_module,https://nginx.org/en/docs/http/ngx_http_limit_req_module.html