I had hoped there would be a good example of code to do this already, and if so, I would appreciate it if someone could point me in that direction. In the mean time, I hacked together the following variation of the code segment from the CheckforMX entry on the Wiki, and would appreciate any feedback regarding the code segment (as I have NOT had the opportunity to test it completely, or to put it into operation yet).
use Net::DNS; use NetAddr::IP;
# GetHostAddress and GetDomainMXAddresses routines # taken from http://www.mimedefang.org/kwiki/index.cgi?CheckForMX
sub GetHostAddresses {
my ($hostname) = @_;
my @addresses;
if ( $hostname =~ m/^\s*(\d{1,3}\.){3}\d{1,3}\s*$/ ) {
push( @addresses, $hostname ); # Host was an IP address, not a hostname
}
else {
my $resolver = Net::DNS::Resolver->new;
my $received = $resolver->search($hostname);
foreach my $rr ( $received->answer ) {
next unless $rr->type eq "A";
push( @addresses, $rr->address );
}
}
return @addresses;
}
# GetDomainMXAddresses(resolver,domain) # returns array of IP addresses for domain's MX list # if no MX records, returns array of IP addresses for this hostname
sub GetDomainMXAddresses {
my ($domain) = @_;
my $resolver = Net::DNS::Resolver->new;
my @mxlist = mx( $resolver, $domain );
my @mxaddresses;
if (@mxlist) {
push( @mxaddresses, map { GetHostAddresses( $_->exchange ); } @mxlist );
}
else { # check for an A record for the domain...
push( @mxaddresses, GetHostAddresses( $domain ) );
}
return @mxaddresses;
}
sub filter_sender {
my ( $sender, $ipaddr, $hostname, $helo ) = @_;
my ( undef, $sender_domain ) = split( /\@/, $sender );# Block information taken from RFC 3330. Remove any in use locally.
my %specialized_blocks = (
"0.0.0.0/8" => { comment => qq{local network block}, rfc => 1700 },
"10.0.0.0/8" => { comment => qq{class A private network block}, rfc => 1918 },
"127.0.0.0/8" => { comment => qq{loopback address block}, rfc => 1700 },
"169.254.0.0/16" => { comment => qq{"LINK LOCAL" block}, rfc => 3330 },
"172.16.0.0/12" => { comment => qq{class B private network block}, rfc => 1918 },
"192.0.2.0/24" => { comment => qq{"TEST-NET" block}, rfc => 3330 },
"192.168.0.0/16" => { comment => qq{class C private network block}, rfc => 1918 },
"224.0.0.0/4" => { comment => qq{IPv4 multicast range}, rfc => 3171 },
);
foreach my $address ( GetDomainMXAddresses($sender_domain) ) {
my $ip = new NetAddr::IP $address;
foreach my $range ( keys %specialized_blocks ) {
if ( $ip->within( new NetAddr::IP($range) ) ) {
return ( "REJECT",
"Addresses from domains with MX entries whose addresses fall within a "
. $specialized_blocks{$range}{comment}
. " not accepted (see also RFC "
. $specialized_blocks{$range}{rfc}
. ")." );
}
}
}
# # Other sender checks here. #
return ( "CONTINUE", "ok" ); }
The modification to the GetHostAddress routine, to check for an IP address in place of a hostname from MX records, was in response to two recently-seen domains in (probably forged) email addresses ('jsctech.com' and 'romymichele.com'). These two domains appeared as follows when examined with dig(1):
$ dig +nostats +nocomments any jsctech.com
; <<>> DiG 9.2.3 <<>> +nostats +nocomments any jsctech.com ;; global options: printcmd ;jsctech.com. IN ANY jsctech.com. 83749 IN NS ns1.nameresolve.com. jsctech.com. 83749 IN NS ns2.nameresolve.com. jsctech.com. 83749 IN NS ns3.nameresolve.com. jsctech.com. 83749 IN NS ns4.nameresolve.com. jsctech.com. 83749 IN MX 0 127.0.1.50. jsctech.com. 86238 IN TXT "v=spf1 mx -all" jsctech.com. 1644 IN A 66.150.161.133 jsctech.com. 1644 IN A 66.150.161.141 jsctech.com. 1644 IN A 66.150.161.136 jsctech.com. 1644 IN A 66.150.161.134 jsctech.com. 1644 IN A 69.25.27.173 jsctech.com. 1644 IN A 69.25.27.171 jsctech.com. 1644 IN A 69.25.27.172 jsctech.com. 1644 IN A 69.25.27.170 jsctech.com. 83749 IN NS ns1.nameresolve.com. jsctech.com. 83749 IN NS ns2.nameresolve.com. jsctech.com. 83749 IN NS ns3.nameresolve.com. jsctech.com. 83749 IN NS ns4.nameresolve.com. ns1.nameresolve.com. 58537 IN A 64.94.117.196 ns2.nameresolve.com. 58537 IN A 63.251.83.77 ns3.nameresolve.com. 30591 IN A 66.150.161.132 ns4.nameresolve.com. 58537 IN A 216.52.121.240
$ dig +nostats +nocomments any romymichele.com
; <<>> DiG 9.2.3 <<>> +nostats +nocomments any romymichele.com ;; global options: printcmd ;romymichele.com. IN ANY romymichele.com. 15540 IN NS ns1.e-access.net. romymichele.com. 15540 IN MX 0 mail.romymichele.com. romymichele.com. 15540 IN NS ns1.e-access.net. ns1.e-access.net. 151939 IN A 63.229.32.2 mail.romymichele.com. 15540 IN A 0.0.0.0
Your time in considering this posting, and any advice/suggestions/feedback provided, are greatly appreciated in advance.
Sincerely, Albert C.
_______________________________________________ Visit http://www.mimedefang.org and http://www.canit.ca MIMEDefang mailing list [email protected] http://lists.roaringpenguin.com/mailman/listinfo/mimedefang

