I don't know perl. I adapted the following script from something I found on the net, and I can't figure out why it doesn't work. It's supposed to monitor the system log for lines such as the following:
[tt]... sshd[9186]: Illegal user foo from x.x.x.x
... sshd[2756]: Did not receive identification string from y.y.y.y[/tt]
and generate a firewall rule to block any IP address that tries and fails to log in more than 3 times (I only allow public-key logins.) What actually happens is that it generates one rule and then stops working. Thanks for replies.
[tt]#!/usr/bin/perl
# usage: sshAction <logfile>
# example: sshAction /var/log/system.log
use File::Tail;
my %failedLogins;
my %alreadyBanned;
# ipfw rules in the range indicated below are reserved for use by this script.
my $startingRule = 100;
my $endingRule = 199;
my $LogAmount = 100;
my $Log;
die "usage " . "$0" . " <logfile>" unless (scalar(@ARGV) >= 1);
my $fileName = $ARGV[0];
my $Rule = $startingRule;
if ( $LogAmount ) { $Log = "log logamount $LogAmount"; }
$file = File::Tail->new(name=>$fileName, debug=>0, interval=>1);
while(my $line=$file->read)
{ if ( $line =~ /.*sshd.*Did not receive identification string from (.*)/ ||
$line =~ /.*sshd.*Timeout before authentication for (.*)/ ||
$line =~ /.*sshd.*Illegal user .* from (.*)/
)
{ if ( ++$failedLogins[$1] >= 3 && ! $alreadyBanned[$1] )
{ exec "ipfw -q add $Rule deny $Log all from $1 to any";
$alreadyBanned[$1] = "true";
if ( ++$Rule > $endingRule ) { $Rule = $startingRule; }
}
}
}[/tt]
[tt]... sshd[9186]: Illegal user foo from x.x.x.x
... sshd[2756]: Did not receive identification string from y.y.y.y[/tt]
and generate a firewall rule to block any IP address that tries and fails to log in more than 3 times (I only allow public-key logins.) What actually happens is that it generates one rule and then stops working. Thanks for replies.
[tt]#!/usr/bin/perl
# usage: sshAction <logfile>
# example: sshAction /var/log/system.log
use File::Tail;
my %failedLogins;
my %alreadyBanned;
# ipfw rules in the range indicated below are reserved for use by this script.
my $startingRule = 100;
my $endingRule = 199;
my $LogAmount = 100;
my $Log;
die "usage " . "$0" . " <logfile>" unless (scalar(@ARGV) >= 1);
my $fileName = $ARGV[0];
my $Rule = $startingRule;
if ( $LogAmount ) { $Log = "log logamount $LogAmount"; }
$file = File::Tail->new(name=>$fileName, debug=>0, interval=>1);
while(my $line=$file->read)
{ if ( $line =~ /.*sshd.*Did not receive identification string from (.*)/ ||
$line =~ /.*sshd.*Timeout before authentication for (.*)/ ||
$line =~ /.*sshd.*Illegal user .* from (.*)/
)
{ if ( ++$failedLogins[$1] >= 3 && ! $alreadyBanned[$1] )
{ exec "ipfw -q add $Rule deny $Log all from $1 to any";
$alreadyBanned[$1] = "true";
if ( ++$Rule > $endingRule ) { $Rule = $startingRule; }
}
}
}[/tt]