Nginx限流防刷与CC攻击防护实战配置

 更新时间:2026年01月19日 10:52:05   作者:嘻哈baby  
本文介绍了Nginx在Web服务中的防护方案,包括限流基础、分场景限流、CC攻击防护、IP黑白名单、监控与告警以及压测验证,感兴趣的可以了解一下

做过Web服务的都知道,接口裸奔是找死。

不设防的后果:羊毛党刷爆优惠券、爬虫拖垮服务器、CC攻击搞瘫业务。

整理一下Nginx层面的防护方案,都是生产环境验证过的配置。

一、限流基础

Nginx有两个核心限流模块:

  • ngx_http_limit_req_module:限制请求速率
  • ngx_http_limit_conn_module:限制连接数

1.1 限制请求速率

http {
    # 定义限流区域
    # $binary_remote_addr:按客户端IP限流
    # zone=req_limit:10m:共享内存区域名和大小
    # rate=10r/s:每秒10个请求
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
    
    server {
        location /api/ {
            # 应用限流
            # burst=20:允许突发20个请求
            # nodelay:突发请求不延迟处理
            limit_req zone=req_limit burst=20 nodelay;
            
            proxy_pass http://backend;
        }
    }
}

参数解释:

  • rate=10r/s:平均每秒10个请求,即每100ms一个
  • burst=20:桶大小,允许突发20个请求
  • nodelay:突发请求立即处理,不排队等待

1.2 限制连接数

http {
    # 按IP限制连接数
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    server {
        location /download/ {
            # 每个IP最多10个连接
            limit_conn conn_limit 10;
            
            # 限制每个连接的速度
            limit_rate 1m;  # 1MB/s
        }
    }
}

适用场景:下载服务、视频流媒体。

二、分场景限流

2.1 登录接口防暴力破解

http {
    # 登录接口严格限流
    limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
    
    server {
        location /api/login {
            limit_req zone=login_limit burst=5 nodelay;
            
            # 超限返回429
            limit_req_status 429;
            
            proxy_pass http://backend;
        }
    }
}

每秒只允许1次登录请求,防止暴力破解。

2.2 短信验证码防刷

http {
    # 验证码接口更严格
    limit_req_zone $binary_remote_addr zone=sms_limit:10m rate=1r/m;
    
    server {
        location /api/sms/send {
            # 每分钟1次
            limit_req zone=sms_limit burst=3;
            
            proxy_pass http://backend;
        }
    }
}

2.3 搜索接口防爬虫

http {
    # 搜索接口中等限流
    limit_req_zone $binary_remote_addr zone=search_limit:10m rate=5r/s;
    
    server {
        location /api/search {
            limit_req zone=search_limit burst=10 nodelay;
            
            proxy_pass http://backend;
        }
    }
}

三、CC攻击防护

CC攻击就是用大量代理IP发请求,单IP限流不够用。

3.1 请求频率+并发连接双重限制

http {
    limit_req_zone $binary_remote_addr zone=cc_req:10m rate=30r/s;
    limit_conn_zone $binary_remote_addr zone=cc_conn:10m;
    
    server {
        # 请求频率限制
        limit_req zone=cc_req burst=50 nodelay;
        
        # 并发连接限制
        limit_conn cc_conn 50;
        
        # 超限状态码
        limit_req_status 503;
        limit_conn_status 503;
    }
}

3.2 基于User-Agent过滤

server {
    # 封禁空UA和常见爬虫UA
    if ($http_user_agent = "") {
        return 403;
    }
    
    if ($http_user_agent ~* "python|curl|wget|scrapy|httpclient") {
        return 403;
    }
    
    # 封禁特定UA
    if ($http_user_agent ~* "MJ12bot|AhrefsBot|SemrushBot") {
        return 403;
    }
}

3.3 基于Referer过滤

server {
    location /api/ {
        valid_referers none blocked server_names *.example.com;
        
        if ($invalid_referer) {
            return 403;
        }
    }
}

3.4 cookie验证

server {
    location / {
        # 检查是否有验证cookie
        if ($cookie_verified != "yes") {
            # 返回验证页面,通过JS设置cookie后重定向
            return 302 /verify.html;
        }
        
        proxy_pass http://backend;
    }
}

这个方法可以过滤掉不执行JS的简单爬虫。

四、IP黑白名单

4.1 黑名单

http {
    # 加载黑名单文件
    geo $blocked_ip {
        default 0;
        include /etc/nginx/blacklist.conf;
    }
    
    server {
        if ($blocked_ip) {
            return 403;
        }
    }
}

黑名单文件:

# /etc/nginx/blacklist.conf
1.2.3.4 1;
5.6.7.0/24 1;

4.2 白名单

http {
    geo $whitelist {
        default 0;
        10.0.0.0/8 1;      # 内网
        192.168.0.0/16 1;  # 内网
    }
    
    server {
        location /admin/ {
            if ($whitelist = 0) {
                return 403;
            }
            
            proxy_pass http://backend;
        }
    }
}

4.3 动态封禁

配合fail2ban实现自动封禁:

# /etc/fail2ban/filter.d/nginx-cc.conf
[Definition]
failregex = ^<HOST> .* "(GET|POST).* HTTP.*" (429|503)
ignoreregex =
# /etc/fail2ban/jail.d/nginx-cc.conf
[nginx-cc]
enabled = true
port = http,https
filter = nginx-cc
logpath = /var/log/nginx/access.log
maxretry = 100
findtime = 60
bantime = 3600

60秒内触发100次429/503就封禁1小时。

五、实战配置模板

综合以上方案的完整配置:

http {
    # 限流区域定义
    limit_req_zone $binary_remote_addr zone=global_limit:20m rate=50r/s;
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;
    limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    # 黑名单
    geo $blocked_ip {
        default 0;
        include /etc/nginx/blacklist.conf;
    }
    
    # 白名单
    geo $whitelist {
        default 0;
        10.0.0.0/8 1;
        192.168.0.0/16 1;
    }
    
    server {
        listen 80;
        server_name example.com;
        
        # 黑名单拦截
        if ($blocked_ip) {
            return 403;
        }
        
        # 空UA拦截
        if ($http_user_agent = "") {
            return 403;
        }
        
        # 全局限流
        limit_req zone=global_limit burst=100 nodelay;
        limit_conn conn_limit 100;
        
        # API接口限流
        location /api/ {
            limit_req zone=api_limit burst=30 nodelay;
            proxy_pass http://backend;
        }
        
        # 登录接口严格限流
        location /api/login {
            limit_req zone=login_limit burst=5 nodelay;
            limit_req_status 429;
            proxy_pass http://backend;
        }
        
        # 静态资源不限流
        location /static/ {
            expires 7d;
            add_header Cache-Control "public, immutable";
        }
        
        # 管理后台白名单
        location /admin/ {
            if ($whitelist = 0) {
                return 403;
            }
            proxy_pass http://backend;
        }
    }
}

六、监控与告警

光限流不够,还要能看到发生了什么。

6.1 日志格式

log_format detailed '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time '
                    '$limit_req_status';

access_log /var/log/nginx/access.log detailed;

6.2 实时统计

# 统计429状态码
tail -f /var/log/nginx/access.log | grep " 429 " | wc -l

# 按IP统计请求数
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

6.3 自定义限流日志

location /api/ {
    limit_req zone=api_limit burst=30 nodelay;
    
    # 限流日志
    limit_req_log_level warn;
}

被限流的请求会记录到error.log:

limiting requests, excess: 30.234 by zone "api_limit"

七、压测验证

配置完要验证效果:

# 用ab压测
ab -n 1000 -c 100 http://example.com/api/test

# 用wrk压测
wrk -t4 -c200 -d30s http://example.com/api/test

观察:

  • 正常请求能过
  • 超限请求返回429或503
  • 服务器资源没被打满

八、远程管理

我们有几个边缘节点部署了Nginx做CDN,分布在不同城市。之前更新配置很麻烦,现在用星空组网把所有节点组到一起,SSH直连更新配置很方便。

总结

Nginx防护策略:

攻击类型防护方案核心配置
单IP刷接口请求速率限制limit_req
下载带宽滥用连接数+速度限制limit_conn + limit_rate
暴力破解严格限流rate=1r/s
CC攻击多层防护限流+UA过滤+黑名单
爬虫UA+Referer过滤if判断

防护策略要分层:

  1. 第一层:IP黑名单
  2. 第二层:速率限制
  3. 第三层:行为判断
  4. 第四层:验证码(业务层)

别等被攻击了才想起来加防护。

到此这篇关于Nginx限流防刷与CC攻击防护实战配置的文章就介绍到这了,更多相关Nginx限流防刷与CC防护内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 编写Go程序对Nginx服务器进行性能测试的方法

    编写Go程序对Nginx服务器进行性能测试的方法

    这篇文章主要介绍了编写Go程序对Nginx服务器进行性能测试的方法,包括对其负载均衡和缓存等方面的测试,极力推荐!需要的朋友可以参考下
    2015-06-06
  • Nginx下WordPress链接(url伪静态)301永久重定向实现方法

    Nginx下WordPress链接(url伪静态)301永久重定向实现方法

    在几个blog程序中折腾的结果,导致url连续二次变化。这是第三次了。 nginx 通过rewrite 使用 permanent; 参数 成301永久url重定向
    2012-09-09
  • 配置nginx隐藏版本号的多种方法

    配置nginx隐藏版本号的多种方法

    在生产环境中,需要隐藏nginx等服务的版本信息,以免造成安全风险,下面小编给大家带来了两种方法,帮助大家学习配置nginx隐藏版本号的相关知识,需要的朋友可以参考下
    2022-01-01
  • Nginx limit 限制访问模块的方法

    Nginx limit 限制访问模块的方法

    本篇文章主要介绍了Nginx limit 限制访问模块的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • Nginx基础配置(main、events、http、server、location)

    Nginx基础配置(main、events、http、server、location)

    本文主要介绍了Nginx基础配置(main、events、http、server、location),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Nginx 启用 OCSP Stapling的配置

    Nginx 启用 OCSP Stapling的配置

    本篇文章主要介绍了Nginx 启用 OCSP Stapling的配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • Nginx结合keepalived实现双机热备方案

    Nginx结合keepalived实现双机热备方案

    Nginx难免遇见故障,可以使用使用keepalived来实现Nginx的高可用,本文主要介绍了Nginx结合keepalived实现双机热备方案,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • 详解nginx同一端口监听多个域名和同时监听http与https

    详解nginx同一端口监听多个域名和同时监听http与https

    这篇文章主要介绍了详解nginx同一端口监听多个域名和同时监听http与https的相关资料,需要的朋友可以参考下
    2017-05-05
  • nginx 流量控制以及访问控制的实现

    nginx 流量控制以及访问控制的实现

    这篇文章主要介绍了nginx 流量控制以及访问控制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Nginx下升级https的方法步骤

    Nginx下升级https的方法步骤

    这篇文章主要介绍了Nginx下升级https的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-06-06

最新评论