一次生产流量攻击防御与解决方案

一、问题背景
1.1 问题发现
某天上班后,运维反馈监控系统突然告警,网站带宽使用率持续飙升至80%以上,服务器CPU负载异常。通过查看Nginx访问日志发现,某个静态资源文件遭受了大规模的异常访问。
1.2 日志分析
正常访问日志示例
首先查看正常时段的访问日志,流量分布较为均匀:
{"@timestamp":"2025-11-11T09:00:00+08:00","host":"172.25.192.5","client":"183.44.115.70","size":792,"responsetime":0.001,"url":"/uploadfiles/nav/nav3_img3.png","status":"200"}
{"@timestamp":"2025-11-11T09:00:00+08:00","host":"172.25.192.5","client":"119.134.146.224","size":1222,"responsetime":0.002,"url":"/uploadfiles/2024/05/20240506180621580.png","status":"200"}
{"@timestamp":"2025-11-11T09:00:00+08:00","host":"172.25.192.5","client":"223.104.87.191","size":367,"responsetime":0.003,"url":"/ytx-api/v1.0.0/loginToken/getApp","status":"200"}
{"@timestamp":"2025-11-11T09:00:00+08:00","host":"172.25.192.5","client":"183.44.115.70","size":4692,"responsetime":0.003,"url":"/cn/js/liMarquee/jquery.liMarquee.js","status":"200"}
异常流量特征
通过日志分析工具统计发现,某个Banner图片的访问量异常激增:
# 统计访问最频繁的URL
cat access.log | jq -r '.url' | sort | uniq -c | sort -rn | head -10
# 输出结果(示例)
6897 /uploadfiles/banner/banner_img.png
342 /uploadfiles/nav/nav3_img3.png
256 /uploadfiles/2024/05/20240506180621580.png
189 /ytx-api/v1.0.0/loginToken/getApp
...
可以看到,某个Banner图片的访问量远超其他资源,占据了绝对优势。
IP来源分析
进一步分析访问该资源的IP分布:
# 统计访问Banner图片的独立IP数
cat access.log | grep "banner_img.png" | jq -r '.client' | sort -u | wc -l
# 输出: 6857
# 统计每个IP的访问次数
cat access.log | grep "banner_img.png" | jq -r '.client' | sort | uniq -c | sort -rn | head -10
# 输出结果(示例)
5 183.44.115.70
4 119.134.146.224
3 223.104.87.191
2 113.117.88.203
1 211.90.250.205
...
关键发现:近7000个IP,每个IP仅访问1-5次,这是典型的分布式低频攻击特征。
1.3 攻击特征总结
通过对日志进行深入分析,确认了以下攻击特征:
攻击特征:
- 目标资源: 网站Banner图片(约900KB)
- 攻击规模: 约7000次/小时,流量达6GB/小时
- 客户端数: 近7000个独立IP(高度分散)
- 攻击模式: 分布式低频攻击(每个IP仅访问1-5次)
- 攻击类型: DDoS(分布式拒绝服务攻击)
- 响应时间: 平均响应时间从0.002s增长到0.5s以上
1.4 攻击危害分析
经过初步评估,此次攻击造成了以下影响:
- 带宽耗尽: 单个文件占用超过60%带宽资源
- 服务器负载: 大量并发请求导致CPU使用率持续在80%以上
- 成本增加: 带宽费用较平时增长3倍以上
- 服务降级: 正常用户访问延迟增加,部分请求超时
二、紧急防御措施(立即部署)
2.1 Nginx限流配置(5分钟内完成)
配置限流规则
# 在 http 块中定义限流区域
http {
# 限制单IP请求频率
limit_req_zone $binary_remote_addr zone=static_limit:10m rate=10r/s;
# 限制单IP并发连接数
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
# 限制总带宽
limit_rate 500k; # 单连接限速500KB/s
server {
listen 80;
server_name www.example.com;
# 针对静态资源的限流
location ~* /uploadfiles/.*\.(png|jpg|jpeg|gif)$ {
# 请求频率限制:每秒10个请求,突发20个
limit_req zone=static_limit burst=20 nodelay;
# 并发连接限制:每IP最多5个连接
limit_conn conn_limit 5;
# 单连接限速
limit_rate 300k;
# 返回静态文件
root /var/www/html;
# 如果超过限制,返回503
limit_req_status 503;
limit_conn_status 503;
}
# 特别保护Banner图片
location = /uploadfiles/banner/banner_img.png {
# 更严格的限制
limit_req zone=static_limit burst=5 nodelay;
limit_conn conn_limit 2;
limit_rate 200k;
root /var/www/html;
}
}
}
配置说明
limit_req_zone: 定义一个限流区域,使用$binary_remote_addr作为键,存储在static_limit区域,设置为10分钟,限速为每秒10个请求。limit_conn_zone: 定义一个连接数限制区域,使用$binary_remote_addr作为键,存储在conn_limit区域,设置为10分钟。limit_rate: 设置单连接限速为500KB/s。limit_req: 对静态资源请求进行限流,设置为每秒10个请求,突发20个,不延迟处理。limit_conn: 对单IP的并发连接数进行限制,设置为每IP最多5个连接。limit_rate: 对单连接限速为300KB/s。limit_req_status: 当超过限流阈值时,返回503状态码。limit_conn_status: 当超过连接数限制时,返回503状态码。
应用配置并重启
# 测试配置文件语法
nginx -t
# 配置无误后重载Nginx
nginx -s reload
# 或使用systemctl方式
systemctl reload nginx
2.2 启用防盗链保护(15分钟内完成)
location ~* /uploadfiles/.*\.(png|jpg|jpeg|gif)$ {
# 防盗链配置
valid_referers none blocked server_names
*.example.com
example.com
localhost;
if ($invalid_referer) {
return 403;
}
# 其他配置...
}
配置说明
valid_referers: 定义允许的Referer列表,包括直接访问、CDN回源IP、CDN域名、本地访问等。if ($invalid_referer): 如果Referer不在允许列表中,则返回403状态码。
三、中期防御方案(24小时内部署)
中期防御方案,需要在服务器上部署CDN + DDoS防护设备,以提供更全面的防御能力。
3.1 接入CDN + DDoS防护
方案选择
阿里云CDN + DDoS高防
# 配置步骤
1. 登录阿里云控制台
2. 开通CDN服务
3. 添加加速域名:www.example.com
4. 配置源站:当前服务器IP
5. 开通DDoS高防IP
6. 将域名解析到高防IP
注意:
- 需要确保CDN和DDoS高防IP的配置正确无误,否则会影响正常访问。
源站Nginx配置
# 源站Nginx配置示例
server {
listen 80;
server_name www.example.com;
# 只允许CDN回源IP访问
allow 47.88.0.0/16; # 阿里云CDN IP段
allow 47.246.0.0/16;
allow 118.178.0.0/16;
deny all;
# 验证CDN回源请求
if ($http_x_forwarded_for = "") {
return 403;
}
location / {
root /var/www/html;
}
}
配置说明:
allow: 允许访问的IP段,这里配置了阿里云CDN的IP段。deny all: 拒绝所有其他IP的访问。if ($http_x_forwarded_for = ""): 如果请求头中没有X-Forwarded-For字段,说明不是CDN回源请求,返回403状态码。
其他CDN方案对比
| 方案 | 优势 | 成本 |
|---|---|---|
| 腾讯云CDN + DDoS防护 | 成本相对较低,国内节点丰富 | 400-1500元/月 |
| Cloudflare(国际方案) | 免费DDoS防护,全球CDN加速 | 免费-200美元/月 |
预期效果
- 防御能力: 100-300 Gbps
- 源站流量减少: 80-95%
- 响应时间: 降低30-50%
- 成本: 约500-2000元/月
四、长期防护策略
4.1 架构优化
静态资源分离
# 主站服务器(动态内容)
server {
listen 80;
server_name www.example.com;
# 静态资源重定向到CDN
location ~* /uploadfiles/ {
return 301 https://cdn.example.com$request_uri;
}
# 动态内容
location / {
proxy_pass http://backend;
}
}
# CDN/静态资源服务器
server {
listen 80;
server_name cdn.example.com;
# 严格限流
limit_req zone=cdn_limit burst=10;
location /uploadfiles/ {
root /var/www/static;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
配置说明:
limit_req: 对CDN请求进行限流,设置为每秒10个请求,突发10个。expires: 设置静态资源缓存时间为30天。add_header: 添加Cache-Control头,设置为public和immutable,确保浏览器缓存。
使用对象存储(OSS)
# 将静态资源迁移到阿里云OSS
# 1. 安装ossutil工具
wget http://gosspublic.alicdn.com/ossutil/1.7.15/ossutil64
chmod +x ossutil64
mv ossutil64 /usr/local/bin/ossutil
# 2. 配置OSS访问凭证
ossutil config
# 3. 批量上传文件到OSS
ossutil cp -r /var/www/html/uploadfiles/ oss://your-bucket/uploadfiles/
# 4. 配置CDN加速OSS
# 在阿里云控制台配置CDN指向OSS bucket
图片压缩与优化
# 批量压缩所有图片
cat > /usr/local/bin/optimize_all_images.sh << 'EOF'
#!/bin/bash
UPLOAD_DIR="/var/www/html/uploadfiles"
BACKUP_DIR="/var/www/backup/uploadfiles_$(date +%Y%m%d)"
# 备份原文件
echo "备份原文件到 $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
cp -r "$UPLOAD_DIR" "$BACKUP_DIR"
# 优化PNG
echo "优化PNG图片..."
find "$UPLOAD_DIR" -name "*.png" -type f | while read img; do
size_before=$(stat -f%z "$img" 2>/dev/null || stat -c%s "$img")
pngquant --quality=65-80 --ext .png --force "$img" 2>/dev/null
size_after=$(stat -f%z "$img" 2>/dev/null || stat -c%s "$img")
saved=$((size_before - size_after))
echo " $img: $(numfmt --to=iec $size_before) -> $(numfmt --to=iec $size_after) (节省 $(numfmt --to=iec $saved))"
done
# 优化JPG
echo "优化JPG图片..."
find "$UPLOAD_DIR" -name "*.jpg" -o -name "*.jpeg" -type f | while read img; do
size_before=$(stat -f%z "$img" 2>/dev/null || stat -c%s "$img")
jpegoptim --max=85 --strip-all "$img" 2>/dev/null
size_after=$(stat -f%z "$img" 2>/dev/null || stat -c%s "$img")
saved=$((size_before - size_after))
echo " $img: $(numfmt --to=iec $size_before) -> $(numfmt --to=iec $size_after) (节省 $(numfmt --to=iec $saved))"
done
echo "优化完成!"
EOF
chmod +x /usr/local/bin/optimize_all_images.sh
配置说明:
UPLOAD_DIR: 静态资源目录。BACKUP_DIR: 备份目录,使用当前日期作为子目录。pngquant: 优化PNG图片,设置质量为65-80,不保留元数据。jpegoptim: 优化JPG图片,设置最大质量为85,不保留元数据。
五、实施时间表
5.1 分阶段实施计划
第一阶段:紧急响应(立即-2小时)
- 部署Nginx限流配置
- 启用IP黑名单
- 配置防盗链
- 压缩关键图片
第二阶段:中期防护(24小时内)
- 接入CDN服务
- 部署WAF规则
- 启动实时监控
- 配置告警系统
第三阶段:长期优化(1周内)
- 静态资源迁移OSS
- 批量优化所有图片
- 部署监控面板
- 制定应急预案
六、验证与测试
6.1 限流功能测试
# 使用ab进行压力测试
ab -n 1000 -c 50 https://www.example.com/uploadfiles/banner/banner_img.png
# 预期结果:大部分请求返回503或429
七、总结
7.1 核心要点
- 立即行动: 部署Nginx限流和IP封禁(30分钟内完成)
- 接入CDN: 最有效的防护手段,24小时内完成接入
- 持续监控: 建立实时监控和告警机制
- 优化资源: 压缩图片、使用OSS减少攻击面
7.2 预期效果
- 防护能力: 从0提升到100+ Gbps
- 带宽节省: 70-90%
- 响应时间: 降低30-50%
- 成本控制: 2000-5000元/月
- 服务稳定性: 99.9%可用性
注意: 可根据实际情况立即部署。建议先在测试环境验证后再应用到生产环境。
参考文章
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 逐光の博客!
评论