Perl Sample Code for Geolocation Lookups with MaxMind GeoLite2

There’s been a lot of changes with MaxMind’s GeoIP database:

  1. You must register for an account to download databases.
  2. The database format was changed from GeoIP to GeoIP2. The free databases are called GeoLite2.
  3. Older lookup APIs no longer work, so you must update your libraries and source code.
  4. The new API supports both IPv4 and IPv6.

There’s a lot of obsolete and unclear examples online.

Here’s complete, tested perl sample (March 2020):

#!/usr/bin/perl

use strict;
use warnings;

use GeoIP2::Database::Reader;

my $ip = "2607:f8b0:4005:804::200e";
my $db = "/usr/share/GeoLite2/GeoLite2-City.mmdb";

# MaxMind's placeholder coordinates for when a geoip lookup fails
my $nf_lat = '37.751';
my $nf_long = '-97.822';

my ($lat, $long) = (0, 0);

eval {
    my $reader = GeoIP2::Database::Reader->new(
       file => $db, locales => ["en"]
    );
    my $where = $reader->city( ip => $ip );
    my $location = $where->location;
    ($lat, $long) = ($location->latitude, $location->longitude);
};
if (@! or ($lat eq $nf_lat and $long eq $nf_long)) {
   print "error: lookup failed on '$ip'\n";
}
else {
   print "$lat, $long\n";
}
$ perl test_geoip2.pl

metacpan.org: GeoIP2::Database::Reader
perladvent.org: Where in the World?

This entry was posted in Open Source, Perl, Tech. Bookmark the permalink.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.