1. 当流量洪水来袭:认识DDoS与Nginx的关系
Nginx作为现代网站的流量守门人,每天要处理数以万计的请求。但当遭遇DDoS攻击时,这个守门人就像突然面临洪水冲击的水闸,处理不当就会导致服务崩溃。不同于传统防火墙,Nginx自身就携带多种"防洪闸门",比如请求速率限制、连接控制等原生功能。
真实案例:某电商网站在大促期间遭遇每秒5万次的CC攻击,攻击者用伪造IP高频请求商品详情页。通过Nginx的限流模块,他们在不增加硬件的情况下将异常请求拦截了87%。
2. 基础防御工事搭建
2.1 请求频率限制(limit_req模块)
http {
# 创建10MB内存区存储访问状态,限制每秒100个请求
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
server {
location /api/ {
# 启用限流,允许突发200个请求,立即执行限制
limit_req zone=api_limit burst=200 nodelay;
proxy_pass http://backend;
}
}
}
参数解析:
$binary_remote_addr
:用二进制格式存储客户端IPzone
:定义存储区域名称和内存大小burst
:类似"缓冲池",允许突发流量nodelay
:立即拒绝超额请求
适用场景:保护API接口、登录页面等关键端点 缺点:无法识别高级伪造IP攻击
2.2 连接数管控(limit_conn模块)
http {
# 每个IP同时最多保持50个连接
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /download/ {
limit_conn addr 50;
limit_rate_after 10m; # 前10MB不限速
limit_rate 100k; # 超过后限速100KB/s
}
}
}
实战效果:某视频站用此配置阻止了攻击者通过海量慢连接耗尽服务器资源
3. 进阶防御策略
3.1 地理围栏(GeoIP模块)
http {
# 加载GeoIP数据库
geoip_country /usr/share/GeoIP/GeoIP.dat;
# 封禁特定国家访问
map $geoip_country_code $allowed_country {
default 1;
CN 0; US 0; JP 0; # 允许中、美、日
RU 1; # 封禁俄罗斯
}
server {
if ($allowed_country) {
return 444; # 特殊状态码直接关闭连接
}
}
}
注意事项:需要定期更新GeoIP数据库
3.2 请求特征过滤(Lua扩展)
location / {
access_by_lua_block {
local headers = ngx.req.get_headers()
-- 拦截非常见User-Agent
if not headers["User-Agent"] then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
-- JS挑战验证
if ngx.var.cookie_js_challenge ~= "passed" then
ngx.header["Set-Cookie"] = "js_challenge=passed"
ngx.say('<script>document.cookie="js_challenge=passed";location.reload();</script>')
ngx.exit(ngx.OK)
end
}
}
技术栈说明:需要OpenResty环境 优势:可有效拦截简单爬虫攻击
4. 防御组合拳实战
4.1 多层过滤架构
- 前端用limit_req拦截高频请求
- 中间层通过Lua脚本做行为验证
- 后端用limit_conn防止连接耗尽
某金融平台配置示例:
http {
limit_req_zone $binary_remote_addr zone=global:20m rate=50r/s;
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
server {
location / {
limit_req zone=global burst=100;
limit_conn conn_zone 30;
access_by_lua_file /etc/nginx/lua/antibot.lua;
# 正常请求处理...
}
}
}
4.2 动态黑名单维护
# 自动封禁异常IP脚本
awk '{if($9>499) print $1}' /var/log/nginx/access.log \
| sort | uniq -c | sort -nr \
| awk '{if($1>1000) print "deny "$2";"}' >> block.conf
# 每小时执行并重载配置
0 * * * * /usr/bin/update_block.sh && nginx -s reload
5. 技术方案对比分析
防御方式 | 配置难度 | 防护效果 | 性能影响 | 适用场景 |
---|---|---|---|---|
基础限流 | ★☆☆☆☆ | ★★☆☆☆ | 5%以下 | 小规模突发流量 |
连接限制 | ★★☆☆☆ | ★★★☆☆ | 3-8% | 慢连接攻击 |
GeoIP过滤 | ★★★☆☆ | ★★★★☆ | 2% | 地域性攻击 |
Lua验证 | ★★★★☆ | ★★★★☆ | 10-15% | 高级脚本攻击 |
动态黑名单 | ★★★★☆ | ★★★★★ | 可变 | 持续定向攻击 |
6. 避坑指南:那些年我们踩过的雷
6.1 配置陷阱
错误示例:
limit_req_zone $remote_addr zone=test:10m rate=10r/s; # 使用ASCII存储IP
正确姿势:
limit_req_zone $binary_remote_addr zone=test:10m rate=10r/s; # 二进制格式省空间
6.2 监控盲区
推荐配置:
# 在http模块添加
log_format security '$remote_addr - $http_x_forwarded_for - [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'Rate:$limit_req_status Conn:$limit_conn_status';
access_log /var/log/nginx/security.log security;
7. 终极防御:云地协同方案
当单机防御达到极限时(通常超过10Gbps流量),建议:
- 启用Cloudflare等CDN服务
- 配置Nginx前置清洗服务器
- 结合iptables进行SYN洪水防护
混合架构示例:
互联网 → Cloudflare → 清洗中心 → Nginx集群 → 业务服务器
技术总结
经过压力测试,合理配置的Nginx可独立抵御5-10Gbps的DDoS攻击。某在线教育平台的实际数据显示:
- 攻击请求拦截率:92.7%
- 误封正常用户率:0.03%
- CPU消耗增长:15-20%
关键配置要诀:
- 限流值从保守值开始,逐步调优
- 定期分析访问日志优化规则
- 重要接口启用二次验证
- 保持Nginx版本更新(特别是修复CVE-2023-44487等漏洞)
记住:没有银弹防御方案,持续监控和策略迭代才是王道。当遇到百G级攻击时,请及时联系专业安全团队。