ASN lookups now work
This commit is contained in:
parent
4eba2a39bc
commit
f2eda74074
@ -39,4 +39,11 @@ sub is_valid_ip {
|
||||
return;
|
||||
}
|
||||
|
||||
sub is_ipv6 {
|
||||
my ($self, $ip) = @_;
|
||||
return if !$ip;
|
||||
return 1 if Net::IP::ip_is_ipv6($ip);
|
||||
return;
|
||||
};
|
||||
|
||||
1;
|
||||
|
@ -102,6 +102,8 @@ data source: http://software77.net/geo-ip/
|
||||
|
||||
=head1 ACKNOWLEDGEMENTS
|
||||
|
||||
MaxMind - the packager and distributor of the free GeoIP data
|
||||
|
||||
Stevan Bajic, the DSPAM author, who suggested SNARE, which describes using
|
||||
geodesic distance to determine spam probability. The research paper on SNARE
|
||||
can be found here:
|
||||
@ -126,27 +128,12 @@ sub register {
|
||||
$self->{_args} = {@args};
|
||||
$self->{_args}{db_dir} ||= '/usr/local/share/GeoIP';
|
||||
|
||||
eval 'use GeoIP2::Database::Reader';
|
||||
if (!$@) {
|
||||
warn "using GeoIP2";
|
||||
$self->log(LOGINFO, "using GeoIP2");
|
||||
$self->load_geoip2() and return;
|
||||
$self->load_geoip1();
|
||||
}
|
||||
|
||||
eval {
|
||||
$self->{_geoip2_city} = GeoIP2::Database::Reader->new(
|
||||
file => $self->{_args}{db_dir} . '/GeoLite2-City.mmdb',
|
||||
);
|
||||
};
|
||||
eval {
|
||||
$self->{_geoip2_country} = GeoIP2::Database::Reader->new(
|
||||
file => $self->{_args}{db_dir} . '/GeoLite2-Country.mmdb',
|
||||
);
|
||||
};
|
||||
$self->register_hook('connect', 'geoip2_lookup');
|
||||
return;
|
||||
}
|
||||
|
||||
warn "could not load GeoIP2";
|
||||
$self->log(LOGERROR, "could not load GeoIP2");
|
||||
sub load_geoip1 {
|
||||
my $self = shift;
|
||||
|
||||
eval 'use Geo::IP';
|
||||
if ($@) {
|
||||
@ -166,6 +153,43 @@ sub register {
|
||||
$self->register_hook('connect', 'geoip_lookup');
|
||||
}
|
||||
|
||||
sub load_geoip2 {
|
||||
my $self = shift;
|
||||
|
||||
eval 'use GeoIP2::Database::Reader';
|
||||
if ($@) {
|
||||
$self->log(LOGERROR, "could not load GeoIP2");
|
||||
return;
|
||||
}
|
||||
|
||||
$self->log(LOGINFO, "GeoIP2 loaded");
|
||||
|
||||
eval {
|
||||
$self->{_geoip2_city} = GeoIP2::Database::Reader->new(
|
||||
file => $self->{_args}{db_dir} . '/GeoLite2-City.mmdb',
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
$self->log(LOGERROR, "unable to load GeoLite2-City.mmdb");
|
||||
}
|
||||
|
||||
eval {
|
||||
$self->{_geoip2_country} = GeoIP2::Database::Reader->new(
|
||||
file => $self->{_args}{db_dir} . '/GeoLite2-Country.mmdb',
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
$self->log(LOGERROR, "unable to load GeoLite2-Country.mmdb");
|
||||
}
|
||||
|
||||
if ($self->{_geoip2_city} || $self->{_geoip2_country}) {
|
||||
$self->register_hook('connect', 'geoip2_lookup');
|
||||
return 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub geoip2_lookup {
|
||||
my $self = shift;
|
||||
|
||||
@ -246,14 +270,18 @@ sub open_geoip_db {
|
||||
my $db_dir = $self->{_args}{db_dir};
|
||||
foreach my $db (qw/ GeoIPCity GeoLiteCity /) {
|
||||
next if !-f "$db_dir/$db.dat";
|
||||
$self->log(LOGDEBUG, "using db $db");
|
||||
$self->log(LOGINFO, "using db $db");
|
||||
$self->{_geoip_city} = Geo::IP->open("$db_dir/$db.dat");
|
||||
}
|
||||
|
||||
foreach my $db (qw/ GeoIPASNum GeoIPASNumv6 /) {
|
||||
next if !-f "$db_dir/$db.dat";
|
||||
$self->log(LOGDEBUG, "using db $db");
|
||||
$self->{$db} = Geo::IP->open("$db_dir/$db.dat");
|
||||
if (-f "$db_dir/GeoIPASNum.dat") {
|
||||
$self->log(LOGINFO, "using GeoIPASNum");
|
||||
$self->{GeoIPASNum} = Geo::IP->open("$db_dir/GeoIPASNum.dat");
|
||||
}
|
||||
|
||||
if (-f "$db_dir/GeoIPASNumv6.dat") {
|
||||
$self->log(LOGINFO, "using GeoIPASNumv6");
|
||||
$self->{GeoIPASNumv6} = Geo::IP->open("$db_dir/GeoIPASNumv6.dat");
|
||||
}
|
||||
|
||||
# can't think of a good reason to load country if city data is present
|
||||
@ -338,23 +366,28 @@ sub get_continent_gc {
|
||||
}
|
||||
|
||||
sub set_asn {
|
||||
my ($self) = @_;
|
||||
my $remote_ip = $self->qp->connection->remote_ip;
|
||||
my ($self, $ip) = @_;
|
||||
$ip ||= $self->qp->connection->remote_ip;
|
||||
|
||||
if (Qpsmtpd::Base->is_ipv6($ip)) {
|
||||
return $self->set_asn_ipv6($ip);
|
||||
}
|
||||
return if ! $self->{GeoIPASNum};
|
||||
|
||||
my $asn = $self->{GeoIPASNum}
|
||||
? $self->get_asn_gc($remote_ip)
|
||||
: $self->{_geoip}->asn_by_addr($remote_ip);
|
||||
|
||||
$asn or return;
|
||||
my $asn = $self->{GeoIPASNum}->name_by_addr($ip) or return;
|
||||
$self->qp->connection->notes('geoip_asn', $asn);
|
||||
return $asn;
|
||||
}
|
||||
|
||||
sub get_asn_gc {
|
||||
my $self = shift;
|
||||
return if !$self->{GeoIPASNum};
|
||||
return $self->{GeoIPASNum}->asn_by_addr();
|
||||
sub set_asn_ipv6 {
|
||||
my ($self, $ip) = @_;
|
||||
$ip ||= $self->qp->connection->remote_ip;
|
||||
|
||||
return if ! $self->{GeoIPASNumv6};
|
||||
|
||||
my $asn = $self->{GeoIPASNumv6}->name_by_addr_v6($ip) or return;
|
||||
$self->qp->connection->notes('geoip_asn', $asn);
|
||||
return $asn;
|
||||
}
|
||||
|
||||
sub set_city_gc {
|
||||
|
@ -13,14 +13,11 @@ sub register_tests {
|
||||
if ( !$@ ) {
|
||||
warn "using GeoIP2\n";
|
||||
$self->register_test('test_geoip2_lookup');
|
||||
return;
|
||||
}
|
||||
|
||||
eval 'use Geo::IP';
|
||||
if ( $@ ) {
|
||||
warn "could not load Geo::IP\n";
|
||||
return;
|
||||
};
|
||||
if ( !$@ ) {
|
||||
warn "loaded Geo::IP\n";
|
||||
|
||||
$self->register_test('test_geoip_lookup');
|
||||
$self->register_test('test_geoip_load_db');
|
||||
@ -29,19 +26,24 @@ sub register_tests {
|
||||
$self->register_test('test_set_country_name');
|
||||
$self->register_test('test_set_continent');
|
||||
$self->register_test('test_set_distance');
|
||||
$self->register_test('test_set_isp');
|
||||
$self->register_test('test_set_asn');
|
||||
};
|
||||
};
|
||||
|
||||
sub test_geoip2_lookup {
|
||||
my $self = shift;
|
||||
|
||||
$self->qp->connection->remote_ip('24.24.24.24');
|
||||
cmp_ok( $self->geoip2_lookup(), '==', DECLINED, "exit code");
|
||||
cmp_ok( $self->geoip2_lookup(), '==', DECLINED, "exit code DECLINED");
|
||||
|
||||
cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "24.24.24.24 is in the US");
|
||||
cmp_ok( $self->connection->notes('geoip_country_name'), 'eq', 'United States', "24.24.24.24 is in the United States");
|
||||
cmp_ok( $self->connection->notes('geoip_continent'), 'eq', 'NA', "24.24.24.24 is in NA");
|
||||
cmp_ok( $self->connection->notes('geoip_city'), 'eq', 'Deer Park', "24.24.24.24 is in Deer Park");
|
||||
if (!$self->load_geoip2()) {
|
||||
warn "failed to load GeoIP2\n";
|
||||
}
|
||||
|
||||
cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "24.24.24.24 is in country US");
|
||||
cmp_ok( $self->connection->notes('geoip_country_name'), 'eq', 'United States', "24.24.24.24 is in country United States");
|
||||
cmp_ok( $self->connection->notes('geoip_continent'), 'eq', 'NA', "24.24.24.24 is in continent NA");
|
||||
cmp_ok( $self->connection->notes('geoip_city'), 'eq', 'Deer Park', "24.24.24.24 is in city of Deer Park");
|
||||
};
|
||||
|
||||
sub test_geoip_lookup {
|
||||
@ -164,3 +166,20 @@ sub test_set_distance {
|
||||
ok( 1, "no distance data");
|
||||
}
|
||||
};
|
||||
sub test_set_asn {
|
||||
my $self = shift;
|
||||
|
||||
$self->qp->connection->remote_ip('');
|
||||
$self->set_asn();
|
||||
my $asn = $self->set_asn();
|
||||
ok( ! $asn, "undef") or warn "$asn\n";
|
||||
|
||||
$self->qp->connection->remote_ip('24.24.24.24');
|
||||
$asn = $self->set_asn();
|
||||
ok( $self->connection->notes('geoip_asn') =~ /^AS11351/, "note has: $asn");
|
||||
|
||||
$self->qp->connection->remote_ip('66.128.51.163');
|
||||
$asn = $self->set_asn();
|
||||
|
||||
ok( $self->connection->notes('geoip_asn') =~ /^AS7819/, "note has: $asn");
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user