OpenResty Edge 的速率限制可以按自定义键(客户端 IP 地址、URI、URI 参数或 Cookie)限制请求速率,并使用两个阈值:软限制 “Shape at” 速率会延迟超出的请求,硬限制 “Reject at” 速率会直接拒绝它们。当客户端发送请求过快时(例如在拒绝服务攻击下),这可以同时保护你的网关服务器和源服务器,使其不会过载。下面我们将一步步添加一个速率限制页面规则,用 wrk 测试它,并把相同的限制扩展到 SSL 握手。

OpenResty Edge 反向代理在客户端请求到达源服务器之前进行过滤

在 OpenResty Edge 中添加限制请求率的页面规则

让我们进入 OpenResty Edge 的 Admin Web 控制台。这是我们控制台的样本部署。每个用户都有自己的本地部署。

列出 HTTP/HTTPS 应用的 OpenResty Edge Web 控制台

我们可以继续使用之前的示例应用,test-edge.com。进入该应用程序。

应用列表中的 test-edge.com 示例应用

我们已经定义了一个页面规则。

OpenResty Edge 应用概览,突出显示 Page Rules 部分

这个页面规则设置了一个反向代理,将请求转发到一个预先定义的上游,此时并没有限制请求速率。

现有页面规则代理到 my_backend 上游,尚未配置速率限制

现在让我们编辑现有的页面规则来添加速率限制。添加一个新的动作,并搜索 “Limit request rate”。

在页面规则编辑器中搜索 Limit request rate 动作

首先,我们需要指定速率限制的 Key。

Limit request rate 动作,Key 字段设置为客户端 IP 地址

有多种 Key 类型可选——客户端 IP 地址、URI、URI 参数、Cookie,以及更多。现在先选择默认的 Key 类型,客户端 IP 地址。这样限制就针对每个单独的客户端 IP 地址。

Key 下拉列表,列出速率限制的 Key 类型:客户端 IP 地址、URI、URI 参数、请求 Cookie、X-Forwarded-For 和请求头

“Shape at” 速率是一个软限制。当客户端试图发送比这个速率更快的请求时,网关服务器会延迟这些过度的请求以匹配这个速率。因此,客户端发送请求的速度越快,网关添加的延迟就越长。这里我们指定每秒 50 个请求的速率。

Shape at 软限制速率设置为每秒 50 个请求

因为我们把 Key 类型设置为客户端 IP 地址,所以限制会应用于每个单独的客户端 IP 地址。

“Reject at” 速率是一个硬限制。当客户端发送请求的速度快到超过这个硬限制时,我们可以采取更积极的动作,比如立即阻止它们而无需等待。在这里指定每秒 100 个请求的速率。

Reject at 硬限制速率设置为每秒 100 个请求

我们可以选择不同的拦截动作——比如立即关闭当前连接、返回错误页面,或者返回验证码页面来阻止机器人。选择默认的 “Error Page”(错误页面)动作,它会通过 HTTP 返回一个错误页面。

Reject 动作下拉列表,显示 Close Connection、Error Page、Enable HCaptcha 和 Enable Edge Captcha

此处使用默认的 HTTP 状态码 503,表示服务不可用。

Reject 动作状态码设置为默认的 503 服务不可用

保存对这个页面规则的修改。然后像往常一样,我们发布来推送这些改动。

已配置的 Limit request rate 页面规则,有一个待发布的改动

发布后,新的页面规则会同步到我们所有的网关服务器。

发布完成,同步状态为 12/12,覆盖所有网关服务器

现在,新的页面规则已经被推送到所有的网关集群和服务器。我们的配置变化不需要服务器重载、重启或二进制升级,所以它非常高效且可扩展。

OpenResty Edge 发布同步到每个网关集群、无需重载的示意图

使用 wrk 测试速率限制

接下来,我们将验证新速率限制的效果。

在终端上,我们可以通过名为 wrk 的开源工具,非常快速地发送大量的请求。

wrk -c 50 -d 1s http://test-edge.com/

这里我们首先使用 50 的并发级别,注意 -c 选项。

wrk 命令以 50 的并发级别向 test-edge.com 发送请求

运行该命令,实际请求率约为每秒 50 个请求。这就是我们的 “Shape at” 速率。

并发为 50 时 wrk 的结果,约为每秒 47.90 个请求,与 Shape at 速率一致

然后我们提高并发级别,使 wrk 发送请求的速度更快。

wrk -c 128 -d 1s http://test-edge.com/

注意 128 的并发级别。

wrk 命令将并发提高到 128 向 test-edge.com 发送请求

运行!请注意,有很多被拒绝的请求返回了错误响应。

并发为 128 时 wrk 的结果,显示 3498 个非 2xx 或 3xx 响应,因为超出的请求被拒绝

这次的请求速率很高,只是因为服务器拒绝那些过度请求的速度非常快。

并发为 128 时 wrk 的结果,约为每秒 3539 个请求,因为被拒绝的请求返回得非常快

限制 SSL/TLS 握手的速率

除了限制请求速率,OpenResty Edge 还可以限制 HTTPS 请求的 SSL 或 TLS 握手的速率。

OpenResty Edge 的 SSL 页面,带有 SSL 握手速率限制部分

在这个页面,我们可以配置 SSL 握手速率限制。打开开关即可显示配置参数。它们与请求速率限制功能相同——选择一个 Key,然后设置 “Shape at” 和 “Reject at” 速率。

已启用的 SSL 握手速率限制,使用客户端 IP 键,Shape at 为 100、Reject at 为 200 每秒请求数

OpenResty Edge 速率限制常见问题

OpenResty Edge 速率限制如何决定限制哪些请求?

它按你选择的 Key 进行限制。默认的 Key 是客户端 IP 地址,因此限制会应用于每个单独的客户端 IP 地址;你也可以按 URI、URI 参数、请求 Cookie、X-Forwarded-For 中的地址或某个请求头来作为 Key。

“Shape at” 和 “Reject at” 速率有什么区别?

“Shape at” 是软限制:网关会延迟超出该速率的请求以匹配它,客户端发送得越快,得到的延迟就越长。“Reject at” 是硬限制:一旦客户端超过它,网关会采取更积极的拦截动作,而不是等待。

超出速率限制的请求会怎样?

你可以为硬限制选择拦截动作:立即关闭连接、返回错误页面,或返回验证码页面来阻止机器人。默认的 “Error Page” 动作会返回 HTTP 状态码 503(服务不可用)。

OpenResty Edge 也能限制 SSL/TLS 握手的速率吗?

可以。除了请求速率,OpenResty Edge 还能限制 HTTPS 请求的 SSL 或 TLS 握手速率,使用与请求速率限制相同的 Key、“Shape at” 和 “Reject at” 参数。

速率限制的更改需要重载或重启服务器吗?

不需要。这些配置更改不需要服务器重载、重启或二进制升级。你只需发布,它就会同步到所有的网关集群和服务器。

如果你喜欢这个教程,请订阅这个博客网站和我们的 YouTube 频道B 站频道。谢谢!

关于作者

章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。

章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴, 是 “边缘计算“、”动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用动态追踪技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,并编写过 60 多个开源软件库。

关注我们

如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:

我们的微信公众号

翻译

我们提供了英文版原文和中译版(本文) 。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!