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 else: 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 break if not batch_mode: print('%s,%s' % (ip, answer)) countries[answer] += 1 fin.close()
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):
~ ./country-by-ip.py ips.txt 242.73.117.31,None 184.108.40.206,United States 220.127.116.11,Brazil 18.104.22.168,United States 22.214.171.124,United States 126.96.36.199,China 188.8.131.52,China 184.108.40.206,United States 220.127.116.11,United States 18.104.22.168,None ~ ./country-by-ip.py --batch ips.txt None,2 Brazil,1 China,2 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.