限制请求速率

页面规则下拉菜单中提供了多个已分类的动作选项。其中,“CC 攻击防御动作”类别包含用于控制请求流量的动作。

选择限制请求速率动作:

请求速率限制基于漏桶算法工作,我们可通过以下三个参数来进行请求管理:

  1. 关键字:默认为客户端的 IP 地址,可通过下拉菜单更改为 URI、URI 参数等,并且可以选择一个或多个关键字。若选择 URI 参数或 Cookie,还需额外指定一个相应的 Argument 字段;详见关键字说明
  2. 调节阈值:低于此速率的请求不受影响;速率介于此阈值与拒绝阈值之间的请求,将被延时处理;
  3. 拒绝阈值:超过此速率的请求执行指定的 拒绝动作
  4. 拒绝动作:指定在达到拒绝阈值后执行的动作。详见拒绝动作说明

这两个阈值参数默认单位是每秒请求数,也可以设置为每分钟请求数

若两阈值设置相同,则超出该速率的请求会立即被拒绝。

请求将依据设定的关键字进行限速,可选关键字包括:

  • 客户端 IP 地址,如:1.1.1.1
  • 请求的 URI,例如:/openresty
  • URI 查询参数,如 /openresty?arg1=val1 中的 arg1
  • 请求 Cookie,比如 cookie: c1=v1 中的键 c1
  • X-Forwarded-For 请求头中的第一个 IP 地址,如 X-Forwarded-For: 1.1.1.1, 1.1.1.2 中的 1.1.1.1
  • X-Forwarded-For 请求头中的最后一个 IP 地址,如 X-Forwarded-For: 1.1.1.1, 1.1.1.2 中的 1.1.1.2
  • 特定的 HTTP 请求头,例如 Host
  • 加密 Cookie:会根据 OpenResty Edge 生成的加密 Cookie 进行限速。当客户请求没有携带加密 Cookie 时,需要回退到不含加密 Cookie 的限速。因此,加密 Cookie 必须和其它的关键字一起使用

达到限速条件后,系统可执行以下预设动作,默认为 返回错误页

  • 关闭请求连接:立即终止与客户端的连接,不再响应请求。
  • 返回错误页,默认为状态码 503:限速生效时向用户展示带有 503 状态码的错误页面,暗示服务器暂时无法处理请求。
  • 完成 hCaptcha 验证:要求用户通过 hCaptcha 挑战,以区分真人和机器行为。
  • 完成 OpenResty Edge Captcha 验证:使用 OpenResty Edge 的验证码系统验证用户身份。
  • 重定向验证:将请求重定向至验证页面,验证通过后方可继续访问。
  • JavaScript 挑战:要求用户浏览器执行 JavaScript 代码,验证非机器人操作。
  • 标记为拒绝:仅将请求标记为拒绝,继续执行后续规则。此动作于 24.9.1-7 中首次引入。

默认情况下,该动作针对所有请求,在客户端地址基础上限速。这种规则可能过于宽泛,我们可以通过下述方式实现更细致的条件控制。 如同动作设置,条件也按照 URI、请求、响应、客户端信息等类别整理。

示例 1:

这里我们以客户端信息中的国家为例,设置仅对来自日本的请求执行上述动作:

输入日本的国家代码 JP,所有大洲、国家、省份、城市的代码可在 Edge 文档中找到:client-country

完成动作和条件设置后,点击右下方的“创建”按钮即可应用规则。页面将自动跳转回规则列表页面。

示例 2:

接下来演示如何使用加密 Cookie加密 Cookie 应该和其他关键字一起使用,这样当 Cookie 不存在时,才能回退成根据其他关键字限速。

关键字我们选择了 客户端地址加密 Cookie 作为关键字,一分钟内只允许一个请求。

这里我们没有设置代理等其他动作,因此预期动作是正常请求会返回 404 状态,被限速的情况会返回 503 状态。保存配置。

发布配置。

接着发送测试请求:curl localhost -H 'Host: test.com' -I

HTTP/1.1 404 Not Found
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw=; Path=/; Secure
Req-ID: 0000008000045ed343300002

此时返回了 Set-Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw=; Path=/; Secure,因为最初是没有 Cookie 的,因此返回了一个。如果我们再次发送不携带 Cookie 的请求,那么将会按照 客户端地址 进行限速。

发送第二个测试请求 curl localhost -H 'Host: test.com' -I -H 'Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw='

HTTP/1.1 404 Not Found
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Req-ID: 0000008000045ed343300003

这是携带 Cookie 的第一个请求,因此没有被限速。

发送第三测试请求 curl localhost -H 'Host: test.com' -I -H 'Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw='

HTTP/1.1 503 Service Temporarily Unavailable
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Req-ID: 0000008000045ed343a80004

请求被限速了。