21 10 月 2026
本文由财富云计算提供,我们提供高防服务器与 CDN 防护服务,NAT 型无独立公网 IP 价格比独立 IP 省一半以上,Nginx 是源站防护的基石,配合我们的高防方案更稳。

一、Nginx 防护三层模型

请求到达
   │
   ▼
┌─────────────────────────────────────┐
│ 连接层 │ worker_connections、超时、    │ ← 防连接耗尽、慢速攻击
│        │ limit_conn、SYN 相关          │
├─────────────────────────────────────┤
│ 请求层 │ limit_req、请求大小限制、      │ ← 防 CC、刷接口、大包攻击
│        │ 方法/头过滤                   │
├─────────────────────────────────────┤
│ 行为层 │ UA/Referer 过滤、URI 特征、   │ ← 防扫描、爬虫、漏洞利用
│        │ 地域/IP 黑白名单              │
└─────────────────────────────────────┘

三层之外还有第四层兜底——fail2ban 看日志封 IP(见基础篇)。本文件聚焦前三层的生产级配置。

二、连接层配置(nginx.conf)

2.1 完整 events + http 基础配置

# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;              # 按 CPU 核数
worker_rlimit_nofile 65535;         # 文件描述符上限

events {
    use epoll;                      # Linux 用 epoll
    worker_connections 10240;       # 单 worker 连接数(总 = ×worker数)
    multi_accept on;                # 一次 accept 多个新连接(抗突发)
}

http {
    # ---- 连接层防护 ----
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 30s;          # 空闲连接回收(防慢速占用)
    keepalive_requests 100;         # 单连接最多请求数
    
    client_header_timeout 10s;      # 头超时(防 Slowloris)
    client_body_timeout 10s;        # body 超时(防 RUDY)
    send_timeout 10s;
    reset_timedout_connection on;   # 超时发 RST 快速释放
    
    client_body_buffer_size 16k;    # 请求体缓冲(防大 body 占内存)
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    client_max_body_size 10m;       # 全局 body 上限
    
    # ---- 隐藏版本信息(防针对性漏洞扫描)----
    server_tokens off;
    
    # ---- 日志格式:记录更多防护相关字段 ----
    log_format security '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" rt=$request_time '
                        'uct=$upstream_connect_time urt=$upstream_response_time';
    access_log /var/log/nginx/access.log security;
}

2.2 连接数限制(http 块定义 zone)

http {
    # 单 IP 连接数
    limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
    # 单 IP 请求速率
    limit_req_zone $binary_remote_addr zone=perip_req:10m rate=30r/s;
    # 全站总请求速率(防分布式 CC)
    limit_req_zone $server_name zone=global_req:10m rate=2000r/s;
}

三个 zone 配合:perip 防单点、global 防总量、conn 防连接占用。

三、请求层配置(server/location)

3.1 全局限流模板

server {
    listen 80;
    server_name z0w.cn;
    
    # 全站总速率(正常业务基线的 2 倍起调)
    limit_req zone=global_req burst=5000 nodelay;
    # 单 IP 速率
    limit_req zone=perip_req burst=50 nodelay;
    # 单 IP 连接数
    limit_conn perip_conn 30;
    
    limit_req_status 429;           # 限流返回 429(语义正确,别用 503)
    limit_conn_status 429;
    limit_req_log_level warn;
    
    location / {
        proxy_pass http://backend;
    }
}

3.2 接口分级(把「贵」的接口保护起来)

# 搜索接口:吃数据库,严格限
location ~ ^/api/(search|query) {
    limit_req zone=perip_req rate=5r/s burst=3 nodelay;
    limit_conn perip_conn 5;
    proxy_pass http://backend;
}

# 登录接口:防爆破
location = /login {
    limit_req zone=perip_req rate=10r/m burst=3;
    # 注意:登录防爆破核心在后端(失败次数锁定),Nginx 只是减速
    proxy_pass http://backend;
}

# 静态资源:放宽(CDN 缓存的对象,打到源站的少)
location ~* \.(jpg|jpeg|png|gif|css|js|woff2?)$ {
    expires 30d;
    access_log off;                 # 静态资源不记日志(省磁盘,也让攻击日志更干净)
}

3.3 请求方法过滤

# 只允许业务需要的方法,其他 405
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) {
    return 405;
}

TRACE/TRACK 方法有 XST 攻击风险,大多数站用不到,禁掉。

3.4 异常请求头过滤

# User-Agent 为空的(脚本小子特征,但注意 API 客户端也可能空)
if ($http_user_agent = "") {
    return 403;
}

# 已知扫描器 UA(示例,按日志里出现的补)
if ($http_user_agent ~* (sqlmap|nikto|nmap|masscan|dirbuster|gobuster|acunetix|nessus)) {
    return 403;
}

# 请求头超长(防缓冲区攻击尝试)
if ($http_content_length > 10485760) {
    return 413;
}

注意 if 的坑:Nginx 的 if 在 location 里行为诡异,只用在 return/rewrite 简单场景,复杂逻辑用 map 或 Lua(见下)。

四、行为层配置

4.1 UA 黑名单(map 实现,比 if 优雅)

http {
    map $http_user_agent $bad_bot {
        default 0;
        ~*sqlmap 1;
        ~*nikto 1;
        ~*nmap 1;
        ~*masscan 1;
        ~*dirbuster 1;
        ~*python-requests 1;         # 按需:会误伤正常 API 客户端,慎用
        ~*curl 1;                    # 慎用:健康检查常用 curl
        "" 1;                        # 空 UA
    }
    
    server {
        if ($bad_bot = 1) {
            return 403;
        }
    }
}

4.2 扫描路径识别( honeypot 思路)

# 敏感路径不存在 → 404,但记高级别日志给 fail2ban
location ~* (\.git|\.env|\.svn|wp-config|phpmyadmin|\.bak|/admin\.php$) {
    access_log /var/log/nginx/honeypot.log security;
    return 444;                     # 不解释,直接断连
}

为什么 444:对扫描器来说,「连接被断开」比 404 更没信息量;对你的日志来说,这些记录就是攻击者指纹(fail2ban 自动封)。

4.3 地域/IP 黑白名单

# 需要 geoip 模块(apt install libnginx-mod-http-geoip)
geo $limited_country {
    default no;
    # 按业务填:只服务国内就列出你的目标国家/地区,反之
}

server {
    if ($limited_country = yes) {
        return 403;
    }
}

地域限制的误杀:CDN 场景下 $remote_addr 是 CDN 节点 IP,地域全错——必须先 real_ip 还原(4.4)。

4.4 拿回真实 IP(CDN/高防场景必须)

http {
    # 只信任 CDN/高防的回源段
    set_real_ip_from 203.0.113.0/24;      # 换成你的 CDN/高防回源段
    set_real_ip_from 198.51.100.0/24;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
}

不配 real_ip 的后果:日志全是 CDN IP、限流限了个寂寞、地域限制全误伤、fail2ban 封的是 CDN 节点——防护体系整体失效。

五、进阶:OpenResty Lua(Nginx 做不到的)

Nginx 配置能做的有限,这些需求上 OpenResty + Lua:

  • 动态限流阈值(按接口、按用户等级、按时间段)
  • 请求体内容检查(POST 里的攻击 payload)
  • 复杂行为逻辑(滑动窗口、多维度关联)
  • 与 Redis 联动(全局封禁名单、验证码状态)
# OpenResty 示例:单 IP 双维度限流(本机 + Redis 全局)
location / {
    access_by_lua_block {
        local limiter = require "resty.limit.req"
        -- 具体实现见 OpenResty 篇
    }
    proxy_pass http://backend;
}

六、fail2ban 联动:日志变封禁

Nginx 记日志,fail2ban 看日志封 IP——自动化闭环:

# /etc/fail2ban/jail.d/nginx.local
[nginx-limit-req]
enabled = true
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 60
bantime = 600
filter = nginx-limit-req
# 匹配 "limiting requests" 日志

[nginx-honeypot]
enabled = true
logpath = /var/log/nginx/honeypot.log
maxretry = 2
findtime = 600
bantime = 86400
# 碰敏感路径 2 次就封一天
systemctl restart fail2ban
fail2ban-client status nginx-honeypot   # 看封禁情况

(fail2ban 完整配置见专题篇)

七、配置验证清单

配完 Nginx 防护,逐项验证:

□ nginx -t 通过,reload 无报错
□ 正常访问首页/接口/登录全部正常(没被自己的规则误杀)
□ 单 IP 高频请求 → 429(测:for i in $(seq 1 100); do curl -s -o /dev/null -w "%{http_code}\n" https://你的域名/; done | sort | uniq -c)
□ 慢速连接被快速断开(slowhttptest 自测)
□ 扫描路径返回 444 且进 honeypot.log
□ CDN 场景下日志显示真实用户 IP(不是 CDN 节点 IP)
□ 静态资源 expires 生效(响应头 Cache-Control)
□ server_tokens off(响应头无 nginx 版本号)

误杀检查最重要:上线前用自己的手机网络、不同浏览器全流程点一遍——Nginx 防护规则的最大风险不是防不住,是把用户挡在门外。

八、配置模板总览

# /etc/nginx/conf.d/security.conf —— 生产级防护模板
# 1. 真实 IP(CDN 场景)
set_real_ip_from 203.0.113.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

# 2. 限流 zone(放 http 块)
# limit_req_zone $binary_remote_addr zone=perip_req:10m rate=30r/s;
# limit_req_zone $server_name zone=global_req:10m rate=2000r/s;
# limit_conn_zone $binary_remote_addr zone=perip_conn:10m;

# 3. server 块引用(见 3.1)
# 4. UA 黑名单 map(见 4.1)
# 5. 敏感路径 444(见 4.2)

完整的 anti-CC + anti-scan 模板和逐行注释在基础篇和CC 变种篇,配合iptables 模板和OpenResty 篇构成源站防护全家桶。

九、小结

Nginx 防护的三层:连接层(超时收紧 + 连接限制,防慢速和连接耗尽)、请求层(分级限流 + 接口保护,防 CC 和精准打击)、行为层(UA/路径/地域过滤,防扫描和爬虫)。配 Nginx 防护的两条铁律:CDN 场景必须 real_ip 还原真实 IP(否则全套规则对着 CDN 节点空转),上线前必须全流程误杀测试(防护规则误杀正常用户的代价比被攻击还高)。Nginx 是源站的地基,大流量攻击还是得靠前面的高防/CDN——这就是纵深防御。


相关阅读:


本文由财富云计算整理,我们提供高防服务器、CDN 防护与 NAT 型云服务器,无独立公网 IP 机型价格比独立 IP 省一半以上,需要源站防护方案设计或高防产品的咨询。更多教程见端口速查表。
延伸阅读
  1. 高防误区与避坑清单:25 个坑+下单前必问 14 问+到货验货流程
  2. DNS 攻击防护专题:劫持、隧道、投毒、放大四类攻击与 DNSSEC
  3. 电商大促防攻击预案:T-14 到当天的分级响应与降级开关
  4. 源站真实 IP 隐藏完全指南:六大暴露面排查+NAT 型终极方案
  5. 日志分析找攻击源:Nginx 日志三维度分析法与证据固定
  6. 攻击应急响应手册:六阶段响应流程,从确认到复盘的照做清单
  7. iptables 抗 DDoS 配置模板:状态过滤+SYN 防护+防扫描+游戏服版
  8. OpenResty Lua 自研 WAF:动态限流+攻击特征检测+Redis 黑名单
更多阅读
  1. 上一篇:慢速攻击 Slowloris/RUDY 防护:超时收紧+连接限制+CDN 终结
  2. 下一篇:OpenResty Lua 自研 WAF:动态限流+攻击特征检测+Redis 黑名单
发表评论 6