Nginx如何防御DDoS攻击?
Nginx 本身不是专用的 DDoS 防护设备,无法单独抵御大规模流量型攻击,但可以通过连接数限制、请求速率限制和资源隔离,缓解部分 HTTP 层 DDoS 和应用层 Flood。
Nginx 的防护能力主要集中在已经到达 Web 服务这一层的请求。例如,攻击者持续向登录接口、搜索接口或 API 发送大量 HTTP 请求时,可以利用 limit_conn 和 limit_req 限制单个客户端的并发量和请求处理速率。
但如果攻击属于:
- SYN Flood;
- UDP Flood;
- 大规模 TCP Flood;
- 带宽耗尽型攻击;
攻击流量可能在进入 Nginx 之前就已经占满服务器带宽、连接表或上游网络资源。这类攻击需要依赖 Linux 内核、云 DDoS 防护、WAF、CDN 或运营商清洗等更靠前的防护层。
因此,实际生产环境更合理的架构是:
攻击流量
↓
CDN / DDoS清洗
↓
WAF
↓
负载均衡
↓
Nginx
↓
应用服务器
Nginx 负责的是最后一层应用请求控制和资源保护,而不是承担整个 DDoS 清洗任务。
一、Nginx能够防御哪些DDoS攻击?
先明确一个边界:
Nginx 更适合缓解 HTTP/HTTPS 层的高频请求攻击,而不是清洗所有类型的 DDoS 流量。
例如攻击者持续请求:
GET /login
GET /api/search
GET /api/order
GET /wp-login.php
如果单个或少数几个 IP 每秒发起大量请求,就可以通过 Nginx 请求限速进行压制。
而下面这种情况:
大量伪造源地址
↓
SYN Flood
↓
TCP连接资源耗尽
Nginx 甚至可能还没有机会接收到 HTTP 请求,因此 limit_req 和 limit_conn 都不能从根本上解决问题。
二、使用limit_conn限制并发连接
Nginx 的 ngx_http_limit_conn_module 可以根据指定的 key 限制并发连接数量,常见做法是使用:
$binary_remote_addr
作为客户端 IP。
例如:
http {
limit_conn_zone $binary_remote_addr zone=perip:10m;
server {
listen 443 ssl;
server_name example.com;
limit_conn perip 10;
}
}
这表示每个客户端 IP 最多允许一定数量的并发请求进入受限范围。
Nginx 官方文档特别指出,HTTP 请求只有在已经读取完整请求头并进入请求处理后才会被计入,因此 limit_conn 不能理解成一个简单的“TCP 连接数防火墙”。
limit_conn适合什么场景?
它比较适合保护:
- 下载接口;
- 长连接接口;
- 慢请求接口;
- 资源消耗较高的 API;
- 容易被连接占满的业务路径。
例如:
location /download/ {
limit_conn perip 5;
}
可以限制单个客户端同时占用过多请求处理资源。
需要注意,HTTP/2 和 HTTP/3 的请求模型与传统 HTTP/1.1 不完全相同,Nginx 当前文档也说明,在 HTTP/2 和 HTTP/3 中,并发请求会分别参与相关限制计算。
三、使用limit_req限制HTTP请求速率
如果攻击主要表现为:
短时间内重复发送大量 HTTP 请求。
那么 limit_req 更适合。
Nginx 官方 ngx_http_limit_req_module 使用 leaky bucket(漏桶) 方法限制请求处理速率。
例如:
http {
limit_req_zone $binary_remote_addr
zone=api_limit:10m
rate=10r/s;
server {
listen 443 ssl;
server_name example.com;
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
}
}
}
这里:
rate=10r/s
表示平均请求处理速率限制为每秒 10 个。
而:
burst=20
允许一定数量的突发请求进入排队/处理范围。
如果使用:
nodelay
超出平均速率但仍处于 burst 范围内的请求不会被额外延迟,而是立即处理;超过整个允许范围后,请求才会被拒绝。
因此,不应该把 limit_req 描述成简单的“每秒固定只能访问 N 次”。
它实际上包含:
平均速率 + 突发容量 + 延迟/拒绝策略。
四、不要把全站所有请求设置成同一个限流值
这是实际部署中很重要的一点。
例如:
/login
/api/search
/api/order
/static/
/health
这些请求对服务器资源的消耗完全不同。
如果直接:
limit_req zone=api_limit burst=20;
应用到整个网站,很容易造成正常用户被误伤。
更合理的是对高风险路径单独配置:
location /login {
limit_req zone=login_limit burst=5 nodelay;
}
location /api/search {
limit_req zone=search_limit burst=20;
}
location /static/ {
# 静态资源一般不直接套用相同的API限流规则
}
特别是登录、验证码、搜索、短信接口、密码重置、支付接口等容易被自动化请求滥用的路径,更值得单独设置限流策略。
五、不要单纯按照IP做限流
单 IP 限流非常简单,但并不适合所有场景。
例如一个企业可能通过 NAT 让几百个员工共享同一个公网 IP:
企业用户
├── 用户A
├── 用户B
├── 用户C
└── 用户D
↓
同一个公网IP
如果设置:
10 requests/s/IP
就可能误伤整个企业网络。
相反,真正的 DDoS 攻击也可能使用大量不同 IP:
攻击IP1
攻击IP2
攻击IP3
...
攻击IP100000
此时单纯按 IP 做 limit_req,效果会非常有限。
所以实际限流策略可以结合:
- IP;
- URI;
- 用户身份;
- API Key;
- Cookie;
- JWT;
- 地域;
- 上游业务特征。
具体采用哪一种,要根据业务架构决定。
六、Nginx为什么不能防御SYN Flood?
SYN Flood 发生在 TCP 连接建立阶段。
典型过程:
攻击者
↓ SYN
服务器
↓ SYN-ACK
等待最终ACK
↓
大量半连接占用资源
此时 HTTP 请求甚至还没有建立。
因此:
limit_req
❌
limit_conn
❌
都不是 SYN Flood 的核心防护手段。
Linux 内核提供了 tcp_syncookies,用于在 SYN backlog 溢出时发送 SYN cookies,从而缓解常见的 SYN Flood 场景。Linux 内核文档明确将其定义为一种 fallback 机制,并提醒不要把它当成处理正常高并发连接的常规办法。
例如可以查看:
sysctl net.ipv4.tcp_syncookies
但不要因为看到 SYN Flood 就直接无限调整内核参数。
如果攻击规模已经达到带宽或网络设备承载能力,最终仍需要上游 DDoS 防护。
七、iptables能不能防DDoS?
iptables 可以用于:
- 阻断特定 IP;
- 限制异常连接;
- 丢弃明显恶意流量;
- 配合其他防护策略做主机级访问控制。
例如简单封禁一个恶意源:
iptables -A INPUT -s 203.0.113.50 -j DROP
但对于:
100000个攻击IP
逐个加入防火墙规则显然不是合理的 DDoS 防护方案。
大量规则还可能增加主机自身处理负担。
所以:
iptables 更适合主机级访问控制,不应该被当成大规模 DDoS 清洗系统。
八、Fail2ban能不能防DDoS?
Fail2ban 更适合处理:
- SSH 暴力破解;
- Web 登录爆破;
- 特定 HTTP 错误频繁出现;
- 扫描和重复认证失败。
典型工作方式是:
日志
↓
Fail2ban检测
↓
发现异常IP
↓
调用防火墙封禁
它属于事后型封禁机制。
如果攻击流量巨大,网络带宽已经被占满,Fail2ban 即使成功把 IP 加入封禁列表,也无法阻止已经进入网络链路的流量。
因此:
Fail2ban适合防暴力破解和低强度恶意请求,不适合作为大型DDoS防护方案。
九、Nginx前面最好增加WAF或CDN
对于公网生产网站,更合理的部署方式是:
Internet
↓
CDN / DDoS Protection
↓
WAF
↓
Load Balancer
↓
Nginx
↓
Application
每层负责的问题不同。
CDN / DDoS清洗
负责:
- 大流量攻击;
- TCP/UDP Flood;
- 带宽保护;
- 全球边缘节点清洗。
WAF
负责:
- SQL注入;
- XSS;
- 恶意 HTTP 请求;
- Bot;
- API 攻击;
- Web 攻击规则。
Nginx
负责:
- HTTP 请求限速;
- 并发控制;
- 连接管理;
- URL 级别资源保护;
- 反向代理;
- upstream 限制。
因此,最合理的思路不是:
“如何让 Nginx 单独防住 DDoS?”
而是:
“如何让 Nginx 成为多层 DDoS 防御架构中的应用层控制点?”
十、Nginx应该监控哪些指标?
要判断限流是否真的有效,不能只配置规则而不监控。
至少应该关注:
- 每秒请求数(RPS);
- 并发连接数;
- 5xx 比例;
- 4xx 比例;
- 平均响应时间;
- upstream 响应时间;
- CPU;
- 内存;
- 网络带宽;
- connection states。
例如:
正常流量
RPS → 1000
5xx → 0.2%
攻击开始
RPS → 50000
5xx → 35%
CPU → 95%
此时说明问题可能已经超出了简单的 Nginx 请求限流能力。
Nginx 可以通过日志、状态模块以及外部监控系统进行指标采集。
如果使用 ngx_http_vhost_traffic_status_module,应明确这是第三方扩展模块,不是 Nginx 官方核心模块。
生产环境更建议将指标接入:
- Prometheus;
- Grafana;
- 日志平台;
- APM;
- 云监控。
十一、如何设计一套实际可用的Nginx限流策略?
不要简单设置:
所有请求
↓
10 requests/s
可以按照业务风险分级。
例如:
普通页面
→ 宽松限制
搜索接口
→ 中等限制
登录接口
→ 严格限制
验证码接口
→ 更严格限制
密码重置
→ 严格限制
支付接口
→ 结合用户身份和业务规则
进一步可以设计:
http {
limit_req_zone $binary_remote_addr
zone=login_limit:10m
rate=2r/s;
limit_req_zone $binary_remote_addr
zone=api_limit:20m
rate=20r/s;
limit_conn_zone $binary_remote_addr
zone=perip:20m;
server {
listen 443 ssl;
server_name example.com;
limit_conn perip 30;
location /login {
limit_req zone=login_limit burst=5 nodelay;
}
location /api/ {
limit_req zone=api_limit burst=40 nodelay;
}
}
}
这里的数值只是配置示例,不能直接当成所有网站通用的最佳值。
正确阈值应该根据正常业务流量基线、客户端分布和接口实际耗时进行压测后确定。
十二、如何判断Nginx限流是否误伤正常用户?
部署限流之前,建议先使用:
limit_req_dry_run on;
和:
limit_conn_dry_run on;
进行观察。
Nginx 官方提供了 dry-run 模式,在该模式下超限请求会被统计,但不会真正执行限制。
这样可以先观察:
哪些IP经常超限?
哪些URI最容易触发?
正常高峰会不会误伤?
确认阈值合理之后,再正式启用。
这个方法比直接在生产环境设置非常严格的限流值更稳妥。
十三、Nginx防DDoS的正确定位
可以把不同技术的职责简单理解成:
| 防护层 | 主要解决的问题 |
|---|---|
| CDN / DDoS清洗 | 大流量、网络层攻击 |
| WAF | Web攻击、恶意请求 |
| 负载均衡 | 流量分配、故障隔离 |
| Nginx | HTTP限流、连接控制、资源保护 |
| Linux内核 | TCP/IP连接层防护 |
| Fail2ban | 暴力破解、异常IP封禁 |
| 应用层 | 账号、API、业务逻辑攻击 |
没有任何一个组件可以单独解决全部 DDoS 问题。
技术总结
Nginx 可以通过 limit_conn 和 limit_req 对 HTTP 层的并发请求和处理速率进行控制,从而缓解部分 HTTP Flood、接口滥用和连接资源消耗问题。limit_req 使用漏桶算法控制请求处理速率,limit_conn 则按指定 key 限制并发请求处理数量。 但对于 SYN Flood、UDP Flood 以及已经造成带宽耗尽的大规模 DDoS,Nginx 处于防线后端,无法从根本上解决问题;这类攻击需要结合 Linux 内核、CDN、WAF、云 DDoS 防护或运营商清洗。Linux 的 tcp_syncookies 可以作为 SYN Flood 的一种内核级缓解机制,但官方文档明确将其定位为 backlog 溢出时的 fallback,而非替代网络扩容和上游清洗。
常见问题 FAQ
Q:Nginx能完全防住DDoS攻击吗?
A:不能。Nginx 更适合缓解 HTTP 层攻击和异常请求。如果攻击已经造成带宽、TCP 连接表或上游网络设备资源耗尽,Nginx 无法在应用层解决问题,应接入 CDN、云 DDoS 防护或运营商清洗。
Q:limit_conn和limit_req有什么区别?
A:limit_conn 用于限制指定 key 的并发请求处理数量;limit_req 用于控制请求处理速率。前者主要解决并发资源占用,后者主要解决单位时间内请求过多的问题。
Q:Nginx使用limit_req是不是令牌桶算法?
A:不是。Nginx 官方文档将 limit_req 描述为基于 leaky bucket(漏桶) 的请求速率限制机制。burst 用于允许一定数量的突发请求,nodelay 控制超出平均速率后的处理方式。
Q:iptables和Fail2ban能防DDoS吗?
A:它们可以处理特定恶意 IP、暴力破解和低强度异常请求,但不适合替代大规模 DDoS 清洗。攻击流量如果已经把公网带宽打满,主机上的封禁规则也无法消除已经进入网络链路的流量。
Q:Nginx配置多少请求每秒才能防DDoS?
A:不存在适用于所有网站的固定数值。应该根据正常 RPS、接口响应时间、客户端 IP 分布和业务峰值进行压测,再设置 rate、burst 和并发限制。生产环境可以先使用 dry-run 模式观察超限情况,再正式启用限制。



京公网安备11010502031690号
网站经营企业工商营业执照
















