阻止某些ip,如果超过'尝试每x'

时间:2013-06-03 11:45:08

标签: python

有一台服务器必须处理来自gprs-modules的大量TCP请求,我认为设置一些东西来保护这台服务器免受来自某些ip的多个请求是很方便的。

现在我想做一些事情(在python中),它将检查某个ip尝试连接多少次,如果超过给定的尝试次数,这个ip将被阻止一段给定的时间(或永远)。

我想知道是否有库存在这样做,或者我应该如何在我的代码中解决这个问题。

4 个答案:

答案 0 :(得分:7)

不要从代码中解决这个问题 - 这就是防火墙的目的。

使用iptables很简单:

iptables -I INPUT -p tcp --dport $PORT -i eth0 -m state --state NEW -m recent --set

iptables -I INPUT -p tcp --dport $PORT -i eth0 -m state --state NEW -m recent --update --seconds 600 --hitcount 2 -j DROP

以上意思是“删除在端口$ PORT 10分钟内连接尝试次数超过2次的任何内容”

答案 1 :(得分:2)

如果您确定要在代码中处理此问题,那么 需要一个单独的库(尽管使用一个可能会更高效),您可以添加以下内容:连接处理程序:

from collections import defaultdict, deque
from datetime import datetime

floodlog = defaultdict(deque)


def checkForFlood(clientIP):
    """check if how many times clientIP has connected within TIMELIMIT, and block if more than MAX_CONNECTEIONS_PER_TIMELIMIT"""

    now = datetime.now()
    clientFloodLog = floodlog[clientIP]
    clientFloodLog.append(now)
    if len(clientFloodLog) > MAX_CONNECTIONS_PER_TIMELIMIT:
        earliestLoggedConenction = clientFloodLog.popleft()
        if now - earliestLoggedConnection < TIMELIMIT:
            blockIP(clientIP)

答案 2 :(得分:2)

正如布尔汉哈立德所说。您不希望在代码中尝试此操作。它并不是非常高效,而且这就是防火墙的用途。

iptables -I INPUT -p tcp --dport $PORT -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport $PORT -i eth0 -m state --state NEW -m recent --update --seconds 600 --hitcount 2 -j DROP

这个例子非常有用,但不是很方便。问题是你也限制了良好/可信赖的连接。

你需要更灵活。在基于Linux的操作系统上,您可以使用fail2ban。它是一个非常方便的工具,可以通过使用动态iptables规则来防止暴力攻击服务。在Debian / Ubuntu上,您可以使用apt-get安装它。如果您使用的是CentOS,则需要使用第三方存储库。

  1. 将每个连接记录到日志文件中:

    [Jun 3 03:52:23] server [pid]: Connect from 1.2.3.4
    [Jun 3 03:52:23] server [pid]: Failed password for $USER from 1.2.3.4 port $DST
    [Jun 3 03:52:23] server [pid]: Connect from 2.3.4.5
    [Jun 3 03:52:23] server [pid]: Successful login from 2.3.4.5
    
  2. 现在使用fail2ban监控此文件,并定义正则表达式,以区别成功登录和失败登录。告诉fail2ban它应该为您阻止IP多长时间以及您是否希望收到电子邮件通知。

  3. 文档非常好,所以请看一下如何配置fail2ban来监控logile:fail2ban docu

    您不必仅关注登录失败。您也可以尝试留意端口扫描。最大的胜利:不仅保护您的应用程序。还可以安全地使用SSH,HTTP等登录进行强制执行! ;)

答案 3 :(得分:1)

对于纯Python解决方案,我认为你可以重用我为同一个问题开发的东西,但是从客户的角度来看:避免向服务提供商发出超过'每秒x次尝试次数'。

代码在GitHub上提供:您可以重复使用其中的大部分内容,但是您需要将time.sleep调用替换为“黑名单”机制。