Udostępnianie zablokowanych adresów IP fail2ban


18

Używam fail2ban na wszystkich serwerach z publicznie widocznymi usługami i zastanawiam się:

  1. Czy istnieje prosty sposób udostępniania zabronionych adresów IP między kontrolowanymi przeze mnie hostami?
  2. Czy istnieje usługa gromadząca i publikująca te dane?

Dostaję niezliczoną liczbę prób logowania od pierwszego dnia konfiguracji tego serwera.


2
Witamy w Internecie. Publikowanie tej listy nie ma sensu - wszyscy znamy tę sytuację zbyt dobrze.
Sven

1
Dzięki. Uważam, że przy opisie czegoś miło jest mieć przykłady. Możesz je zignorować, jeśli wiesz lepiej.
ndemou

Usunąłem listę adresów IP i skorzystałem z okazji, aby zamienić twoje pytanie w pytanie. Publikowanie listy nie tylko nie ma sensu, ale również zaśmieca pytanie i będzie szybko przestarzałe.
gparent

2
Moją propozycją jest również usunięcie fail2ban i przestanie się tym przejmować. Jeśli wyłączyłeś uwierzytelnianie hasłem, niewiele możesz zrobić. fail2ban był wykorzystywany w przeszłości, a dodanie potencjalnej luki w zabezpieczeniach, która nie zapewnia absolutnie żadnych korzyści, jest stratą netto.
gparent

@ rodzic: Jeśli chodzi o twoje sugestie: Dzięki - nigdy wcześniej nie patrzyłem na historię wykorzystania fail2ban. Dla bezpieczeństwa S / WI oczekuje lepszych wyników. Jeśli chodzi o twoje zmiany: nie sądzę, że dobrze jest zmieniać tak bardzo pytanie. Jeśli to złe pytanie, niech plakat poniesie konsekwencje. W każdym razie zostawię to tak, jak jest teraz.
ndemou

Odpowiedzi:


8

Kiedyś widziałem system centralizacji danych fail2ban na tej stronie i stworzyłem zmodyfikowaną wersję. Baza danych jest taka sama, ale zmieniłem i stworzyłem kilka skryptów.

Mój system ma 4 elementy:

  1. baza danych fail2ban

    Jest to baza danych MySQL zawierająca tylko jedną tabelę 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

    Za każdym razem, gdy host jest zbanowany, zapełni bazę danych:

    
    <?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

    Każdą minutę uruchamiasz na crontabie. Pobierze ostatnio dodane hosty i zablokuje je.

    
    <?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

    Ten plik trafia do / etc / fail2ban i ma konfigurację bazy danych oraz wybór więzienia.

    
    <?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');
    
    ?>
    

Utwórz te pliki i zmień konfigurację z fail2ban:

Po wierszu z actionban = .....wstawionym nowym wierszem, aby wywołać skrypt PHP:

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

Używanie tej struktury na wszystkich serwerach zapewni, że za każdym razem, gdy jeden host zostanie zbanowany na jednym serwerze, wszystkie inne serwery również go zbanują.


3

Zrobiłem więc wiele badań, jak to zrobić po tym, jak ten sam adres IP uderzył w mój klaster serwerów sieciowych jeden po drugim. Ponieważ korzystam z AWS, pomyślałem, że może być prosty sposób, który działa pięknie w pierwszych dwóch dniach testowania 5 serwerów.

Pierwszą rzeczą, którą polecam, jest tymczasowe wyłączenie SELinux, poradzimy sobie z tym na końcu. Nie jestem ekspertem SELinux, ale to, co zrobiłem, działa do tej pory.

Podstawowym wymaganiem jest udostępnione źródło plików, używam AWS EFS. Po udostępnieniu i zamontowaniu nowego dysku zmieniłem logtarget w /etc/fail2ban/fail2ban.conf na podfolder na dysku EFS.

logtarget = /efsmount/fail2ban/server1.log

Potem napisałem prosty filtr i umieściłem go w /etc/fail2ban/filter.d/fail2ban-log.conf

[Definition]

failregex = .* Ban <HOST>

ignoreregex =

Dodano filtr do /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

Następnie ponownie uruchomiłem fail2ban

sudo fail2ban-client reload

Jak na razie dobrze! Nie, bolesną częścią jest SELinux. Po tym, jak pozwoliłem trochę uruchomić fail2ban, uruchomiłem tę komendę, która pozwoliłaby fail2ban przez filtry.

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

Audit2allow powie Ci, aby uruchomić to polecenie

sudo semodule -i fail2ban-nfs.pp

Nadal sprawdzam moje dzienniki SELinuksa tu i tam, aby sprawdzić, czy są jakieś odmowy. Jeśli ktoś ma wskazówkę, jak uzyskać czysty SELinux za pomocą innej metody, która byłaby niesamowita.

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

W tym momencie wciąż pojawiały się błędy podczas restartowania fail2ban. Wystąpił błąd podczas używania action = action_mwl w jail.local. Po trochę googlingu znalazłem to, które działa do tej pory. Z tego, co przeczytałem, z powodu podziałów linii w dyrektywie logpath wskazujących na wiele plików. Próbowałem z przecinkami, spacjami itp. Nic innego nie działało z 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

Nie zapomnij ponownie włączyć SELinux!


Jak ty, ja zainwestowaliśmy dużo wysiłku w fail2ban (I zostały zaksięgowane to pytanie), ale po poradę nieco więcej badań Wziąłem gparent do usunięcia fail2ban (patrz komentarze na pytanie)
ndemou

2

Właśnie to zaimplementowałem i do tej pory wydaje się, że działa dobrze. Musiałem jednak zaktualizować część php, ponieważ skrypty w oryginalnej odpowiedzi używają przestarzałych funkcji.

Oto zaktualizowane skrypty

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);
?>

Ponadto, gdziekolwiek umieścisz akcję fail2ban.php, musi być wcięta tak samo jak linia powyżej. Na przykład:

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

W przeciwnym razie fail2ban nie uruchomi się. Mam nadzieję, że pomoże to każdemu, kto spróbuje to wdrożyć.


1

Alternatywą fail2banjest DenyHosts która pochodzi z funkcji synchronizacji. Instalacja jest dość podobna do fail2ban, zobacz więcej informacji w tutorialu Cyberciti .

Problem polega na tym, że usługa synchronizacji jest scentralizowana, a kod źródłowy po stronie serwera wydaje się być niedostępny, więc nie możesz łatwo uruchomić własnej usługi DenyHosts i musisz polegać na firmach trzecich (co może być w porządku dla niektórych przypadków użycia).


FWIW link do usługi synchronizacji jest dzisiaj
niedostępny

0

Tak i tak. Oba można zrobić.

Musisz znaleźć odpowiedni mechanizm do udostępniania listy adresów IP. Jeśli na przykład używasz AWS, możesz skorzystać z s3. Możesz użyć rsync między hostami Linux lub bazą danych wspólną dla wszystkich hostów. Możesz uruchomić usługę z ulubionym językiem programowania, który zapewnia spokojny interfejs API, wybór należy do Ciebie.

Jeśli udostępnisz listę publicznie sojusznikowi, możesz stworzyć stronę internetową i hostować prosty plik tekstowy, niektórzy już udostępniają takie listy (nie wiem, czy pochodzą z tłumu). Jak stworzyć własną stronę / usługę, nie można znaleźć odpowiedzi, jednak nie powinno to być trudne.


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

Dość ręczna konfiguracja polegałaby na zmianie konfiguracji wywołującej iptablesaktualizację reguł, tak aby wywoływał własny skrypt, który zapętla listę hostów (czyta z pliku?) I wykonuje iptablespołączenia na każdym za pośrednictwem SSH. Potrzebujesz uwierzytelnienia opartego na kluczach między wszystkimi skonfigurowanymi hostami, aby to działało. Narzędzia do automatyzacji administracji, takie jak marionetka, mogą ułatwić konfigurację i konserwację. Nie byłoby to zbyt wydajne, ale jeśli nie zobaczysz ogromnej ilości sondującego ruchu (i / lub masz ogromną liczbę hostów), to jestem pewien, że byłoby wystarczająco dobre. Jeśli masz tylko kilka hostów, nie musisz nawet zapętlać pliku: skonfiguruj każdy z nich, aby po prostu wywoływał pozostałe. Nakład skryptów będzie minimalny.

Is there a way to share banned IPs publicly?

Bez wątpienia jest wiele sposobów. Poproś skrypty o upuszczenie danych do bazy danych i poproś klientów, aby z nich odczytali, przeszukując nowe reguły i uruchamiając je w miarę wchodzenia. Proste „uruchom regułę tak, jak widzisz” nie będzie idealne, jeśli wielu gospodarze przesyłają informacje, na przykład ten przypadek:

  1. O 12:00 serwer 1 mówi „zablokuj hosta X teraz” i „odblokuj hosta X za godzinę”.
  2. O 12:45 serwer 2 mówi „zablokuj hosta X teraz” i „odblokuj hosta X za godzinę”.
  3. Nakładanie się oznacza, że ​​serwer 3 zbanuje hosta X na godzinę, a nie godzinę + 45 minut, jeśli wykona instrukcje w kolejności.

ale nie powinno to stanowić poważnego problemu, a jeśli staniesz się nieco bardziej sprytny z bazą danych, możesz lepiej zarządzać wieloma zgłoszeniami, jeśli zdecydujesz, że warto.

Uruchomienie tego jako usługi publicznej otworzyłoby cię w świecie problemów administracyjnych:

  • Zarządzanie przepustowością i innymi zasobami, jeśli zyskujesz wielu użytkowników.
  • Organizowanie i egzekwowanie metod płatności w przypadku próby rozwiązania problemu dotyczącego zasobów poprzez pobieranie opłat za dostęp w jakiś sposób.
  • Radząc sobie z próbami zanieczyszczenia bazy danych, zły aktor próbuje wyrzucić konkurenta z miejsc subskrybujących listę jako niedogodność komercyjna lub próba szantażu.
  • Radzenie sobie ze skargami, gdy ktoś zostaje zbanowany i uważa, że ​​nie powinien.
  • Radzenie sobie z atakami DDoS, które pojawią się, jeśli Twoja usługa w ogóle sprawi kłopot botom.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.