Hi,

as nobody seems to have a working solution I built a little Perl script
that adds the IP of the server receiving outgoing mail to
postgrey_clients.db

It's still a little unfinished but working fine on my server. There's
room for improvement though (IPv6 missing, rsyslog spawning and lastline
fetching is non-optimal). Maybe I will improve this with piping and a fifo.

If somebody wants to help/try it, here it is:

Requirements:
* A log file containing only postfix/smtp delivery success messages
* Method to start the script when a new delivery is logged

For these I used rsyslog like that:

rsyslog.conf:

if $syslogtag contains 'postfix/smtp' and $msg contains 'status=sent'
then      /var/log/mail.outgoing
& ^/root/postgrey_clients_add.pl


Perl Script (works on debian):
postgrey_clients_add.pl:

#!/usr/bin/perl -w

# Add IPs to postgrey's auto-whitelist

use BerkeleyDB;
use Socket;

my $dbdir = '/var/lib/postgrey';
my $logfile = '/var/log/mail.outgoing';

sub main()
{
    my %db;

    my $dbenv = BerkeleyDB::Env->new(
        -Home     => $dbdir,
        -Flags    => DB_INIT_TXN|DB_INIT_MPOOL|DB_INIT_LOG,
    ) or die "ERROR: can't open DB environment: $!\n";

    tie(%db, 'BerkeleyDB::Btree',
        -Filename => "postgrey_clients.db",
        -Env      => $dbenv,
    ) or die "ERROR: can't open database $dbdir/postgrey_clients.db: $!\n";

    my $lastlogline = `tail -n1 $logfile`;
    my($lastip) = $lastlogline =~ /.*relay=.*\[([0-9\.]+)\]/;
    exit(1) if (!$lastip);
    open LOGFILE, '>>', $logfile;
    print LOGFILE "postgrey whitelister: ";

    if (exists $db{$lastip}){
        print LOGFILE "$lastip exists: $db{$lastip}\n";
    }else{
        #default purge time is 35days give client 5 days and 4 tries
        my $tstamp = time - 30*24*60*60;
        $db{$lastip} = "4,$tstamp";
        print LOGFILE "$lastip added: $db{$lastip}\n";
    }
    close LOGFILE;

    untie %db;
}

main;

# vim: sw=4

--

Claudius

Reply via email to