Chia sẻ IP bị lỗi fail2ban


18

Tôi đang sử dụng fail2ban trên tất cả các máy chủ có dịch vụ hiển thị công khai và tôi tự hỏi:

  1. Có cách nào dễ dàng để chia sẻ IP bị cấm giữa các máy chủ tôi kiểm soát không?
  2. Có một dịch vụ ngoài đó thu thập và xuất bản dữ liệu đó?

Tôi đã nhận được vô số lần đăng nhập kể từ ngày 1 khi thiết lập máy chủ này.


2
Chào mừng bạn đến với internet. Không có điểm nào trong việc đăng danh sách này - tất cả chúng ta đều biết tình huống này quá rõ.
Sven

1
Cảm ơn. Tôi tin rằng các ví dụ là tốt đẹp để có khi mô tả một cái gì đó. Hãy bỏ qua chúng nếu bạn biết rõ hơn.
ndemou

Tôi đã xóa danh sách IP và nhân cơ hội biến câu hỏi của bạn thành câu hỏi. Không chỉ không có điểm trong việc đăng danh sách, nó còn làm mờ câu hỏi và sẽ nhanh chóng bị lỗi thời.
gparent

2
Ngoài ra đề nghị của tôi là loại bỏ fail2ban và ngừng quan tâm về điều này. Nếu bạn đã tắt xác thực mật khẩu, bạn có thể làm rất ít việc khác. fail2ban đã được khai thác trong quá khứ và thêm một lỗ hổng bảo mật tiềm năng cung cấp hoàn toàn không có lợi ích là một tổn thất ròng.
gparent

@gparent: Liên quan đến các đề xuất của bạn: Cảm ơn - Tôi chưa bao giờ nhìn vào lịch sử khai thác fail2ban trước đây. Để bảo mật, S / WI sẽ mong đợi một hồ sơ theo dõi tốt hơn. Về các chỉnh sửa của bạn: Tôi không tin rằng thật tốt khi thay đổi một câu hỏi nhiều như vậy. Nếu đó là một câu hỏi tồi hãy để người đăng chịu hậu quả. Dù sao tôi sẽ rời khỏi nó như bây giờ.
ndemou

Câu trả lời:


8

Tôi đã từng thấy một hệ thống tập trung dữ liệu fail2ban trên trang web này và tạo ra một phiên bản sửa đổi. Cơ sở dữ liệu là như nhau, tôi đã thay đổi và tạo ra một số tập lệnh.

Hệ thống của tôi có 4 thành phần:

  1. cơ sở dữ liệu fail2ban

    Đó là cơ sở dữ liệu MySQL chỉ chứa một bảng 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

    Mỗi khi máy chủ bị cấm, nó sẽ điền vào cơ sở dữ liệu:

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

    Bạn đặt cái này để chạy trên crontab, mỗi phút. Nó sẽ lấy các máy chủ được thêm vào cuối cùng và cấm chúng.

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

    Tập tin này đi đến / etc / fail2ban và có cấu hình cơ sở dữ liệu và lựa chọn tù.

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

Tạo các tệp đó và thay đổi cấu hình từ fail2ban:

Sau dòng có actionban = .....một hàng mới được chèn để gọi tập lệnh PHP:

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

Sử dụng cấu trúc này trên tất cả các máy chủ của bạn sẽ đảm bảo rằng mỗi khi một máy chủ bị cấm trên một máy chủ, tất cả các máy chủ khác cũng sẽ cấm nó.


3

Vì vậy, tôi đã thực hiện một loạt nghiên cứu về cách thực hiện việc này sau khi xem cùng một địa chỉ IP lần lượt đánh vào cụm máy chủ web của tôi. Vì tôi đang sử dụng AWS, tôi cho rằng có thể có một cách dễ dàng và nó hoạt động rất tốt trong hai ngày đầu thử nghiệm 5 máy chủ.

Điều đầu tiên tôi khuyên là tạm thời vô hiệu hóa SELinux, chúng tôi sẽ giải quyết vấn đề này vào cuối. Tôi không phải là chuyên gia của Selinux nhưng những gì tôi đã làm cho đến nay.

Yêu cầu chính là nguồn tệp chia sẻ, tôi sử dụng AWS EFS. Khi ổ đĩa mới được cung cấp và gắn kết, tôi đã thay đổi logtarget bên trong /etc/fail2ban/fail2ban.conf thành thư mục con trong ổ EFS.

logtarget = /efsmount/fail2ban/server1.log

Sau đó, tôi đã viết một bộ lọc đơn giản và đặt nó vào /etc/fail2ban/filter.d/fail2ban-log.conf

[Definition]

failregex = .* Ban <HOST>

ignoreregex =

Đã thêm bộ lọc vào /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

Sau đó khởi động lại fail2ban

sudo fail2ban-client reload

Càng xa càng tốt! Không có phần đau đớn là SELinux. Sau khi tôi để fail2ban chạy một chút, tôi đã chạy lệnh này cho phép fail2ban thông qua các bộ lọc.

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

Audit2allow sẽ bảo bạn chạy lệnh này

sudo semodule -i fail2ban-nfs.pp

Tôi vẫn đang kiểm tra nhật ký SELinux của mình ở đây và ở đó để xem liệu có thêm từ chối nào không. Nếu bất cứ ai có một mẹo về cách làm cho Selinux rõ ràng đó bằng một phương pháp khác sẽ rất tuyệt vời.

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

Tại thời điểm này tôi vẫn gặp lỗi khi khởi động lại fail2ban. Có một lỗi khi sử dụng action = action_mwl trong jail.local. Sau một chút loay hoay, tôi thấy cái này đang hoạt động cho đến nay. Từ những gì tôi đọc được vì dòng ngắt trong chỉ thị logpath trỏ đến nhiều tệp. Tôi đã thử với dấu phẩy, dấu cách, v.v. không có gì khác hoạt động với 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

Đừng quên bật lại Selinux!


Cũng giống như bạn, tôi đã đầu tư rất nhiều công sức trong fail2ban (tôi đã đăng câu hỏi này) nhưng sau khi tư vấn nhiều hơn một chút nghiên cứu tôi đã lấy gparent để loại bỏ fail2ban (xem bình luận về vấn đề)
ndemou

2

Tôi mới thực hiện điều này và cho đến nay nó dường như đang hoạt động tốt. Tuy nhiên, tôi đã phải cập nhật một số php vì các tập lệnh trong câu trả lời ban đầu sử dụng các hàm không dùng nữa.

Dưới đây là các kịch bản cập nhật

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

Ngoài ra, bất cứ nơi nào bạn đặt hành động fail2ban.php, nó phải được thụt lề nhiều như dòng trên nó. Ví dụ:

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

Nếu không fail2ban sẽ không bắt đầu. Tôi hy vọng điều này sẽ giúp bất cứ ai cố gắng triển khai điều này.


1

Một thay thế cho fail2bandenyhosts mà đi kèm với một tính năng đồng bộ hóa. Cài đặt khá giống với fail2ban, xem hướng dẫn của Cyberciti để biết thêm chi tiết .

Vấn đề là dịch vụ đồng bộ hóa tập trung và mã nguồn của phía máy chủ dường như không khả dụng, do đó bạn không thể dễ dàng bắt đầu dịch vụ Denyhost của riêng mình và bạn phải dựa vào bên thứ 3 (có thể tốt cho một số người trường hợp sử dụng).


0

Vâng và vâng. Cả hai đều có thể được thực hiện.

Bạn cần tìm một cơ chế phù hợp để chia sẻ danh sách IP. Nếu bạn đang sử dụng AWS chẳng hạn, bạn có thể tận dụng s3. Bạn có thể sử dụng rsync giữa các máy chủ Linux hoặc cơ sở dữ liệu chung cho tất cả các máy chủ. Bạn có thể loại bỏ một dịch vụ với ngôn ngữ lập trình yêu thích cung cấp API yên tĩnh, sự lựa chọn là của bạn.

Về mặt nếu chia sẻ danh sách đồng minh công khai, bạn có thể tạo một trang web và lưu trữ một tệp văn bản đơn giản, một số đã cung cấp các danh sách đó (không phải đám đông có nguồn gốc mà tôi biết). Cách tạo trang web / dịch vụ của riêng bạn sẽ nằm ngoài phạm vi của câu trả lời, tuy nhiên không nên quá khó thực hiện.


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

Một thiết lập khá thủ công sẽ là thay đổi cấu hình gọi iptablesđể cập nhật các quy tắc để nó gọi một tập lệnh của chính bạn nghĩ ra các vòng lặp thông qua một danh sách các máy chủ (đọc từ một tệp?) Và thực hiện các iptablescuộc gọi trên mỗi thông qua SSH. Bạn sẽ cần auth dựa trên khóa giữa tất cả các máy chủ được cấu hình để làm việc này. Các công cụ tự động hóa của quản trị viên như con rối có thể giúp thiết lập và duy trì nó dễ dàng hơn. Điều này sẽ không hiệu quả khủng khiếp nhưng trừ khi bạn thấy một lượng lớn lưu lượng truy cập thăm dò (và / hoặc có số lượng lớn máy chủ lưu trữ) thì tôi chắc chắn rằng nó sẽ đủ tốt. Nếu bạn chỉ có một vài máy chủ thì bạn thậm chí không cần phải lặp qua một tệp: cấu hình từng máy chủ để chỉ gọi các máy chủ khác theo thứ tự. Nỗ lực kịch bản sẽ là tối thiểu.

Is there a way to share banned IPs publicly?

Không có nghi ngờ nhiều cách. Có (các) tập lệnh ở trên thả dữ liệu vào DB và để khách hàng đọc từ đó, bỏ phiếu cho các quy tắc mới và chạy chúng khi chúng đến. Cách đơn giản "chạy quy tắc như bạn thấy" sẽ không hoàn hảo nếu nhiều máy chủ đang gửi thông tin, ví dụ như trường hợp này:

  1. Lúc 12:00 máy chủ 1 nói "cấm máy chủ X ngay bây giờ" và "máy chủ unban X trong một giờ".
  2. Lúc 12:45, máy chủ 2 nói "cấm máy chủ X ngay bây giờ" và "máy chủ unban X trong một giờ".
  3. Sự chồng lấp có nghĩa là máy chủ 3 sẽ cấm máy chủ X trong một giờ chứ không phải một giờ + 45 phút nếu làm theo hướng dẫn theo thứ tự.

nhưng đây không phải là một vấn đề quan trọng và nếu bạn thông minh hơn một chút với cơ sở dữ liệu, bạn có thể quản lý nhiều bài nộp một cách sạch sẽ hơn nếu bạn quyết định rằng nó đáng để nỗ lực.

Hoạt động như một dịch vụ công cộng sẽ mở ra cho bạn một thế giới rắc rối của quản trị viên:

  • Quản lý băng thông và các tài nguyên khác nếu bạn có được nhiều người dùng.
  • Sắp xếp và thực thi các phương thức thanh toán, bạn nên thử đối phó với vấn đề cung cấp lại bằng cách tính phí để truy cập theo một cách nào đó.
  • Đối phó với các nỗ lực gây ô nhiễm cơ sở dữ liệu của bạn, một diễn viên xấu cố gắng để đối thủ bị cấm ở những nơi đăng ký vào danh sách như một sự bất tiện thương mại hoặc cố gắng tống tiền.
  • Xử lý khiếu nại khi ai đó bị cấm và nghĩ rằng họ không nên.
  • Xử lý các cuộc tấn công DDoS sẽ đến nếu dịch vụ của bạn hoàn toàn thành công trong việc làm phiền các bot của ai đó.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.