summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@luxion>2007-12-27 18:49:47 +0000
committerdakkar <dakkar@luxion>2007-12-27 18:49:47 +0000
commit94d1d4ab12b1a9f7ba56402e2cc1d4fc1e2a249c (patch)
tree4ddc7e1ab80d8fd54f2f07b283c12fcdb7912678
parent r3304@rfc-1918: dakkar | 2007-12-27 13:19:58 +0100 (diff)
downloadGraylister-94d1d4ab12b1a9f7ba56402e2cc1d4fc1e2a249c.tar.gz
Graylister-94d1d4ab12b1a9f7ba56402e2cc1d4fc1e2a249c.tar.bz2
Graylister-94d1d4ab12b1a9f7ba56402e2cc1d4fc1e2a249c.zip
r3320@rfc-1918: dakkar | 2007-12-27 19:49:40 +0100HEADmaster
branched Net::DNSBLLookup for ease of customization
-rw-r--r--lib/DAKKAR/Graylister.pm85
-rw-r--r--lib/DAKKAR/Net/DNSBLLookup.pm209
-rw-r--r--lib/DAKKAR/Net/DNSBLLookup/Result.pm144
3 files changed, 356 insertions, 82 deletions
diff --git a/lib/DAKKAR/Graylister.pm b/lib/DAKKAR/Graylister.pm
index 9ee9be0..bd07e6d 100644
--- a/lib/DAKKAR/Graylister.pm
+++ b/lib/DAKKAR/Graylister.pm
@@ -1,88 +1,9 @@
package DAKKAR::Graylister;
use strict;
use warnings;
-use Net::DNSBLLookup;
+use DAKKAR::Net::DNSBLLookup;
use DBI;
-{
- %Net::DNSBLLookup::dns_servers=(
- 'dnsbl.sorbs.net' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_PROXY_HTTP,
- '127.0.0.3' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_PROXY_SOCKS,
- '127.0.0.4' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_PROXY_MISC,
- '127.0.0.5' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_RELAY,
- '127.0.0.6' => Net::DNSBLLookup::DNSBLLOOKUP_SPAMHOUSE,
- '127.0.0.7' => Net::DNSBLLookup::DNSBLLOOKUP_FORMMAIL,
- '127.0.0.8' => Net::DNSBLLookup::DNSBLLOOKUP_CONFIRMED_SPAM,
- '127.0.0.9' => Net::DNSBLLookup::DNSBLLOOKUP_HIJACKED,
- '127.0.0.10' => Net::DNSBLLookup::DNSBLLOOKUP_DYNAMIC_IP,
- },
- 'dnsbl.njabl.org' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_RELAY,
- '127.0.0.3' => Net::DNSBLLookup::DNSBLLOOKUP_DYNAMIC_IP,
- '127.0.0.4' => Net::DNSBLLookup::DNSBLLOOKUP_SPAMHOUSE,
- '127.0.0.5' => Net::DNSBLLookup::DNSBLLOOKUP_MULTI_OPEN_RELAY,
- '127.0.0.8' => Net::DNSBLLookup::DNSBLLOOKUP_FORMMAIL,
- '127.0.0.9' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_PROXY,
- },
- 'bl.spamcop.net' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_UNKNOWN,
- },
- 'unconfirmed.dsbl.org' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_UNKNOWN,
- },
- 'list.dsbl.org' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_UNKNOWN,
- },
- 'sbl.spamhaus.org' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_SPAMHOUSE,
- },
- 'pbl.spamhaus.org' => {
- '127.0.0.10' => Net::DNSBLLookup::DNSBLLOOKUP_DYNAMIC_IP,
- '127.0.0.11' => Net::DNSBLLookup::DNSBLLOOKUP_DYNAMIC_IP,
- },
- 'cbl.abuseat.org' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_PROXY,
- },
- 'psbl.surriel.com' => {
- '127.0.0.2' => Net::DNSBLLookup::DNSBLLOOKUP_OPEN_PROXY,
- },
- );
-
- use Net::DNSBLLookup::Result;
- {package Net::DNSBLLookup::Result;
- our %result_type;
- no warnings 'redefine';
- sub breakdown {
- my ($self)=@_;
- my ($total_spam, $total_proxy, $total_unknown, $total_dyn) = (0,0,0);
- return unless exists $self->{results};
- while (my ($dnsbl, $v) = each %{$self->{results}}) {
- my ($is_spam, $is_proxy, $is_unknown, $is_dyn) = (0,0,0,0);
- for my $retval (@$v) {
- my $result_type = $result_type{$retval};
- if ($result_type == DNSBLLOOKUP_RESULT_OPEN_PROXY) {
- $is_proxy = 1;
- } elsif ($result_type == DNSBLLOOKUP_RESULT_SPAM) {
- $is_spam = 1;
- } elsif ($result_type == DNSBLLOOKUP_RESULT_UNKNOWN) {
- $is_unknown = 1;
- } elsif ($result_type == DNSBLLOOKUP_RESULT_DYNAMIC_IP) {
- $is_dyn = 1;
- }
- }
- $total_proxy += $is_proxy;
- $total_spam += $is_spam;
- $total_dyn += $is_dyn;
- unless ($is_proxy || $is_spam || $is_dyn) {
- $total_unknown += $is_unknown;
- }
- }
- return ($total_proxy, $total_spam, $total_dyn, $total_unknown);
- }
-}
-}
-
my $DBNAME;
sub get_from_env {
@@ -191,7 +112,7 @@ sub check {
{},time(),$host,$from,$to);
}
else {
- # prbobaly a bounce
+ # probably a bounce
my $ret=$dbh->do('DELETE FROM attempts WHERE host=? AND smtpfrom=? AND smtprcpt=?',
{},$host,$from,$to);
}
@@ -207,7 +128,7 @@ sub check {
sub is_blacklisted {
my ($host)=@_;
- my $look=Net::DNSBLLookup->new();
+ my $look=DAKKAR::Net::DNSBLLookup->new();
my $ret=$look->lookup($host);
my ($proxy, $spam, $dyn, $unknown) = $ret->breakdown;
return ($proxy+$spam+$dyn+$unknown > 0);
diff --git a/lib/DAKKAR/Net/DNSBLLookup.pm b/lib/DAKKAR/Net/DNSBLLookup.pm
new file mode 100644
index 0000000..9b03cbb
--- /dev/null
+++ b/lib/DAKKAR/Net/DNSBLLookup.pm
@@ -0,0 +1,209 @@
+package DAKKAR::Net::DNSBLLookup;
+
+# copied from Net::DNSBLLookup v0.03
+
+use 5.005;
+use strict;
+
+require Exporter;
+use AutoLoader qw(AUTOLOAD);
+use vars qw($VERSION @EXPORT @ISA);
+use Net::DNS;
+use IO::Select;
+$VERSION = '0.04';
+@ISA = qw(Exporter);
+
+@EXPORT = qw(DNSBLLOOKUP_OPEN_RELAY DNSBLLOOKUP_DYNAMIC_IP
+ DNSBLLOOKUP_CONFIRMED_SPAM DNSBLLOOKUP_SMARTHOST DNSBLLOOKUP_SPAMHOUSE DNSBLLOOKUP_LISTSERVER
+ DNSBLLOOKUP_FORMMAIL DNSBLLOOKUP_OPEN_PROXY DNSBLLOOKUP_OPEN_PROXY_HTTP DNSBLLOOKUP_OPEN_PROXY_SOCKS
+ DNSBLLOOKUP_OPEN_PROXY_MISC DNSBLLOOKUP_HIJACKED DNSBLLOOKUP_MULTI_OPEN_RELAY DNSBLLOOKUP_UNKNOWN);
+
+use constant DNSBLLOOKUP_OPEN_RELAY => 1;
+use constant DNSBLLOOKUP_DYNAMIC_IP => 2;
+use constant DNSBLLOOKUP_CONFIRMED_SPAM => 3;
+use constant DNSBLLOOKUP_SMARTHOST => 4;
+use constant DNSBLLOOKUP_SPAMHOUSE => 5;
+use constant DNSBLLOOKUP_LISTSERVER => 6;
+use constant DNSBLLOOKUP_FORMMAIL => 7;
+use constant DNSBLLOOKUP_OPEN_PROXY => 8;
+use constant DNSBLLOOKUP_OPEN_PROXY_HTTP => 9;
+use constant DNSBLLOOKUP_OPEN_PROXY_SOCKS => 10;
+use constant DNSBLLOOKUP_OPEN_PROXY_MISC => 11;
+use constant DNSBLLOOKUP_HIJACKED => 12;
+use constant DNSBLLOOKUP_MULTI_OPEN_RELAY => 13;
+use constant DNSBLLOOKUP_UNKNOWN => 14;
+
+require DAKKAR::Net::DNSBLLookup::Result;
+
+# updated DNSBL lists
+
+our %dns_servers = (
+ 'dnsbl.sorbs.net' => {
+ '127.0.0.2' => DNSBLLOOKUP_OPEN_PROXY_HTTP,
+ '127.0.0.3' => DNSBLLOOKUP_OPEN_PROXY_SOCKS,
+ '127.0.0.4' => DNSBLLOOKUP_OPEN_PROXY_MISC,
+ '127.0.0.5' => DNSBLLOOKUP_OPEN_RELAY,
+ '127.0.0.6' => DNSBLLOOKUP_SPAMHOUSE,
+ '127.0.0.7' => DNSBLLOOKUP_FORMMAIL,
+ '127.0.0.8' => DNSBLLOOKUP_CONFIRMED_SPAM,
+ '127.0.0.9' => DNSBLLOOKUP_HIJACKED,
+ '127.0.0.10' => DNSBLLOOKUP_DYNAMIC_IP,
+ },
+ 'dnsbl.njabl.org' => {
+ '127.0.0.2' => DNSBLLOOKUP_OPEN_RELAY,
+ '127.0.0.3' => DNSBLLOOKUP_DYNAMIC_IP,
+ '127.0.0.4' => DNSBLLOOKUP_SPAMHOUSE,
+ '127.0.0.5' => DNSBLLOOKUP_MULTI_OPEN_RELAY,
+ '127.0.0.8' => DNSBLLOOKUP_FORMMAIL,
+ '127.0.0.9' => DNSBLLOOKUP_OPEN_PROXY,
+ },
+ 'bl.spamcop.net' => {
+ '127.0.0.2' => DNSBLLOOKUP_UNKNOWN,
+ },
+ 'unconfirmed.dsbl.org' => {
+ '127.0.0.2' => DNSBLLOOKUP_UNKNOWN,
+ },
+ 'list.dsbl.org' => {
+ '127.0.0.2' => DNSBLLOOKUP_UNKNOWN,
+ },
+ 'sbl.spamhaus.org' => {
+ '127.0.0.2' => DNSBLLOOKUP_SPAMHOUSE,
+ },
+ 'pbl.spamhaus.org' => {
+ '127.0.0.10' => DNSBLLOOKUP_DYNAMIC_IP,
+ '127.0.0.11' => DNSBLLOOKUP_DYNAMIC_IP,
+ },
+ 'cbl.abuseat.org' => {
+ '127.0.0.2' => DNSBLLOOKUP_OPEN_PROXY,
+ },
+ 'psbl.surriel.com' => {
+ '127.0.0.2' => DNSBLLOOKUP_OPEN_PROXY,
+ },
+);
+
+sub new {
+ my ($class) = shift;
+ my $self = { @_ };
+ bless $self, $class;
+ unless (exists $self->{zones}) {
+ @{$self->{zones}} = grep !/^relays.osirusoft.com$/, keys %dns_servers;
+ }
+ $self->{timeout} ||= 5;
+ return $self;
+}
+
+sub lookup {
+ my ($self, $ip) = @_;
+
+ my $res = Net::DNS::Resolver->new;
+ my $sel = IO::Select->new;
+ my @sockets;
+
+ my $result = DAKKAR::Net::DNSBLLookup::Result->new();
+
+ my $reverse_ip = join('.',reverse split('\.',$ip));
+
+ for my $zone (@{$self->{zones}}) {
+ my $host = join('.',$reverse_ip,$zone);
+ my $socket = $res->bgsend($host);
+ $sel->add($socket);
+ undef $socket;
+ }
+
+ while ($sel->count > 0) {
+ my @ready = $sel->can_read($self->{timeout});
+ last unless @ready;
+ foreach my $sock (@ready) {
+ my $packet = $res->bgread($sock);
+ my ($question) = $packet->question;
+ next unless $question;
+ my $qname = $question->qname;
+ (my $dnsbl = $qname) =~ s!^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.!!;
+ $result->add_dnsbl($dnsbl);
+ foreach my $rr ($packet->answer) {
+ next unless $rr->type eq "A";
+ $result->add($dnsbl, $rr->address);
+ }
+ $sel->remove($sock);
+ $sock = undef;
+ }
+ }
+ return $result;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Net::DNSBLLookup - Lookup IP Address in Open Proxy and SPAM DNS Blocklists
+
+=head1 SYNOPSIS
+
+ use Net::DNSBLLookup;
+ my $dnsbl = Net::DNSBLLookup->new(timeout => 5);
+ my $res = $dnsbl->lookup($ip_addr);
+ my ($proxy, $spam, $unknown) = $res->breakdown;
+ my $num_responded = $res->num_proxies_responded;
+
+=head1 ABSTRACT
+
+This module queries the major Open Proxy DNS Blocklists, including Sorbs,
+Easynet, NJABL, DSBL, Blitzed, CBL and PSBL. Open Proxies are servers that allow
+hackers to mask their true IP address. Some of these blocklists also contain
+hosts that have been known to send spam. This module distinguishes the
+results between Open Proxy and Spam/Open Relay servers.
+
+=head1 DESCRIPTION
+
+This module can be used to block or flag Internet connections coming from
+Open Proxy or Spam servers. Why would you want to do this? Hackers often
+use Open Proxy servers to hide their true IP address when doing "bad" stuff.
+This includes using purchasing stuff with stolen credit cards, and getting
+around IP Address based restrictions
+
+=head1 METHODS
+
+=over 4
+
+=item new
+
+Calls C<new()> to create a new DNSBLLookup object:
+
+ $dnsbl = new Net::DNSBLLookup(timeout => 5);
+
+Takes timeout as an argument, defaults to 5 seconds if not specified. The module
+waits C<timeout> seconds before giving up on a slow DNS host.
+
+=item lookup
+
+This sends out a lookup to the major DNS Blocklists, and waits up to C<timeout>
+seconds then returns the results:
+
+ $res = $dnsbl->lookup($ip_addr);
+
+=back
+
+=head1 SEE ALSO
+
+L<Net::DNSBLLookup::Result>
+
+There is a free credit card fraud prevention service that
+uses this module located at
+L<http://www.maxmind.com/app/ccv>
+
+=head1 AUTHOR
+
+TJ Mather, E<lt>tjmather@maxmind.comE<gt>
+
+Paid support is available from directly from the author of this package.
+Please see L<http://www.maxmind.com/app/opensourceservices> for more details.
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2003 by Maxmind LLC
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/lib/DAKKAR/Net/DNSBLLookup/Result.pm b/lib/DAKKAR/Net/DNSBLLookup/Result.pm
new file mode 100644
index 0000000..1c57e8f
--- /dev/null
+++ b/lib/DAKKAR/Net/DNSBLLookup/Result.pm
@@ -0,0 +1,144 @@
+package DAKKAR::Net::DNSBLLookup::Result;
+
+# copied from Net::DNSBLLookup v0.03
+
+use DAKKAR::Net::DNSBLLookup;
+
+use strict;
+
+use constant DNSBLLOOKUP_RESULT_OPEN_PROXY => 1;
+use constant DNSBLLOOKUP_RESULT_SPAM => 2;
+use constant DNSBLLOOKUP_RESULT_UNKNOWN => 3;
+use constant DNSBLLOOKUP_RESULT_DYNAMIC_IP => 4;
+
+my %result_type = (
+ DNSBLLOOKUP_OPEN_RELAY() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_DYNAMIC_IP() => DNSBLLOOKUP_RESULT_DYNAMIC_IP,
+ DNSBLLOOKUP_CONFIRMED_SPAM() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_SMARTHOST() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_SPAMHOUSE() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_LISTSERVER() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_FORMMAIL() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_OPEN_PROXY() => DNSBLLOOKUP_RESULT_OPEN_PROXY,
+ DNSBLLOOKUP_OPEN_PROXY_HTTP() => DNSBLLOOKUP_RESULT_OPEN_PROXY,
+ DNSBLLOOKUP_OPEN_PROXY_SOCKS() => DNSBLLOOKUP_RESULT_OPEN_PROXY,
+ DNSBLLOOKUP_OPEN_PROXY_MISC() => DNSBLLOOKUP_RESULT_OPEN_PROXY,
+ DNSBLLOOKUP_HIJACKED() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_MULTI_OPEN_RELAY() => DNSBLLOOKUP_RESULT_SPAM,
+ DNSBLLOOKUP_UNKNOWN() => DNSBLLOOKUP_RESULT_UNKNOWN,
+ );
+
+sub new {
+ my ($class) = @_;
+ my $self = bless {}, $class;
+ $self->{results} = {};
+ return $self;
+}
+
+sub add {
+ my ($self, $dnsbl, $address) = @_;
+ my $address_lookup = $Net::DNSBLLookup::dns_servers{$dnsbl};
+ if (ref($address_lookup) eq 'HASH') {
+ push @{$self->{results}->{$dnsbl}}, $address_lookup->{$address};
+ } elsif (ref($address_lookup) eq 'CODE') {
+ push @{$self->{results}->{$dnsbl}}, &$address_lookup($address);
+ }
+}
+
+sub add_dnsbl {
+ my ($self, $dnsbl) = @_;
+ $self->{dnsbl_responded}->{$dnsbl} = 1;
+}
+
+sub num_proxies_responded {
+ my ($self) = @_;
+ return scalar(keys %{$self->{dnsbl_responded}});
+}
+
+sub breakdown {
+ my ($self) = @_;
+ my ($total_spam, $total_proxy, $total_dyn, $total_unknown) = (0,0,0,0);
+ return unless exists $self->{results};
+ while (my ($dnsbl, $v) = each %{$self->{results}}) {
+ my ($is_spam, $is_proxy, $is_dyn, $is_unknown) = (0,0,0,0);
+ for my $retval (@$v) {
+ my $result_type = $result_type{$retval};
+ if ($result_type == DNSBLLOOKUP_RESULT_OPEN_PROXY) {
+ $is_proxy = 1;
+ } elsif ($result_type == DNSBLLOOKUP_RESULT_SPAM) {
+ $is_spam = 1;
+ } elsif ($result_type == DNSBLLOOKUP_RESULT_DYNAMIC_IP) {
+ $is_dyn = 1;
+ } elsif ($result_type == DNSBLLOOKUP_RESULT_UNKNOWN) {
+ $is_unknown = 1;
+ }
+ }
+ $total_proxy += $is_proxy;
+ $total_spam += $is_spam;
+ $total_dyn += $is_dyn;
+ unless ($is_proxy || $is_spam || $is_dyn) {
+ $total_unknown += $is_unknown;
+ }
+ }
+ return ($total_proxy, $total_spam, $total_dyn, $total_unknown);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Net::DNSBLLookup::Result - Analyze the DNS Blocklist lookup results
+
+=head1 SYNOPSIS
+
+ use Net::DNSBLLookup;
+ my $dnsbl = Net::DNSBLLookup->new(timeout => 5);
+ my $res = $dnsbl->lookup($ip_addr);
+ my ($proxy, $spam, $unknown) = $res->breakdown;
+ my $num_responded = $res->num_proxies_responded;
+
+=head1 DESCRIPTION
+
+The class represents objects returned by the lookup method of L<Net::DNSBLLookup>.
+Currently it supports the breakdown between the number of Open Proxy and Spam hosts, as
+well as the number of DNS Blocklist servers that actually responded.
+
+=head1 METHODS
+
+=over 4
+
+=item breakdown
+
+Returns the breakdown between the number of Open Proxy and Spam/Open Relay hosts.
+It also returns the number of hits that are unknown - for example the DSBL blocklist
+lumps all Open Proxy and Spam results into one code.
+
+ ($proxy, $spam, $unknown) = $res->breakdown;
+
+=item num_responded
+
+Returns the total number of DNS Blocklists that responded to our queries within
+C<timeout> seconds or less.
+
+ $num_responded = $res->num_proxies_responded;
+
+=back
+
+=head1 SEE ALSO
+
+L<Net::DNSBLLookup>
+
+=head1 AUTHOR
+
+TJ Mather, E<lt>tjmather@maxmind.comE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2003 by MaxMind LLC
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut