限速单个URL请求


8

我有一个正在开发的Flask应用程序,该应用程序在很大程度上依赖于外部网站的交互,并由最终用户启动。如果我离开该应用程序时没有任何带宽控制/速率限制,那么此行为者可能出于恶意的目的而滥用该应用程序。

我的目标是一个相当简单的两阶段方法:

  1. 对单个IP源的速率进行限制x,以使其每分钟执行的连接数不会超过此数量。使用可以轻松实现iptables这是与我的目标相似的示例:

     iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 \
       --connlimit-mask 32 -j REJECT --reject-with tcp-reset  
    
  2. 速率限制了应用程序执行每个URLx的查找数量以上的能力。例:

     APP ---- 10 pps --->  stackexchange.com   PERMIT
     APP ---- 25 pps --->  google.com          DENY / 15 SECOND BACKOFF
    

据我所知,iptables它无法跟踪单独的URL。只能对整个连接进行速率限制。这似乎也不是我要实现的唯一限制。如果可以通过这种方式进行设置iptables,则由于我的请求是由用户发起的,因此它可能会给我的Web应用程序带来一些问题。

我正在使用Flask,一个可行的选择可能是使用before_request钩子,并使用数据存储(例如Redis)手动跟踪这些目的地。但是,以这种方式处理连接在堆栈中相当高。我真正需要的(或认为我需要的)是一个智能防火墙应用程序,可以以自定义的方式剖析请求并在达到某些断点时关闭连接。

有什么方法可以实现我的目标吗?

如果是这样,怎么办?

Answers:


3

iptables 处理Internet和传输层(在Internet模型中)或OSI模型中的第3层和第4层,只有少数例外(对MAC地址进行过滤,NAT协议帮助程序)。

URI是应用程序层的一部分。iptables不与他们打交道。

您可以使用iptables通过Web代理定向所有传出的TCP端口80流量,这可以限制您的速率(例如,Squid的延迟池可以做到这一点。或者Apache可以做到mod_proxy。)使用HTTPS这样做更困难(尽管也许您可以仅将您的应用配置为使用网络代理,但是与透明代理相比,这将是更好的方法)。

但是您确实应该将两个速率限制都移到您的应用程序中。原因是您要设置的UX 太糟糕了;“拒绝连接”根本无法解释正在发生的事情。这将会是多少为您的用户更好,如果你不是给了一个错误页面解释说,他们正在做的请求太快,谁为支持联系人,也许给解决了CAPTCHA继续等选项

在传入连接上设置连接速率限制是合理的,但应该防止应用程序由于DoS攻击而掉线-如此之多的请求使您的应用程序甚至无法向用户提供超出速率的错误页面。它应该比开始为错误页面提供服务时的价格高一些(并且可能应该是全局限制,而不是每个源IP限制)。请注意,如果您的应用程序通过Web服务器和/或反向代理运行,则可以在此处配置传入速率限制(而不是通过iptables)- 通过发送静态错误页面甚至不传递请求来进行非常廉价的拒绝到您的应用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.