共享fail2ban禁止的IP


18

我在具有公开可见服务的所有服务器上使用了fail2ban,我想知道:

  1. 是否有一种简单的方法可以在我控制的主机之间共享禁止的IP?
  2. 那里有收集和发布数据的服务吗?

自设置此服务器的第一天以来,我一直在进行无数次登录尝试。


2
欢迎使用互联网。发布此列表没有意义-我们都非常清楚这种情况。
斯文

1
谢谢。我相信在描述某些东西时,示例很不错。如果您知道的更多,请随时忽略它们。
ndemou 2014年

我已经删除了IP列表,并借此机会将您的问题变成一个问题。发布列表不仅没有意义,而且还会使问题变得混乱,并且很快就会过时。
gparent 2014年

2
另外我的建议是删除fail2ban并停止对此进行关注。如果您关闭了密码认证,那么您将无能为力。fail2ban过去已被利用,添加潜在的安全漏洞绝对不会带来任何好处,这就是净损失。
gparent 2014年

@gparent:关于您的建议:谢谢-我以前从未看过fail2ban利用历史。为了安全起见,S / WI希望有更好的记录。关于您的修改:我认为改变这么多的问题是没有好处的。如果是一个不好的问题,请让张贴者承担后果。无论如何,我将保留现在的状态。
ndemou 2014年

Answers:


8

我曾经在该站点上看到过一个用于集中fail2ban数据的系统,并创建了一个修改后的版本。数据库是相同的,但是我更改并创建了一些脚本。

我的系统包含4个组件:

  1. fail2ban数据库

    这是一个仅包含一个表的MySQL数据库erp_core_fail2ban

    CREATE TABLE IF NOT EXISTS 'erp_core_fail2ban' (
      'id' bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      'hostname' varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
      'created' datetime NOT NULL,
      'name' text COLLATE utf8_unicode_ci NOT NULL,
      'protocol' varchar(16) COLLATE utf8_unicode_ci NOT NULL,
      'port' varchar(32) COLLATE utf8_unicode_ci NOT NULL,
      'ip' varchar(64) COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY ('id'),
      KEY 'hostname' ('hostname','ip')
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
  2. fail2ban.php

    每次禁止主机时,它将填充数据库:

    
    <?php
    require_once("/etc/fail2ban/phpconfig.php");
    
    $name = $_SERVER["argv"][1];
    $protocol = $_SERVER["argv"][2];
    $port = $_SERVER["argv"][3];
    if (!preg_match('/^\d{1,5}$/', $port))
        $port = getservbyname($_SERVER["argv"][3], $protocol);
    $ip = $_SERVER["argv"][4];
    
    $hostname = gethostname();
    
    $query = "INSERT INTO 'erp_core_fail2ban' set hostname='" . addslashes($hostname) . "', name='" . addslashes($name) ."', protocol='" . addslashes($protocol) . "', port='" . addslashes($port) . "', ip='" . addslashes($ip) . "', created=NOW()";
    $result = mysql_query($query) or die('Query failed: ' . mysql_error());
    mysql_close($link);
    exit;
    ?>
    
  3. cron2ban

    您可以每分钟在crontab上运行它。它将检索最后添加的主机,并禁止它们。

    
    <?php
    // phpconfig.php will have database configuration settings
    require_once("/etc/fail2ban/phpconfig.php");
    
    // file with only a line, containing the last id banned
    $lastbanfile="/etc/fail2ban/lastban";
    
    $lastban = file_get_contents($lastbanfile);
    
    // select only hosts banned after last check
    $sql = "select id, ip from erp_core_fail2ban where id > $lastban";
    $result = mysql_query($sql) or die('Query failed: ' . mysql_error());
    mysql_close($link);
    
    while ($row = mysql_fetch_array($result)) {
            //
            $id = $row['id'];
            $ip = $row['ip'];
    
    
        exec("fail2ban-client set $jail banip $ip");
    
    } // $id contains the last banned host, add it to the config file file_put_contents($lastbanfile, $id); ?>
  4. phpconfig

    该文件转到/ etc / fail2ban并具有数据库配置和监狱选择。

    
    <?php
    // jail to be used
    $jail = "ssh";
    
    // file to keep the last ban
    $lastbanfile="/etc/fail2ban/lastban";
    
    // database configuration
    $dbserver="localhost";
    $dbuser="root";
    $dbpass="root";
    $dbname="fail2ban";
    
    // connect to database
    $link = mysql_connect($dbserver, $dbuser, $dbpass) or die('Could not connect: ' . mysql_error());
    mysql_select_db($dbname) or die('Could not select database');
    
    ?>
    

创建这些文件并从fail2ban更改配置:

actionban = .....插入新行以调用PHP脚本的行之后:

/root/fail2ban.php <name> <protocol> <port> <ip>

在所有服务器上使用此结构将确保每次一台主机禁止一台服务器,其他所有服务器也将禁止该主机。


3

因此,在观看相同的IP地址一个接一个击中我的Web服务器群集之后,我进行了很多研究。由于我使用的是AWS,因此我发现在测试5台服务器的前两天,可能会有一种简便的方法,并且可以很好地运行。

我建议的第一件事是暂时禁用SELinux,最后我们将对其进行处理。我不是SELinux专家,但是到目前为止,我的工作仍然有效。

主要要求是共享文件源,我使用AWS EFS。设置并装入新驱动器后,我将/etc/fail2ban/fail2ban.conf内的logtarget更改为EFS驱动器中的子文件夹。

logtarget = /efsmount/fail2ban/server1.log

然后,我编写了一个简单的过滤器,并将其放在/etc/fail2ban/filter.d/fail2ban-log.conf中

[Definition]

failregex = .* Ban <HOST>

ignoreregex =

将过滤器添加到/etc/fail2ban/jail.local

[fail2ban-log]
enabled = true
port = http,https
findtime = 86400 ; 1 day
logpath  = /efsmount/fail2ban/server1.log
        /efsmount/fail2ban/server2.log
        /efsmount/fail2ban/server3.log
        /efsmount/fail2ban/server4.log
maxretry = 1

然后重启fail2ban

sudo fail2ban-client reload

到目前为止,一切都很好!没有痛苦的部分是SELinux。在使fail2ban运行一段时间后,我运行了该命令,该命令将允许fail2ban通过过滤器。

sudo grep fail2ban /var/log/audit/audit.log | sudo audit2allow -M fail2ban-nfs

Audit2allow将告诉您运行此命令

sudo semodule -i fail2ban-nfs.pp

我仍然在这里和那里检查我的SELinux日志,以查看是否还有其他拒绝。如果有人对如何使用另一种很棒的方法获得清晰的SELinux有所提示。

sudo cat /var/log/audit/audit.log |grep fail2ban |grep denied

此时,重新启动fail2ban时仍然出现错误。在jail.local中使用action = action_mwl时存在错误。经过一番谷歌搜索后,我发现这是到目前为止。从我读到的内容来看,因为指向多个文件的logpath指令中的换行符。我尝试使用逗号,空格等,而action_mwl则不起作用。

action_mwm = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
             %(mta)s-whois-matches[name=%(__name__)s, dest="%(destemail)s", chain="%(chain)s"]

action = %(action_mwm)s

不要忘记重新打开SELinux!


像您一样,我在fail2ban上投入了很多精力(我已经发布了这个问题),但是经过更多研究后,我采纳了gparent的建议以删除fail2ban(请参阅对该问题的评论)
ndemou

2

我刚刚实现了这一点,到目前为止,它似乎运行良好。但是,我必须更新一些php,因为原始答案中的脚本使用了不推荐使用的功能。

这是更新的脚本

phpconfig.php

#!/usr/bin/php
<?php
// jail to be used
$jail = "ssh";

// file to keep the last ban
$lastbanfile="/etc/fail2ban/lastban";

// database configuration
$dbserver="[your.mysql.hostname]";
$dbport="[sql.port.default.is.3306]";
$dbuser="[sql.user";
$dbpass="[sql.password]";
$dbname="[sql.table]";

// connect to database
$link = mysqli_connect($dbserver, $dbuser, $dbpass, $dbname, $dbport) or die('Could not connect: ' . mysqli_error());
mysqli_select_db($link,$dbname) or die('Could not select database');

?>

fail2ban.php

#!/usr/bin/php 
<?php
require_once("/etc/fail2ban/phpconfig.php");

$name = $_SERVER["argv"][1];
$protocol = $_SERVER["argv"][2];
$port = $_SERVER["argv"][3];
if (!preg_match('/^\d{1,5}$/', $port))
    $port = getservbyname($_SERVER["argv"][3], $protocol);
$ip = $_SERVER["argv"][4];

$hostname = gethostname();

$query = "INSERT INTO erp_core_fail2ban (hostname,created,name,protocol,port,ip) VALUES ('$hostname',NOW(),'$name','$protocol','$port','$ip')";
echo $query;
$result = mysqli_query($link,$query) or die('Query failed: ' . mysqli_error($link));
mysqli_close($link);
exit;
?>

cron2ban.php

#!/usr/bin/php
<?php
// phpconfig.php will have database configuration settings
require_once("/etc/fail2ban/phpconfig.php");

// file with only a line, containing the last id banned
$lastbanfile="/etc/fail2ban/lastban";

$lastban = file_get_contents($lastbanfile);
// select only hosts banned after last check
$sql = "SELECT id,ip FROM erp_core_fail2ban WHERE id > $lastban";
$result = mysqli_query($link,$sql) or die('Query failed: ' . mysqli_error($link));
mysqli_close($link);

while ($row = mysqli_fetch_array($result)) {
        //
        $id = $row['id'];
        $ip = $row['ip'];

    exec("fail2ban-client set $jail banip $ip");


}

// $id contains the last banned host, add it to the config file
file_put_contents($lastbanfile, $id);
?>

另外,无论您在哪里放置fail2ban.php操作,都必须使其缩进至其上方的所有行。例如:

actionban = ...
            /etc/fail2ban/fail2ban.php

否则,fail2ban将不会启动。希望这对尝试部署此功能的人有所帮助。



0

是的,是的。两者都可以做到。

您需要找到一种合适的机制来共享IP列表。例如,如果您使用的是AWS,则可以利用s3。您可以在Linux主机之间或所有主机共用的数据库之间使用rsync。您可以使用自己喜欢的编程语言来提供一项服务,该语言提供一个宁静的API,供您选择。

用术语来说,如果与公众共享列表,则可以创建一个网站并托管一个简单的文本文件,其中一些已经提供了此类列表(据我所知并非来自众包)。如何创建自己的站点/服务将超出答案的范围,但是并不难做到。


0
Is there an easy way to share banned IPs between hosts I control?

相当手动的设置是更改调用iptables更新规则的配置,以便它调用您自己设计的脚本,该脚本循环遍历主机列表(从文件中读取?),并iptables通过SSH在每个主机上进行调用。您需要在所有为此配置的主机之间进行基于密钥的身份验证。诸如puppet之类的管理自动化工具可以使设置和维护变得更容易。这并不是非常有效,但是除非您看到大量的探测流量(和/或拥有大量的主机),否则我相信它已经足够了。如果只有几个主机,那么您甚至不需要遍历文件:将每个主机配置为仅按顺序调用其他主机。脚本编写工作将是最少的。

Is there a way to share banned IPs publicly?

毫无疑问,有很多方法。让上面的脚本将数据拖放到数据库中,并让客户端从中读取数据,轮询新规则并在新规则运行时运行它们。如果有很多规则,那么简单的“按需运行规则”就不完美主机正在提交信息,例如这种情况:

  1. 在12:00,服务器1表示“立即禁止X主机”,然后“在一小时内取消X主机”。
  2. 在12:45,服务器2说“现在禁止主机X”,然后“在一小时内取消主机X的主机”。
  3. 重叠意味着服务器3将禁止主机X一个小时,而不是一个小时+45分钟,如果按照顺序进行操作。

但这不是一个严重的问题,如果您对数据库有了更多的了解,并且认为值得付出努力,则可以更清晰地管理多个提交。

但是,将其作为公共服务运行会给您带来管理麻烦的世界:

  • 如果您获得大量用户,则管理带宽和其他资源。
  • 如果您尝试通过某种方式收取访问费用来解决资源问题,则可以安排和执行付款方式。
  • 在处理污染数据库的企图时,一个不好的角色试图将竞争对手作为商业上的不便或勒索行为而禁止其进入该列表所在的位置。
  • 当某人被禁止并认为自己不应该处理投诉时。
  • 与DDoS攻击其处理来,如果你的服务是所有成功的不便别人的机器人。
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.