Если у кого то есть возможность протестируйте.
Поддерживает ipfw и демоны dropbear и sshd.
Добавляет правило в ipfw под номером 54998
Установка:
в /etc/syslog.conf
Код: Выделить всё
auth.info;authpriv.info |exec /PATH/TO/sshglite -n 10
Код: Выделить всё
55100 17031 1019976 allow log logamount 10000 tcp from any to me dst-port 22 in via re0
-h - help
-n - количество попыток
-s - через сколько секунд фиксировать попытки (если за этот промежуток времени было > n то блокирует)
-f - когда удалять из истории, если не было попыток то обнуляем счетчик.
-l - отбаниваем пользователя (внимание работает только если кто пытался зайти по ssh, сам не отбанивает)
Вот что увидете в syslog
Код: Выделить всё
Feb 1 17:12:46 yashin sshglite[73907]: Start n=6, s=20, f=60, l=600
Feb 1 17:31:35 yashin sshglite[73907]: Find attempts <1> ip <121.207.230.69>
Feb 1 17:31:35 yashin sshglite[73907]: Delete ip <140.113.218.23> from history
Feb 1 17:31:38 yashin sshd[74222]: Invalid user test from 121.207.230.69
Feb 1 17:31:38 yashin sshglite[73907]: Find attempts <2> ip <121.207.230.69>
Feb 1 17:31:40 yashin sshd[74225]: Invalid user test from 121.207.230.69
Feb 1 17:31:40 yashin sshglite[73907]: Find attempts <3> ip <121.207.230.69>
Feb 1 17:31:43 yashin sshd[74227]: Invalid user test from 121.207.230.69
Feb 1 17:31:43 yashin sshglite[73907]: Find attempts <4> ip <121.207.230.69>
Feb 1 17:31:46 yashin sshd[74230]: Invalid user test from 121.207.230.69
Feb 1 17:31:46 yashin sshglite[73907]: Find attempts <5> ip <121.207.230.69>
Feb 1 17:31:48 yashin sshd[74232]: Invalid user test from 121.207.230.69
Feb 1 17:31:48 yashin sshglite[73907]: Find attempts <6> ip <121.207.230.69>
Feb 1 17:31:48 yashin sshglite[73907]: Add ip <121.207.230.69> to firewall rule
Код: Выделить всё
54998 3 180 deny ip from 121.207.230.69 to me
54999 0 0 deny ip from 95.178.44.26 to me in via re0
54999 0 0 deny ip from 92.48.196.110 to me in via re0
55100 17031 1019976 allow log logamount 10000 tcp from any to me dst-port 22 in via re0
65535 6484 879149 deny ip from any to any
Код: Выделить всё
#!/usr/bin/env perl
use strict;
use warnings;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Getopt::Long 'GetOptions';
# Var
my %list_ip;
# Options
my $help;
my $o_num = 6;
my $o_save_time = 20;
my $o_drop_time = 60;
my $o_life_time = 600;
GetOptions(
'h|help' => sub { $help = 1 },
'n=i' => sub { $o_num = $_[1] },
's=i' => sub { $o_save_time = $_[1] },
'f=i' => sub { $o_drop_time = $_[1] },
'l=i' => sub { $o_life_time = $_[1] },
);
die <<"EOF" if $help;
usage: $0 [OPTIONS]
sshglite -n 10 -s 10 -f 60
These options are available:
-help Show this message.
-n Number of failed login attempts. (Default: $o_num)
-s Time in seconds in which all failed login attempts must occur. (Default: $o_save_time sec.)
-f Time in seconds to forgotten login attempts. (Default: $o_drop_time sec.)
-l Time in seconds delete from firewall rule. (Default: $o_life_time sec.)
EOF
setlogsock('unix');
openlog("sshglite[$$]", "ndelay", 'LOG_AUTH');
syslog('LOG_INFO', "Start n=$o_num, s=$o_save_time, f=$o_drop_time, l=$o_life_time");
while (my $buf = <STDIN>) {
# sshd[96634]: Invalid user adolf from 61.100.30.241
# dropbear[18865]: Login attempt for nonexistent user from 189.16.156.242:46779
if ($buf =~ m/(dropbear|sshd)\[\d+\]:\s(Bad|Login|User|Invalid|Illegal|Failed|Did)\s(.*)\sfrom\s((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?|0)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?|0)){3})/gi) {
my $reg_ip = $4;
if (exists($list_ip{$reg_ip})) {
if (time - $list_ip{$reg_ip}{t} <= $o_save_time) {
$list_ip{$reg_ip}{n}++;
syslog('LOG_ERR', "Find attempts <$list_ip{$reg_ip}{n}> ip <$reg_ip>");
$list_ip{$reg_ip}{t} = time;
} else {
unless (exists($list_ip{$reg_ip}{b})) {
syslog('LOG_ERR', "Find attempts <1> ip <$reg_ip>");
$list_ip{$reg_ip} = {i => $reg_ip, n => 1, t => time};
}
}
if (time - $list_ip{$reg_ip}{t} >= $o_drop_time && !exists($list_ip{$reg_ip}{b})) {
syslog('LOG_ERR', "Delete ip <$reg_ip> from history");
delete $list_ip{$reg_ip} unless exists($list_ip{$reg_ip}{b});
}
if ($list_ip{$reg_ip}{n} >= $o_num && !exists($list_ip{$reg_ip}{b})) {
syslog('LOG_ERR', "Add ip <$reg_ip> to firewall rule");
$list_ip{$reg_ip}{b} = 1;
firewall('add', $list_ip{$reg_ip}{i});
}
} else {
syslog('LOG_ERR', "Find attempts <1> ip <$reg_ip>");
$list_ip{$reg_ip} = {i => $reg_ip, n => 1, t => time};
}
for my $key (keys %list_ip) {
if (time - $list_ip{$key}{t} >= $o_drop_time && $list_ip{$key}{i} && !exists($list_ip{$key}{b})) {
syslog('LOG_ERR', "Delete ip <$list_ip{$key}{i}> from history");
delete $list_ip{$key};
}
if (time - $list_ip{$key}{t} >= $o_life_time && $list_ip{$key}{i} && exists($list_ip{$key}{b})) {
syslog('LOG_ERR', "Delete ip <$list_ip{$key}{i}> from firewall rule");
firewall('delete', $list_ip{$key}{i});
delete $list_ip{$key};
}
}
}
}
sub firewall {
my ($a, $ip) = @_;
if ($a eq 'add') {
system("/sbin/ipfw -q add 54998 deny ip from $ip to me");
}
if ($a eq 'delete') {
system("/sbin/ipfw -q delete 54998 deny ip from $ip to me");
}
}
Спасибо.