[Mimedefang] Filesystem based greylisting
Atanas
atanas at asd.aplus.net
Thu Aug 26 16:25:23 EDT 2004
I'd like to share something that already works for me for about 2
months. It's extremely simple, fast and reliable:
use String::CRC32;
my $grey_spooldir = '/var/spool/MD-Greylist';
my $grey_allow = 5*60;
sub filter_recipient
{ my ($to, $from, $ip, $name, $first, $helo) = @_;
my $relay_ip = $ip;
$ip =~ s/\.\d+$//; # remove the last byte from IP addresses
my $file = $ip.$from.$to; # this is the greylist tuple file name
$file =~ s/\///g; # remove slashes from email sddresses
my $path = sprintf "$grey_spooldir/%03X", (crc32 $file)%1024;
#-d $path or mkdir $path; # create hash subdirectory when necessary
$file = "$path/$file";
if( !-f $file ) { # first attempt ==> tempfail
open TF, ">$file"; close TF;
md_syslog('info', "Tempfail $ip$from$to");
return ('TEMPFAIL', 'Please try again');
}
my $now = time;
if( !-x $file ) { # next attempt (already tempfailed) ...
my $dtime = $now - (stat _)[9];
if( $dtime >= $grey_allow ) { # ... long enough ==> greylist
& continue
chmod 0755, $file;
utime $now, $now, $file;
md_syslog('info', "Greylist $ip$from$to");
} else { # otherwise ==> tempfail again
md_syslog('info', "Tempfail (again) $ip$from$to")
return ('TEMPFAIL', 'Please try again later');
}
} else { # already greylisted ==> update & continue
utime $now, $now, $file;
md_syslog('info', "Allow (greylisted) $ip$from$to");
}
return ('CONTINUE', 'OK');
}
The above is a stripped down version of the greylisting code only. It
just creates or updates greylist entries (one empty file per entry).
There's also a cron job for cleaning any expired entries, something for
authenticated users to bypass the greylist, a whitelist per relay IP and
recipient domain, simple HELO checks, etc.
It's not a rocket science and anybody knowing perl could write it, but
if anyone is interested I could post the whole thing, it's probably just
about 2-3 times bigger than the above.
For me it handles about 3M greylist entries and so far I had no
problems. It runs on a single box together with Mimedefang/SA/Clamd
processing about 350K messages a day. Before the greylist implementation
the same box was hit by 550-600K messages a day, so the greylist
effectively stops about 30-40% of the email traffic. Some time in the
future I'm planning to share it among multilpe mimedefang machines over NFS.
Disclaimer: I'm not a perl programmer. The above code works for me, but
might not work for you and/or could have bugs. I tried to make it
efficient, but possibly it could have been written better.
Regards,
Atanas
More information about the MIMEDefang
mailing list