Python 限制来自任何给定IP地址的请求数
我正在从事一个Google应用程序引擎项目(python/webapp2),在该项目中,我有点担心有人滥用/滥发我正在创建的服务,并提出大量请求。为了消除这种可能性,我的想法是限制应用程序某些部分在任何给定时间内每个IP地址允许的请求数。我目前的计划如下: 根据每项要求,我将:Python 限制来自任何给定IP地址的请求数,python,google-app-engine,webapp2,Python,Google App Engine,Webapp2,我正在从事一个Google应用程序引擎项目(python/webapp2),在该项目中,我有点担心有人滥用/滥发我正在创建的服务,并提出大量请求。为了消除这种可能性,我的想法是限制应用程序某些部分在任何给定时间内每个IP地址允许的请求数。我目前的计划如下: 根据每项要求,我将: 从标头中获取ip地址 使用时间戳将此ip地址存储在数据存储中 删除中超过一小时的所有ip地址实体 计算具有该IP地址的数据存储实体的数量 如果超过给定限制,则不允许访问 我的问题是: 这是最好的方法吗?我只是一个初学者,
这是最好的方法吗?我只是一个初学者,我想这样做会有相当大的开销,可能这是一个常见的任务,可能有更好的解决方案。有没有更好的方法来做到这一点,而不是资源密集型的?在过去,我使用memcache来实现这一点,它要快得多,特别是因为您只关心近似限制(近似,因为memcache可以由系统刷新,可能不会由所有实例共享,等等)。您甚至可以使用它使密钥过期。类似这样的情况(假设
self
是一个webapp2请求处理程序,并且您已经导入了GAE的memcache库):
这将创建一个密钥,该密钥在大约MAX_请求在WINDOW_秒时间内拒绝用户,并将每个WINDOW_秒时间内的计数重新归零。(即,它不是滑动窗口;每个时间段都会重置为零。)首先,您的设计有两个注意事项:
- 人们通常很容易获得一个新的IP地址,将iPhone从LTE切换到3G,然后再切换回来,拔下并重新安装DSL型号,选择一个新的开放代理,等等。因此,如果你希望这样做能够防止故意滥用,而不仅仅是人们没有意识到他们做得太多,那么这并没有多帮助
- IP地址通常由或按顺序共享。如果每个IP每小时200个请求意味着一个人,那么这似乎是合理的,但如果它意味着BigCorp区域办事处的所有7500名员工呢
如果还不够好,我可能会在考虑优化实现之前先考虑是否可以简化设计。例如,如果是每个日历小时每个IP有N个连接,那么这会使一切变得更加简单,只需在每个IP(数据存储或memcache)中存储一个计数器,并在每个XX:00擦除所有计数器。这可以接受吗?需要担心的一件事是NAT。如果NAT系统(例如公司或某些ISP)后面有大量用户,则您看到的所有用户的传入地址都是相同的(或分散在一个小集合中)。+1到DrC。但值得注意的是,不管怎样,许多服务都能做到这一点,从AmpliFIND这样的小型服务到Twitter这样的巨头。解决这一问题的通常方法是为开发人员和/或最终用户提供一个选项,让他们可以使用某种每用户/-system/-program/-which身份验证(例如OAuth令牌)。对于静态IP地址,您可以在应用程序中使用拒绝服务配置文件dos.xml。只要将滥用您服务的IP地址列入黑名单,并按照上面所述重新部署您的应用程序,这些都是我必须研究的极好建议。谢谢你的帮助这正是我要找的。非常简单,你甚至给了我一个很好的开始。非常感谢:)请注意,如果尚未在Memcache中设置密钥,您应该在第一个if语句中检查
count不是None和count>MAX\u REQUESTS
。
memcache_key = 'request-count-' + self.request.remote_addr
count = memcache.get(memcache_key)
if count is not None and count > MAX_REQUESTS:
logging.warning("Remote user has %d requests; rejecting." % (count))
self.error(429)
return
count = memcache.incr(memcache_key)
if count is None:
# key didn't exist yet
memcache.add(memcache_key, 1, time=WINDOW_IN_SECONDS)