Determining country by IP

In my line of research, it’s often useful to be able to identify where a country is using just it’s IP address. I’ve done it a few different ways over the years, but the simplest I’ve found is using the MaxMind GeoLite Country database directly. To speed such lookups, I’ve written a simple Python script that can run a whole series of such queries for you.

Basically, the MaxMind “database” is a CSV file that contains the first and last IP in each range, those same IPs as an integer value, and then country code and country containing that IP range. So it’s a simple matter to load all of the IPs into a list containing (first, last, country) tuples (using the integer versions to make comparisons quicker):

ipdb = []
with open(ip_file, 'r') as fin:
    for line in fin:
        parts = [part.strip('"') for part in line.strip().split(',')]
        if len(parts) == 6:
            from_ip, to_ip, from_int, to_int, cc, country = parts
            ipdb.append((itn(from_int), int(to_int), country))

After that, it’s a simple matter of scanning through input files. I added the ability to read stdin as a file as well by specifying the file ‘-’ to match other Unix scripts.

for file in files:
    if file == '-':
        fin = sys.stdin
        fin = open(file, 'r')

    for line in fin:
        ip = line.strip()
        if not ip: continue

        ip_int = ip_to_int(ip)
        answer = None
        for from_int, to_int, country in ipdb:
            if from_int <= ip_int <= to_int:
                answer = country

        if not batch_mode:
            print('%s,%s' % (ip, answer))

        countries[answer] += 1


And that’s it. I could use a more intelligent data structure for the IP ranges, but honestly, it runs quickly enough. Perhaps sometime in the future.

Here are a few cases of the script in action (using the default ‘GeoIPCountryWhois.csv’ in the same directory, using randomly generated IPs):

~ ./ ips.txt,None,United States,Brazil,United States,United States,China,China,United States,United States,None

~ ./ --batch ips.txt

United States,5

And that’s all there is to it. Hope someone out there finds it useful, I sure did.

If you’d like to download the entire source (with the setup and command line processing included), you can do so here: country-by-ip source.