#!/usr/local/bin/perl use warnings; use strict; use Email::Simple; use Net::CIDR; use Tie::DNS; my $from_ = <>; my $msg = Email::Simple->new(do { local (@ARGV, $/); <>}); open(EXIMCONF, '/etc/exim.conf') || die("Can't read /etc/exim.conf\n$!\n"); my @host_reject = split(':', ( map { s/\+allow_unknown//; s/\s//g; s/host_reject=//; $_; } grep { /^\s*host_reject\s*=/ } )[0]); close(EXIMCONF); my @recdIPs = grep { defined } map { ( # CHANGEME - this looks for the Received header inserted by your # secondary MX, and extracts the IP of the host that connected # to *it* $_ =~ /by\s+whitemail.nildram.co.uk/ && $_ =~ /\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]/ ) ? $1 : undef } $msg->header('Received'); my $result = 'neither whitelisted nor blacklisted'; OUTER: foreach my $ip (@recdIPs) { tie(my %dns, "Tie::DNS"); my $hostname = $dns{$ip}; WHITE: foreach my $white (map { s/!//; $_ } grep { $_ && /^!/ } @host_reject) { if($ip eq $white) { $result = "whitelisted IP ($ip)"; last OUTER; } elsif($white =~ /\// && Net::CIDR::cidrlookup($ip, $white)) { $result = "whitelisted netblock ($ip is in $white)"; last OUTER; } } BLACK: foreach my $black (grep { $_ && $_ !~ /^!/ } @host_reject) { if($ip eq $black) { $result = "blacklisted IP ($ip)"; last OUTER; } elsif($black =~ /\// && Net::CIDR::cidrlookup($ip, $black)) { $result = "blacklisted netblock ($ip is in $black)"; last OUTER; } elsif($hostname && $black =~ /[^0-9\.\/]/i) { if($hostname eq $black) { $result = "blacklisted hostname ($ip is $black)"; last OUTER; } my $origblack = $black; $black =~ s/\./\\./g; $black =~ s/\*/.+/g; if($hostname =~ /^$black$/) { $result = "blacklisted hostname ($hostname is in $origblack)"; last OUTER; } } } } # *IF* this message came from the secondary MX, this header is always # inserted. Look for "^X-Dodgy-Received: blacklisted" in subsequent # procmail recipes or in a spamassassin rule to spot naughty messages. $msg->header_set('X-Dodgy-Received', $result) if(@recdIPs); print $from_, $msg->as_string;