Files
parserfilter/lib/stats.pm
2024-03-09 15:36:42 +01:00

91 lines
3.3 KiB
Perl

package My::parser::stats;
use strict;
use warnings;
use DBI;
sub new {
my $class = shift;
my $config = shift;
my $self = {};
bless ($self, $class);
$self->{'config'} = $config;
my $short_time = $config->get_as_single_val('config','short') || die "Failed to get short value";
my $long_time = $config->get_as_single_val('config','long') || die "Failed to get long value";
$self->{'short'} = $short_time;
$self->{'long'} = $long_time;
return $self;
}
sub recent_hostile {
my $self = shift;
$self->{'dbh'} = $self->{'config'}->get_dbh unless($self->{'dbh'});
my $sth = $self->{'dbh'}->prepare("
SELECT COUNT(1)
FROM reject
WHERE time > DATE_SUB(NOW(), INTERVAL 5 MINUTE)")
|| return { retval => 0, retmsg => 'Failed checking for rejects last 5 minutes: '.DBI::errstr };
$sth->execute() || return { retval => 0, retmsg => 'Failed execute on checking for rejects last 5 minutes: '.DBI::errstr };
my $rows = $sth->fetchrow_arrayref->[0];
return { retval => 1, rows => $rows, retmsg => $rows.' the last 5 minutes' };
}
sub checker {
my $self = shift;
my $tocheck = shift;
my $host = $tocheck->{'host'};
my $asn = $tocheck->{'asn'};
my $iso = $tocheck->{'iso'};
unless($self && $host) {
return { retval => 0, retmsg => "Too few variables to run My::parser::stats->checker, got host($host), asn($asn), iso($iso)" };
}
my $retval;
my $rows;
my $msg;
my $return = { retval => 1 };
my @times = ($self->{'short'},$self->{'long'});
#### Mapping between checks and tables in db
my %checks = ('reject' => 'reject','blocks' => 'reject_iptables','iso' => 'reject','asn' => 'reject', 'block_iso' => 'reject_iptables', 'block_asn' => 'reject_iptables');
#### Mapping between checks and column in db
my %values = ('reject' => 'ip','blocks' => 'ip', 'iso' => 'iso', 'asn' => 'asn', 'block_iso' => 'iso', 'block_asn' => 'asn');
my %keys = ('reject' => $host, 'blocks' => $host, 'iso' => $iso, 'block_iso' => $iso, 'asn' => $asn, 'block_asn' => $asn);
$self->{'dbh'} = $self->{'config'}->get_dbh unless($self->{'dbh'});
foreach my $time(@times) {
foreach my $c(keys %checks) {
my $fromcheck = $self->check($keys{$c},$time,$values{$c},$checks{$c});
if($fromcheck->{'retval'}) {
my $temp = $fromcheck->{'rows'};
$return->{$time}->{$c} = $temp;
# } else {
# $self->{'config'}->{'logger'}->log("Check failed: $fromcheck->{'retmsg'}");
}
}
}
return $return;
}
sub check {
my $self = shift;
my $host = shift;
my $allowed_time = shift;
my $value = shift;
my $table = shift;
my $retval;
my $rows;
my $msg;
if($host && $allowed_time && $value && $table) {
my $sth = $self->{'dbh'}->prepare("
SELECT COUNT(1)
FROM $table
WHERE $value = ? AND
time > DATE_SUB(NOW(), INTERVAL ? MINUTE)")
|| return { retval => 0, retmsg => "Checking $host in $table for $value in the last $allowed_time minutes failed: ".DBI::errstr };
$sth->execute($host,$allowed_time) || return { retval => 0, retmsg => "Execute failed on $table, checking for $host in $allowed_time: ".DBI::errstr };
my $rows = $sth->fetchrow_arrayref->[0];
return { retval => 1, rows => $rows, retmsg => "$rows in $allowed_time minutes" };
} else {
return { retval => 0, retmsg => "Check called with too few arguments, we got host: $host, allowed_time: $allowed_time, value: $value, table: $table" };
}
}
1;