网站被CC攻击?Nginx限流配置实战

网站被CC攻击?Nginx限流配置实战

你有没有遇到过这种怪事:服务器CPU突然飙到100%,带宽没跑满,但网站打不开了。你查了日志,发现同一秒内有几百个请求刷同一个页面。不是DDoS(那种会把你带宽打爆),而是CC攻击——用大量看似正常的请求,耗尽你的应用资源。你的CPU被PHP占满,数据库连接数爆了,但防火墙没报警,因为每个请求看起来都像真人。

这就是CC攻击的狡猾之处。它不拼流量,拼的是你服务器的处理能力。而对付它最直接的手段,就是在Nginx层面做限流。今天教你配置。


先看一个场景

一个做在线教育的朋友,有天下午网站突然挂了。上去一看,CPU 100%,全是PHP-FPM进程。

查访问日志,发现同一个IP每秒请求200多次同一个搜索接口。这个接口本身消耗就大,每秒200次直接打爆。他没装任何限流措施,攻击者用一台小破电脑就把他整站搞瘫痪了。

后来他在Nginx里加了两行限流配置,类似的攻击再来时,服务器稳如泰山,只是攻击者的请求被直接拒绝了。


限流是什么?——给每个IP设定“访问速度上限”

Nginx限流的核心是限制每个IP在单位时间内的请求次数。比如,限制每个IP每秒最多只能发10个请求。超过的部分,你可以选择拒绝(返回503),或者排队慢慢处理。

Nginx实现限流主要靠两个模块:

  • limit_req_zone:限制请求频率(每秒/每分钟多少个请求)
  • limit_conn_zone:限制并发连接数(同一时刻多少个连接)

CC攻击通常用高频请求打你,所以limit_req更对症。


配置实战

第一步:定义限流规则

nginx.confhttp块里添加:

nginx

http {
    # 定义限流规则
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
}

参数说明:

  • $binary_remote_addr:按客户端IP限流
  • zone=mylimit:10m:分配10MB共享内存,用于存储IP状态
  • rate=10r/s:限制每个IP每秒最多10个请求

第二步:应用限流

在需要保护的location块里加上:

nginx

location / {
    limit_req zone=mylimit burst=20 nodelay;
    # 其他配置...
}

参数说明:

  • zone=mylimit:引用上面定义的规则
  • burst=20:允许突发20个请求排队,超过的部分直接拒绝
  • nodelay:排队中的请求不延迟处理,立即处理但计入burst限额

效果:正常情况下,用户一秒发10个请求(比如疯狂点按钮),前10个正常处理,后10个排队(如果加了burst),再多的直接返回503。

反常识点burst不是越大越好。给攻击者留了更多空间。建议默认10-20,特殊情况单独调整。

第三步:返回友好提示

被限流的请求默认返回503。可以自定义错误页面:

nginx

limit_req zone=mylimit burst=20 nodelay;
limit_req_status 429;

429 Too Many Requests是比503更符合语义的状态码。然后在server块里定义错误页:

nginx

error_page 429 /429.html;
location = /429.html {
    root /usr/share/nginx/html;
}

限流策略分级

不同接口的限流阈值应该不同:

接口类型示例建议限流原因
静态文件(CSS/JS/图片)/static/*不限流或高阈值(100r/s)消耗小,对服务器压力低
普通页面/article/*30-50r/s有缓存,相对轻量
搜索接口/search5-10r/s查询数据库,消耗大
登录接口/login3-5r/s防暴力破解,低阈值
API接口/api/*根据业务定需评估正常峰值

配置示例:

nginx

# 搜索接口严格限流
location /search {
    limit_req zone=mylimit burst=10 nodelay;
    limit_req_status 429;
    proxy_pass http://backend;
}

# 静态文件不限流
location ~* \.(css|js|jpg|png)$ {
    expires 30d;
    # 不应用限流
}

进阶:白名单与黑名单

白名单:给搜索引擎、合作伙伴的IP放行

nginx

geo $limit {
    default 1;
    192.168.1.0/24 0;  # 内网不限流
    1.2.3.4 0;          # 合作方IP不限流
}

map $limit $limit_key {
    1 $binary_remote_addr;
    0 "";
}

limit_req_zone $limit_key zone=mylimit:10m rate=10r/s;

黑名单:手动封掉恶意IP

直接在server块里用deny

nginx

location / {
    deny 123.45.67.89;
    deny 98.76.54.32;
}

或者用include引用黑名单文件:include /etc/nginx/blacklist.conf;


限流效果测试

配置完成后,用ab(Apache Bench)测试一下:

bash

# 模拟100个请求,并发10个
ab -n 100 -c 10 http://你的域名/

观察返回结果。如果有限流,会看到一部分请求返回429。再查看Nginx日志,确认限流生效。


一个真实案例

一个WordPress新闻站,被CC攻击打搜索接口。攻击者用肉鸡轮换IP,每个IP频率不高但总量大,IP分散很难封。他们在Nginx里对/search接口设置了rate=5r/s。攻击流量一来,大部分请求直接在Nginx层被挡掉,后端PHP-FPM压力骤降。服务器从CPU 100%恢复到正常水平,网站恢复正常访问。

攻击持续了几天,但网站再也没挂过。运维说:“Nginx挡了99%的恶意请求,我们只需要偶尔看一眼日志。”


最后一句

CC攻击不是大网站的专利。小网站更容易被打,因为攻击成本低,你的服务器扛不住。Nginx限流是性价比最高的防御手段。不需要装额外软件,不需要改代码,几行配置就能让你的服务器在攻击中活下来。

限流不是让你永远不怕打,而是让你被打的时候,还有机会喘口气,还有时间去看日志、封IP、调策略。

去检查一下你的Nginx配置,该加限流的地方加上。真要被打的时候,你会感谢今天这几行配置。

知识库

超实用!Linux服务器常用命令速查手册

2026-5-12 15:19:28

实操指南知识库

裸金属服务器 vs 虚拟化服务器:哪种架构更适合企业 IT?

2025-1-21 12:21:09

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧