速率限制是计算机系统中用于控制请求发送或处理速率以维护系统稳定性和安全性的技术。在 Web 应用程序中,速率限制限制了客户端在给定时间内可以向服务器发出的请求数量,以防止滥用并确保多个客户端公平使用资源。
随着我们对 Web 应用程序和服务的依赖日益增长,网络攻击的风险也随之增加。根据 RiskIQ 的一份报告,2020 年发生了超过 20 亿次网络攻击。速率限制是抵御此类攻击的有效工具。通过限制给定时间内可以访问网站或应用程序的流量数量,它可以帮助防止过载。这项技术可以抵御网络威胁,并维护系统的稳定性。
总的来说,速率限制是确保计算机系统安全性和可靠性的重要机制,它广泛应用于各种应用程序,包括 Web API、Web 服务器和网络基础设施。
速率限制是实际应用程序和系统管理的任何安全策略的重要组成部分。通过限制对应用程序或系统发出的请求或连接数量,它有助于防止多种恶意活动,例如 DDoS 攻击、暴力破解攻击、凭证填充、库存囤积攻击和数据抓取。
实施速率限制可以帮助组织确保所有用户都能获得资源,并防止恶意活动使系统不堪重负。通过限制请求数量,公司可以防御各种类型的攻击,例如:
DDoS 攻击:通过将请求数量限制在合理水平,组织可以防止 DDoS 攻击导致系统过载并崩溃。
凭证填充:限制来自单个 IP 地址或用户的登录尝试次数可以防止凭证填充攻击,即攻击者使用自动化脚本尝试不同的用户名和密码组合,直到找到匹配项为止。
暴力破解攻击:限制访问资源的请求或尝试次数可以帮助防止暴力破解攻击,即攻击者尝试不同的字符组合以获取对系统或应用程序的访问权限。
数据抓取:速率限制可以通过限制单个用户或 IP 地址发出的请求数量来帮助防止数据抓取。这可以阻止攻击者抓取敏感数据。
库存囤积攻击:限制对特定物品或资源的请求数量可以阻止库存囤积攻击,即攻击者试图购买热门物品的所有可用库存,以便以更高的价格转售。
总的来说,速率限制是应用程序和系统确保资源安全性和可靠性,同时防御恶意活动所必需的工具。通过实施速率限制,公司可以提高其安全态势并防止攻击,确保所有用户都能获得资源。
基于 IP
一种常见的速率限制类型是基于 IP 的,它根据请求的源 IP 地址限制访问。它可以帮助防御来自少数 IP 地址的攻击,但对于分布式攻击效果较差。
基于用户
基于用户的速率限制是另一种方法,它根据发出请求的用户帐户限制访问。它可以帮助防止凭证填充攻击,但这需要在不同会话中识别唯一用户,这可能具有挑战性。
基于应用
基于应用的速率限制根据发出请求的应用类型限制访问。它可以帮助防止库存囤积和数据抓取攻击,但对于来自合法应用的攻击可能无效。
令牌桶
令牌桶速率限制是一种流行的方法,它使用令牌桶调节请求流量。每个请求消耗桶中的一个令牌,一旦桶空了,在桶被重新填满之前不再允许更多请求。
组织应定期审查和更新其速率限制策略,以确保它们对新的和正在出现的威胁仍然有效。此外,选择最适合组织特定需求和要求的速率限制方法至关重要。
速率限制就像夜总会的保安一样。保安会评估进入夜总会的人流量,如果人数过多且不安全,则会阻止入场。类似地,速率限制控制对应用程序的请求数量,以防止其不堪重负或崩溃。就像保安可能将每小时进入夜总会的人数限制在一定数量一样,速率限制可以将每秒或每分钟的请求数量限制在一定数量。通过仔细管理人员或请求的流量,保安和速率限制都有助于维持一个安全可靠的环境。
速率限制通常基于跟踪 IP 地址并测量每个请求之间的时间。当用户发出请求时,系统会对其进行跟踪,并将发出的请求数量与预定义的阈值进行比较。如果请求数量超过阈值,则速率限制会生效,并且系统在一定时间内将不会处理用户的请求。
速率限制算法是使组织能够控制和限制对其应用程序和系统的传入请求速率的基本工具。可以根据应用程序或系统的特定需求使用不同的算法。
固定窗口速率限制:这是一种简单的算法,它计算在固定时间窗口(例如一分钟)内接收到的请求数量。一旦达到最大请求数量,在下一个窗口开始之前,额外的请求将被拒绝。该算法易于实现,对 DDoS 攻击有效,但可能会限制合法用户。
滑动窗口速率限制:该算法使用随时间移动的滑动窗口跟踪最近接收到的请求数量。该算法比固定窗口速率限制更灵活,可以根据流量高峰进行调整,使其成为具有不同使用模式的应用程序的更好选择。然而,对于持续性攻击可能效果不佳。
令牌桶速率限制:它维护一个以固定速率重新填充的令牌桶。每个请求消耗一个令牌,一旦桶空了,额外的请求将被拒绝。令牌桶速率限制适合处理突发流量,因为它允许同时处理一定数量的请求。然而,对于持续流量可能效果不佳。
漏桶速率限制:类似于令牌桶速率限制,但将请求放入一个会随时间逐渐清空的“桶”中,从而允许处理更多请求。该算法对突发流量有效,并有助于防止过载,但对于持续性攻击可能效果不佳。
选择正确的速率限制算法取决于几个因素,包括应用程序的流量模式以及所需的防御恶意活动的保护级别。组织必须在保护其系统和提供良好用户体验之间取得平衡。定期审查和更新速率限制策略对于确保它们对新的和正在出现的威胁仍然有效也至关重要。
许多流行的网站和应用程序使用速率限制来防止恶意攻击、提高性能并确保所有用户都能公平使用。以下是一些速率限制的真实世界用例:
在所有这些示例中,速率限制帮助这些网站和应用程序保护自己免受攻击,并确保其服务对合法用户保持可用。
使用 Redis 构建速率限制器非常容易,因为有两个命令 INCR 和 EXPIRE。基本概念是您希望在给定时间内限制对特定服务的请求。假设我们有一个服务,其用户由 API 密钥标识。该服务规定,在任何给定分钟内最多只能有 20 个请求。
为此,我们需要为每个 API 密钥每分钟创建一个 Redis 键。为了确保我们不会用垃圾填满整个数据库,我们也会在一分钟后使该键过期。将其可视化如下:
用户 API 密钥 = zA21X31,绿色表示无限制,红色表示受限制。
Redis 键 | zA21X31:0 | zA21X31:1 | zA21X31:2 | zA21X31:3 | zA21X31:4 |
值 | 3 | 8 | 20 | >2 | 20 |
过期时间 | 最新 12:02 | 最新 12:03 | 最新 12:04 | 最新 12:05 | 最新 12:06 |
时间 | 12:00 | 12:01 | 12:02 | 12:03 | 12:04 |
键由用户 API 密钥与分钟数用冒号连接而成。由于我们总是让键过期,我们只需要跟踪分钟数——当小时从 59 滚动到 00 时,我们可以确定另一个 59 不存在(它会在 58 分钟前过期)。
我们来看看伪代码如何实现这一点。
1 | >GET [用户 API 密钥]:[当前分钟数] |
2 | 如果第 1 行的结果小于 20(或未设置),则跳转到第 4 行,否则执行第 3 行。 |
3 | 显示错误消息并结束连接。退出。 |
4 | >MULTIOK > INCR [用户 API 密钥]:[当前分钟数] 已入队 > EXPIRE [用户 API 密钥]:[当前分钟数] 59 已入队 >EXECOK |
5 | 执行服务操作 |
从此例程中需要理解的两个关键点:
最糟糕的失败情况是,如果由于某种非常奇怪且不太可能的原因,Redis 服务器在 INCR 和 EXPIRE 之间崩溃。当从 AOF 或内存复制中恢复时,INCR 将不会被恢复,因为事务尚未完成。
使用这种模式,任何一个用户都可能有两个限流键,一个正在当前使用,另一个将在同一分钟窗口内过期,但除此之外它非常高效。