From 6fbfbcb3b3f72bedbd82614dc07282016c321f75 Mon Sep 17 00:00:00 2001 From: Reio Remma Date: Sat, 29 Apr 2023 23:39:50 +0300 Subject: [PATCH] Add auth failures summary by IP addresses. --- etc/logwatch/conf/services/opensmtpd.conf | 1 + etc/logwatch/scripts/services/opensmtpd | 46 ++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/etc/logwatch/conf/services/opensmtpd.conf b/etc/logwatch/conf/services/opensmtpd.conf index 7835152..b3404d1 100644 --- a/etc/logwatch/conf/services/opensmtpd.conf +++ b/etc/logwatch/conf/services/opensmtpd.conf @@ -74,6 +74,7 @@ $threshold_senders = 2 $threshold_recipients = 1 $threshold_smtp_failures = 2 $threshold_auth = 0 +$threshold_auth_failures_ip = 1 $threshold_auth_failures_user = 0 $threshold_auth_ip_warning = 3 # Always display and warn about users with logins from many different IPs. $threshold_relay = 2 diff --git a/etc/logwatch/scripts/services/opensmtpd b/etc/logwatch/scripts/services/opensmtpd index 5d42cdd..6ab0f01 100644 --- a/etc/logwatch/scripts/services/opensmtpd +++ b/etc/logwatch/scripts/services/opensmtpd @@ -32,6 +32,7 @@ my %Defaults = ( threshold_recipients => 0, threshold_smtp_failures => 0, threshold_auth => 0, + threshold_auth_failures_ip => 0, threshold_auth_failures_user => 0, threshold_auth_ip_warning => 3, threshold_relay => 0, @@ -643,7 +644,13 @@ sub print_summary() { } if( $var->{auth}{failure} ) { - my $failures = auth_summary_users('Authentication failures', $var->{auth}{failure}, $Opts{threshold_auth_failures}, $geoip_bin, $geoip_dat ); + my $failures = auth_summary_users('Authentication failures by user', $var->{auth}{failure}, $Opts{threshold_auth_failures_user}, $geoip_bin, $geoip_dat ); + + if( $failures ) { + push @ret, $failures; + } + + $failures = auth_summary_ips('Authentication failures by IP', $var->{auth}{failure}, $Opts{threshold_auth_failures_ip}, $geoip_bin, $geoip_dat ); if( $failures ) { push @ret, $failures; @@ -829,6 +836,43 @@ sub auth_summary_users($$$$$) { } } +sub auth_summary_ips($$$$$) { + my ( $title, $arr, $threshold, $geoip_bin, $geoip_dat ) = @_; + + $threshold = 0 unless $threshold; + + if( $arr ) { + my %ips; + my %totals; + my $ret = ''; + + for my $user ( keys %{ $arr } ) { + for my $ip ( keys %{ $arr->{$user} } ) { + $ips{$ip}{$user} += $arr->{$user}{$ip}; + $totals{$ip} += $arr->{$user}{$ip}; + } + } + + for my $ip ( sort { $totals{$b} <=> $totals{$a} or ipcmp( $a, $b ) } keys %ips ) { + my $userstr = ''; + my $users = $ips{$ip}; + + for my $user ( sort { $users->{$b} <=> $users->{$a} or $a cmp $b } keys %{ $users } ) { + $userstr .= sprintf("%16s %s\n", $users->{$user}, $user ); + } + + if( $totals{$ip} > $threshold ) { + $ret .= line( $totals{$ip}, geoip( $geoip_bin, $geoip_dat, $ip ) ) . $userstr; + } + } + + return unless $ret ne ''; + + return title( $title . ( $threshold > 0 ? " (threshold of $threshold)" : "") ) . $ret; + + } +} + print_summary(); #