如何使用 Apache 实现速率限制? (每秒请求数)

Posted

技术标签:

【中文标题】如何使用 Apache 实现速率限制? (每秒请求数)【英文标题】:How can I implement rate limiting with Apache? (requests per second) 【发布时间】:2010-09-12 23:59:41 【问题描述】:

有哪些技术和/或模块可用于在 apache 中实现稳健的速率限制(请求数/字节数/IP/单位时间)?

【问题讨论】:

我在 Web 服务器上使用 Linux 的 tc,因为 Red Hat 6 只有 Apache 2.2。 【参考方案1】:

最好的

mod_evasive(更专注于减少 DoS 暴露) mod_cband(“正常”带宽控制的最佳功能)

其他的

mod_limitipconn mod_bw mod_bwshare

【讨论】:

我找不到任何东西可以通过 IP 地址限制每天的连接数。我花了一整夜寻找,真可惜。 有谁知道是否有办法让 mod_evasive 在反向代理后面运行时查看标头而不是 IP? 4 年后,mod_evasive 仍然是“最好的”吗? 支持您的声明。为什么 _evasive 和 _cband 最好? mod_evasive 获得了很多在线推荐,但截至 2017 年年中,它似乎已被其作者 Jonathan Zdziarski 抛弃,他奇怪地从他的博客中删除了所有对它的引用 -尽管源代码仍以upload 的形式提供。在过去 6 年(或 mod_limitipconn 的情况下为 15 年),其他项目均未更新。【参考方案2】:

正如this blog 帖子中所述,似乎可以使用mod_security 来实现每秒速率限制。

配置是这样的:

SecRuleEngine On

<LocationMatch "^/somepath">
  SecAction initcol:ip=%REMOTE_ADDR,pass,nolog
  SecAction "phase:5,deprecatevar:ip.somepathcounter=1/1,pass,nolog"
  SecRule IP:SOMEPATHCOUNTER "@gt 60" "phase:2,pause:300,deny,status:509,setenv:RATELIMITED,skip:1,nolog"
  SecAction "phase:2,pass,setvar:ip.somepathcounter=+1,nolog"
  Header always set Retry-After "10" env=RATELIMITED
</LocationMatch>

ErrorDocument 509 "Rate Limit Exceeded"

【讨论】:

这对我来说非常完美,modsec2 已经在运行。只需将 id 添加到规则中以匹配 modsec 版本,如下所示: SecAction initcol:ip=%REMOTE_ADDR,pass,nolog,id:10000001 SecAction "phase:5,deprecatevar: ip.somepathcounter=1/1,pass,nolog,id:10000002" SecRule IP:SOMEPATHCOUNTER "@gt 60" "phase:2,pause:300,deny,status:509,setenv:RATELIMITED,skip:1,nolog, id:10000003" SecAction "phase:2,pass,setvar:ip.somepathcounter=+1,nolog,id:10000004" 标头总是设置 Retry-After "10" env=RATELIMITED 另请注意,您可以通过编辑“@gt 60”来更改允许的初始突发请求数量,以及通过编辑 ip.somepathcounter=1/ 来“重新充电”限制的速度。 1位。 1/1 允许每秒一个额外的请求。 1/2 允许每 2 秒增加一个请求,以此类推。 Apache 2.4 将抱怨 ErrorDocument 中的 509,一个选项将其更改为 429(当然,Apache 2.2 不支持)。此外,从 mod_security 2.7 开始,所有 SecAction 和 SecRule-s 都需要一个 id。 仅供参考 mod_security 不是 Apache 项目。【参考方案3】:

有很多方法,包括 Web 应用程序防火墙,但如果使用 Apache mod,最容易实现。

我喜欢推荐的一个这样的模组是mod_qos。它是一个免费模块,对某些 DOS、Bruteforce 和 Slowloris 类型的攻击非常有效。这将大大减轻您的服务器负载。

非常强大

mod_qos 模块的当前版本实现了控制机制来管理:

对某个位置/资源的最大并发请求数 (URL) 或虚拟主机。

带宽限制,例如 每秒对 URL 的最大允许请求数或每秒下载的最大/最小千字节数。

限制每秒请求事件的数量(特殊请求 条件)。

在定义的时间段内限制请求事件的数量。 它还可以检测到非常重要的人 (VIP) 可能访问 没有限制或限制较少的网络服务器。

用于拒绝未经授权的通用请求行和标头过滤器 操作。

请求正文数据限制和过滤(需要 mod_parp)。

限制单个客户端 (IP) 的请求事件数。

TCP 连接级别的限制,例如,最大连接数 允许来自单个 IP 源地址或动态的连接 保持活动控制。

当服务器用尽空闲 TCP 时首选已知 IP 地址 连接。

这是您可以使用它的示例配置。有数百种可能的配置可以满足您的需求。有关控件的更多信息,请访问该网站。

Sample configuration:
# minimum request rate (bytes/sec at request reading):
QS_SrvRequestRate                                 120

# limits the connections for this virtual host:
QS_SrvMaxConn                                     800

# allows keep-alive support till the server reaches 600 connections:
QS_SrvMaxConnClose                                600

# allows max 50 connections from a single ip address:
QS_SrvMaxConnPerIP                                 50

# disables connection restrictions for certain clients:
QS_SrvMaxConnExcludeIP                    172.18.3.32
QS_SrvMaxConnExcludeIP                    192.168.10.

http://opensource.adnovum.ch/mod_qos/

【讨论】:

这个只能在旧的 apache2.2 中工作,不能在 apache2.4 + 中工作,是吗? @infiniteloop mod_quos sourceforge 页面说它适用于 apache2.4。但是这里有一个关于一些不起作用的功能的具体讨论:***.com/a/15726540/1402498【参考方案4】:

在 Apache 2.4 中,有一个名为 mod_ratelimit 的新库存模块。要模拟调制解调器速度,您可以使用mod_dialup。虽然我不明白为什么你不能对所有事情都使用 mod_ratelimit。

【讨论】:

请注意,mod_dialup 使用异步SUSPENDED 状态,不会在等待时浪费线程,而到目前为止,mod_ratelimit 严格来说是每个连接的线程。参看。 thread.gmane.org/gmane.comp.apache.cvs/20490【参考方案5】:

遗憾的是,mod_evasive 在非 prefork 配置中使用时无法按预期工作(最近的 apache 设置主要是 MPM)

【讨论】:

【参考方案6】:

另一个选项 - mod_qos

配置并不简单,但功能强大。

http://opensource.adnovum.ch/mod_qos/

【讨论】:

我和 Adnovum 的人一起工作过 - 很有趣。【参考方案7】:

取决于你为什么要限制速率。

如果是为了防止服务器过载,实际上将nginx放在它前面并在那里配置rate limiting是有意义的。这是有道理的,因为 NGINX 使用的资源要少得多,比如每万个连接只有几 MB。因此,如果服务器被淹没,NGINX 将进行速率限制(使用少量资源)并且只将允许的流量传递给 Apache。

如果您追求的只是简单,那么请使用 mod_evasive 之类的东西。

像往常一样,如果要防止 DDoS 或 DoS 攻击,请使用 Cloudflare 之类的服务,它也有速率限制。

【讨论】:

Nginx 是要走的路,别到处找了。所有其他基于 apache 模块的建议解决方案要么没有维护,要么复杂,要么效率低。

以上是关于如何使用 Apache 实现速率限制? (每秒请求数)的主要内容,如果未能解决你的问题,请参考以下文章

每秒仅插入 1 次后的 403 速率限制

每秒仅插入 1 次后的 403 速率限制

如何限制请求 python 库中 HTTP 请求的下载速率?

如何限制/速率限制请求以防止 Axios 出现 429 错误

为 Web 请求实现速率限制算法的最佳方法是啥?

如何在 Linux 中获取 Apache 的“每秒请求数”?