Berbagi gagal2ban IP yang dilarang

18

Saya menggunakan fail2ban di semua server dengan layanan yang dapat dilihat secara publik dan saya bertanya-tanya:

  1. Apakah ada cara mudah untuk membagikan IP yang diblokir di antara host yang saya kontrol?
  2. Apakah ada layanan di luar sana yang mengumpulkan dan menerbitkan data itu?

Saya sudah mendapatkan upaya login yang tak terhitung sejak hari pertama menyiapkan server ini.

ndemou
sumber
2
Selamat datang di internet. Tidak ada gunanya memposting daftar ini - kita semua tahu situasi ini dengan sangat baik.
Sven
1
Terima kasih. Saya percaya bahwa contoh itu bagus untuk menggambarkan sesuatu. Jangan ragu untuk mengabaikannya jika Anda lebih tahu.
ndemou
Saya telah menghapus daftar IP dan mengambil kesempatan untuk mengubah pertanyaan Anda menjadi pertanyaan. Tidak hanya tidak ada gunanya memposting daftar, itu juga mengacaukan pertanyaan dan akan cepat usang.
gparent
2
Juga saran saya adalah untuk menghapus fail2ban dan berhenti peduli tentang ini. Jika Anda telah mematikan otentikasi kata sandi, ada sangat sedikit hal lain yang dapat Anda lakukan. fail2ban telah dieksploitasi di masa lalu dan menambahkan lubang keamanan potensial yang sama sekali tidak memberikan manfaat adalah kerugian bersih.
gparent
@gparent: Mengenai saran Anda: Terima kasih - Saya tidak pernah melihat riwayat exploit fail2ban sebelumnya. Untuk keamanan, S / WI akan mengharapkan rekam jejak yang lebih baik. Mengenai pengeditan Anda: Saya tidak percaya baik mengubah pertanyaan sebanyak itu. Jika ini adalah pertanyaan yang buruk, biarkan pengirimnya menanggung akibatnya. Pokoknya saya akan membiarkannya seperti sekarang.
ndemou

Jawaban:

8

Saya pernah melihat sistem untuk memusatkan data fail2ban di situs ini , dan membuat versi modifikasi. Basis datanya sama, tetapi saya mengubah dan membuat beberapa skrip.

Sistem saya memiliki 4 komponen:

  1. basis data fail2ban

    Ini adalah database MySQL yang hanya berisi satu 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

    Setiap kali sebuah host diblokir, itu akan mengisi basis data:

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

    Anda meletakkan ini di crontab, setiap menit. Ini akan mengambil host yang terakhir ditambahkan, dan mencekal mereka.

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

    File ini menuju ke / etc / fail2ban dan memiliki konfigurasi database dan pemilihan jail.

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

Buat file-file itu dan ubah konfigurasi dari fail2ban:

Setelah baris dengan actionban = .....baris baru dimasukkan untuk menjalankan skrip PHP:

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

Menggunakan struktur ini di semua server Anda akan memastikan bahwa setiap kali satu host diblokir di satu server, semua server lain juga akan mencekalnya.

ToriumBR
sumber
3

Jadi saya melakukan banyak penelitian tentang bagaimana melakukan ini setelah menonton alamat ip yang sama mengenai server web saya satu demi satu. Karena saya menggunakan AWS, saya pikir mungkin ada cara yang mudah dan berfungsi dengan baik dalam dua hari pertama saya menguji 5 server.

Hal pertama yang saya sarankan adalah menonaktifkan SELinux untuk sementara, kami akan mengatasinya pada akhirnya. Saya bukan ahli SELinux tetapi apa yang saya lakukan sejauh ini berhasil.

Persyaratan utama adalah sumber file bersama, saya menggunakan AWS EFS. Setelah drive baru disediakan dan dipasang, saya mengubah logtarget di dalam /etc/fail2ban/fail2ban.conf ke subfolder di drive EFS.

logtarget = /efsmount/fail2ban/server1.log

Lalu saya menulis filter sederhana dan meletakkannya di /etc/fail2ban/filter.d/fail2ban-log.conf

[Definition]

failregex = .* Ban <HOST>

ignoreregex =

Menambahkan filter ke /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

Kemudian restart fail2ban

sudo fail2ban-client reload

Sejauh ini baik! Tidak ada bagian yang menyakitkan adalah SELinux. Setelah saya membiarkan fail2ban berjalan sebentar, saya menjalankan perintah ini yang akan memungkinkan fail2ban melalui filter.

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

Audit2allow akan memberitahu Anda untuk menjalankan perintah ini

sudo semodule -i fail2ban-nfs.pp

Saya masih memeriksa log SELinux saya di sana-sini untuk melihat apakah ada lagi penolakan. Jika ada yang punya tip tentang cara mendapatkan SELinux yang jelas dengan metode lain yang akan luar biasa.

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

Pada titik ini saya masih mendapatkan kesalahan saat memulai kembali fail2ban. Ada bug saat menggunakan action = action_mwl di jail.local. Setelah sedikit googling saya menemukan ini yang berfungsi sejauh ini. Dari apa yang saya baca karena garis istirahat dalam arahan logat menunjuk ke beberapa file. Saya mencoba dengan koma, spasi, dll tidak ada yang berfungsi dengan 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

Jangan lupa untuk mengaktifkan SELinux kembali!

prophoto
sumber
Seperti Anda, saya telah menginvestasikan banyak upaya dalam fail2ban (saya telah memposting pertanyaan ini) tetapi setelah sedikit riset saya telah mengambil saran gparent untuk menghapus fail2ban (lihat komentar pada pertanyaan)
ndemou
2

Saya baru saja mengimplementasikan ini dan sejauh ini tampaknya berfungsi dengan baik. Namun, saya harus memperbarui beberapa php karena skrip dalam jawaban asli menggunakan fungsi yang sudah usang.

Berikut ini skrip yang diperbarui

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

Juga, di mana pun Anda menempatkan aksi fail2ban.php, itu harus diindentasi sebanyak baris di atasnya. Sebagai contoh:

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

Kalau tidak fail2ban tidak akan mulai. Saya harap ini membantu siapa pun yang mencoba menyebarkan ini.

Simba Lion
sumber
1

Alternatif untuk fail2banadalah DenyHosts yang dilengkapi dengan fungsi sinkronisasi. Instalasi cukup mirip dengan fail2ban, lihat tutorial Cyberciti untuk lebih jelasnya .

Masalahnya adalah bahwa layanan sinkronisasi terpusat dan kode sumber sisi server tampaknya tidak tersedia, sehingga Anda tidak dapat dengan mudah memulai layanan DenyHosts Anda sendiri dan Anda harus bergantung pada pihak ke-3 (yang mungkin baik untuk beberapa gunakan kasing).

Tombart
sumber
FWIW tautan ke layanan sinkronisasi turun hari ini
ndemou
0

Ya dan ya. Keduanya bisa dilakukan.

Anda perlu menemukan mekanisme yang sesuai untuk membagikan daftar IP. Jika Anda menggunakan AWS misalnya, Anda bisa memanfaatkan s3. Anda bisa menggunakan rsync antara host Linux, atau database yang umum untuk semua host. Anda dapat mengetuk layanan dengan bahasa pemrograman favorit Anda yang menyediakan API yang tenang pilihannya adalah milik Anda.

Dalam hal jika berbagi sekutu daftar publik Anda dapat membuat situs web dan meng-host file teks sederhana, beberapa sudah menyediakan daftar seperti itu (bukan kerumunan yang bersumber yang saya tahu). Cara membuat situs / layanan Anda sendiri akan berada di luar ruang lingkup jawaban, namun seharusnya tidak terlalu sulit untuk dilakukan.

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

Pengaturan yang cukup manual adalah mengubah konfigurasi yang memanggil iptablesuntuk memperbarui aturan sehingga memanggil skrip Anda sendiri yang menyusun loop melalui daftar host (baca dari file?) Dan membuat iptablespanggilan pada masing-masing melalui SSH. Anda akan memerlukan otentikasi berbasis kunci antara semua host yang dikonfigurasikan agar ini berfungsi. Alat otomatisasi admin seperti boneka dapat membuat pengaturan ini dan mempertahankannya lebih mudah. Ini tidak akan sangat efisien tetapi kecuali jika Anda melihat sejumlah besar lalu lintas menyelidik (dan / atau memiliki sejumlah besar host) maka saya yakin itu akan cukup baik. Jika Anda hanya memiliki beberapa host maka Anda bahkan tidak perlu mengulang-ulang file: konfigurasikan masing-masing untuk hanya memanggil yang lain secara berurutan. Upaya skrip akan minimal.

Is there a way to share banned IPs publicly?

Tidak ada keraguan banyak cara. Buat skrip di atas memasukkan data ke dalam DB dan minta klien membaca dari situ, polling untuk aturan baru dan menjalankannya saat mereka masuk. Sederhana "jalankan aturan seperti yang Anda lihat" tidak akan sempurna jika banyak host mengirimkan informasi, misalnya kasus ini:

  1. Pada 12:00 server 1 mengatakan "ban host X sekarang", dan "batalkan host X dalam satu jam".
  2. Pada 12:45 server 2 mengatakan "ban host X sekarang", dan "batalkan host X dalam satu jam".
  3. Tumpang tindih berarti server 3 akan melarang host X selama satu jam, bukan satu jam + 45 menit jika mengikuti instruksi secara berurutan.

tetapi ini seharusnya tidak menjadi masalah yang signifikan, dan jika Anda mendapatkan sedikit lebih pintar dengan database Anda dapat mengelola banyak pengiriman lebih bersih jika Anda memutuskan itu sepadan dengan usaha.

Menjalankannya sebagai layanan publik akan membuka Anda ke dunia admin yang rumit:

  • Mengelola bandwidth dan sumber daya lainnya jika Anda mendapatkan banyak pengguna.
  • Mengatur dan menegakkan metode pembayaran jika Anda mencoba menangani masalah sumber daya dengan menagih untuk akses dengan cara tertentu.
  • Berhadapan dengan upaya untuk mencemari basis data Anda, aktor jahat yang mencoba membuat pesaing dilarang dari tempat yang berlangganan daftar sebagai upaya ketidaknyamanan komersial atau pemerasan.
  • Berurusan dengan keluhan ketika seseorang dilarang dan berpikir mereka seharusnya tidak.
  • Menghadapi serangan DDoS yang akan datang jika layanan Anda sama sekali tidak berhasil membuat bot seseorang tidak nyaman.
David Spillett
sumber