碳基体

奋斗在产品安全第一线的安全妹子

使用免费的本地IP地理库来定位IP地理位置-GeoIP lookup

网上有不少IP地理位置查询的API,像ip-api.com,但为了避免造成查询服务超载,都限制了查询数,所以最好的办法还是将IP地理库下载到本地,然后进行查询。


而其中IP地理库会按精确程度(其实就是更新是否及时)进行收费,当然也会好心的开放一下不用收费但没有那么准确的数据库


以下介绍利用maxMind提供的免费的IP地理库来定位IP的地理位置

一、GeoIP的使用

第一步:安装geoiplookup

以debian为例,安装包安装

apt-get install geoip-bin


在其他操作系统上可以采用手动编译安装

wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz

tar zxvf GeoIP.tar.gz

cd GeoIP-1.4.8/

./configure

make

make install

echo '/usr/local/lib' > /etc/ld.so.conf.d/geoip.conf

ldconfig


安装成功后,有以下重要文件

可执行文件:geoiplookup   geoiplookup6  geoipupdate

配置文件/etc/GeoIP.conf.default (数据库更新需要的身份认证配置),对于免费用户,不用管


第二步:下载(更新)IP地理库

maxMind提供按月更新的数据库,可以使用crontab 来定期更新这些数据库

以下编写一个脚本来下载数据库,并检查是否存在更新,脚本运行环境需要安装wget,gunzip,md5sum,当然大多数linux环境都已经安装

vim installGEODB.sh


#!/bin/bash
#下载免费数据库

#GeoLite Country
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
#GetLite Country IPv6
#wget http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz
#GeoLite City
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
#GeoLite City IPv6(Beta)
#wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz
#GeoLite ASN
wget http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
#GeoLite ASN IPv6
#wget http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNumv6.dat.gz


#解压缩

#gunzip
gunzip GeoIP.dat.gz
gunzip GeoLiteCity.dat.gz
gunzip GeoIPASNum.dat.gz

#get the md5 of binary file
#generate md5 value of the dat


#根据数据库文件的md5值来判断是否存在更新
if [ ! -f GeoIP_md5 ]
then
   md5sum  -b GeoIP.dat > GeoIP_md5
   cp -f GeoIP.dat /usr/share/GeoIP/
else
   GeoIP_result=$(md5sum -c GeoIP_md5)
fi

if [ ! -f  GeoLiteCity_md5 ]
then
   md5sum  -b GeoLiteCity.dat > GeoLiteCity_md5
   cp -f GeoLiteCity.dat /usr/share/GeoIP/
else
   GeoLiteCity_result=$(md5sum -c GeoLiteCity_md5)
fi


if [ ! -f GeoIPASNum_md5 ]
then
   md5sum  -b GeoIPASNum.dat > GeoIPASNum_md5
   cp -f  GeoIPASNum.dat /usr/share/GeoIP/
else
   GeoIPASNum_result=$(md5sum -c GeoIPASNum_md5)
fi


if [[ $GeoIP_result =~ OK$ ]]
then
   echo "GeoIP.dat not updating"
   rm -f GeoIP.dat
else
   echo "GeoIP.dat updating"
   md5sum  -b GeoIP.dat > GeoIP_md5
   mv -f GeoIP.dat /usr/share/GeoIP/
fi


if [[ $GeoLiteCity_result =~ OK$ ]]
then
   echo "GeoLiteCity.dat not updating"
   rm -f GeoLiteCity.dat
else
   echo "GeoLiteCity.dat updating"
   md5sum  -b GeoLiteCity.dat > GeoLiteCity_md5
   mv -f GeoLiteCity.dat /usr/share/GeoIP/
fi

if [[ $GeoIPASNum_result =~ OK$ ]]
then
   echo "GeoIPASNum.dat not updating"
   rm -f GeoIPASNum.dat
else
   echo "GeoIPASNum.dat updating"
   md5sum  -b GeoIPASNum.dat > GeoIPASNum_md5
   mv -f GeoIPASNum.dat /usr/share/GeoIP/
fi


chmod +x installGEODB.sh 


使用crontab在每月的1号执行更新操作

00 00 1 * * cd /home/getipDB ; /bin/bash /home/getipDB/installGEODB.sh 2>&1 &


第三步:使用geoiplookup获得地理位置

接下来我们就可以使用geoiplookup来查看指定的ip信息了

-bash-4.2# geoiplookup -f /usr/share/GeoIP/GeoIP.dat 61.55.186.15
GeoIP Country Edition: CN, China
-bash-4.2# geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat 61.55.186.15
GeoIP City Edition, Rev 1: CN, 10, Hebei, N/A, 39.889702, 115.275002, 0, 0
-bash-4.2# geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat 61.55.186.15
GeoIP ASNum Edition: AS4837 CNCGROUP China169 Backbone


在上面的基础上(安装了getiplookup, 和ip地理库)我们可以编写脚本来一次性获得指定ip或者host的所有ip地理位置,脚本如下所示:脚本使用perl编写,运行前需要安装

cpan -i Getopt::Long

cpan -i Term::ANSIColor

vim geoiplookup.pl

#!/usr/bin/perl -w
use Getopt::Long;
use Term::ANSIColor qw(:constants);

#命令行选项部分
my $help = "";
my $ip = "";
my $host = "";

local $Term::ANSIColor::AUTORESET = 1;

GetOptions(
'help|h'=>\$help,
'ip=s'=>\$ip,
'host=s'=>\$host
);


if($help){
print <<__HELP__;
Usage: $0 -ip 61.55.186.15 -host tanjiti.com

where:
-ip : Specify the ip address to query
-host: Specify the host address to query

__HELP__
exit 0;

}

chomp $ip;

die "You need to specify the ip address or hostname to query!!!! " if  ($ip eq "" and $host eq "");

#查询指定ip的地理信息
#query the specify ip geo information
geoiplookup($ip) if $ip ne "";

#查询指定host的地理信息
#query the specify host geo information
if ($host){
   my $ips=hosttoIP($host); 

   my @ips = split(' ',$ips);
   
   print BOLD RED "$host GEO information: \n";

   foreach (@ips){
      geoiplookup($_);
   }
}


#hosttoIP子函数:host反查获的域名对应的ip
sub hosttoIP{
   my $host = shift;
   my $ips = `host $host  | awk '{i=1; if(NF>0) do {if (\$i ~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/) print \$i; i++;} while (i <=NF);}'`;
   return $ips;
}

#geoiplookup子函数,调用geoiplookup与对应的地理数据库获得指定ip的地理信息
sub  geoiplookup{
   my $ip = shift;
   chomp $ip;

   my $country = `geoiplookup -f /usr/share/GeoIP/GeoIP.dat $ip`;
   my $city = `geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat $ip`;
   my $ASNum = `geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat $ip`;

   print BOLD BLUE "$ip GEO information: \n";
   print "\t",$country;
   print "\t",$city;
   print "\t",$ASNum;
}


chmod +x geoiplookup.pl

该脚本的使用方法

perl geoiplookup.pl --help
Usage: geoiplookup.pl -ip 61.55.186.15 -host tanjiti.com

where:
-ip : Specify the ip address to query
-host: Specify the host address to query

获得指定ip的地理信息

perl geoiplookup.pl -ip 61.55.186.15
61.55.186.15 GEO information: 
        GeoIP Country Edition: CN, China
        GeoIP City Edition, Rev 1: CN, 10, Hebei, N/A, 39.889702, 115.275002, 0, 0
        GeoIP ASNum Edition: AS4837 CNCGROUP China169 Backbone

获得指定host的地理信息

perl geoiplookup.pl -host weibo.com
weibo.com GEO information: 
114.134.80.187 GEO information: 
        GeoIP Country Edition: HK, Hong Kong
        GeoIP City Edition, Rev 1: HK, N/A, N/A, N/A, 22.250000, 114.166702, 0, 0
        GeoIP ASNum Edition: AS9304 Hutchison Global Communications



二、GeoIP2的使用

我们也可以直接读取地理数据库的内容来获得ip地理信息


第一步:下载地理数据库(免费版本)

wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gzwget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz (其实,有上面那个就ok了gunzip  GeoLite2-Country.mmdb.gz gunzip  GeoLite2-City.mmdb.gz

第二步:使用python解析数据库,查询指定的ip地理信息

pip install maxminddb #用于解析maxmind DB

vim geoiplookup.py  

#!/usr/bin/env python

import sys

import maxminddb

import subprocess

import re

import json

import getopt


#specify the ip geo db path
GeoLit2_city = "/root/getipDB/GeoLite2-City.mmdb"


#ipInfo():获得指定ip的地理信息 ,以json格式返回

def ipInfo(ip):
   readerCity = maxminddb.Reader(GeoLit2_city)

   cityInfo = readerCity.get(ip)
   print "\033[1;33;40m"
   print "%s 's Geo information:" % ip
   print "\033[0m"
   print json.dumps(cityInfo, sort_keys=True, indent=2)

   readerCity.close()


#hostToIP():调用外部命令host,反查域名所在ip

def hostToIP(host):
   try:
      ipInfo = subprocess.check_output(['host',host],stderr=subprocess.STDOUT,)
   except subprocess.CalledProcessError as err:
      print "ERROR:",err
   else:
      ips = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',ipInfo)

      return ips


#hostInfo():获得指定域名的地理信息
def hostInfo(host):

   print "\033[1;31;40m"
   print "%s 's gep information: " % host
   print "\033[0m"
   ips = hostToIP(host)
   for item in ips:

      ipInfo(item)chmod +x geoiplookup.py


#usage(): 脚本帮助信息,显示各个选项的使用方法

def usage():

   print "%s [-ip 61.55.186.15] [-host tanjiti.com]" % sys.argv[0]
   print "\t -d or --domain : specify the host for query"
   print "\t -i or --ip: specify the ip for query"
   print "\t -h or --help: for more help"


#main():主函数体

def main():
   try:
      opts,args = getopt.getopt(sys.argv[1:],"i:d:h",["ip=","domain=","help"])
   except getopt.GetoptError as err:
      print str(err)
      usage()
      sys.exit(2)
   else:
      for opt,val in opts:
         if opt in ('-h','--help'):
            usage()
            sys.exit()
         elif opt in ('-i','--ip'):
            ipInfo(val)
         elif opt in ('-d','--domain'):
            hostInfo(val)
         else:
            assert False,"unhandled option"

if __name__ == "__main__":
   main()

该脚本的使用方法

python geoiplookup.py -h
geoiplookup.py [-ip 61.55.186.15] [-host tanjiti.com]
 -d or --domain : specify the host for query
 -i or --ip: specify the ip for query
 -h or --help: for more help

获得指定ip的地理信息

python geoiplookup.py --ip 74.125.224.84

74.125.224.84 's Geo information:

{
  "city": {
    "geoname_id": 5375480, 
    "names": {
      "de": "Mountain View", 
      "en": "Mountain View", 
      "fr": "Mountain View", 
      "ru": "\u041c\u0430\u0443\u043d\u0442\u0438\u043d-\u0412\u044c\u044e", 
      "zh-CN": "\u8292\u5ef7\u7ef4\u5c24"
    }
  }, 

...

获得指定host的地理信息

python geoiplookup.py --domain tanjiti.com

tanjiti.com 's gep information: 


190.93.246.150 's Geo information:

{
  "city": {
    "geoname_id": 3621849, 
    "names": {
      "de": "San Jos\u00e9", 
      "en": "San Jos\u00e9", 
      "es": "San Jos\u00e9", 
      "fr": "San Jos\u00e9", 
      "ja": "\u30b5\u30f3\u30db\u30bb", 
      "pt-BR": "San Jos\u00e9", 
      "ru": "\u0421\u0430\u043d-\u0425\u043e\u0441\u0435"
    }
  }, 

源码放在我的github上,https://github.com/tanjiti/perl_tools/blob/master/getIPinfoOffline.pl



参考:

http://www.geekfan.net/7863/

http://xmodulo.com/2014/03/geographic-location-ip-address-command-line.html

来源:碳基体