> For the complete documentation index, see [llms.txt](https://www.axisnow.io/zh/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.axisnow.io/zh/docs/edge/policies/rate-limiting/use-cases.md).

# 防护场景

速率控制的典型防护场景与可直接套用的规则参数

按攻击面整理的几组规则，每组给出完整参数和这样配的理由，也是我们推荐的做法。阈值都是起步值，不是推荐值：每个站点的正常流量差异很大，请先用**观察**动作跑一两天，对照[洞察与日志](/zh/docs/edge/policies/rate-limiting/insight.md)里的**观察请求**和[配置项 › 限速阈值](/zh/docs/edge/policies/rate-limiting/configuration.md#threshold)的参考图再切成阻断或封禁。各字段的含义见[配置项](/zh/docs/edge/policies/rate-limiting/configuration.md)。

## API 防 CC 兜底 <a href="#api-flood" id="api-flood"></a>

**攻击面**：对公开 API 的高频请求。不管来源是脚本、失控的客户端重试还是分布式刷接口，单看每个请求都合法，只有频率不正常。这条规则不针对任何具体接口，是整组规则里最后的兜底。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>请求 URI 路径 开头为 <code>/api/</code>（没有统一前缀时选「任意」，并按下文「页面与静态资源」排除静态文件）</td></tr><tr><td>计数 Key</td><td>常用组合「客户端 IP 地址」</td></tr><tr><td>响应计数条件</td><td>关闭</td></tr><tr><td>限速阈值</td><td>10 秒内不超过 500 请求</td></tr><tr><td>限速动作</td><td>先「观察」；确认误伤面后改「阻断」，响应状态码 429</td></tr><tr><td>优先级</td><td>最后 1 个</td></tr></tbody></table>

**为什么只按 IP、阈值放宽**：兜底算的是一个来源的总量，不分路径，洪水摊到多个接口上也跑不掉；按 IP + 路径计数反而会漏掉这种分散的刷法。代价是同一个出口后面所有客户端的合法调用都在这个计数器里，阈值必须高于单个 IP 的正常峰值，先观察，按看到的最大值放几倍。针对单个接口的精细限制交给前面按密钥、按 IP + 路径的规则，这条只拦总量明显失常的来源。

**注意**：

* 阈值以内的请求照常放行，只有突破阈值的 Key 会在接下来的 N 秒内被拒绝，所以这条规则对正常客户端是透明的；被拒绝的 API 客户端会收到 429 Too Many Requests 和 `X-RateLimit-*` 响应头，见[工作原理 › 响应头](/zh/docs/edge/policies/rate-limiting/how-it-works.md#response-headers)。
* 命中缓存的请求同样被计数，接口如果开了缓存，阈值要按缓存前的请求量估，见[工作原理 › 一次请求经历什么](/zh/docs/edge/policies/rate-limiting/how-it-works.md#request-flow)。
* 计数按边缘节点独立，攻击流量分散到多个节点时，总放行量约是阈值乘以节点数，见[工作原理 › 计数的作用域](/zh/docs/edge/policies/rate-limiting/how-it-works.md#scope)。

## 匿名写接口 <a href="#anonymous-write" id="anonymous-write"></a>

**攻击面**：登录、注册、发送验证码、找回密码、提交评论——这些接口在用户还没有身份时就必须开放，又每次都触发真实开销（查库、发短信、写数据），是撞库、短信轰炸和垃圾内容的入口。正常用户在这些接口上的频率极低：一分钟内登录十次的真人几乎不存在。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>请求 URI 路径 在以下各项之中 <code>/api/login</code>、<code>/api/register</code>、<code>/api/sms/send</code>，并且 HTTP 请求方法 在以下各项之中 <code>POST</code></td></tr><tr><td>计数 Key</td><td>客户端 IP 地址</td></tr><tr><td>响应计数条件</td><td>关闭</td></tr><tr><td>限速阈值</td><td>60 秒内不超过 10 请求</td></tr><tr><td>限速动作</td><td>阻断，响应状态码 429</td></tr><tr><td>优先级</td><td>第 1 个</td></tr></tbody></table>

这条规则放在最前面，比 API 兜底规则严格一个数量级。两条规则独立计数：登录接口的请求既进这条规则的计数器，也进兜底规则的计数器，哪条先超限哪条生效。

**进阶一**：只数失败。开启响应计数条件，设为「响应状态码 在以下各项之中 `401`、`403`」，阈值收紧到 60 秒内不超过 5 请求。这样计数的是“密码错误”的次数而不是请求次数：正常用户偶尔输错一两次不受影响，撞库脚本的每一次尝试都在累加。前提是您的登录接口对失败返回 401 或 403 而不是 200 加错误码；如果是后者，可以让后端在失败响应上加一个自定义响应头，用「响应头 存在」做条件。

**进阶二**：按账号而不是按 IP。撞库脚本换 IP 很便宜，但它要试的账号是固定的。把计数 Key 换成「POST 表单」并填入账号字段名（例如 `username`），同一个账号无论从多少个 IP 来，都在同一个计数器里。发送验证码接口同理，按手机号字段计数。两点限制：这个维度只解析 `application/x-www-form-urlencoded` 的请求体，`multipart/form-data` 和 JSON 请求体都取不到值；取不到值的请求全部落进同一个空值计数器（见[工作原理 › 计数 Key](/zh/docs/edge/policies/rate-limiting/how-it-works.md#counting-key)），所以按账号计数的规则要和上面按 IP 的规则同时存在，而不是替代它。

**不建议用挑战**：这些接口几乎都是前端用 XHR 或 fetch 调用的，挑战只对浏览器页面导航请求有意义，见[工作原理 › 四种动作](/zh/docs/edge/policies/rate-limiting/how-it-works.md#actions)。

## 登录用户的高频操作 <a href="#authenticated-actions" id="authenticated-actions"></a>

**攻击面**：登录之后的写操作——发帖、下单、改资料、导出、批量删除。账号是真的，凭证是真的，攻击者（或失控的脚本）拿着它反复执行同一个操作。按 IP 计数在这里会误伤：同一个办公室出口后面可能有几十个正常登录的用户。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>请求 URI 路径 开头为 <code>/api/orders</code>，并且 HTTP 请求方法 在以下各项之中 <code>POST</code>、<code>DELETE</code></td></tr><tr><td>计数 Key</td><td>常用组合「会话 Cookie + 请求 URI 路径」，Cookie 名称填您的登录态 Cookie（例如 <code>session_id</code>）</td></tr><tr><td>响应计数条件</td><td>关闭</td></tr><tr><td>限速阈值</td><td>60 秒内不超过 20 请求</td></tr><tr><td>限速动作</td><td>阻断，响应状态码 429</td></tr><tr><td>优先级</td><td>匿名写接口之后</td></tr></tbody></table>

**为什么按会话 Cookie 计数**：登录态 Cookie 一个账号一个值，共享出口后面的用户互不影响；加上请求 URI 路径，是让“一分钟下 20 单”和“一分钟改 20 次资料”各算各的。没带这个 Cookie 的请求会落进同一个空值计数器，所以条件里要么限定只对带 Cookie 的请求生效（「匹配指定 Cookie 值 `session_id` 存在」），要么让前面的匿名写接口规则兜住它们。

**递进**：对同一组接口可以配两条阈值不同、动作不同的规则——阈值低的一条用**观察**或**挑战**（页面导航类操作），阈值高的一条用**阻断**。两条各自计数，低阈值的先触发，正常用户偶尔手快只会被观察到或验证一次，持续刷的脚本才会撞到阻断。

## 开放 API 调用方配额 <a href="#api-quota" id="api-quota"></a>

**攻击面**：面向第三方开发者的开放 API。威胁不一定是攻击，更多是某个调用方的失控重试或超额使用拖垮所有人；而调用方通常走云函数或 NAT 出口，只按 IP 分不开不同的客户，所以在按 IP 兜底之外再按 API 密钥计数。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>请求 URI 路径 开头为 <code>/v1/</code>，并且 请求头 <code>authorization</code> 存在</td></tr><tr><td>计数 Key</td><td>常用组合「API 密钥」，请求头名称填 <code>authorization</code>（或您的 <code>x-api-key</code>）</td></tr><tr><td>响应计数条件</td><td>关闭</td></tr><tr><td>限速阈值</td><td>60 秒内不超过 600 请求</td></tr><tr><td>限速动作</td><td>阻断，响应状态码 429；用「上传内容」上传一个 JSON 文件作为响应体，便于调用方程序化处理</td></tr><tr><td>优先级</td><td>最后 1 个</td></tr></tbody></table>

**配套规则一**：没带密钥的请求。新建一条规则，条件为「请求头 `authorization` 不存在」，计数 Key 用客户端 IP 地址，阈值收紧到 60 秒内不超过 20 请求，优先级第 1 个。没有这条规则，所有没带密钥的请求会落进上一条规则的同一个空值计数器。

**配套规则二**：昂贵接口单独限。导出、报表、批量查询这类接口单次开销大，新建一条规则，条件为「请求 URI 路径 开头为 `/v1/export`」并且「请求头 `authorization` 存在」，计数 Key 用常用组合**API 密钥 + 请求 URI 路径**，阈值 60 秒内不超过 10 请求，优先级放在总配额之前。同一个密钥在昂贵接口上先触发这条，其它接口仍按总配额计。

**注意**：计数 Key 取请求头的完整值，`Bearer` 前缀和令牌一起参与计数，同一个令牌必须每次以同一种写法发送。请在接口文档里告诉调用方读 `X-RateLimit-Reset`（单位秒）作为最长退避时间，响应的 `Content-Type` 固定为 `text/html`，见[配置项 › 阻断](/zh/docs/edge/policies/rate-limiting/configuration.md#action-block)。

## 扫描器与随机 URL <a href="#scanners" id="scanners"></a>

**攻击面**：漏洞扫描器、目录爆破和随机 URL 攻击。它们的共同特征不是请求多，而是响应里 404 Not Found 多——正常用户几乎不会在一分钟内撞上几十个不存在的页面。随机 URL 还会穿透缓存，每个请求都回源。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>任意</td></tr><tr><td>计数 Key</td><td>客户端 IP 地址</td></tr><tr><td>响应计数条件</td><td>开启，响应状态码 在以下各项之中 <code>404</code></td></tr><tr><td>限速阈值</td><td>60 秒内不超过 30 请求</td></tr><tr><td>限速动作</td><td>IP 封禁，封禁时长 600 秒</td></tr><tr><td>优先级</td><td>第 1 个</td></tr></tbody></table>

**为什么用 IP 封禁**：扫描器的请求对业务没有任何价值，而且会持续很久；IP 封禁一旦触发，封禁时长内该 IP 的请求不再进入处理，开销最低。已验证的搜索引擎爬虫即使撞上大量失效链接也不会被封禁（IP 封禁对已验证 Bot 自动豁免），不必为它们单独排除。

**替代动作**：如果不想封整个 IP，用阻断并选择**断开连接**，不返回任何页面内容；代价是误拦截时客户端也拿不到 Request ID，排查要靠日志。

**注意**：

* 阈值由站点自己的 404 率决定。前端路由的单页应用通常对任意路径返回 200，404 很少，30 可以更低；缺少 favicon 或大量失效外链的站点，先观察一天再定。
* 触发前只有 404 参与计数，正常浏览不会推高计数，这条规则对真实用户的影响接近零；但一旦触发，该 IP 的全部请求都会被封禁 600 秒，所以阈值宁可先放宽。

## 网站页面超速挑战 <a href="#page-challenge" id="page-challenge"></a>

**攻击面**：面向真人的页面被脚本高频抓取或刷接口。对面有真人，所以动作用挑战而不是阻断或封禁：超速的客户端做一次人机验证，真人几秒钟通过、有效期内不再被打扰，脚本过不去，反复触发又不完成验证的 IP 被自动封禁。这条规则不依赖通用访问控制，是没有配访问控制的站点的第一道闸。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>请求 Host 在以下各项之中 <code>www.example.com</code>，并且 文件后缀 不在以下各项之中 <code>js</code>、<code>css</code>、<code>png</code>、<code>jpg</code>、<code>gif</code>、<code>svg</code>、<code>ico</code>、<code>woff</code>、<code>woff2</code></td></tr><tr><td>计数 Key</td><td>会话标识</td></tr><tr><td>响应计数条件</td><td>关闭</td></tr><tr><td>限速阈值</td><td>10 秒内不超过 60 请求</td></tr><tr><td>限速动作</td><td>挑战，AxisNow 挑战；通过有效期和自动封禁保持默认</td></tr><tr><td>优先级</td><td>最后 1 个</td></tr></tbody></table>

**为什么排除静态资源**：一个页面会并发拉几十个 js、css 和图片，不排除的话计数被资源请求撑满；静态资源也不能被挑战，浏览器拿到验证页只会加载失败。

**为什么按会话标识计数**：它是 AxisNow 为每个浏览器下发的跟踪 Cookie，同一个公共出口后面的不同浏览器各自计数，不依赖站点自己的登录态；没带时自动回退为客户端 IP。

**为什么放最后**：持有有效通过凭证的客户端超限时直接放行，并结束这个请求在速率控制里的评估；这条规则放在最后，前面的兜底规则才看得到这些请求。

**注意**：

* 页面里的 XHR 调用也在这条规则里，超限时拿到的是验证页，接口会报错，直到用户下一次页面导航通过验证。页面内接口调用很多的站点，在条件里再加一行「请求头 `accept` 包含字符 `text/html`」把规则收窄到页面导航。
* 阈值按站点自己的浏览节奏定：10 秒 60 次相当于一个浏览器 10 秒内打开五六个页面，有轮询或无限滚动的站点要放宽，先用观察跑一天。
* 挑战动作的类型、通过有效期和自动封禁的可选范围见[配置项 › 挑战](/zh/docs/edge/policies/rate-limiting/configuration.md#action-challenge)。

## 穿过挑战的自动化浏览器 <a href="#passed-challenge" id="passed-challenge"></a>

**攻击面**：[通用访问控制的挑战](/zh/docs/edge/policies/access-control/how-it-works.md#challenge-details)能挡住绝大多数脚本，但带完整浏览器引擎的攻击工具（无头 Chrome、自动化框架）能把 AxisNow 挑战算出来，甚至雇人点过第三方验证码。它们拿到通过凭证后，在有效期内畅通无阻，访问控制不会再拦它们。这时限速是第二道闸：一个通过了挑战的“访客”仍然不该在一分钟里翻几百页。

<table data-search="false"><thead><tr><th width="140">配置项</th><th>取值</th></tr></thead><tbody><tr><td>条件</td><td>挑战通过 等于 <code>true</code></td></tr><tr><td>计数 Key</td><td>会话标识 + 请求 URI 路径</td></tr><tr><td>响应计数条件</td><td>关闭</td></tr><tr><td>限速阈值</td><td>60 秒内不超过 60 请求</td></tr><tr><td>限速动作</td><td>阻断，响应状态码 429</td></tr><tr><td>优先级</td><td>紧随扫描器规则之后</td></tr></tbody></table>

**为什么条件是「挑战通过」**：这个字段由通用访问控制在前面写好——请求带着有效的挑战凭证进来，访问控制放行的同时把它标成“已通过挑战”，速率控制在后面能直接读到。于是这条规则只盯着那部分已经证明过“我是浏览器”的客户端，普通没触发挑战的访客不受它影响，也不会和别的规则重复计数。

**为什么按会话标识计数**：能通过挑战的客户端一定维护 Cookie，所以它必然带着 AxisNow 为浏览器下发的跟踪 Cookie，会话标识是区分同一出口后面不同浏览器实例的最稳维度；万一没带，这个维度会自动回退为客户端 IP。再加请求 URI 路径，是因为真人浏览通常在不同页面间跳转，而抓取工具会集中打少数几个路径。如果攻击工具会清 Cookie 重来，可以把计数 Key 换成或追加 **TLS 客户端 JA4 指纹**——换 Cookie 不换指纹。

**注意**：挑战的通过凭证本身与客户端 IP 和 TLS 指纹绑定，换 IP 要重新验证；这条规则防的是“不换 IP、拿着同一份凭证硬刷”的情况。通过挑战后仍被这条规则阻断的客户端，从洞察页「阻断」一格的**查看日志**进入日志检索就能看到，见[洞察与日志 › 日志](/zh/docs/edge/policies/rate-limiting/insight.md#logs)。

## 分层 <a href="#layering" id="layering"></a>

上面七组规则可以同时启用。它们按优先级依次评估，每条独立计数，一个请求可以同时进入多条规则的计数器；建议的顺序是严格的在前、宽松的兜底在后：

<table data-search="false"><thead><tr><th width="60">顺序</th><th width="200">规则</th><th>理由</th></tr></thead><tbody><tr><td>1</td><td>扫描器与随机 URL</td><td>只数 404，对正常用户无感；IP 封禁一旦触发，后面的规则都不用再处理这个来源</td></tr><tr><td>2</td><td>穿过挑战的自动化浏览器</td><td>条件只命中已通过挑战的客户端，先评估能更早拦住；未超限的请求照常进入后面的规则计数</td></tr><tr><td>3</td><td>匿名写接口</td><td>阈值最低、覆盖面最窄</td></tr><tr><td>4</td><td>登录用户的高频操作</td><td>按会话计数，只影响带登录态的请求</td></tr><tr><td>5</td><td>开放 API 的配套规则</td><td>没带密钥的请求、昂贵接口</td></tr><tr><td>6</td><td>开放 API 调用方配额</td><td>按密钥的总配额</td></tr><tr><td>7</td><td>API 防 CC 兜底</td><td>覆盖面最宽、阈值最高，放最后</td></tr><tr><td>8</td><td>网站页面超速挑战</td><td>持有效凭证的客户端超限时直接放行并结束评估，放在网站规则的最后；与 API 兜底作用于不同 Host，互不影响</td></tr></tbody></table>

顺序影响的是动作而不是计数：前面的规则一旦执行阻断、IP 封禁或挑战，这个请求不再进入后面规则的计数；**观察**不中断评估。所以严格规则在前既能更早拦住攻击，也能让兜底规则的计数更干净。

**页面与静态资源**：如果站点同时提供 HTML 页面和静态资源，兜底规则的条件建议排除静态文件：「文件后缀 不在以下各项之中 `js`、`css`、`png`、`jpg`、`woff2`……」，否则一个页面带的几十个资源请求会把计数撑满。面向真人的页面流量可以单独配一条按 IP 计数、动作为**挑战**的规则：真人通过验证后在有效期内不再受这条规则限制，脚本则被挡在验证页。

**先观察再切换**：新规则用**观察**动作上线，在洞察页看**观察请求**的量和来源：几乎为零说明阈值太宽，集中在少数来源说明阈值合适，分散在大量普通来源说明阈值太紧或者计数 Key 选错了。调整到满意再改成阻断或封禁，期间计数不受影响。

## 共同的注意事项 <a href="#common-notes" id="common-notes"></a>

* **路径按原样比较**：条件和计数 Key 里的路径区分大小写、不做等价归一。上线前把同一个接口的几种写法（大小写变化、末尾斜杠、URL 编码）各请求一次，确认规则匹配到的和源站实际处理的是同一个接口，否则攻击者换一种写法就绕过了。
* **先豁免，再收紧**：监控探针、合作伙伴固定 IP、搜索引擎在通用访问控制里用跳过动作绕过速率控制插件，再把阈值往下调，见[配置项 › 给可信来源豁免](/zh/docs/edge/policies/rate-limiting/configuration.md#allowlist)。
* **按单个节点的流量设定阈值**：计数按边缘节点独立，不做跨节点汇总。流量分布在多个节点时，每个节点只看到其中一部分请求，阈值应按单个节点承接的流量设定，比按总流量估算的值更低，见[工作原理 › 计数的作用域](/zh/docs/edge/policies/rate-limiting/how-it-works.md#scope)。
* **改动作不用重建规则**：从观察切到阻断、封禁只是改动作，已有计数照常累积；删除重建才会清零。

## 下一步 <a href="#next-steps" id="next-steps"></a>

* [配置项](/zh/docs/edge/policies/rate-limiting/configuration.md)：示例里每个字段的完整取值范围。
* [洞察与日志](/zh/docs/edge/policies/rate-limiting/insight.md)：规则上线后怎么看观察请求、阻断和封禁。
* [防 CC 攻击](/zh/docs/guide/cc-attack-protection.md)、[保护对外 API 和 URL 鉴权](/zh/docs/guide/authn-authz.md)：限速和挑战、认证鉴权怎么配合成一套防线。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://www.axisnow.io/zh/docs/edge/policies/rate-limiting/use-cases.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
