[Mimedefang] Greylisting is GREY-ATE
Mark Sheppard
mark at ddf.net
Thu Jan 1 00:49:34 EST 2004
On 2003-12-31 (Wednesday) at 22:36:54 +0100, Jonas Eckerman wrote:
> On Sun, 28 Dec 2003 01:59:00 -0600, Steven Rocha wrote:
>
> > WOW!!! This is about all I can say.
>
> Agreed. :-)
>
> > their installations. I have looked at Jonas' greylisting
> > implementation but I could not get around the O_EXLOCK flag, YET!
>
> I don't think that'd bee too hard. I think David uses the more
> portable method with a lock file in his code. That method should
> work fine with my code as well.
I use this in my mimedefang-filter (on a Debian system):
use BerkeleyDB;
use LockFile::Simple;
# must be writable be user "defang"
my $greylist_db_file = '/var/spool/MIMEDefang/greylist.db';
my $greylist_min = 30; # 30 seconds
my $greylist_max = 60 * 60 * 24;# 24 hours
my $lockmgr;
BEGIN{
$lockmgr = LockFile::Simple->make(-format => '%f.lock',
-hold => 600,
-delay => 1);
}
[...]
sub greylist{
my($key) = @_;
$lockmgr->lock($greylist_db_file) or
die "Can't lock `$greylist_db_file'\n";
my $db = BerkeleyDB::Hash->new(-Filename => $greylist_db_file,
-Flags => DB_CREATE) or
die "Can't open `$greylist_db_file': $!\n";
my $now = time();
my $bad = 0;
my $then;
if($db->db_get($key, $then) or
($now - $then) < $greylist_min or
($now - $then) > $greylist_max){
# never seen before, or not in the greylist window
$bad = 1;
}
my $status = $db->db_put($key, $now);
if($status){
die "Can't set `$key' in database: $status $Berkeley::Error\n";
}
md_syslog('warning', "Set $key = $now in greylist, " .
($bad? 'rejecting': 'accepting'));
$db->db_close();
$lockmgr->unlock($greylist_db_file);
return $bad;
}
Then this after the SpamAssassin stuff in filter_end():
# greylisting
if(greylist($RelayAddr)){
action_tempfail("Not seen $RelayAddr recently, try again to verify you're not brain-dead spamware");
md_syslog('warning', "Temp failed $RelayAddr ($RelayHostname) due to greylist");
return;
}
Seems to work quite well. The Berkeley DB library supports database
locking, but after banging my head against a brick wall for far too
long I gave up on it. I don't know if it's me or the perl module at
fault, but it just wasn't happening. So I wrapped all the database
access stuff in a LockFile::Simple which neatly side-stepped the
problem.
Mark.
More information about the MIMEDefang
mailing list