MaxMind es conocida en el mundo del desarrollo web por ser la empresa que ofrece el módulo GeoIP y bases de datos tanto gratuitas como de pago, para geolocalizar las visitas que llegan a nuestro sitio web.

Hace un tiempo lanzó un nuevo módulo, GeoIP2, con algunas mejoras interesantes y un nuevo formato .mmdb
.
El funcionamiento es bastante similar a la antigua versión (ahora Legacy), y las mejoras no son tan sustanciales para el usuario común como para necesitar una actualización, pero os vamos a ayudar a integrar este nuevo módulo en Nginx utilizando un reciente aporte de la comunidad: ngx_http_geoip2_module.
Instalando el módulo de nginx
A parte de las instrucciones para el resto de distribuciones y aprovechando que nos encanta Gentoo, os ofrecemos un ebuild e instrucciones para ésta.
Todas las distribuciones
Lo primero que necesitamos es compilar la librería creada por MaxMind para leer este nuevo formato de bases de datos.
Podemos encontrarla en https://github.com/maxmind/libmaxminddb y se instala de la siguiente manera:
Esta librería también puede instalarse mediante git clone
, brew install
o aptitude install
. Consulta la documentación en el enlace anterior para más información.
El siguiente paso es descargar el módulo de nginx desde https://github.com/leev/ngx_http_geoip2_module y compilamos nuevamente nginx con los siguientes comandos:
Gentoo
En Gentoo hemos creado un ebuild para instalar todo esto de manera más rápida, fácil, y sobre todo, mediante emerge
.
El ebuild lo podéis encontrar en https://github.com/whiledev/whiledev-overlay y es muy fácil instalarlo desde Layman. Si no tenéis instalado Layman, se hace mediante emerge -av layman
.
Después sincronizamos Layman y añadimos el repositorio:
Editamos el fichero /etc/portage/make.conf
y añadimos geoip2
a nuestra lista de módulos requeridos por nginx: NGINX_MODULES_HTTP="... geoip2 ..."
.
Tras esto, seguramente necesitemos añadir el keyword ~amd64
a nuestra lista de keywords aceptadas:
Y por último, el esperado emerge -av nginx
.
Instalando y configurando las bases de datos
Para utilizar el módulo necesitamos descargar las bases de datos gratuitas (o de pago) y guardarlas en algún lugar, por ejemplo /usr/share/GeoIP
. Si no existe el directorio lo creamos y ejecutamos los siguientes comandos:
El siguiente paso es conectar nginx con las bases de datos a través del módulo ngx_http_geoip2_module
y la librería libmaxminddb
. Sin entrar en mayor detalle, añadimos lo siguiente a nuestro fichero de configuración de nginx (generalmente /etc/nginx/nginx.conf
):
http {
# ...
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_iso_code country iso_code;
$geoip2_data_country_name country names en;
$geoip2_data_continent_code continent code;
$geoip2_data_continent_name continent names en;
}
geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
$geoip2_data_city_name city names en;
$geoip2_data_subdivision_iso_code subdivisions 0 iso_code;
$geoip2_data_subdivision_name subdivisions 0 names en;
$geoip2_data_postal_code postal code;
$geoip2_data_location_latitude location latitude;
$geoip2_data_location_longitude location longitude;
$geoip2_data_location_metro_code location metro_code;
}
# ...
}
Si queremos que los nombres aparezcan en español, basta con cambiar names en
por names es
.
Utilizando GeoIP2
Ya podemos utilizar nuestras variables de GeoIP2 a través de nuestro back-end preferido. Aquí un par de ejemplos.
PHP
En el caso de PHP, retocaremos nuestro bloque de configuración de nginx para que quede más o menos parecido a esto:
location ~ \.php$ {
include /etc/nginx/fastcgi.conf;
fastcgi_param GEOIP_COUNTRY_CODE $geoip2_data_country_iso_code;
fastcgi_param GEOIP_COUNTRY_NAME $geoip2_data_country_name;
fastcgi_param GEOIP_CONTINENT_CODE $geoip2_data_continent_code;
fastcgi_param GEOIP_CONTINENT_NAME $geoip2_data_continent_name;
fastcgi_param GEOIP_CITY $geoip2_data_city_name;
fastcgi_param GEOIP_REGION $geoip2_data_subdivision_iso_code;
fastcgi_param GEOIP_REGION_NAME $geoip2_data_subdivision_name;
fastcgi_param GEOIP_POSTAL_CODE $geoip2_data_postal_code;
fastcgi_param GEOIP_LATITUDE $geoip2_data_location_latitude;
fastcgi_param GEOIP_LONGITUDE $geoip2_data_location_longitude;
fastcgi_param GEOIP_AREA_CODE $geoip2_data_location_metro_code;
limit_conn phplimit 5;
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/php-fpm.socket;
}
Y todo listo, ya podemos utilizar la geolocalización a través de PHP mediante las variables $_SERVER['GEOIP_COUNTRY_NAME']
, $_SERVER['GEOIP_CITY']
, etc.
Node.js
En el caso de Node.js, pasaremos nuestras variables desde nginx a Node.js de la siguiente forma:
upstream nodejs_app {
server 127.0.0.1:3000;
}
location / {
try_files $uri @nodejs_app;
}
location @nodejs_app {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-GEOIP_COUNTRY_CODE $geoip2_data_country_iso_code;
proxy_set_header X-GEOIP_COUNTRY_NAME $geoip2_data_country_name;
proxy_set_header X-GEOIP_CONTINENT_CODE $geoip2_data_continent_code;
proxy_set_header X-GEOIP_CONTINENT_NAME $geoip2_data_continent_name;
proxy_set_header X-GEOIP_CITY $geoip2_data_city_name;
proxy_set_header X-GEOIP_REGION $geoip2_data_subdivision_iso_code;
proxy_set_header X-GEOIP_REGION_NAME $geoip2_data_subdivision_name;
proxy_set_header X-GEOIP_POSTAL_CODE $geoip2_data_postal_code;
proxy_set_header X-GEOIP_LATITUDE $geoip2_data_location_latitude;
proxy_set_header X-GEOIP_LONGITUDE $geoip2_data_location_longitude;
proxy_set_header X-GEOIP_AREA_CODE $geoip2_data_location_metro_code;
proxy_pass http://nodejs_app;
proxy_redirect off;
}
Si utilizamos el framework Express, accedemos a los datos mediante req.get('X-GEOIP_COUNTRY_NAME');
, req.get('X-GEOIP_CITY');
, etc.