从一次线上服务卡顿说起:我是如何用Nginx限流和Cloudflare CDN挡住HTTP Flood攻击的
从一次线上服务卡顿说起:我是如何用Nginx限流和Cloudflare CDN挡住HTTP Flood攻击的
那天下午三点,监控系统的告警突然炸开了锅。CPU使用率从平时的30%飙升至95%,响应时间从200ms暴涨到5秒以上,服务器像被灌了铅一样沉重。登录服务器一看,Nginx错误日志里密密麻麻全是499状态码——客户端主动断开连接的标志。这不是普通的流量高峰,而是一场蓄谋已久的HTTP Flood攻击。
1. 攻击现象分析与快速响应
当我第一次看到监控图表上那条陡峭的上升曲线时,第一反应是检查最近是否有营销活动或内容上了热搜。但后台数据显示新增用户数并没有明显变化,这排除了正常流量激增的可能性。
关键异常指标:
- 每秒请求数(RPS)从200激增至8000+
- 同一IP在1分钟内发起300+请求
- User-Agent集中在"Go-http-client/1.1"和"python-requests/2.26.0"
- 请求路径集中在/login和/search等计算密集型接口
通过实时流量分析工具,我快速锁定了攻击特征:
# 统计前10个高频率IP cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10 # 分析异常User-Agent grep -E 'Go-http-client|python-requests' /var/log/nginx/access.log | wc -l2. Nginx层防御:构建第一道防线
面对汹涌而来的恶意请求,我决定先在Nginx层面实施紧急限流措施。Nginx的limit_req模块能有效控制请求速率,而limit_conn模块则可以限制并发连接数。
2.1 基础限流配置
在Nginx配置文件的http块中添加共享内存区定义:
http { limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/m; limit_conn_zone $binary_remote_addr zone=addr:10m; }然后在敏感接口的location块中应用这些限制:
location /login { limit_req zone=api_limit burst=5 nodelay; limit_conn addr 3; proxy_pass http://backend; # 返回429状态码而非默认的503 limit_req_status 429; limit_conn_status 429; }参数说明:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| zone | 定义共享内存区 | 每1MB可存约8000个IP |
| rate | 允许的请求速率 | 30r/m (每分钟30次) |
| burst | 允许的突发请求数 | 5-10 |
| nodelay | 立即拒绝超额请求 | 建议启用 |
2.2 高级防护策略
针对更狡猾的攻击者,我增加了基于地理位置的过滤和User-Agent验证:
map $http_user_agent $bad_ua { default 0; "~*Go-http-client" 1; "~*python-requests" 1; "~*curl" 1; } geo $block_country { default 0; # 已知攻击源国家代码 CN 1; RU 1; } server { if ($bad_ua) { return 444; } if ($block_country) { return 403; } }3. Cloudflare防护:构建分布式防御体系
仅靠服务器自身防御还不够,我决定启用Cloudflare的企业级防护能力。通过其免费套餐就能获得基础DDoS防护,而Pro套餐则提供更精细的WAF规则。
3.1 基础防护设置
- 在Cloudflare控制台启用"I'm Under Attack"模式
- 配置安全级别为"High"
- 开启Bot Fight Mode
- 设置浏览器完整性检查
Cloudflare防护层级对比:
| 功能 | 免费套餐 | Pro套餐 | Business套餐 |
|---|---|---|---|
| DDoS防护 | ✓ | ✓ | ✓ |
| WAF规则数 | 5 | 20 | 100 |
| 速率限制 | 1条规则 | 10条规则 | 15条规则 |
| Bot防护 | 基础 | 增强 | 高级 |
3.2 自定义防火墙规则
针对本次攻击特征,我创建了以下规则:
(http.user_agent contains "Go-http-client" or http.user_agent contains "python-requests") and (cf.threat_score gt 10) and not (ip.src in {192.0.2.1 203.0.113.0/24})动作设置为"Block",并添加验证码挑战作为备用措施。这条规则成功拦截了85%的恶意流量。
4. 事后分析与系统加固
攻击平息后,我进行了全面的复盘,发现几个关键漏洞:
- 监控系统告警阈值设置过高,导致响应延迟
- 关键API接口没有单独的限流策略
- 缺少对异常User-Agent的主动过滤
加固措施清单:
- 将CPU告警阈值从90%下调至70%
- 为所有动态接口添加单独的限流配置
- 部署Fail2Ban自动封禁恶意IP
- 定期更新已知恶意User-Agent列表
- 启用Nginx的缓存机制减轻后端压力
# Fail2Ban配置示例 [nginx-http-flood] enabled = true filter = nginx-http-flood logpath = /var/log/nginx/access.log maxretry = 100 findtime = 60 bantime = 86400 action = cloudflare5. 成本效益分析与方案选型
防御DDoS攻击需要在安全性和成本之间找到平衡。经过这次事件,我总结出不同规模网站的防护方案:
小型网站(预算有限):
- Cloudflare免费套餐 + Nginx基础限流
- 最大程度利用CDN缓存
- 启用基本的WAF规则
中型业务(有一定预算):
- Cloudflare Pro套餐($20/月)
- 精细化的速率限制规则
- 自定义WAF规则
- 第三方监控服务如Pingdom
关键业务(不计成本):
- 专用DDoS防护服务如Cloudflare Enterprise
- 多地负载均衡
- 自动扩展的云基础设施
- 24/7安全运维团队
实际测试中,纯Nginx方案能抵御约5000 RPS的攻击,而配合Cloudflare后,系统成功扛住了超过20000 RPS的冲击。
