Hi,

This little script was developed which analyses output postqueue -p
and prints the report on the greatest abusers. It was developed
to quickly clear the queue of the deferred spam messages.
It is a stream processor and does not hogs memory , can analyze really
large volumes from postqueue -p.

Usage: postqueue -p | ./analyse_postfix_queue.pl

If is useful when used in conjunction to another script pfdel.pl
contributed by someone else , but repeated in this email.

Note: some paths in script pfdel.pl may need adjustment as per
local conditions.


# cat  ./analyse_postfix_queue.pl


#!/usr/bin/perl -w
use strict;
my ($email,$total_rcpt) ;
my %h = ();
while (<>) {
        chomp ;
        my $line = $_;

        if($line =~ /^[A-Z0-9]{13}.*\s+(\S+)/)
        {
                $email = $1;
        }
        if($line =~ /^\s+(\S+)$/) {
                $h{$email}++;
        }
}
my @keys = sort {$h{$b} <=> $h{$a} } keys %h;
my $i=0;
printf("%3s %-30s %6s\n","SNO","E-mail","Total");
while($i < 10)
{
        $i++;
        printf("%3d %-30s %6d\n",$i,$keys[$i-1],$h{$keys[$i-1]});
}


------------------------------------------
#!/usr/bin/perl -w
#
# pfdel - deletes message containing specified address from
# Postfix queue. Matches either sender or recipient address.
#
# Usage: pfdel <email_address>
#

use strict;

# Change these paths if necessary.
my $LISTQ = "/opt/zimbra/postfix/sbin/postqueue -p";
my $POSTSUPER = "/opt/zimbra/postfix/sbin/postsuper";

my $email_addr = "";
my $qid = "";
my $euid = $>;

if ( @ARGV !=  1 ) {
        die "Usage: pfdel <email_address>\n";
} else {
        $email_addr = $ARGV[0];
}

if ( $euid != 0 ) {
        die "You must be root to delete queue files.\n";
}


open(QUEUE, "$LISTQ |") ||
  die "Can't get pipe to $LISTQ: $!\n";

my $entry = <QUEUE>;    # skip single header line
$/ = "";                # Rest of queue entries print on
                        # multiple lines.
while ( $entry = <QUEUE> ) {
        if ( $entry =~ / ($email_addr)$/m ) {
                ($qid) = split(/\s+/, $entry, 2);
                $qid =~ s/[\*\!]//;
                next unless ($qid);

                #
                # Execute postsuper -d with the queue id.
                # postsuper provides feedback when it deletes
                # messages. Let its output go through.
                #
                print "deleting $qid .... " ;
                if ( system($POSTSUPER, "-d", $qid) != 0 ) {
                        # If postsuper has a problem, bail.
                        die "Error executing $POSTSUPER: error " .
"code " .  ($?/256) . "\n";
                }
                print "done\n";
        }
}
close(QUEUE);

if (! $qid ) {
        die "No messages with the address <$email_addr> " .
          "found in queue.\n";
}

exit 0;

Reply via email to