当前位置:首页 > 云谷精选

基于Nginx的防CC攻击配置教程:限流与黑白名单实战

admin2026年03月19日云谷精选24.35万
摘要:# 别让CC攻击拖垮你的网站:一个Nginx老手的实战配置手记 我前两天刚处理完一个客户的紧急工单,那场面,真够呛的。一个做电商促销的站点,活动页面突然就卡死了,后台一看,全是来自一堆陌生IP的、高频的、针对某个特定商品页的请求。服务器CPU直接飙满,数…

别让CC攻击拖垮你的网站:一个Nginx老手的实战配置手记

我前两天刚处理完一个客户的紧急工单,那场面,真够呛的。一个做电商促销的站点,活动页面突然就卡死了,后台一看,全是来自一堆陌生IP的、高频的、针对某个特定商品页的请求。服务器CPU直接飙满,数据库连接池耗尽,正常用户根本刷不出来。说白了,这就是典型的CC攻击(Challenge Collapsar),不搞垮你服务器,就专门恶心你,让你业务中断。

很多刚接触这行的朋友,一听说要防CC,第一反应就是“上高防”、“买WAF”。当然,有钱上高防IP、高防CDN肯定是省心,但说实话,对于很多中小项目、或者预算有限的团队来说,第一道真正靠谱的防线,往往就是你手头那台Nginx

今天咱不聊那些PPT上吹得天花乱坠的“全自动智能清洗”,就扎扎实实地,把我自己常用的、基于Nginx的防CC配置掰开揉碎了讲给你听。这方案不敢说能扛住国家级别的攻击,但对付市面上90%的瞎搞、爬虫乱刷、恶意竞争,真够用了。而且,配置就在你手里,效果立竿见影

核心就两板斧:限流与黑白名单

防CC,本质上是在和“频率”与“身份”作斗争。限流,管的是“频率”,甭管你是谁,每秒请求太多我就掐掉。黑白名单,管的是“身份”,是朋友就放行,是恶客就坚决拦在门外。这两招配合起来,效果1+1>2。

第一板斧:用limit_req模块给请求“上笼头”

Nginx自带的limit_req_zonelimit_req指令,是我们做限流最核心的工具。它的原理叫“漏桶算法”,你可以想象成在水龙头下面放个桶,水(请求)可以任意速率流进来,但只能以固定的速率流出去。超出的部分,要么排队等着(延迟处理),要么直接溢出去(拒绝)。

来,看配置。我们一般先在Nginx的http区块里,定义一个共享内存区来存放限流状态:

http {
    # 定义一个名为“perip”的限流规则,以客户端IP作为键值。
    # 分配10MB的内存空间来存储状态,平均速率限制为每秒10个请求(rate=10r/s)。
    limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

    # 再定义一个针对服务器全局的限流区,防止总请求数过高(可选)
    limit_req_zone $server_name zone=perserver:10m rate=100r/s;

    ... 其他http配置 ...
}

我解释一下几个关键点:

  • $binary_remote_addr:这是用客户端的IP地址。用二进制格式存,比字符串省空间。这是最常用、也最有效的维度,因为大多数CC攻击来自分散的IP。
  • zone=perip:10m:定义了一个叫“perip”的共享内存区,大小10MB。1MB大概能存1.6万个IP的状态,10MB对付一般情况绰绰有余了。
  • rate=10r/s:核心参数!意思是每个IP每秒最多只允许通过10个请求。这个数你得自己掂量,动态页面(像PHP、Node.js渲染的)可以设低点(比如5-10),静态资源(图片、CSS)可以设高点(比如50)。设太低可能误伤正常用户,太高又没防护效果。

定义好了规则,怎么用呢?在具体的serverlocation区块里加上:

server {
    location / {
        # 应用名为“perip”的限流规则
        # burst参数是“桶”的容量,允许突发超过rate的请求先排队,这里设5。
        # nodelay参数表示,如果请求数在burst范围内,则立即处理,无需排队等待。
        limit_req zone=perip burst=5 nodelay;

        # 如果需要,也可以应用全局限流
        # limit_req zone=perserver burst=20 nodelay;

        ... 你的代理配置或root目录 ...
    }

    # 对于静态文件,可以放宽限制或者干脆不限
    location ~* \.(jpg|jpeg|gif|png|css|js|ico)$ {
        # 静态资源,可以放宽到每秒50次,突发20个
        limit_req zone=perip burst=20 nodelay;
        expires 30d;
        access_log off; # 顺便关个日志,减轻磁盘压力
    }

    # 特别关键的登录或提交接口,可以限制得更死
    location /api/login {
        limit_req zone=perip burst=3 nodelay;
        ... 代理到后端 ...
    }
}

这里有个大坑我得提醒你burstnodelay的配合。如果只设burst=5,不设nodelay,那么超出的前5个请求会被放入队列延迟处理,用户会感觉变慢。加上nodelay,这5个请求会立刻被处理,但同时也立刻开始计算下一个请求的等待时间,攻击者依然能瞬间发出5个请求。所以,对于明确要防CC的路径,我的建议是:要么burst设很小(比如1-3)并加nodelay,追求绝对频率限制;要么针对某些接口干脆不用nodelay,让恶意请求去排队,拖慢攻击者效率。

第二板斧:黑白名单,把“熟人”和“恶客”分清

限流是“一刀切”,黑白名单就是“精准打击”。尤其在你已经通过日志分析出攻击IP特征的时候,这招特别管用。

黑名单:把捣蛋鬼关外面。

http {
    # 可以定义一个黑名单IP列表文件,方便管理
    include blacklist.conf;
}

# 在server区块里
server {
    location / {
        # 如果IP在黑名单,直接返回403
        if ($blacklisted_ip) {
            return 403;
        }
        ... 其他配置 ...
    }
}

blacklist.conf文件里可以这样写(使用geo模块):

geo $blacklisted_ip {
    default 0;
    # 把要封禁的IP或网段设为1
    123.123.123.123 1;
    124.124.124.0/24 1; # 封禁整个C段
}

更灵活的方式是结合map模块,动态一点:

map $remote_addr $is_badguy {
    default 0;
    "~*^(123\.123\.|124\.124\.)" 1; # 用正则匹配IP段
}
server {
    if ($is_badguy) {
        return 444; # 444是Nginx特有的,直接关闭连接,不返回任何内容,更省资源
    }
}

白名单:给自己人开绿灯。这个在维护后台、API接口时特别有用。

geo $is_trusted {
    default 0;
    192.168.1.0/24 1; # 公司内网
    你的家庭公网IP 1; # 在家办公
}

server {
    location /admin/ {
        if ($is_trusted != 1) {
            # 非白名单IP访问管理后台,直接拒绝
            return 403;
            # 或者更狠一点,重定向到一个迷惑性的错误页
            # rewrite ^ /404.html;
        }
        ... 代理到后端管理程序 ...
    }
}

白名单的优先级一定要高于限流规则!不然你自己可能都被自己的限流给挡在外面,那可就闹笑话了。通常顺序是:先判断黑白名单,再执行限流。

实战组合拳:一个真实场景的配置思路

假设你有一个博客,评论系统老是被人用脚本刷垃圾评论。你怎么弄?

  1. 定位攻击点:看日志,发现是/wp-comments-post.php这个接口被高频POST请求攻击。
  2. 施加精准限流:单独给这个location加上严格的限流。
    location ~ /wp-comments-post\.php$ {
        # 评论提交,每个IP每秒只能请求1次,不允许突发(burst=0)
        limit_req zone=perip burst=0 nodelay;
        # 同时,可以针对这个URI设置一个更小的全局并发限制
        limit_conn perip_comment 3; # 每个IP同时最多3个连接
        ... fastcgi配置 ...
    }
  3. 识别并封禁:分析一段时间日志,把那些频繁返回403、404的IP(可能是扫描器)或者评论内容有明显规律的IP段,加入黑名单。
  4. 保护正常用户:确保静态资源(主题图片、CSS)的location限流宽松,或者不做限流。

几个“踩过坑”才懂的提醒

  1. 别光盯着“平均速率”(rate):CC攻击往往是脉冲式的。burst参数就是用来应对这种突发的。设得太死板,一个正常用户多刷新几下页面可能就被拒了。
  2. 日志是你的眼睛:一定要把被限流拒绝的请求记录下来。在limit_req后面加上limit_req_status 503;(默认就是503),然后在access_log里就能看到哪些IP老返回503。这是你完善黑白名单最重要的依据。
  3. 动态IP和代理池是难题:现在的攻击很多用代理IP或者云主机,IP海量变化。纯IP限流和黑名单效果会打折扣。这时候,limit_req_zone的键值可以换,比如用$http_x_forwarded_for(如果前面有代理)的最后一段,或者结合$http_user_agent(虽然UA可伪造)来综合判断。更高级的可以上limit_req zone=perip rate=5r/s key=${binary_remote_addr}${http_user_agent}这种组合键(需要OpenResty或Lua模块支持)。
  4. “一刀切”可能误伤:公共WiFi(比如机场、咖啡馆)、学校/企业出口NAT,可能成千上万人用一个出口IP。你的限流如果太狠,会把所有正常用户都挡住。对于这种,白名单机制或者针对特定URL放宽限制就很重要。
  5. 测试!测试!测试!:配置改完,千万别直接在生产环境重启Nginx。先用nginx -t测试语法。有条件的话,在测试环境用abwrk或者jmeter模拟一下并发请求,看看效果和日志是否符合预期。

说到底,Nginx的防CC配置就像给你的网站大门加装了一套“智能门禁+流量阀门”。它不贵,也不花哨,但足够有效。在考虑那些昂贵的高防方案之前,先把自家门口的这块阵地经营好,往往能解决大部分头疼的问题。

安全这事儿,从来就没有一劳永逸。攻击手段在变,你的策略也得跟着调整。多看看日志,多分析分析异常流量,这套配置用熟了,你对自己网站的抗压能力心里自然就有底了。

行了,配置大概就这些,细节还得你自己根据业务慢慢调。有什么坑或者更好的招,咱们评论区接着聊。

扫描二维码推送至手机访问。

版权声明:本文由www.ysyg.cn发布,如需转载请注明出处。

本文链接:http://www.ysyg.cn:80/?id=783

“基于Nginx的防CC攻击配置教程:限流与黑白名单实战” 的相关文章

详解如何通过高防 CDN 日志定位攻击源 IP 及其所属僵尸网络特征

# 高防CDN日志里,藏着攻击者的“身份证” 前两天,一个做电商的朋友半夜给我打电话,语气都快急哭了:“流量又炸了,后台卡得一笔,高防CDN那边显示是‘已防护’,可我这业务还是半瘫。钱没少花,可攻击到底从哪来的?我总不能一直蒙在鼓里吧?” 这话我听着太…

详解高防 CDN 故障时的回源切换逻辑与源站防火墙的联动配合

# 高防CDN挂了怎么办?聊聊回源切换那些“不能说的秘密” 前两天,有个做电商的朋友半夜给我打电话,声音都抖了:“我们高防CDN的节点好像出问题了,用户访问卡成PPT,但后台显示攻击流量才几十G——这防护是纸糊的吗?” 我让他把源站防火墙的日志拉出来一…

分析自建高防 CDN 系统的资源隔离技术:防止单客户被攻击影响全网

# 自建高防CDN,别让一个客户“炸”了你的整个网络 前两天跟一个做游戏的朋友聊天,他愁得不行。他们公司自己搭了一套高防CDN,本来想着省钱又可控,结果上个月出事了——平台里一个电商客户被DDoS打瘫了,流量直接冲垮了共享的清洗节点,导致他家的游戏也跟着…

详解自建高防 CDN 的黑名单库实时分发机制:一处封禁全网同步

# 详解自建高防 CDN 的黑名单库实时分发机制:一处封禁全网同步 ˃ 一个IP在杭州节点被识别为攻击源,几秒钟后,这个IP在上海、北京、广州的所有节点上同时被封禁——这种全网秒级同步,不是魔法,而是自建高防CDN里最核心的“黑名单库实时分发机制”在起作…

详解自建高防 CDN 的流量调度算法:根据各节点实时带宽自动分发

# 别再瞎配了!自建高防CDN,流量调度才是真“命门” 你猜怎么着?我最近跟几个自己折腾高防CDN的哥们聊,发现一个挺有意思的事儿。 他们服务器买的是顶配,BGP线路拉了好几条,DDoS防护策略也调得贼细。结果呢?真遇上流量高峰或者攻击突袭,网站该卡还…

解析自建高防 CDN 的多级清洗逻辑:集成开源 WAF 与黑白名单系统

# 自建高防CDN,别光听概念,先看看你的“多级清洗”是不是摆设 我最近帮一个做电商的朋友看他们的防护配置,好家伙,后台界面花里胡哨,什么“智能清洗”、“多层过滤”的按钮一大堆。结果一问,真遇到一波CC攻击,流量是拦下来不少,可自家正常用户也卡得进不来,…