GeoIp es una aplicación/base de datos desarrollada por MaxMind que permite a partir de la IP de un ordenador obtener su ubicación geográfica a nivel de país o incluso ciudad (Over 99.5% on a country level and 78% on a city level for the US within a 40 kilometer radius.).
Existe una versión comercial y una gratuita distribuida bajo licencia Creative Commons y que se compone de dos archivos, el más elemental (GeoIP.dat 1,3Mg) nos permite obtener el país de origen, el más completo (GeoLiteCity.dat 21Mg) la ciudad donde está registrada dicha IP.

La fórmula más sencilla para instalarlos sería hacer algo como:
wget -N -q http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
wget -N -q http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gzip -d GeoIP.dat.gz
gzip -d GeoLiteCity.dat.gz
mkdir /var/lib/GeoIP
mv GeoLiteCity.dat /var/lib/GeoIP/GeoIP.dat
mv GeoLiteCity.dat /var/lib/GeoIP/GeoLiteCity.dat


Cliente GeoIP

Una vez instalado estas dos archivos solo necesitaríamos un cliente que consulte dicha base de datos y los tienes disponibles en los lenguajes más habituales: C, mod_Apache, PHP, JAVA, Javascript, Ruby, etc. Tanto los anteriores archivos DAT como los clientes los he instalado en openSuse 11.4 usando el repositorio Opensuse GEOIP para evitar compilar el módulo Apache en el que estaba interesado.

Una vez instalados los archivos .dat y los binarios, para hacer una consulta bastaría hacer en una consola
~> geoiplookup -f /var/lib/GeoIP/GeoLiteCity.dat 183.203.16.8
~> GeoIP City Edition, Rev 1: CN, 22, Beijing, N/A, 39.928902, 116.388298, 0, 0

Configurar módulo Apache

Bien, ya tenemos instalada la base de datos de Geoip, los binarios para su consulta y el módulo Apache, ahora cargaremos el nuevo módulo en nuestra configuración del servidor simplemente editando (para openSuse) el archivo /etc/sysconfig/apache2 y en la línea APACHE_MODULES=”actions alias auth….” añadir APACHE_MODULES=”geoip actions alias auth…”

Seguidamente incluimos un par de líneas en la configuración del servidor web, ya sea en httpd.conf del servidor web, en el vhost.conf ó incluso en el .htaccess del servidor web de la siguiente manera:
<IfModule mod_geoip.c>
GeoIPEnable On
GeoIPEnableUTF8 On
GeoIPOutput All
GeoIPDBFile /var/lib/GeoIP/GeoIP.dat MemoryCache
</IfModule>

Reinicia el servidor, crea un archivo geo.php con el siguiente contenido<?php
print_r($_SERVER);
?>

Guardalo en tu servidor y dirige el navegador hasta geo.php, verás que el array $_SERVER contiene algunos valores nuevos como:

  • GEOIP_ADDR=>123.456.78.9
  • GEOIP_COUNTRY_CODE=>es
  • GEOIP_CONTINENT_CODE=>eu
  • GEOIP_COUNTRY_NAME=>spain

Si en lugar de cargar /var/lib/GeoIP/GeoIP.dat usasemos /var/lib/GeoIP/GeoLiteCity.dat el array $_SERVER contendría además las variables GEOIP_CITY, GEOIP_METRO_CODE, GEOIP_AREA_CODE, GEOIP_LATITUDE, GEOIP_LONGITUDE y GEOIP_POSTAL_CODE.

Nota: estos datos se emiten solo en el caso de que la IP (GEOIP_ADDR) sea localizada en la base de datos. Si el servidor web está en tu máquina y accedes via localhost tu IP será probablemente 127.0.0.1 la cual NO está registrada por lo que de todas estas variables solo aparecerá definida GEOIP_ADDR.


Afinando el uso

Una vez hechos los pasos superiores podríamos saludar a nuestras visitas haciendo algo como<?php echo "Hola querido visitante, bonito país .$_SERVER['GEOIP_COUNTRY_NAME'].", bienvenido";?>
Ahora bien, esto no es gratis, especialmente si usamos el archivo GeoLiteCity.dat de más de 20Mg y que el servidor va a consultar a cada visita o va a cargar en memoria, así es que para no sobrecargar más de lo necesario activaré GEOIP únicamente para el archivo wp-comments-post.php desde donde espero cribar el spam que se está colando desde hace unos días. Para ello cambio la configuración del servidor apache a esta otra:<IfModule mod_geoip.c>
GeoIPEnable Off
GeoIPEnableUTF8 On
GeoIPOutput All
GeoIPDBFile /var/lib/GeoIP/GeoIP.dat Standard
</IfModule>
<Files "wp-comments-post.php" >
GeoIPEnable On
</Files>

Ahora las variables de GEOIP solo están disponibles en wp-comments-post.php, donde inserto la siguiente línea:
if($_SERVER["GEOIP_COUNTRY_CODE"]=="CN") die("Putos chinos folloneros");