On 2007-09-07 14:10:34 -0500, Chris Garrigues wrote:
> It was very curious.  I could see in the logs lines like this:
> 
> 2007-09-06 15:04:18.705745500 13257 greylisting plugin: key 
> 68.180.197.125:[EMAIL PROTECTED]:[EMAIL PROTECTED] initial DENYSOFT, unknown
> 
> but when I looked in the db file, there'd be no entry for this triplet
> "68.180.197.125:[EMAIL PROTECTED]:[EMAIL PROTECTED]", so the 
> message would never get through.
> 
> I can't see how the code could do that unless something was wrong with the 
> tie 
> to the db or maybe the filelocking wasn't working.
> 
> I then realized that I have no idea how an error would get reported if there 
> were a problem with the tie to the DB other than an error while opening the 
> file.  It may be a problem on my system, but I can't diagnose it.

If the tie fails, you get an error message at level LOGCRIT. However, if
the db file is subtly corrupted, you will see exactly the behaviour you
are observing: Entries are never written to the database, or vanish
mysteriously after some time. 

I have seen these issues before I added file locking, so I suspect that
file locking doesn't work for you. Do you keep the DB file on an NFS
filesystem?

If your database keeps getting corrupted and you can't figure out why, a
temporary relieve can be to copy all the "good" records to a new
database periodically and discard the old file. In fact, that's probably
a good idea anyway, because otherwise records are never deleted.

I have attached a script to do this.

> Anyway, now that it's been explained to me that the included greylisting 
> plugin isn't "recommended" per se, but is considered example code,

Only in the sense that all the plugins are examples and you are welcome
to adapt them to your own needs. I think the greylisting plugin is
actually of quite good quality.

> I'm curious what other plugins are out there that do greylisting?
> Peter Holzer sent me a pointer to his implementation when I was having
> problem with the whitelisting in this plugin.  I'll take a look at
> that.

"My" implementation is a straight fork of Gavin's plugin. The
whitelisting wasn't flexible enough for my needs so I added a much more
elaborate scheme with recipient, sender and client options, but the core
is the same.


> Are there any others worth looking at?

There was at least one variant which uses an SQL database instead of the
DB file, but the URL is dead. You may find something in the wiki
(http://wiki.qpsmtpd.org), and if you find something somewhere else,
please add it there.

        hp



-- 
   _  | Peter J. Holzer    | I know I'd be respectful of a pirate 
|_|_) | Sysadmin WSR       | with an emu on his shoulder.
| |   | [EMAIL PROTECTED]         |
__/   | http://www.hjp.at/ |    -- Sam in "Freefall"
#!/usr/bin/perl -w
use strict;
use Fcntl qw(:DEFAULT :flock);

BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File) }
use AnyDBM_File;
use Fcntl;

my $src = $ARGV[0];
my $dst = $ARGV[1];
my $mints;
my $mintsb;

if (defined $ARGV[2]) {
    if ($ARGV[2] =~ /-(\d+(?:\.\d+)?)([hd])/) {
        $mints = time() - $1 * ($2 eq 'h' ? 3600 : 
                                $2 eq 'd' ? 86400 :
                                            undef);
    } else {
        $mints = $ARGV[2];
    }
} else {
    $mints = time() - 36 * 86400;
}

if (defined $ARGV[3]) {
    if ($ARGV[3] =~ /-(\d+(?:\.\d+)?)([hd])/) {
        $mintsb = time() - $1 * ($2 eq 'h' ? 3600 : 
                                 $2 eq 'd' ? 86400 :
                                             undef);
    } else {
        $mintsb = $ARGV[3];
    }
} else {
    $mintsb = time() - 1 * 86400;
}

unless (open LOCK, ">$src.lock") {
    print STDERR "opening lockfile failed: $!";
    exit(1);
}
unless (flock LOCK, LOCK_EX) {
    print STDERR "flock of lockfile failed: $!";
    close LOCK;
    exit(1);
}
tie my %db1, 'AnyDBM_File', $src, O_CREAT|O_RDWR, 0600
    or die "cannot tie to $src: $!";

tie my %db2, 'AnyDBM_File', $dst, O_CREAT|O_RDWR, 0600
    or die "cannot tie to $dst: $!";


my $copied = 0;
my $skipped = 0;
while (my ($k, $v) = each(%db1)) {
    my ($ts, $new, $black, $white) = split /:/, $v;
    if ( $ts >= ($white ? $mints : $mintsb) ) {
        print STDERR "copying $k, $v\n";
        $copied++;
        $db2{$k} = $v;
    } else {
        print STDERR "skipping $k, $v\n";
        $skipped++;
    }
}
print STDERR "$copied copied, $skipped skipped\n";
untie %db1;
untie %db2;
close(LOCK);
#!/usr/bin/perl -w
use strict;

BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File) }
use AnyDBM_File;
use Fcntl;

tie my %db, 'AnyDBM_File', $ARGV[0], O_CREAT|O_RDWR, 0600
    or die "cannot tie to $ARGV[0]: $!";

while (my ($k, $v) = each(%db)) {
    print "$k $v\n";
}
untie %db;

Attachment: signature.asc
Description: Digital signature

Reply via email to