返回首页

Nginx 安全配置实战 — 防DDoS/限流/WAF 规则编写

📅 创建于 2026-05-12 🔄 更新于 2026-05-19 📝 696 字

Nginx 安全配置实战:防DDoS、限流与WAF规则编写

Nginx 只能看到自己所在层面的连接、请求、URI、Header、Body 和上游交互结果。 超过这个边界的事情——大带宽 DDoS、链路拥塞、源站前设备被打满——单靠 Nginx 配置解决不了。 核心原则:先分层判断,再做针对性限制。

一、三层攻击防御坐标系

攻击类型 Nginx 可见层级 首选能力 误用方向
大带宽 DDoS 网络入口之前 CDN/高防清洗 指望 Nginx 单机硬扛
连接洪泛 连接层 limit_conn、超时、backlog 只靠 URI 级限流
请求洪泛 请求层 limit_req 只看 active connections
扫描/注入探测 规则层 WAF、黑白名单 只调连接数
撞库/爆破 接口行为层 限速+验证码+账号联动 仅按 IP 限制

二、先修观测面

2.1 真实源地址恢复(前提)

限流、封禁、黑白名单全部建立在正确源地址之上,否则全部失真。

# /etc/nginx/conf.d/security/realip.conf
set_real_ip_from 10.10.0.0/16;
set_real_ip_from 172.20.0.0/16;
set_real_ip_from 192.168.10.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

⚠️ 关键: 不要写 0.0.0.0/0,否则任何客户端都能伪造 XFF 绕过限流。

# 验证:第一列应该是真实客户端 IP,而不是代理 IP
tail -n 20 /var/log/nginx/access.security.log | awk '{print $1}'

2.2 日志格式补齐

log_format security_main '$realip_remote_addr [$time_local] '
  '"$request" $status $body_bytes_sent '
  'rt=$request_time urt=$upstream_response_time '
  'uaddr="$upstream_addr" uri="$uri" '
  'args="$args" ua="$http_user_agent" '
  'xff="$http_x_forwarded_for"';
access_log /var/log/nginx/access.security.log security_main;

关键字段:$realip_remote_addr(真实 IP)、$request_time$upstream_response_time$status

2.3 连接状态页

server {
  listen 127.0.0.1:8080;
  location /nginx_status {
    stub_status;
    allow 127.0.0.1;
    deny all;
  }
}

Active connections 持续高但 QPS 不高 → 慢连接/空闲连接占坑。


三、连接层防护

limit_conn — 并发连接限制

# http 层:定义统计键和内存区
limit_conn_zone $binary_remote_addr zone=conn_per_ip:20m;

# server/location 层:应用
location /admin/ {
  limit_conn conn_per_ip 10;
  proxy_pass http://admin_backend;
}

常见误改: 全站统一低阈值 → HTTP/2 用户误伤。应该按业务路径拆阈值。

关键超时配置

keepalive_timeout 15;
keepalive_requests 1000;
reset_timedout_connection on;
client_header_timeout 10s;
client_body_timeout 15s;
send_timeout 15s;

四、请求层防护

limit_req — 请求速率限制

# http 层:定义限流区
limit_req_zone $binary_remote_addr zone=req_login:20m rate=5r/s;
limit_req_zone $binary_remote_addr zone=req_sms:20m rate=2r/s;
limit_req_zone $binary_remote_addr zone=req_default:50m rate=30r/s;

# location 层:按接口应用
location = /api/login {
  limit_req zone=req_login burst=10 nodelay;
  proxy_pass http://auth_backend;
}

location = /api/sms/send {
  limit_req zone=req_sms burst=5;          # 不加 nodelay:平滑排队
  proxy_pass http://sms_backend;
}

nodelay vs 不加:

  • nodelay → 超过速率后快速拒绝,适合不允许多次重试的接口
  • 不加 nodelay → 短时突刺被延迟处理,用户体验更平滑

分级原则: 对登录、短信、注册等敏感接口用低阈值;对公开 API 用较高阈值。

限流也常出现在踩坑清单中,详见 nginx-config-pitfalls 踩坑点十二「核心接口未做限流」及真实 IP 配置踩坑点十一。


五、规则层防护(原生 WAF)

危险方法拦截

if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 405; }

常见扫描路径拦截

location ~* /(\.git|\.svn|\.env|wp-admin|wp-login\.php|
               phpmyadmin|actuator|jenkins|manager/html) {
  return 403;
}

恶意 UA 拦截

map $http_user_agent $bad_ua {
  default 0;
  ~*(sqlmap|nmap|nikto|masscan|acunetix|dirbuster|gobuster) 1;
}
server { if ($bad_ua) { return 403; } }

低阶参数特征拦截(必须先用审计模式)

map $query_string $bad_args_audit {
  default 0;
  ~*(union\s+select|sleep\(|benchmark\(|
     information_schema|/etc/passwd|<script) 1;
}

# ⚠️ 先审计,不拦截
log_format waf_audit '$time_local ip=$realip_remote_addr '
  'uri="$uri" args="$args" hit=$bad_args_audit';
access_log /var/log/nginx/waf_audit.log waf_audit if=$bad_args_audit;

# 确认误伤可控后再升级为拦截
# if ($bad_args_audit) { return 403; }

误杀重灾区: 搜索接口、富文本接口、上传或模板编辑接口。


六、ModSecurity + CRS 接入

# 先「检测」后「拦截」
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;

# main.conf — 先检测
SecRuleEngine DetectionOnly
Include /etc/nginx/modsec/crs/crs-setup.conf
Include /etc/nginx/modsec/crs/rules/*.conf

# 误伤可控后改为
# SecRuleEngine On

精准启用: 只对高风险路径开启,不要全站一把梭。

location /api/ {
  modsecurity on;
  modsecurity_rules_file /etc/nginx/modsec/api-only.conf;
  proxy_pass http://api_backend;
}

七、黑白名单与可信来源

geo $office_allow {
  default 0;
  203.0.113.0/24  1;
  198.51.100.10/32 1;
}
map $office_allow $admin_guard {
  0 1;
  1 0;
}
location /admin/ {
  if ($admin_guard) { return 403; }
  proxy_pass http://admin_backend;
}

八、配置目录结构(可独立回滚)

/etc/nginx/
├── nginx.conf
├── conf.d/
│   ├── site.conf
│   └── security/
│       ├── realip.conf              # 真实地址恢复
│       ├── rate-limit-zones.conf    # 限流区定义
│       ├── waf-maps.conf            # WAF 规则 map
│       ├── allow-deny.conf          # 黑白名单
│       └── site-policy.conf         # 站点级应用策略
└── modsec/
    ├── main.conf
    └── crs/

每层独立回滚: 新 WAF 规则误伤时只回滚 waf-maps.conf,不影响真实 IP 和限流。


九、判断坐标系

现象 首看指标 更可能的问题层 第一动作
active connections 高,QPS 不高 stub_status, request_time 连接层 调连接限制/超时
某 URI QPS 高,连接数一般 URI TopN, IP TopN 请求层 limit_req 按接口
403/444 上升,URI 离散 UA 异常 access log, 规则命中日志 规则层 审计扫描特征和黑白名单
5xx 上升 + upstream_time 高 upstream 日志 上游已满 限流入口保护上游
所有来源像同一 IP $realip_remote_addr 地址恢复错误 先修 real IP

关联页面

页面 关联点
nginx-config-pitfalls 踩坑点十一(真实 IP)+ 踩坑点十二(限流)的安全配置上下文
nginx-502-504-connection-reset-guide 上游异常与入口拦截的区别判断
nginx-pre-launch-checklist 上线前检查(限流项与此文配套)
server-security-hardening-checklist 服务器安全加固总纲(Nginx 加固上下文)
rate-limiting-algorithms 接口限流 5 种算法详解(计数器/滑动窗口/令牌桶/漏桶/Redis+Lua)——限流的算法原理参考
nginx-realtime-push-guide SSE/WebSocket 推送 — WSS 安全配置参考
nginx-load-balancing-strategy-guide Nginx 负载均衡策略选择实战指南 — 加权轮询与 IP Hash 深度对比、混合策略最佳实践
nginx-log-analysis-monitoring-guide Nginx 日志分析与监控体系构建指南 — 自定义日志格式、性能分析技巧、GoAccess 可视化、
nginx-production-performance-optimization 生产级 Nginx 性能优化 — OS 内核/Worker 进程/HTTP I/O/Upstream
network-troubleshooting-order 防火墙/iptables 与 Nginx 安全联动