ASN lookups now work
This commit is contained in:
parent
4eba2a39bc
commit
f2eda74074
@ -39,4 +39,11 @@ sub is_valid_ip {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub is_ipv6 {
|
||||||
|
my ($self, $ip) = @_;
|
||||||
|
return if !$ip;
|
||||||
|
return 1 if Net::IP::ip_is_ipv6($ip);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -102,6 +102,8 @@ data source: http://software77.net/geo-ip/
|
|||||||
|
|
||||||
=head1 ACKNOWLEDGEMENTS
|
=head1 ACKNOWLEDGEMENTS
|
||||||
|
|
||||||
|
MaxMind - the packager and distributor of the free GeoIP data
|
||||||
|
|
||||||
Stevan Bajic, the DSPAM author, who suggested SNARE, which describes using
|
Stevan Bajic, the DSPAM author, who suggested SNARE, which describes using
|
||||||
geodesic distance to determine spam probability. The research paper on SNARE
|
geodesic distance to determine spam probability. The research paper on SNARE
|
||||||
can be found here:
|
can be found here:
|
||||||
@ -126,27 +128,12 @@ sub register {
|
|||||||
$self->{_args} = {@args};
|
$self->{_args} = {@args};
|
||||||
$self->{_args}{db_dir} ||= '/usr/local/share/GeoIP';
|
$self->{_args}{db_dir} ||= '/usr/local/share/GeoIP';
|
||||||
|
|
||||||
eval 'use GeoIP2::Database::Reader';
|
$self->load_geoip2() and return;
|
||||||
if (!$@) {
|
$self->load_geoip1();
|
||||||
warn "using GeoIP2";
|
|
||||||
$self->log(LOGINFO, "using GeoIP2");
|
|
||||||
|
|
||||||
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";
|
sub load_geoip1 {
|
||||||
$self->log(LOGERROR, "could not load GeoIP2");
|
my $self = shift;
|
||||||
|
|
||||||
eval 'use Geo::IP';
|
eval 'use Geo::IP';
|
||||||
if ($@) {
|
if ($@) {
|
||||||
@ -166,6 +153,43 @@ sub register {
|
|||||||
$self->register_hook('connect', 'geoip_lookup');
|
$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 {
|
sub geoip2_lookup {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
@ -246,14 +270,18 @@ sub open_geoip_db {
|
|||||||
my $db_dir = $self->{_args}{db_dir};
|
my $db_dir = $self->{_args}{db_dir};
|
||||||
foreach my $db (qw/ GeoIPCity GeoLiteCity /) {
|
foreach my $db (qw/ GeoIPCity GeoLiteCity /) {
|
||||||
next if !-f "$db_dir/$db.dat";
|
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");
|
$self->{_geoip_city} = Geo::IP->open("$db_dir/$db.dat");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $db (qw/ GeoIPASNum GeoIPASNumv6 /) {
|
if (-f "$db_dir/GeoIPASNum.dat") {
|
||||||
next if !-f "$db_dir/$db.dat";
|
$self->log(LOGINFO, "using GeoIPASNum");
|
||||||
$self->log(LOGDEBUG, "using db $db");
|
$self->{GeoIPASNum} = Geo::IP->open("$db_dir/GeoIPASNum.dat");
|
||||||
$self->{$db} = Geo::IP->open("$db_dir/$db.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
|
# 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 {
|
sub set_asn {
|
||||||
my ($self) = @_;
|
my ($self, $ip) = @_;
|
||||||
my $remote_ip = $self->qp->connection->remote_ip;
|
$ip ||= $self->qp->connection->remote_ip;
|
||||||
|
|
||||||
|
if (Qpsmtpd::Base->is_ipv6($ip)) {
|
||||||
|
return $self->set_asn_ipv6($ip);
|
||||||
|
}
|
||||||
return if ! $self->{GeoIPASNum};
|
return if ! $self->{GeoIPASNum};
|
||||||
|
|
||||||
my $asn = $self->{GeoIPASNum}
|
my $asn = $self->{GeoIPASNum}->name_by_addr($ip) or return;
|
||||||
? $self->get_asn_gc($remote_ip)
|
|
||||||
: $self->{_geoip}->asn_by_addr($remote_ip);
|
|
||||||
|
|
||||||
$asn or return;
|
|
||||||
$self->qp->connection->notes('geoip_asn', $asn);
|
$self->qp->connection->notes('geoip_asn', $asn);
|
||||||
return $asn;
|
return $asn;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_asn_gc {
|
sub set_asn_ipv6 {
|
||||||
my $self = shift;
|
my ($self, $ip) = @_;
|
||||||
return if !$self->{GeoIPASNum};
|
$ip ||= $self->qp->connection->remote_ip;
|
||||||
return $self->{GeoIPASNum}->asn_by_addr();
|
|
||||||
|
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 {
|
sub set_city_gc {
|
||||||
|
@ -13,14 +13,11 @@ sub register_tests {
|
|||||||
if ( !$@ ) {
|
if ( !$@ ) {
|
||||||
warn "using GeoIP2\n";
|
warn "using GeoIP2\n";
|
||||||
$self->register_test('test_geoip2_lookup');
|
$self->register_test('test_geoip2_lookup');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eval 'use Geo::IP';
|
eval 'use Geo::IP';
|
||||||
if ( $@ ) {
|
if ( !$@ ) {
|
||||||
warn "could not load Geo::IP\n";
|
warn "loaded Geo::IP\n";
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
$self->register_test('test_geoip_lookup');
|
$self->register_test('test_geoip_lookup');
|
||||||
$self->register_test('test_geoip_load_db');
|
$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_country_name');
|
||||||
$self->register_test('test_set_continent');
|
$self->register_test('test_set_continent');
|
||||||
$self->register_test('test_set_distance');
|
$self->register_test('test_set_distance');
|
||||||
$self->register_test('test_set_isp');
|
$self->register_test('test_set_asn');
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sub test_geoip2_lookup {
|
sub test_geoip2_lookup {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
$self->qp->connection->remote_ip('24.24.24.24');
|
$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");
|
if (!$self->load_geoip2()) {
|
||||||
cmp_ok( $self->connection->notes('geoip_country_name'), 'eq', 'United States', "24.24.24.24 is in the United States");
|
warn "failed to load GeoIP2\n";
|
||||||
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");
|
|
||||||
|
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 {
|
sub test_geoip_lookup {
|
||||||
@ -164,3 +166,20 @@ sub test_set_distance {
|
|||||||
ok( 1, "no distance data");
|
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