Aug 152011

I received email from someone fiew days ago, he directed me to an article about senderscore and and asked if I could make it usable. Actually, I’m not very familiar with how senderscore work. I’ve read the article and see the FAQ at I have found that senderscore can be queried with a format like this:

Ie, I want to know the score value of ip address, the format of the query would be like this:

$ dig a +short

Look at the answers given by senderscore’s NS. last octet is the score of the ip address, which scored 75.

Excerpts from senderscore faq:

All scores are based on a scale of 0 to 100, where 0 is the worst, and 100 is the best possible score. A score represents that IP address’s rank as measured against other IP addresses, much like a percentile ranking.

Now back to the article, The authors make a perl module that can perform queries to senderscore ns, put a “reputation score” into memcache, at the same time, calculating how many times an ip address connected to our smtp.

Let’s begin, first of all download Policy::Memcache from this git repository 
Create a working directory, and extract the tarball.

$ mkdir pol-mem && cd pol-mem
$ tar --extract --file=petermblair-libemail-f73612c.tar.gz petermblair-libemail-f73612c/perl/senderscore/memcache/
$ mv petermblair-libemail-f73612c/perl/senderscore/memcache/* .

Continue reading »

Jul 282011

In my last article about the DNSBL and memcached, I wrote how to use memcached to store the data for the DNSBL. It led me to other new ideas to make the Geo Location DNSBL. In previous article I put data into memcached with the following format:

_prefix_ = _a_ or _txt_
ip = ip address to blacklist
_txt_192.168.1.1	Blacklisted

Each ip address has a pair of _a_ and _txt_ record.
For This experiment records will be store in following format:

_prefix_ = _a_ or _txt_
country_code = country code to blacklist
_txt_ID	Blacklisted Perl script

use Net::DNS::Nameserver;
use Cache::Memcached;
use Geo::IP;
use strict;
use warnings;

our $our_dnsbl = "";

# Configure the memcached server
my $memd = new Cache::Memcached {
            'servers' => [ '' ],

my $gi = Geo::IP->new(GEOIP_STANDARD);

#sub reverse_ipv4 {
#        my $ip = $_[0];
#        my ($a1, $a2, $a3, $a4) = split /\./, $ip;
#        my $reversed_ipv4 = join('.', $a4,$a3,$a2,$a1);
#        return $reversed_ipv4;

sub reverse_ipv4 {
        my @ips = split /\./, $_[0];
        my @r;
        push @r, pop @ips while @ips;
        return join('.', @r);

sub strip_domain_part {
        my $strip_domain = $_[0];
        $strip_domain =~ s/$our_dnsbl//ig;
        return $strip_domain;

sub reply_handler {
        my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
        my ($rcode, @ans, @auth, @add);
        my ($memc_a_val, $memc_txt_val);

        #print "Received query from $peerhost to ". $conn->{"sockhost"}. "\n";

        my $striped_domain = strip_domain_part($qname);
        my $reverse_striped_domain = reverse_ipv4($striped_domain);

        my $country_code = $gi->country_code_by_addr($reverse_striped_domain);

        if ($qtype eq "A" && $qname eq $striped_domain . $our_dnsbl) {
                my $vmemc_a_val = sprintf("_a_%s", lc($country_code));
                $memc_a_val = $memd->get($vmemc_a_val);
                if (defined($memc_a_val)) {
                        my ($ttl, $rdata) = (86400, $memc_a_val);
                        push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata");
                        $rcode = "NOERROR";
        } elsif ( $qname eq "" ) {
                $rcode = "NOERROR";

        } else {
                $rcode = "NXDOMAIN";

        if ($qtype eq "TXT" && $qname eq $striped_domain . $our_dnsbl) {
                my $vmemc_txt_val = sprintf("_txt_%s", lc($country_code));
                $memc_txt_val = $memd->get($vmemc_txt_val);
                if (defined($memc_txt_val)) {
                        my ($ttl, $rdata) = (86400, $memc_txt_val);
                        push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata");
                        $rcode = "NOERROR";
        } elsif ( $qname eq "" ) {
                $rcode = "NOERROR";

        } else {
                $rcode = "NXDOMAIN";

        # mark the answer as authoritive (by setting the 'aa' flag
        return ($rcode, \@ans, \@auth, \@add, { aa => 1 });

my $ns = Net::DNS::Nameserver->new(
     LocalAddr    => "",
     LocalPort    => 5353,
     ReplyHandler => \&reply_handler,
     Verbose      => 0,
) || die "couldn't create nameserver object\n";


Continue reading »