Nginx 如何防御 DDOS 攻击?

更新时间:2026-01-17 来源:TopSSL技术团队

Nginx如何防御DDoS攻击?

Nginx 本身不是专用的 DDoS 防护设备,无法单独抵御大规模流量型攻击,但可以通过连接数限制、请求速率限制和资源隔离,缓解部分 HTTP 层 DDoS 和应用层 Flood。

Nginx 的防护能力主要集中在​已经到达 Web 服务这一层的请求​。例如,攻击者持续向登录接口、搜索接口或 API 发送大量 HTTP 请求时,可以利用 limit_connlimit_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_reqlimit_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清洗大流量、网络层攻击
WAFWeb攻击、恶意请求
负载均衡流量分配、故障隔离
NginxHTTP限流、连接控制、资源保护
Linux内核TCP/IP连接层防护
Fail2ban暴力破解、异常IP封禁
应用层账号、API、业务逻辑攻击

没有任何一个组件可以单独解决全部 DDoS 问题。

技术总结

Nginx 可以通过 limit_connlimit_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 分布和业务峰值进行压测,再设置 rateburst 和并发限制。生产环境可以先使用 dry-run 模式观察超限情况,再正式启用限制。

立即探索,帮您快速寻找适合您的SSL数字证书 申请SSL证书
免费SSL证书 - SSL证书申请与HTTPS安全服务平台 | TopSSL
提供免费与付费SSL证书申请
关注 TopSSL 公众号, RSS订阅SSL资讯与技术支持

TopSSL是一站式SSL证书服务平台,提供免费SSL证书申请、商业SSL证书服务及HTTPS安全解决方案,支持DV、OV、EV、通配符和国密SSL证书服务。2004-2026 © 北京传诚信  版权所有 |  北京市朝阳区鹏景阁大厦16层

技术协助:wo@topssl.cn 企业咨询:vip@topssl.cn