#!/usr/bin/perl # # Original Version # ----------------- # http://www.Linux-Sec.net/Mail/Logger/spam.count.pl # # # Other smtp Log analayzers # http://www.linux-sec.net/Mail/#Log # # # ---------------------------------------------------------------- # Count the Different Type of Spams # ---------------------------------------------------------------- # counts based on Linux-Sec's AntiSpam Filters # # http://www.linux-sec.net/Mail/Sendmail/#Macro # http://www.Linux-Sec.net/Mail/AntiSpam # http://www.Linux-Sec.net/Mail/etc.mail/sendmail-8.12.x/*check_local.mc # # # # 30-Mar-03 amo Date-of-Birth # 02-Apr-03 amo Added spam error sort if not found # 04-Apr-03 amo Added From and To counters # 25-Jul-03 amo Sort the From/To Results # # # # Which Rules # -------------- # grep -i check_ /var/log/mail.log | cut -d " " -f 8 | grep ruleset | uniq # # # Where did Mail Come From # -------------------------- # spam.count.pl -from # - or - # cut -d " " -f 8 /var/log/maillog | grep from= | egrep -iv "root|IgnoreMe|IgnoreThem" # # # Who was the Email addressed to # ------------------------------- # spam.count.pl -to # - or - # cut -d " " -f 8 /var/log/maillog | grep to= | egrep -iv "root|IgnoreMe|IgnoreThem" # # # Sort the List of From # --------------------- # IDCounter Number-of-Spams Spammer # # spam.count.pl -from | sort +1 # # # my ( $LOG ) = "/var/log/mail.log"; # # # Check for mail log files # ------------------------ # if ( ! -f $LOG ) { $LOG = "/var/log/maillog"; # other possibility # if ( ! -f $LOG ) { printf "\n"; printf "ERROR: Could not find /var/log/mail.log nor /var/log/maillog\n"; printf "\n"; # exit 1; } # } # check for mail log files # # # Incoming emails came From my ( $From ) = 0; # # # Incoming emails went to my ( $To ) = 0; # # # Sort the results # my ( $Sort ) = 0; # # # cut fields for extracting from= # my ( $CutF ) = "-f 8"; #y ( $CutF ) = "-f 7"; # some older sendmail logfile formats # # # Check for Command Line options # ------------------------------ &check_cmd; # # # # Sorted List of Spam Counts # -------------------------- # my ( %SPAM ) = (); # # # Types of spam error messages # ---------------------------- # - antispam rules are defined in http://www.linux-sec.net/Mail/etc.mail/sendmail-8.12.x/*check_local.mc # # my ( @ERR ) = ( "check_all", "check_compat", "check_ct", "check_date", "check_eoh", "check_errto", "check_happy99", "check_header", "check_header_Cc", "check_header_From", "check_header_Message-Id", "check_header_Received", "check_header_Reply-To", "check_header_Sender", "check_header_To", "check_mailer", "check_ole", "check_parse_from", "check_parse_from_domain", "check_rcpt", "check_sircam", "check_subject", "check_to", "check_unknown_header", "check_xlib", "check_xuser", "Relaying denied", "Bad Received", "did not issue MAIL/EXPN/VRFY/ETRN", "does not exist", # domain "does not resolve", # domain "hostname resolve fail", "HTML jibberish", "Junk mail", "license", # license required "lost input channel", "may be forged", "premature EOM", "Rejected by RBL", "Rejected by Postmaster", "Reject Message", "Reject Received", "Message Id corrupt", "Spamware Detected", "Spam house and liars", "timeout waiting for input", "unknown header", "User Unknown" ) ; # # # # # my ( $spam ) = ` egrep -i "xxSpammer|reject" $LOG | wc -l `; # my ( $Emails ) = ` egrep -i "root|localhost|127.0.0" $LOG | wc -l `; # # # Ignore locally generated emails # my ( $Emails ) = ` grep -i "from=" $LOG | wc -l `; chomp ( $Emails ); # printf "\n"; printf "$Emails Total Number of Emails, including Possible Spammers and Rejected Emails\n"; printf "\n"; printf "\n"; printf "Various Possible Reasons for the Rejected Spam - could have multiple reasons\n"; # # # Where did incoming emails come from # ----------------------------------- if ( $From eq 1 ) { my ( @From ) = ` cut -d " " $CutF $LOG | grep from= | egrep -iv "root|IgnoreMe|IgnoreThem" | sort `; # if ( $#From == -1 ) { printf "\n"; printf "ERROR: You probably need to use \"-f7\" instead for cut fields \n"; printf "\n"; # exit 1; } # printf "\n"; printf "$#From Incoming Emails came from:\n"; # # if ( $Sort eq 1 ) { &pr_sort ( @From ); } else { printf "%s\n", join ( "", @From ); } # exit 0; } # # # Where did incoming emails go to # ------------------------------- if ( $To eq 1 ) { my ( @To ) = ` cut -d " " $CutF $LOG | grep to= | egrep -iv "root|IgnoreMe|IgnoreThem" | sort `; # if ( $#To == -1 ) { printf "\n"; printf "ERROR: You probably need to use \"-f7\" instead for cut fields \n"; printf "\n"; # exit 1; } # printf "\n"; printf "$#To Incoming Emails went to:\n"; # # if ( $Sort eq 1 ) { &pr_sort ( @To ); } else { printf "%s\n", join ( "", @To ); } # exit 0; } # # # Count the Spams and types of spam filters # ------------------------------------------ # my ( $id, $cnt ) = 0; my ( $len, $err, $err1 ) = ""; my ( @errn ) = (); # while ( $id <= $#ERR ) { # $err = $ERR[$id]; # $cmd = " grep -i '$err' $LOG "; # chomp ( $cnt = ` $cmd | wc -l ` ); # $key = "$cnt.$id"; # sort key # # # 02-Apr-03 amo Added spam error sort if not found # $len = $cnt; $len =~ s/\s+//; # if ( $len eq 0 ) { ( $err1, @errn ) = split ( /\s+/, $err ); $key = "$cnt.$err1"; } # no spam fond # # $SPAM{ "$key" } = "$cmd" ; # $id += 1; # } # types # # my ( $SpamCnt, $cnt, $id ) = ""; # # Sort the List of Spam # ---------------------- # for $SpamCnt ( reverse sort keys %SPAM ) { # $cmd = $SPAM{ $SpamCnt } ; # # truncate unique id index ( $cnt, $id ) = split ( /\./, $SpamCnt ); # printf "$cnt $cmd\n"; # } # sort # # # Other Possible Options/Reasons # my ( $Other ) =""; # $other = join ( "|", @ERR ); $other .= "|SYSERR"; $other .= "|relay=localhost"; $other .= "|relay=root"; $other .= "|stat=sent"; # $cmd = " egrep -iv '$other' $LOG "; # printf "\n\n"; printf "Other Possible Reasons\n"; printf "\n"; printf "$cmd\n"; printf "\n"; # # # done exit ( 0 ); # # # Sort the List of Entries # ------------------------ # sub pr_sort { my ( @list ) = @_; # my ( $id ) = 0; # while ( $id <= $#list ) { # chomp ( $lst = $list[$id] ); # # remove leading "from=" and leading < and trailing , and > $lst =~ s/^from=//; $lst =~ s/,$//; $lst =~ s/^$//; # # printf "..lst[$id]=$lst..\n"; # # break up the domain names # ( $uid, $did ) = split ( /\@/, $lst ); @f = split ( /\./, $did ); # # # concatenate the domain name in reverse order $jd = $#f; $sstr = ""; while ( $jd >= 0 ) { $sstr .= ".$f[$jd]"; $jd -= 1; } # $sstr =~ s/^\.//; # get rid of my leading "." # # $Sort_c{ "$sstr" } += 1; # count $Sort_d{ "$sstr" } = $lst; # spammer # # printf "..lst[$id]=$uid....d[$#f]=$did....rev[$Sorted{ $sstr }]=$sstr..\n"; # $id += 1; } # extract user@domain # # # Now show the sorted results # ---------------------------- # $id = 0; foreach $sstr ( sort keys %Sort_c ) { # printf "%5d %5d $Sort_d{ $sstr }\n", $id, $Sort_c{ $sstr }; $id += 1; # } # # } # pr_sort # # # -------------------------------------------------------------- # # Check for Command Line Options # ------------------------------ sub check_cmd { my ( $id ) = 0; # while ( $id <= $#ARGV ) { # $argv = $ARGV[$id]; # if ( $argv eq "-h" ) { # &pr_help ; # } elsif ( $argv eq "-from" ) { # $From = 1; # show where incoming emails came from # } elsif ( $argv eq "-to" ) { # $To = 1; # show where incoming emails went to # } elsif ( $argv eq "-sort" ) { # $Sort = 1; # show the sorted results # } elsif ( $argv eq "-f7" ) { # $CutF = "-f 7"; # cut field option in sendmail logs # } # $id += 1; } # } # check_cmd # # sub pr_help { printf "\n"; printf "Usage: $0 [ -h | -to | -from ]\n"; printf "\t -h this help file\n"; printf "\n"; printf "\t -from where did incoming emails come from\n"; printf "\t -to to whom was incoming emails addressed to \n"; printf "\n"; printf "\t -sort sort the from or to results\n"; printf "\t -f7 use cut field option for older sendmail logfile format\n"; printf "\n"; # exit 1; } # # # End of file