独立站防CC攻击,Nginx限流
如果你的独立站经常出现服务器 CPU 飙高、数据库连接数爆满,或者某个接口被频繁请求刷爆,那很可能是被 CC 攻击盯上了。
CC 攻击的核心就是不断向动态接口发送大量真实请求,让服务器忙于处理而无法响应正常访客。
其中 /wp-json 和 checkout 这两个接口最容易被利用,前者是 WordPress 的 REST API 入口,后者是下单结算页面,两者都是高消耗接口。
通过 Nginx 的 limit_req 模块对它们做限流,可以在不改动业务代码的情况下快速拦截异常流量,本文就把完整配置步骤和避坑方法讲清楚。
为什么先限流这两个接口
/wp-json 接口常用于登录、
查询文章、
上传图片等操作,
攻击者可以批量调用它来生成大量数据库查询。checkout 接口则直接触发订单创建、
库存扣减、
支付回调等重量级逻辑,
一旦被并发刷入,
很可能导致数据库锁死甚至服务崩溃。
给这两个接口单独限流,但不要限制整个站点,是为了避免误伤正常访客浏览静态页面。
正确的思路是:让动态接口承受能力可控,让静态资源保持畅通。
配置前的准备工作
在动手之前,先确认两件事:
- 查看 Nginx 版本,保证支持
limit_req模块(一般 1.18 以上都支持):
nginx -v
- 找到当前站点的 Nginx 配置文件。如果你用的是宝塔面板,路径通常在
/www/server/panel/vhost/nginx/你的站点.conf;如果是源码安装,一般在/usr/local/nginx/conf/nginx.conf或者/etc/nginx/nginx.conf。
操作前一定先备份原配置:
cp /www/server/panel/vhost/nginx/你的站点.conf /www/server/panel/vhost/nginx/你的站点.conf.bak
在 Nginx 中配置接口限流
第一步:在 http 块定义限流规则
打开 Nginx 主配置,找到 http { ... } 块,在最外层加上请求速率限制配置:
http {
# 每个 IP 每秒允许 1 个请求,突发 5 个后开始延迟或拒绝
limit_req_zone $binary_remote_addr zone=wpjson_limit:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=checkout_limit:10m rate=2r/s;
# 当超过限流时,返回 503 而不是默认的 503?其实默认就是 503,这里可自定义
limit_req_status 503;
}
这里 $binary_remote_addr 表示用访客 IP 作为 key,10m 是共享内存大小,rate=1r/s 表示平均每秒只允许 1 个请求。
你可以根据站点实际流量调整,建议先从 1r/s 开始,不要一开始就设得太低,否则会把正常用户也挡在外面。
第二步:在 server 块或 location 中启用限流
在站点配置的 server { ... } 中,针对接口路径单独写 location:
server {
# 限制 /wp-json 接口
location ^~ /wp-json {
limit_req zone=wpjson_limit burst=5 nodelay;
limit_req_log_level error;
proxy_pass http://你的后端地址; # 如果用了反代,换成实际地址
}
# 限制 checkout 相关接口
location ^~ /checkout {
limit_req zone=checkout_limit burst=8 nodelay;
limit_req_log_level error;
proxy_pass http://你的后端地址;
}
# 其余请求走正常处理逻辑
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
注意 ^~ 表示优先匹配这些前缀,
避免被普通 location / 抢先。burst=5 表示允许瞬间多出 5 个请求排队,
超过后直接拒绝。nodelay 表示排队时不延迟,
如果不想丢弃太多请求可以不加 nodelay,
但这样会导致请求排队变慢。
第三步:重新加载 Nginx 配置
修改完成后,先检查配置语法:
nginx -t
确认没问题后重新加载:
nginx -s reload
如果是宝塔面板,也可以直接在网站设置中点击“重载配置”,不过建议先在命令行执行 nginx -t 检查。
避坑和常见问题
- 不要限制所有 /wp-json 请求:如果你用 WooCommerce,很多插件会通过
/wp-json/wc/*正常通信。把速率设得太低会导致后台页面加载缓慢、插件同步失败。建议先观察一天正常流量,再选择合理的rate。 - 白名单问题:如果发现自己的 IP 也被限流,可以在
location中加allow和deny规则,例如:
location ^~ /wp-json {
allow 你的IP;
deny all;
limit_req zone=wpjson_limit burst=5 nodelay;
}
- 503 报错太频繁:默认超限后返回 503,但很多爬虫和攻击者会无视 503 继续请求。建议改成 444 直接断开连接,减少资源消耗:
limit_req_status 444;
- Nginx 配置不生效:检查是否在
http块定义了limit_req_zone,并且location中引用的 zone 名称完全一致。如果用了不同文件,记得确保主配置include了该文件。
验证限流是否生效
配置完成后,使用 curl 连续请求受保护的接口,观察返回状态码:
for i in $(seq 1 20); do curl -o /dev/null -s -w "%{http_code}\n" http://你的域名/wp-json/; done
正常情况应该看到前几个请求返回 200,后续请求开始出现 503 或 444。
如果你使用的是 444,curl 会显示 000 或报错,同样说明连接被服务端主动断开。
同时查看 Nginx 错误日志,确认限流记录:
tail -f /var/log/nginx/error.log
日志中会出现类似 limiting requests, excess: ... by zone "wpjson_limit" 的提示,说明限流已经开始生效。
完成以上配置后,你的独立站就已经具备针对 /wp-json 和 checkout 接口的基础抗 CC 能力。
之后如果再遇到异常流量,可以结合 CDN 防护、WAF 规则和 Redis 缓存进一步加固。
不要指望一次配置免疫所有攻击,限流只是给服务器争取缓冲时间,重点还是观察日志、持续调整参数。