{"id":730,"date":"2019-12-11T16:36:01","date_gmt":"2019-12-11T15:36:01","guid":{"rendered":"https:\/\/www.tiraquelibras.com\/blog\/?p=730"},"modified":"2020-06-11T11:32:07","modified_gmt":"2020-06-11T09:32:07","slug":"geolocalizacion-ip-en-python3-con-maxmind-y-nominatim","status":"publish","type":"post","link":"https:\/\/blog.tiraquelibras.com\/?p=730","title":{"rendered":"Geolocalizaci\u00f3n IP en Python3 con MaxMind y Nominatim"},"content":{"rendered":"\n<p><span style=\"color: #ff0000;\"><strong>Actualizado el 7\/4\/2020.<\/strong><\/span> <strong><span style=\"color:#ff0000\" class=\"has-inline-color\">\/ Actualizado el 11\/6\/2020.<\/span><\/strong><\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_76 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de contenidos<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69f0d8769c5da\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69f0d8769c5da\"  aria-label=\"Alternar\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Introduccion\"  rel=\"nofollow\" target=\"_blank\">Introducci\u00f3n<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#MaxMind\"  rel=\"nofollow\" target=\"_blank\">MaxMind<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Nominatim\"  rel=\"nofollow\" target=\"_blank\">Nominatim<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-4 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Instalacion\"  rel=\"nofollow\" target=\"_blank\">Instalaci\u00f3n<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Descarga_con_Git\"  rel=\"nofollow\" target=\"_blank\">Descarga con Git<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Instalacion_manual\"  rel=\"nofollow\" target=\"_blank\">Instalaci\u00f3n manual<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Instalacion_de_modulos_necesarios\"  rel=\"nofollow\" target=\"_blank\">Instalaci\u00f3n de m\u00f3dulos necesarios<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#DescargaActualizacion_de_las_bases_de_datos_de_MaxMind\"  rel=\"nofollow\" target=\"_blank\">Descarga\/Actualizaci\u00f3n de las bases de datos de MaxMind<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-9 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Ejecucion_del_programa\"  rel=\"nofollow\" target=\"_blank\">Ejecuci\u00f3n del programa<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-10 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\/#Enlaces_de_interes\"  rel=\"nofollow\" target=\"_blank\">Enlaces de inter\u00e9s<\/a><\/li><\/ul><\/nav><\/div>\n<h1 class=\"wp-block-heading\" id=\"introducci\u00f3n\"><span class=\"ez-toc-section\" id=\"Introduccion\"><\/span>Introducci\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p><strong>GeoIp<\/strong>&nbsp;es un programa destinado a la geolocalizaci\u00f3n de una direcci\u00f3n IP con licencia libre para su uso sin restricci\u00f3n alguna.<br>No solo permite la obtenci\u00f3n de la Geolicalizaci\u00f3n, sino que tambi\u00e9n permite obtener el&nbsp;<strong>Sistema Aut\u00f3nomo<\/strong>&nbsp;(ASN) al que pertenece la IP y la organizaci\u00f3n que lo tiene registrado.<\/p>\n\n\n\n<p>Se encuentra escrito en&nbsp;<strong>Python3<\/strong>, adjuntando tambi\u00e9n un script escrito en&nbsp;<strong>Bash<\/strong>&nbsp;para actualizar las bases de datos de&nbsp;<strong>MaxMind<\/strong>&nbsp;peri\u00f3dicamente desde el&nbsp;<strong>Cron<\/strong>&nbsp;del sistema.<\/p>\n\n\n\n<p>Para ello se utilizan las siguientes herramientas:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"maxmind\"><span class=\"ez-toc-section\" id=\"MaxMind\"><\/span>MaxMind<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Bases de datos de&nbsp;<strong><a href=\"https:\/\/www.maxmind.com\/en\/home\" target=\"_blank\" rel=\"noreferrer noopener nofollow\" class=\"external external_icon\">MaxMind<\/a>,<\/strong> en concreto las bases de datos <em><strong>City<\/strong><\/em> y <em><strong>ASN<\/strong><\/em> de su producto gratuito&nbsp;<strong><a title=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" type=\"\" data-from-md=\"\" href=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">Geo<\/a><a href=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\" class=\"external external_icon\">L<\/a><a title=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" type=\"\" data-from-md=\"\" href=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">ite2<\/a>.<\/strong><\/p>\n\n\n\n<p><span style=\"color: #ff0000;\"><strong><u>ACTUALIZACI\u00d3N<\/u><\/strong><\/span><br>Tras los \u00faltimos cambios aplicados el&nbsp;<strong>30 de Diciembre del 2019<\/strong>&nbsp;es necesario disponer de una cuenta gratuita en esta plataforma, pudiendo registrarse en el siguiente&nbsp;<a title=\"https:\/\/www.maxmind.com\/en\/geolite2\/signup\" href=\"https:\/\/www.maxmind.com\/en\/geolite2\/signup\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">enlace<\/a>.<\/p>\n\n\n\n<p>Una vez creada la cuenta hay que generar un c\u00f3digo o&nbsp;<em><strong>token<\/strong><\/em>&nbsp;para poder descargarse las bases de datos. Este c\u00f3digo lo generamos, una vez validados en el portal, en el siguiente&nbsp;<a title=\"https:\/\/www.maxmind.com\/en\/accounts\/current\/license-key\" href=\"https:\/\/www.maxmind.com\/en\/accounts\/current\/license-key\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">enlace<\/a>.<\/p>\n\n\n\n<p>Las instrucciones para descargar los archivos a partir de su URL se pueden consultar&nbsp;<a title=\"https:\/\/dev.maxmind.com\/geoip\/geoipupdate\/#Direct_Downloads\" href=\"https:\/\/dev.maxmind.com\/geoip\/geoipupdate\/#Direct_Downloads\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>Toda la informaci\u00f3n de estos cambios se pueden consultar en el siguiente&nbsp;<a title=\"https:\/\/blog.maxmind.com\/2019\/12\/18\/significant-changes-to-accessing-and-using-geolite2-databases\/\" href=\"https:\/\/blog.maxmind.com\/2019\/12\/18\/significant-changes-to-accessing-and-using-geolite2-databases\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">enlace<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"nominatim\"><span class=\"ez-toc-section\" id=\"Nominatim\"><\/span>Nominatim<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>A partir de las coordenadas de&nbsp;<em>latitud<\/em>&nbsp;y&nbsp;<em>longitud<\/em>&nbsp;obtenidas con las bases de datos de&nbsp;<strong>MaxMind<\/strong>&nbsp;obtenemos la ubicaci\u00f3n con la herramienta&nbsp;<strong><a href=\"https:\/\/wiki.openstreetmap.org\/wiki\/Nominatim\" target=\"_blank\" rel=\"noreferrer noopener nofollow\" class=\"external external_icon\">Nominatim<\/a>,<\/strong> la cual hace uso de la informaci\u00f3n de&nbsp;<a href=\"https:\/\/www.openstreetmap.org\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\" class=\"external external_icon\"><strong>OpenStreetMap<\/strong><\/a>.<\/p>\n\n\n\n<p>Esta herramienta tiene una serie de restricciones y limitaciones que debemos de tener en cuenta para su uso. Se encuentran&nbsp;<a title=\"https:\/\/operations.osmfoundation.org\/policies\/nominatim\/\" href=\"https:\/\/operations.osmfoundation.org\/policies\/nominatim\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"instalaci\u00f3n\"><span class=\"ez-toc-section\" id=\"Instalacion\"><\/span>Instalaci\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p>Se recomienda hacer uso de&nbsp;<em>entornos virtuales<\/em>&nbsp;de&nbsp;<strong>Python<\/strong>&nbsp;para desplegar la herramienta. Puedes consultar como instalarlo en entornos Linux&nbsp;<a title=\"https:\/\/blog.tiraquelibras.com\/?p=723\" href=\"https:\/\/blog.tiraquelibras.com\/?p=723\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>Nos ubicamos en el directorio en donde vayamos a desplegar el programa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">cd \/path\/to\/your\/program<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"descarga-del-programa-con-git\"><span class=\"ez-toc-section\" id=\"Descarga_con_Git\"><\/span>Descarga con Git<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Descargamos el programa con el siguiente comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">git clone https:\/\/sergiobr@bitbucket.org\/sergiobr\/geoip.git<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"instalaci\u00f3n-manual\"><span class=\"ez-toc-section\" id=\"Instalacion_manual\"><\/span>Instalaci\u00f3n manual<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Debemos de crear el directorio&nbsp;<em><strong><code class=\"inline-code\">dbs<\/code><\/strong><\/em>&nbsp;en donde se ubicar\u00e1n las bases de datos de&nbsp;<strong>MaxMind<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">mkdir -p dbs<\/code><\/pre>\n\n\n\n<p>Creamos el archivo&nbsp;<em><strong><code class=\"inline-code\">geoIp.py<\/code><\/strong><\/em>&nbsp;con el contenido del programa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import maxminddb\nimport sys\nfrom geopy.geocoders import Nominatim\nfrom optparse import OptionParser\nfrom IPy import IP\n\n######################\n# Funciones y Clases #\n######################\n\n# Clase para interactuar con MaxMind y Nominatim\nclass getIpInfo:\n\n    # Constructor de la clase\n    def __init__(self,ip):\n        self.ip = str(ip)\n\n    # Obtener la info de MaxMind\n    def getMaxMind(self):\n        try:\n            # Obtener la info de la base de datos City de MaxMind\n            reader = maxminddb.open_database('dbs\/GeoLite2-City.mmdb')\n            res = reader.get(self.ip)\n            # Devolver el resultado de MaxMind\n            return res\n        except Exception as e:\n            raise ValueError('class - error getting MaxMind info: %s' % (str(e)))\n\n    # Funcion para obtener la direccion a partir de las coordenadas Latitud y Longitud\n    def getAddress(self,coordenates):\n        try:\n            # Crear la aplicacion de Nominatim\n            geolocator = Nominatim(user_agent=\"my-application\")\n            # Obtener la localizacion a partir de la Latitud y Longitud\n            location = geolocator.reverse(coordenates)\n            # Devolver la informacion con la localizacion\n            return location.raw\n        except Exception as e:\n            raise ValueError('class - error getting Nominatim info from coordenates: %s' % (str(e)))\n\n\n    # Obtener la info del ASN de MaxMind\n    def getAsnInfo(self):\n        try:\n            # Obtener la info de la base de datos ASN de MaxMind\n            reader = maxminddb.open_database('dbs\/GeoLite2-ASN.mmdb')\n            res = reader.get(self.ip)\n            # Devolver el resutlado de MaxMind\n            return res\n        except Exception as e:\n            raise ValueError('class - getting MaxMind ASN info: %s' % (str(e)))\n\n\n# Mostar el resultado final\ndef printResult(info,arguments):\n    try:\n        if info == 'default':\n            keys = ['IP','Latitude','Longitude','ContCode','Continent','CounCode','Country']\n            for key in keys:\n                print('%-15s  -  %-15s' % (str(key), str(arguments[key])))\n        elif info == 'full':\n            keys = ['Region','Address','Timezone','Licence']\n            for key in keys:\n                print('%-15s  -  %-15s' % (str(key), str(arguments[key])))\n        elif info == 'asn':\n            keys = ['ASN','ASN Org']\n            for key in keys:\n                print('%-15s  -  %-15s' % (str(key), str(arguments[key])))\n        else:\n            print('Nothing to show.')\n    except Exception as e:\n        raise ValueError('function - error printing results: %s' % (str(e)))\n\n# Creacion de las opciones e info del programa\ndef programParser():\n    try:\n        usage = \"Address info of an IP address.\\nUsage: %prog [options] ip_address.\"\n        description = 'IP geolocation info. Add only one IP address. Ranges are not allowed.'\n        version = '%prog: version 1.0'\n        parser = OptionParser(usage,version=version,description=description,add_help_option=True)\n        parser.add_option('-a', '--asn', dest = 'asn', help = 'Get only ASN info.', action='store_true')\n        parser.add_option('-f', '--full', dest = 'full', help = 'Get full address info.', action='store_true')\n        return parser\n    except Exception as e:\n        raise ValueError('function - creating program parser: %s' % (str(e)))\n\n\n############\n# Programa #\n############\n\ntry:\n    # Crear el Parser del programa\n    parser = programParser()\n\n    # Obtener los argumentos y opciones\n    (options, args) = parser.parse_args()\n\n    # Confirmar el total de argumentos. Solo se permite uno\n    if len(args) == 0:\n        raise ValueError('No argument has been indicated.')\n    elif len(args) > 1 or len(args) &lt; 0:\n        raise ValueError('Only one argument is allowed.')\n    else:\n\n        # Confirmar si el argumento es una IP valida o no\n        try:\n            ip = IP(args[0])\n        except Exception as e:\n            raise ValueError('The IP %s is not valid. %s' % (str(args[0]),str(e)))\n\n        # Confirmar si la IP es publica o no\n        if ip.iptype() == 'PUBLIC':\n\n            # Crear la clase para obtener la informacion de la IP\n            geoIpCommands = getIpInfo(ip)\n\n            # Declaramos las variables con los resultados\n            finalResult = {}\n            finalResultFull = {}\n            finalResultAsn = {}\n\n            # Obtener la direccion de la IP dependiendo de los argumentos indicados\n            # Obtener la info de MaxMind\n            maxMindRes = geoIpCommands.getMaxMind()\n\n            # Info por defecto\n            finalResult = {'IP':str(ip)}\n            finalResult['Latitude'] = str(maxMindRes['location']['latitude'])\n            finalResult['Longitude'] = str(maxMindRes['location']['longitude'])\n            finalResult['ContCode'] = str(maxMindRes['continent']['code'])\n            finalResult['Continent'] = str(maxMindRes['continent']['names']['en'])\n            if 'country' in maxMindRes:\n                finalResult['CounCode'] = str(maxMindRes['country']['iso_code'])\n                finalResult['Country'] = str(maxMindRes['country']['names']['en'])\n            elif 'registered_country' in maxMindRes:\n                finalResult['CounCode'] = str(maxMindRes['registered_country']['iso_code'])\n                finalResult['Country'] = str(maxMindRes['registered_country']['names']['en'])\n            else:\n                finalResult['CounCode'] = 'None'\n                finalResult['Country'] = 'None'\n\n            # Info completa, opcion '-f' o '--full'\n            if options.full:\n                # Obtener las coordenadas (Latitud y Longitud)\n                coordenates = finalResult['Latitude'],finalResult['Longitude']\n                # Obtener la info de Nominatim a partir de las cordenadas\n                nominatimRes = geoIpCommands.getAddress(coordenates)\n                # Info completa\n                if 'state' in nominatimRes['address']:\n                    finalResultFull['Region'] = nominatimRes['address']['state']\n                elif 'state_district' in nominatimRes['address']:\n                    finalResultFull['Region'] = nominatimRes['address']['state_district']\n                else:\n                    finalResultFull['Region'] = 'None'\n                finalResultFull['Address'] = nominatimRes['display_name']\n                finalResultFull['Timezone'] = str(maxMindRes['location']['time_zone'])\n                finalResultFull['Licence'] = nominatimRes['licence']\n                #finalResultFull['City'] = str(maxMindRes['city']['names']['en'])\n                #finalResultFull['Postcode'] = str(maxMindRes['postal']['code']\n                #finalResultFull['Postcode'] = nominatimRes['address']['postcode']\n\n            # Info del ASN, opcion '-a' o '--asn'\n            if options.asn:\n                # Obtener la info del ASN\n                asnRes = geoIpCommands.getAsnInfo()\n                # Info del ASN\n                finalResultAsn['ASN'] = asnRes['autonomous_system_number']\n                finalResultAsn['ASN Org'] = asnRes['autonomous_system_organization']\n\n            # Mostrar los resultados 'autonomous_system_number' y 'autonomous_system_organization'\n            printResult('default',finalResult)\n            if finalResultFull:\n                printResult('full',finalResultFull)\n            if finalResultAsn:\n                printResult('asn',finalResultAsn)\n\n        else:\n            raise ValueError('The IP %s is not public.' % (str(ip)))\n\nexcept Exception as e:\n    print('ERROR - Reason: %s' % (str(e)))\n    sys.exit(1)\nfinally:\n    print('\\nPowered by https:\/\/blog.tiraquelibras.com\\n')<\/code><\/pre>\n\n\n\n<p>Creamos el archivo&nbsp;<em><strong><code class=\"inline-code\">updateMaxMind.sh<\/code><\/strong><\/em>&nbsp;para descargar y actualizar las bases de datos de&nbsp;<strong>MaxMind<\/strong>, con el siguiente contenido, sustituyendo <span style=\"color: #ff0000;\"><strong>YOUR_MAXMIND_TOKEN<\/strong><\/span> por el <strong>token<\/strong> que debes haber obtenido en tu cuenta de <strong>MaxMind<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code EnlighterJSRAW\"><code lang=\"bash\" class=\"language-bash\">#!\/bin\/bash\n\n### Variables\n\n# DB files path\ndb_path='dbs'\n\n# DB files name\ncity_file='GeoLite2-City.mmdb'\ncountry_file='GeoLite2-Country.mmdb'\nas_file='GeoLite2-ASN.mmdb'\n\n# DB files downloaded\ncity_file_gz='GeoLite2-City.tar.gz'\ncountry_file_gz='GeoLite2-Country.tar.gz'\nas_file_gz='GeoLite2-ASN.tar.gz'\n\n# Max Mind token\nmaxMind_token='YOUR_MAXMIND_TOKEN'\n\n# URLs to download all databases (City, Country, ASN)\ncity_url=\"https:\/\/download.maxmind.com\/app\/geoip_download?edition_id=GeoLite2-City&amp;license_key=$maxMind_token&amp;suffix=tar.gz\n\"\ncountry_url=\"https:\/\/download.maxmind.com\/app\/geoip_download?edition_id=GeoLite2-Country&amp;date=20191231&amp;license_key=$maxMind_token&amp;suffix=tar.gz\"\nas_url=\"https:\/\/download.maxmind.com\/app\/geoip_download?edition_id=GeoLite2-ASN&amp;license_key=$maxMind_token&amp;suffix=tar.gz\"\n\n\n### Getting all files\n\n# City\nwget -c $city_url -O $city_file_gz\nif [ $? != 0 ];then\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0echo \"Failed gettig $city_file_gz MaxMind database\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0exit 1\nfi\n\n# Country\nwget -c $country_url -O $country_file_gz\nif [ $? != 0 ];then\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0echo \"Failed gettig $country_file_gz MaxMind database\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0exit 1\nfi\n\n# ASN\nwget -c $as_url -O $as_file_gz\nif [ $? != 0 ];then\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0echo \"Failed gettig $as_file_gz MaxMind database\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0exit 1\nfi\n\n### Deleting all stored databases (.mmdb)\nrm -rf $db_path\/*\n\n### Uncompress all files downloaded\n\n# City\ntar xzvf $city_file_gz\n# Country\ntar xzvf $country_file_gz\n# ASN\ntar xzvf $as_file_gz\n\n### Moving all db files (.mmdb) to the final path\n\n# City\npath=$( find . -name $city_file -exec dirname {} \\;)\nmv $path'\/'$city_file $db_path'\/'\n\n# Country\npath2=$( find . -name $country_file -exec dirname {} \\;)\nmv $path2'\/'$country_file $db_path'\/'\n\n# ASN\npath3=$( find . -name $as_file -exec dirname {} \\;)\nmv $path3'\/'$as_file $db_path'\/'\n\nrm -rf .\/Geo*<\/code><\/pre>\n\n\n\n<p>Le damos permisos de ejecuci\u00f3n a este archivo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">chmod 744 updateMaxMind.sh<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"instalaci\u00f3n-de-m\u00f3dulos-necesarios\"><span class=\"ez-toc-section\" id=\"Instalacion_de_modulos_necesarios\"><\/span>Instalaci\u00f3n de m\u00f3dulos necesarios<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Instalamos los m\u00f3dulos necesarios indicados en el archivo&nbsp;<em><strong>requirements.txt<\/strong><\/em>&nbsp;con el siguiente comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">pip install -r requirements.txt<\/code><\/pre>\n\n\n\n<p>Se instalar\u00e1n los siguientes m\u00f3dulos de&nbsp;<strong>Python3<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>maxminddb==1.5.1<\/li><li>pprint==0.1<\/li><li>geopy==1.20.0<\/li><li>IPy==1.00<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"descargaactualizaci\u00f3n-de-las-bases-de-datos-de-maxmind\"><span class=\"ez-toc-section\" id=\"DescargaActualizacion_de_las_bases_de_datos_de_MaxMind\"><\/span>Descarga\/Actualizaci\u00f3n de las bases de datos de MaxMind<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Primero editamos el archivo <em><strong><code class=\"inline-code\">updateMaxMind.sh<\/code><\/strong><\/em>e indicamos nuestro&nbsp;<em><strong>token<\/strong><\/em>&nbsp;en la siguiente l\u00ednea:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># Max Mind token\nmaxMind_token='YOUR_MAXMIND_TOKEN'<\/code><\/pre>\n\n\n\n<p>Sustituimos&nbsp;<em><strong>YOUR_MAXMIND_TOKEN<\/strong><\/em>&nbsp;por nuestro&nbsp;<em><strong>token<\/strong><\/em>&nbsp;creado.<\/p>\n\n\n\n<p>Ejecutamos el script de&nbsp;<strong>Bash<\/strong>&nbsp;para descargar las bases de datos de&nbsp;<strong>MaxMind<\/strong>&nbsp;que vamos a utilizar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">.\/updateMaxMind.sh<\/code><\/pre>\n\n\n\n<p>Podemos configurar este en el&nbsp;<strong>Cron<\/strong>&nbsp;de nuestro sistema, por ejemplo para que se ejecute los&nbsp;<em>lunes<\/em>&nbsp;y&nbsp;<em>viernes<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">02 19 * * 1,5 cd \/path\/to\/your\/program; .\/updateMaxMind.sh<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ejecuci\u00f3n-del-programa\"><span class=\"ez-toc-section\" id=\"Ejecucion_del_programa\"><\/span>Ejecuci\u00f3n del programa<span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p>Importante ejecutar el programa en un entorno con&nbsp;<strong>Python3<\/strong>&nbsp;instalado.<\/p>\n\n\n\n<p>El programa dispone de una ayuda contextual descriptiva:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># python geoIp.py --help\nUsage: Address info of an IP address.\nUsage: geoIp.py [options] ip_address.\n\nIP geolocation info. Add only one IP address. Ranges are not allowed.\n\nOptions:\n  --version   show program's version number and exit\n  -h, --help  show this help message and exit\n  -a, --asn   Get only ASN info.\n  -f, --full  Get full address info.\n\nPowered by https:\/\/blog.tiraquelibras.com\n\ufeff<\/code><\/pre>\n\n\n\n<p>Las opciones disponibles son:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>-h<\/strong> o <strong>&#8211;help:<\/strong> permite mostrar la ayuda del programa.<\/li><li><strong>-a<\/strong> o <strong>&#8211;asn:<\/strong> muestra la informaci\u00f3n del ASN junto a la informaci\u00f3n por defecto.<\/li><li><strong>-f<\/strong> o <strong>&#8211;full:<\/strong> muestra la informaci\u00f3n por defecto ampliada.<\/li><li><strong>&#8211;version:<\/strong> muestra la versi\u00f3n desplegada del programa.<\/li><\/ul>\n\n\n\n<p>Un ejemplo de ejecuci\u00f3n con informaci\u00f3n por defecto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># python geoIp.py 8.8.8.8\nIP               -  8.8.8.8\nLatitude         -  37.751\nLongitude        -  -97.822\nContCode         -  NA\nContinent        -  North America\nCounCode         -  US\nCountry          -  United States\n\nPowered by https:\/\/blog.tiraquelibras.com<\/code><\/pre>\n\n\n\n<p>Otro ejemplo con informaci\u00f3n del&nbsp;<em><strong>ASN<\/strong><\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># python geoIp.py 8.8.8.8 -a\nIP               -  8.8.8.8\nLatitude         -  37.751\nLongitude        -  -97.822\nContCode         -  NA\nContinent        -  North America\nCounCode         -  US\nCountry          -  United States\nASN              -  15169\nASN Org          -  Google LLC\n\nPowered by https:\/\/blog.tiraquelibras.com<\/code><\/pre>\n\n\n\n<p>Y por \u00faltimo con informaci\u00f3n ampliada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># python geoIp.py 8.8.8.8 -f\nIP               -  8.8.8.8\nLatitude         -  37.751\nLongitude        -  -97.822\nContCode         -  NA\nContinent        -  North America\nCounCode         -  US\nCountry          -  United States\nRegion           -  Kansas\nAddress          -  Reno County, Kansas, United States\nTimezone         -  America\/Chicago\nLicence          -  Data \u00a9 OpenStreetMap contributors, ODbL 1.0. https:\/\/osm.org\/copyright\n\nPowered by https:\/\/blog.tiraquelibras.com<\/code><\/pre>\n\n\n\n<p>Versi\u00f3n del programa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># python geoIp.py --version\ngeoIp.py: version 1.0\n\nPowered by https:\/\/blog.tiraquelibras.com<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"enlaces-de-inter\u00e9s\"><span class=\"ez-toc-section\" id=\"Enlaces_de_interes\"><\/span>Enlaces de inter\u00e9s<span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p>Enlace al proyecto en Bitbucket pincha <a href=\"https:\/\/bitbucket.org\/sergiobr\/geoip\/src\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>MaxMind pincha&nbsp;<a title=\"https:\/\/www.maxmind.com\/en\/home\" href=\"https:\/\/www.maxmind.com\/en\/home\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a><\/p>\n\n\n\n<p>GeoLite2 de MaxMind pincha&nbsp;<a title=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" href=\"https:\/\/dev.maxmind.com\/geoip\/geoip2\/geolite2\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a><\/p>\n\n\n\n<p>Nominatim Wiki pincha&nbsp;<a title=\"https:\/\/wiki.openstreetmap.org\/wiki\/Nominatim\" href=\"https:\/\/wiki.openstreetmap.org\/wiki\/Nominatim\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a><\/p>\n\n\n\n<p>Nominatim pol\u00edtica de uso pincha&nbsp;<a title=\"https:\/\/operations.osmfoundation.org\/policies\/nominatim\/\" href=\"https:\/\/operations.osmfoundation.org\/policies\/nominatim\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a><\/p>\n\n\n\n<p>Nominatim OpenStreetMap tool pincha&nbsp;<a title=\"https:\/\/nominatim.openstreetmap.org\/\" href=\"https:\/\/nominatim.openstreetmap.org\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a><\/p>\n\n\n\n<p>OpenStreetMap pincha&nbsp;<a title=\"https:\/\/nominatim.openstreetmap.org\/\" href=\"https:\/\/nominatim.openstreetmap.org\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>Actualizaci\u00f3n de Max Mind para el acceso pincha <a href=\"https:\/\/blog.maxmind.com\/2019\/12\/18\/significant-changes-to-accessing-and-using-geolite2-databases\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Actualizado el 7\/4\/2020. \/ Actualizado el 11\/6\/2020. Introducci\u00f3n GeoIp&nbsp;es un programa destinado a la geolocalizaci\u00f3n de una direcci\u00f3n IP con licencia libre para su uso<span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/blog.tiraquelibras.com\/?p=730\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":731,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,22],"tags":[94,27],"class_list":["post-730","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacion","category-ti","tag-geoip","tag-python"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/730","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=730"}],"version-history":[{"count":0,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/730\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/media\/731"}],"wp:attachment":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=730"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=730"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=730"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}