Saturday, April 26, 2008

Count emails

One thing I like to keep track of is if there's any email abuse going on. One way to determine this is if there's a specific email address that's being sent a high volume of email from our domain.

The output looks something like this:

Local User Remote Email Count
nwo nwo@someotherdomain.com 48
joe joeswife@gmail.com 37
bob bobsbrother@hotmail.com 92
..etc..


#!/usr/bin/perl
#
# Count the amount of emails sent from an address at @ourdomain.com
#
# - nwo - 3/25/2008

# Open the maillog
#open(F, "/var/log/maillog") || die "$!";
#while() {
while() {
if(/^.*?sendmail.*?:\s+(.*?):\s+from\=\<(.*?)\@ourdomain.com\>.*/i) {
# Create a hash of all of the from email addresses we find
$emails{$2}++;
# Create an array with the name of the email address and push
# the message ID into the array.. ie:
# @nwo = ('m2PK7tVC002488', 'etc', 'etc', 'etc');
push(@$2, $1);
}
if(/^.*?sendmail.*?:\s+(.*?):\s+to\=\<(.*?)\>\,.*/) {
# Create a hash with the name of the message ID and the person that
# message was sent to, ie:
# %h=('m2PK7tVC002488' => 'nwo@someotherdomain.com');
$mid{$1} = $2;
}
}

# Cycle through the keys of the %emails hash which gives us the names of all
# of the arrays we created because we don't know what they are yet.
foreach $name (keys %emails) {
# Now cycle through the array and pick out each message ID
foreach $id (@$name) {
# Create a new hash which has the name of $name and $mid{$id} separated
# by a '|' so we can split it later.
# %maild{'nwo|nwo@someotherdomain.com' => '2'} (2 being the amount of times a
# specific email address is found - this increments each cycle when that
# email already exists as a key in the %maild hash)
$maild{"$name|$mid{$id}"}++;
}
}
# OK - now, cycle and sort each of the keys in %maild
foreach $line (sort keys %maild) {
# Assign the amount of hits for each key to $value
$value = $maild{$line};
# Grab the $sender and $receiver from the key, which we're able to do
# because that handy '|' delimeter we used when we created the key.
($sender, $receiver) = split(/\|/,$line);
# Now print it!
print "$sender - $receiver - $value\n";
}

No comments: