########################################################################## ########################################################################## # # Barracuda Spam Firewall parser # Written by Hugo van der Kooij (HvdK) # Based on existing code of logwatch and the docuemntation on: # http://www.barracudanetworks.com/ns/downloads/BarracudaSyslog.pdf # # Revision 0.9 2007/08/27 HvdK # Started the scanner for the logs of Barracuda Spam firewalls. ######################################################## ## Copyright (c) 2008 Hugo van der Kooij ## Covered under the included MIT/X-Consortium License: ## http://www.opensource.org/licenses/mit-license.php ## All modifications and contributions by other persons to ## this script are assumed to have been donated to the ## Logwatch project and thus assume the above copyright ## and licensing terms. If you want to make contributions ## under your own copyright or a different license this ## must be explicitly stated in the contribution an the ## Logwatch project reserves the right to not accept such ## contributions. If you have made significant ## contributions to this script and want to claim ## copyright please contact logwatch-devel@lists.sourceforge.net. ######################################################### my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; sub Round { my $input = $_[0]; my $digits = $_[1]; my $factor = (10**$digits); my $result = (int( ($input * $factor) + .5) / $factor); return $result; } # Text messages for the RECV and SCAN action codes: $RSaction[0] = "Allowed Message(s)"; $RSaction[1] = "Aborted Message(s)"; $RSaction[2] = "Blocked Message(s)"; $RSaction[3] = "Quarantined Message(s)"; $RSaction[4] = "Tagged Message(s)"; $RSaction[5] = "Deferred Message(s)"; $RSaction[6] = "Per-User Quarantined Message(s)"; $RSaction[7] = "Whitelisted Message(s)"; # Text messages for the SEND action codes: $Saction[0] = "UNKNOWN"; $Saction[1] = "Delivered Message(s)"; $Saction[2] = "Rejected Message(s)"; $Saction[3] = "Deferred Message(s)"; $Saction[4] = "Expired Message(s)"; # Text messages for the reason codes: $Reason[0] = "Allowed"; $Reason[1] = "Virus detected"; $Reason[2] = "Banned attachment"; $Reason[3] = "RBL Match"; $Reason[4] = "Rate Control"; $Reason[5] = "Too Many Message(s) In Session"; $Reason[6] = "Timeout Exceeded"; $Reason[7] = "No such Domain"; $Reason[8] = "No such User"; $Reason[9] = "Subject Filter Match"; $Reason[10] = "UNKNOWN (10)"; $Reason[11] = "Client IP"; $Reason[12] = "Recipient Address Rejected"; $Reason[13] = "No valid Recipients"; $Reason[14] = "Domain Not Found"; $Reason[15] = "Sender Address Rejected"; $Reason[16] = "UNKNOWN (16)"; $Reason[17] = "Need Fully Qualified Recipient"; $Reason[18] = "Need Fully Qualified Sender"; $Reason[19] = "Unsupported Command"; $Reason[20] = "MAIL FROM Syntax Error"; $Reason[21] = "Bad Address Syntax"; $Reason[22] = "RCPT TO Syntax Error"; $Reason[23] = "Send EHLO/HELO First"; $Reason[24] = "Need MAIL Command"; $Reason[25] = "Nested MAIL Comand"; $Reason[26] = "UNKNOWN (26)"; $Reason[27] = "EHLO/HELO Syntax Error"; $Reason[28] = "UNKNOWN (28)"; $Reason[29] = "UNKNOWN (29)"; $Reason[30] = "Mail Protocol Error"; $Reason[31] = "Score"; $Reason[32] = "UNKNOWN (32)"; $Reason[33] = "UNKNOWN (33)"; $Reason[34] = "Header Filter Match"; $Reason[35] = "Sender Block/Accept"; $Reason[36] = "Recipient Block/Accept"; $Reason[37] = "Body Filter Match"; $Reason[38] = "Message Size Bypass"; $Reason[39] = "Intention Analysis Match"; $Reason[40] = "SPF/Caller-ID"; $Reason[41] = "Client Host Rejected"; $Reason[42] = "UNKNOWN (42)"; $Reason[43] = "UNKNOWN (43)"; $Reason[44] = "Authentication Not Enabed"; $Reason[45] = "Allowed Message Size Exceeded"; $Reason[46] = "Too Many Recipients"; $Reason[47] = "Need RCPT Command"; $Reason[48] = "DATA Syntax Error"; $Reason[49] = "Internal Error"; $Reason[50] = "Too Many Hops"; $Reason[51] = "UNKNOWN (51)"; $Reason[52] = "UNKNOWN (52)"; $Reason[53] = "UNKNOWN (53)"; $Reason[54] = "UNKNOWN (54)"; $Reason[55] = "Invalid Parameter Syntax"; $Reason[56] = "STARTTLS Syntax Error"; $Reason[57] = "TLS Allready Active"; $Reason[58] = "Too Many Errors"; $Reason[59] = "Need STARTTLS First"; $Reason[60] = "Spam Fingerprint Found"; while (defined($ThisLine = )) { if ( ($address, $id, $start_time, $end_time, $type, $info) = ($ThisLine =~ /([^\s]+)\s([^\s]+)\s(\d+)\s(\d+)\s(RECV|SCAN|SEND)\s(.*)$/) ) { ($ip) = ($address =~ /\[(.*)\]/); $time = ($end_time - $start_time); if ( $type =~ /RECV/ ) { if ( ($sender, $recipient, $action, $reason, $reason_extra) = ($info =~ /([^\s]+)\s([^\s]+)\s(\d+)\s(\d+)\s(.*)$/) ) { $RECVaction{$action}++; $RECVreason{$reason}++; $RECVreason_extra{$reason_extra}++; if ( ($reason_extra =~ /^-[| ]$/) or ($reason < 1) ) { } else { $RECVReasons{$reason_extra}++; $RECVReason{$reason_extra} = $reason; } $RECVtime_total{$action} = ($RECVtime_total{$action} + $time); $RECVtime_div{$action}++; if ($time < $RECVtime_min{$action}) { $RECVtime_min{$action} = $time; } elsif ($RECVtime_min{$action} eq "") { $RECVtime_min{$action} = $time; } if ($time > $RECVtime_max{$action}) { $RECVtime_max{$action} = $time; } elsif ($RECVtime_max{$action} eq "") { $RECVtime_max{$action} = $time; } } else { push @OtherList,$ThisLine; } } elsif ( $type =~ /SCAN/ ) { if ( ($enc, $sender, $recipient, $score, $action, $reason, $reason_extra, $subject) = ($info =~ /([^\s]+)\s([^\s]+)\s([^\s]+)\s([-\.\d+]+)\s(\d+)\s(\d+)\s(.*)\sSUBJ:(.*)$/) ) { if ( ($size) = ($reason_extra =~ /\sSZ:(\d+)$/) ) { $reason_extra =~ s/\sSZ:(\d+)$//; $SCANsize_total{$action} = ($SCANsize_total{$action} + $size); $SCANsize_div{$action}++; } $SCANaction{$action}++; $SCANreason{$reason}++; if ($score =~ /^-$/) { } else { $score_total{$action} = ($score_total{$action} + $score); $score_div{$action}++; if ($score < $score_min{$action}) { $score_min{$action} = $score; } elsif ($score_min{$action} eq "") { $score_min{$action} = $score; } if ($score > $score_max{$action}) { $score_max{$action} = $score; } elsif ($score_max{$action} eq "") { $score_max{$action} = $score; } } if ($reason_extra =~ /^-$/) { } else { $SCANReasons{$reason_extra}++; $SCANReason{$reason_extra} = $reason; } $SCANtime_total{$action} = ($SCANtime_total{$action} + $time); $SCANtime_div{$action}++; if ($time < $SCANtime_min{$action}) { $SCANtime_min{$action} = $time; } elsif ($SCANtime_min{$action} eq "") { $SCANtime_min{$action} = $time; } if ($time > $SCANtime_max{$action}) { $SCANtime_max{$action} = $time; } elsif ($SCANtime_max{$action} eq "") { $SCANtime_max{$action} = $time; } } else { push @OtherList,$ThisLine; } } elsif ( $type =~ /SEND/ ) { if ( ($enc, $action, $qid, $response) = ($info =~ /([^\s]+)\s(\d+)\s([^\s]+)\s(.*)$/) ) { $SENDaction{$action}++; if (($delivery) = ($response =~/^(\d+)\s.*/) ) { $SENDresponse{$delivery}++; } } else { push @OtherList,$ThisLine; } } else { push @OtherList,$ThisLine; } } elsif ( $ThisLine =~ /\s(RECV|SCAN|SEND)\s/) { push @OtherList,$ThisLine; } } ################################################################## if ($#OtherList >= 0) { print "\n\n**Unmatched Entries**\n\n"; print @OtherList; } if (keys %RECVaction) { print "\nReceive actions:\n"; foreach $action (sort {$a cmp $b} keys %RECVaction) { print ' ' . $RSaction[$action] . ": ". $RECVaction{$action} . "\n"; } } if (keys %SCANaction) { print "\nScanning actions:\n"; foreach $action (sort {$a cmp $b} keys %SCANaction) { print ' ' . $RSaction[$action] . ": ". $SCANaction{$action} . "\n"; } } if (keys %SENDaction) { print "\nSending actions:\n"; foreach $action (sort {$a cmp $b} keys %SENDaction) { print ' ' . $Saction[$action] . ": ". $SENDaction{$action} . "\n"; } } if (keys %RECVreason) { print "\nBlocked incoming messages:\n"; foreach $reason (sort {$a cmp $b} keys %RECVreason) { if ($reason > 0) { print ' ' . $Reason[$reason] . " : ". $RECVreason{$reason} . "\n"; } } } if ( ($Detail >= 10) and (keys %RECVReasons) ) { print "\nDetails of blocked incoming messages :\n"; foreach $reason (sort {$a cmp $b} keys %RECVReasons) { print ' ' . $Reason[$RECVReason{$reason}] . " : " . $reason . " : ". $RECVReasons{$reason} . "\n"; } } if (keys %RECVtime_total) { print "\nReceive timing:\n"; foreach $action (sort {$a cmp $b} keys %RECVtime_total) { $RECVtime = ($RECVtime_total{$action} / $RECVtime_div{$action}); print ' ' . $RSaction[$action] . " :\n"; print "\tMinimum : " . $RECVtime_min{$action} . "\n"; print "\tAverage : " . Round($RECVtime, 1) . "\n"; print "\tMaximum : " . $RECVtime_max{$action} . "\n"; } } if (keys %SCANreason) { print "\nDecisions while scanning:\n"; foreach $reason (sort {$a cmp $b} keys %SCANreason) { print ' ' . $Reason[$reason] . " : ". $SCANreason{$reason} . "\n"; } } if ( ($Detail >= 10) and (keys %SCANReasons) ) { print "\nDetails of decisions while scanning:\n"; foreach $reason (sort {$a cmp $b} keys %SCANReasons) { print ' ' . $Reason[$SCANReason{$reason}] . " : " . $reason . " : ". $SCANReasons{$reason} . "\n"; } } if (keys %SCANtime_total) { print "\nScan timing:\n"; foreach $action (sort {$a cmp $b} keys %SCANtime_total) { $SCANtime = ($SCANtime_total{$action} / $SCANtime_div{$action}); print ' ' . $RSaction[$action] . " :\n"; print "\tMinimum : " . $SCANtime_min{$action} . "\n"; print "\tAverage : " . Round($SCANtime, 1) . "\n"; print "\tMaximum : " . $SCANtime_max{$action} . "\n"; } } if (keys %SCANsize_total) { print "\nMessage sizes:\n"; foreach $action (sort {$a cmp $b} keys %SCANsize_total) { $SCANsize = ($SCANsize_total{$action} / $SCANsize_div{$action}); print ' ' . $RSaction[$action] . " :\n"; # print "\tMinimum : " . $SCANsize_min{$action} . "\n"; print "\tAverage : " . Round($SCANsize, 0) . "\n"; # print "\tMaximum : " . $SCANsize_max{$action} . "\n"; } } if (keys %SENDreason) { print "\nSending reasons:\n"; foreach $reason (sort {$a cmp $b} keys %SENDreason) { print ' ' . $Reason[$reason] . " : ". $SENDreason{$reason} . "\n"; } } if (keys %SENDresponse) { print "\nSending responses:\n"; foreach $response (sort {$a cmp $b} keys %SENDresponse) { print ' ' . $response . ": ". $SENDresponse{$response} . "\n"; } } if (keys %score_total) { print "\nScores:\n"; foreach $action (sort {$a cmp $b} keys %score_total) { $score = ($score_total{$action} / $score_div{$action}); print ' ' . $RSaction[$action] . " :\n"; print "\tMinimum : " . $score_min{$action} . "\n"; print "\tAverage : " . Round($score, 3) . "\n"; print "\tMaximum : " . $score_max{$action} . "\n"; } } exit(0); # vi: shiftwidth=3 tabstop=3 syntax=perl et # Local Variables: # mode: perl # perl-indent-level: 3 # indent-tabs-mode: nil # End: