安全与治理 · 收录于 2026-08-29 · 适用 1 工具 ✓ 实测验证

短信接口被狂刷(短信费用飙升/接口被打垮,怎么限流止损)

已验证 2026-08-29短信接口被狂刷——nginx 层 IP 限流止损:limit_req_zone(rate=5r/s)+ location 内 limit_req burst=10 nodelay,超限返回 503。

快速修复

# 一键:nginx 层加 IP 限流(http 块加 zone,location 内启用;超限返回 503)
# http 块:limit_req_zone $binary_remote_addr zone=sms:10m rate=5r/s;
# location 内:limit_req zone=sms burst=10 nodelay;

burst = 突发桶容量,nodelay = 超限立即拒绝;默认拒绝 503,可 limit_req_status 429 改 429。

你会遇到什么

短信接口被脚本/恶意流量狂刷:短时间内大量请求、短信费用飙升、接口被打垮。泛化到任意业务接口就是:同一 IP/同一手机号高频请求、代理 IP 池轮换刷量、验证码接口被撞库。一次被刷就是真金白银损失。

本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。

为什么会这样

接口没有频率限制与黑名单:短信/验证码接口天然可被无限调用(无频次、无来源限制)。紧急止损手段(熔断/降级/黑名单/限流)缺失或配置无效——实测发现 limit_req 与 return 写在同一 location 时被短路,配置"看似有"实则无。

防护层手段实测状态
紧急止损测试模式/熔断、Nginx deny、全局限流✅ nginx deny 实测 403
Nginx 限流limit_req_zone + limit_req✅ 静态/反代形态实测生效(503)
业务层Redis 频次、布隆过滤器、设备指纹⏳ 本机无 redis/docker,未实测
监控复盘请求量基线 + 异常告警上线后长期动作

短信/验证码接口被刷的本质是「无状态接口 + 无频次约束」:接口本身不记调用来源与次数,攻击者可以无限调用(撞库/骚扰/刷量),而成本由你承担。防护手段的「配置无效」是独立陷阱:nginx 的 limit_req 与 return 写在同一 location 时,return 直接短路后续指令——配置「看似有」实则无,这是实测复现的坑。

确定性推论:先验证防护真的生效(实测:nginx deny 403、limit_req 503),不验证的配置等于没有;防护分三层——网络层(nginx deny/限流,可立即上)、业务层(Redis 频次/设备指纹,需依赖)、监控层(基线+告警,长期);紧急止损用测试模式/熔断最直接(先止血再补防护);判断路径:被刷先确认「防护是否真的返回预期状态码」,再谈策略。

一步步来

1. 紧急止损(黄金 30 分钟) — 必做

配置中心把短信接口切"测试模式"(返回成功但不真发)或直接熔断;Nginx 层封禁异常 IP(deny,实测 403);无效则临时关停短信功能保核心业务。

2. Nginx 频率限制(实测生效形态) — 必做

http 块定义 zone:

limit_req_zone $binary_remote_addr zone=sms:10m rate=5r/s;

location 内启用(反代/静态文件形态均实测生效):

limit_req zone=sms burst=10 nodelay;

3. 业务层防护 — 必做

手机号频次限制(Redis INCR+EXPIRE,过期自动重置);布隆过滤器快速过滤无效/风险手机号(千万级 12MB);设备指纹/行为风控;API 签名。(本机无 redis-server 与 docker daemon,未实测,如实标注。)

4. 监控复盘 — 必做

按 IP/手机号/设备统计请求量基线,异常自动告警;新风控规则灰度发布。

怎么确认修好了

压测断言(实测输出形态:限流 15 连发):

curl 连发 15 次
→ 1×200 + 14×503(rate=2r/s 静态文件形态)
→ 错误日志:limiting requests, excess: 0.974 by zone "min"

deny 127.0.0.1 后请求 → 403(日志 access forbidden by rule)。

其它环境的表现

环境说明
静态文件形态limit_req 实测生效:1×200 + 14×503
proxy_pass 反代形态生产形态实测生效:1×200 + 14×503
deny + return 同 location实测失效(return 短路 preaccess/access 阶段)
limit_req + return 同 location实测失效(连发全 200、日志无记录)——文章未写的坑
业务层Redis 令牌桶/布隆过滤器未实测(无 redis-server / docker daemon)

症状

短信接口被脚本/恶意流量狂刷:短时间内大量请求、短信费用飙升、接口被打垮;泛化到任意业务接口——同一 IP/同一手机号高频请求、代理 IP 池轮换刷量、验证码接口被撞库。

原因

接口没有频率限制与黑名单:短信/验证码接口天然可被无限调用(无频次、无来源限制),一次被刷就是真金白银损失;紧急止损手段(熔断/降级/黑名单/限流)缺失或配置无效(见验证证据:limit_req 与 return 同 location 时被短路,配置"看似有"实则无)。

解法

  1. 紧急止损(黄金 30 分钟):配置中心把短信接口切"测试模式"(返回成功但不真发)或直接熔断;Nginx 层封禁异常 IP(deny,实测 403);网关层开全局限流;无效则临时关停短信功能保核心业务。
  2. Nginx 频率限制(实测生效形态):
   limit_req_zone $binary_remote_addr zone=sms:10m rate=5r/s;   # http 块
   # location 内(反代/静态文件形态均实测生效,超限返回 503):
   limit_req zone=sms burst=10 nodelay;
  • burst = 突发桶容量,nodelay = 超限立即拒绝;默认拒绝状态码 503(可 limit_req_status 429 改 429)。
  • 实测坑(文章未写):limit_req/deny 与 return 写在同一个 location 里不生效——return 在 rewrite 阶段终止请求,跳过 preaccess/access 阶段;location = /api/sms/send { limit_req ...; return 200 "ok"; } 这类配置等于无限流。接口必须走静态文件/proxy_pass 反代形态,或把限流放 server 层。
  1. 业务层防护:手机号频次限制(Redis INCR+EXPIRE,过期自动重置);布隆过滤器快速过滤无效/风险手机号(千万级 12MB);设备指纹/行为风控;API 签名。本机无 redis-server 与 docker daemon,未实测(如实标注)。
  2. 监控复盘:按 IP/手机号/设备统计请求量基线,异常自动告警;新风控规则灰度发布。
验证证据
  • 本地实测(2026-08-29,nginx/1.28.3 nginx-light + python3,纯本地零网络):
  1. 对照:无限流接口 15 连发全 200。
  2. limit_req zone=min rate=2r/s + 静态文件:15 连发 = 1×200 + 14×503,错误日志记录 limiting requests, excess: 0.974 by zone "min"。
  3. limit_req rate=2r/s + proxy_pass 反代:15 连发 = 1×200 + 14×503(生产形态正常生效)。
  4. deny 127.0.0.1:请求 403,日志 access forbidden by rule。
  5. 坑:limit_req + return 200 同 location 连发全 200、日志无记录;deny + return 同样失效——return 短路 preaccess/access 阶段(第一版配置实测发现,修正后才有 2/3/4 的结果)。
  • Redis/Lua 令牌桶、布隆过滤器:未实测(本机无 redis-server;Docker daemon 未运行,镜像拉取受限)。
  • 实测复现日志(2026-08-29)

适用工具 (1)

本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。

nginx · 外部工具

来源与证据

收录 验证 ✓ 实测验证适用 1 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://www.cnblogs.com/zrui-xyu/p/22612063

← 安全与治理 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡