Спільний доступ до заборонених IP-адрес заборонено


18

Я використовую fail2ban на всіх серверах із загальнодоступними сервісами, і мені цікаво:

  1. Чи є простий спосіб ділитися забороненими IP-адресами між хостами, якими я керую?
  2. Чи існує служба, яка збирає та публікує ці дані?

Я отримую незліченні спроби входу з першого дня налаштування цього сервера.


2
Ласкаво просимо в Інтернет. Немає сенсу публікувати цей список - ми всі дуже добре знаємо цю ситуацію.
Свен

1
Спасибі. Я вважаю, що приклади приємно мати, коли щось описують. Сміливо ігноруйте їх, якщо знаєте краще.
ndemou

Я видалив список IP-адрес і скористався можливістю перетворити ваше запитання на запитання. Мало того, що немає жодного сенсу розміщувати список, він також переймає питання і буде швидко застарівати.
геп

2
Також моя пропозиція - зняти fail2ban і перестати дбати про це. Якщо ви вимкнули автентифікацію пароля, ви можете зробити ще дуже мало. fail2ban використовувався в минулому, і додавання потенційної діри в безпеці, яка не дає абсолютно ніякої користі, є чистою втратою.
гені

@gparent: Щодо пропозицій: Спасибі - я ніколи раніше не переглядав історію експлуатації fail2ban. Для безпеки S / WI очікує кращого результату. Щодо ваших змін: я не вважаю, що добре так сильно змінювати питання. Якщо це погане питання, нехай плакат потерпить наслідки. У будь-якому випадку я залишу це як зараз.
ndemou

Відповіді:


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

    Ви ставите це для запуску на кронтаб, щохвилини. Він отримає останні додані хости та заборонить їх.

    
    <?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 адресу, яка потрапляє на моє скупчення веб-серверів. Оскільки я використовую AWS, я зрозумів, що це може бути простий спосіб, і він працює прекрасно в перші два дні тестування 5 серверів.

Перше, що я рекомендую, тимчасово вимкнути SELinux, ми з цим розберемося наприкінці. Я не експерт SELinux, але те, що я робив, працює до цих пір.

Основна вимога - це спільне джерело файлів, я використовую AWS EFS. Після того, як новий накопичувач буде налаштований і встановлений, я змінив logtarget всередині /etc/fail2ban/fail2ban.conf на підпапку на накопичувачі 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. Під час використання action = action_mwl в jail.local є помилка. Після трохи гуглив я знайшов це що працює до сих пір. З того, що я прочитав його через перерви рядків у директиві 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 не запуститься. Я сподіваюся, що це допомагає тому, хто намагається це розгорнути.


1

Альтернативою fail2banє DenyHosts, який постачається з функцією синхронізації. Інсталяція досить схожа на fail2ban, див. Підручник із Cyberciti для отримання більш детальної інформації .

Проблема полягає в тому, що служба синхронізації є централізованою, а вихідний код серверної сторони, здається, не доступний, тому ви не можете легко запустити власну службу DenyHosts і вам доведеться покладатися на третьої сторони (що може бути добре для деяких випадки використання).


FWIW посилання на службу синхронізації знижується сьогодні
ndemou

0

Так і так. І те й інше можна зробити.

Потрібно знайти відповідний механізм для спільного використання списку ІС. Якщо ви, наприклад, використовуєте AWS, ви можете скористатися s3. Ви можете використовувати rsync між хостами Linux або спільною для всіх хостів базою даних. Ви можете зв'язати послугу з улюбленою мовою програмування, яка забезпечує спокійний API, вибір - за вами.

З точки зору, якщо спільний спільний доступ до спільного ви можете створити веб-сайт і розмістити простий текстовий файл, деякі вже надають такі списки (не натовп, який я знаю). Як створити свій власний сайт / послугу не входить у відповідь, однак це не повинно бути дуже важко зробити.


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

Досить ручним налаштуванням було б змінити конфігурацію, яка закликає iptablesоновити правила, щоб вона викликала сценарій власного розробки, який проходить цикл через список хостів (прочитаний з файлу?) Та здійснює iptablesдзвінки по кожному через SSH. Вам знадобиться авторизація на основі ключів між усіма хостами, налаштованими для цього. Інструменти автоматизації адміністратора, такі як лялька, можуть полегшити налаштування та підтримку. Це не було б надзвичайно ефективно, але якщо ви не побачите величезну кількість пробного трафіку (та / або маєте величезну кількість хостів), то я впевнений, що це було б досить добре. Якщо у вас є лише кілька хостів, вам навіть не потрібно прокручувати файл: налаштовуйте кожного, щоб просто зателефонувати іншим за порядком. Зусилля сценаріїв будуть мінімальними.

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 - атаками , які будуть прийти , якщо ваш сервіс на все успішно утруднити чиї - боти.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.