การแบ่งปันของ fail2ban ห้าม IP


18

ฉันใช้ fail2ban ในเซิร์ฟเวอร์ทั้งหมดที่มีบริการที่เปิดเผยต่อสาธารณะและฉันสงสัยว่า:

  1. มีวิธีง่าย ๆในการแบ่งปัน IP ที่ถูกแบนระหว่างโฮสต์ที่ฉันควบคุมหรือไม่?
  2. มีบริการออกจากที่นั่นเพื่อรวบรวมและเผยแพร่ข้อมูลดังกล่าวหรือไม่

ฉันได้รับความพยายามในการเข้าสู่ระบบนับไม่ถ้วนตั้งแต่วันที่ 1 ของการตั้งค่าเซิร์ฟเวอร์นี้


2
ยินดีต้อนรับสู่อินเทอร์เน็ต ไม่มีจุดในการโพสต์รายการนี้ - เราทุกคนรู้ว่าสถานการณ์นี้ทั้งหมดดีเกินไป
สเวน

1
ขอบคุณ ฉันเชื่อว่าตัวอย่างเป็นสิ่งที่ดีเมื่ออธิบายบางสิ่งบางอย่าง อย่าลังเลที่จะเพิกเฉยถ้าคุณรู้ดีกว่า
ndemou

ฉันได้ลบรายการ IP และใช้โอกาสเปลี่ยนคำถามของคุณเป็นคำถาม ไม่เพียงมีจุดในการโพสต์รายการเท่านั้น แต่มันยังรวมคำถามและจะล้าสมัยอย่างรวดเร็ว
เรียบร้อย

2
นอกจากนี้ข้อเสนอแนะของฉันคือการลบ fail2ban และหยุดการดูแลเกี่ยวกับเรื่องนี้ หากคุณปิดการพิสูจน์ตัวตนด้วยรหัสผ่านมีสิ่งอื่นที่คุณทำได้น้อยมาก fail2ban ได้รับการใช้ประโยชน์ในอดีตและเพิ่มช่องโหว่ความปลอดภัยที่อาจไม่ได้รับประโยชน์อย่างแน่นอนคือขาดทุนสุทธิ
ชัดเจน

@ โปร่งใส: เกี่ยวกับคำแนะนำของคุณ: ขอบคุณ - ฉันไม่เคยดูประวัติการใช้ 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

    คุณวางสิ่งนี้ให้ทำงานบน 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 เดียวกันกับที่โดนกลุ่มของเว็บเซิร์ฟเวอร์ เนื่องจากฉันใช้ 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 หลังจาก googling นิดหน่อยฉันก็พบสิ่งนี้ซึ่งใช้งานได้ดี จากสิ่งที่ฉันอ่านเพราะการแบ่งบรรทัดในคำสั่ง 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 (ฉันโพสต์คำถามนี้) แต่หลังจากการค้นคว้าเพิ่มเติมอีกเล็กน้อยฉันได้รับคำแนะนำที่ชัดเจนในการลบ 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

ใช่และใช่ ทั้งสามารถทำได้

คุณต้องหากลไกที่เหมาะสมในการแบ่งปันรายการ IP หากคุณใช้ 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 บอกว่า "ban host X now" และ "unban host X ภายในหนึ่งชั่วโมง"
  2. เมื่อเวลา 12:45 น. เซิร์ฟเวอร์ 2 บอกว่า "ห้าม host X ตอนนี้" และ "ยกเลิกการห้ามโฮสต์ X ในเวลาหนึ่งชั่วโมง"
  3. การทับซ้อนหมายถึงเซิร์ฟเวอร์ 3 จะห้ามโฮสต์ X เป็นเวลาหนึ่งชั่วโมงไม่ใช่ชั่วโมง +45 นาทีหากทำตามคำแนะนำตามลำดับ

แต่สิ่งนี้ไม่ควรเป็นปัญหาที่สำคัญและถ้าคุณได้รับฐานข้อมูลที่ชาญฉลาดมากขึ้นคุณสามารถจัดการการส่งหลายรายการได้อย่างชัดเจนยิ่งขึ้นหากคุณตัดสินใจว่ามันคุ้มค่ากับความพยายาม

การดำเนินการดังกล่าวในฐานะบริการสาธารณะจะเปิดคุณสู่โลกแห่งความยุ่งยากของผู้ดูแลระบบ:

  • การจัดการแบนด์วิดท์และทรัพยากรอื่น ๆ หากคุณได้รับผู้ใช้จำนวนมาก
  • การจัดเรียงและบังคับใช้วิธีการชำระเงินคุณควรลองจัดการกับปัญหาการจัดหาทรัพยากรใหม่โดยการเรียกเก็บเงินสำหรับการเข้าถึงในบางวิธี
  • การจัดการกับความพยายามในการสร้างมลภาวะฐานข้อมูลของคุณเป็นนักแสดงที่ไม่ดีที่พยายามทำให้คู่แข่งถูกแบนจากสถานที่ที่สมัครรับรายชื่อเพื่อความไม่สะดวกเชิงพาณิชย์หรือการพยายามแบล็กเมล์
  • การจัดการกับข้อร้องเรียนเมื่อมีคนถูกแบนและคิดว่าไม่ควรทำ
  • การจัดการกับการโจมตี DDoS ซึ่งจะเกิดขึ้นหากบริการของคุณประสบความสำเร็จในการทำให้บ็อตของใครบางคนไม่สะดวก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.