Este tutorial explica cómo usar el módulo GeoIP con nginx en Ubuntu 16.04 para averiguar de dónde provienen sus visitantes. El módulo GeoIP establece múltiples variables como $geoip_country_name, $geoip_country_code, $geoip_city, etc. que puede usar en sus scripts PHP o directamente en su configuración nginx, por ejemplo, para servir contenido en diferentes idiomas según el país del usuario.
1 nota preliminar
Estoy usando el sitio web www.example.com aquí con la raíz del documento /var/www/www.example.com/web/ y el archivo de configuración de Nginx vhost /etc/nginx/sites-enabled/www.example.com. anfitrión Usaré este tutorial para la configuración básica de Ubuntu-Nginx. https://www.howtoforge.com/tutorial/instalación-nginx-con-php7-fpm-and-mysql-on-ubuntu-16.04-lts-lemp/
Este tutorial también es compatible con las configuraciones de ISPConfig nginx.
Una nota para los usuarios de Ubuntu:
Debido a que debemos ejecutar todos los pasos de este tutorial con privilegios de root, podemos anteponer todos los comandos en este tutorial con la cadena sudo, o convertirnos en root ahora mismo escribiendo
sudo -s
2 Averigüe si Nginx es compatible con GeoIP
Antes de comenzar, debemos averiguar si el módulo GeoIP está integrado en nuestro servidor nginx:
nginx -V
[email protected]:~# nginx -V
nginx version: nginx/1.10.0 (Ubuntu)
built with OpenSSL 1.0.2g-fips 1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads
3 Descarga las bases de datos GeoIP
En Debian y Ubuntu, existe el paquete geoip-database que se puede instalar a través de apt, pero está un poco desactualizado y solo contiene GeoIP.dat (base de datos de países), no GeoLiteCity.dat (base de datos de ciudades). Por lo tanto, no instalamos ese paquete, sino que descargamos copias nuevas desde el sitio web de GeoIP al directorio /etc/nginx/geoip:
mkdir /etc/nginx/geoip
cd /etc/nginx/geoip
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gunzip GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz
4 Configurar Nginx
Ahora configuramos nginx. Abra /etc/nginx/nginx.conf...
nano /etc/nginx/nginx.conf
... y agregue las directivas geoip_country y geoip_city al contenedor http {}:
[...] http {
##
# Basic Settings
##
geoip_country /etc/nginx/geoip/GeoIP.dat; # the country IP database
geoip_city /etc/nginx/geoip/GeoLiteCity.dat; # the city IP database [...]
La directiva geoip_country pone a disposición las siguientes variables:
- $geoip_country_code:código de país de dos letras, por ejemplo, RU, EE. UU.
- $geoip_country_code3:código de país de tres letras, por ejemplo, RUS, EE. UU.
- $geoip_country_name:el nombre (detallado) del país, por ejemplo, Federación Rusa, Estados Unidos, etc.
La directiva geoip_city proporciona las siguientes variables:
- $geoip_city_country_code:código de país de dos letras, por ejemplo, RU, EE. UU.
- $geoip_city_country_code3:código de país de tres letras, por ejemplo, RUS, EE. UU.
- $geoip_city_country_name:el nombre del país, por ejemplo, Federación Rusa, Estados Unidos, si está disponible.
- $geoip_region:el nombre de la región (provincia, región, estado, provincia, territorio federal y similares), por ejemplo, Moscow City, DC, si está disponible.
- $geoip_city:el nombre de la ciudad, por ejemplo, Moscú, Washington, Lisboa, etc., si está disponible.
- $geoip_postal_code - código postal o código postal - si está disponible.
- $geoip_city_continent_code - si está disponible.
- $geoip_latitude - latitud - si está disponible.
- $geoip_longitude - longitud - si está disponible.
Para que estas variables también estén disponibles para sus scripts PHP, debemos establecer algunas directivas fastcgi_param. Es mejor hacer esto en el archivo /etc/nginx/fastcgi_params donde están las otras directivas fastcgi_param:
nano /etc/nginx/fastcgi_params
[...] ### SET GEOIP Variables ### fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code; fastcgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3; fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name; fastcgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code; fastcgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3; fastcgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name; fastcgi_param GEOIP_REGION $geoip_region; fastcgi_param GEOIP_CITY $geoip_city; fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code; fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code; fastcgi_param GEOIP_LATITUDE $geoip_latitude; fastcgi_param GEOIP_LONGITUDE $geoip_longitude;
(Asegúrese de tener la línea include /etc/nginx/fastcgi_params; en su ubicación ~ \.php$ {} contenedor en su configuración de vhost, porque de lo contrario, la configuración anterior es inútil para su vhost).
Si usa nginx como proxy inverso y desea pasar las variables GeoIP al backend, debe crear/editar el archivo /etc/nginx/proxy.conf...
nano /etc/nginx/proxy.conf
... y añádele las siguientes líneas:
[...] ### SET GEOIP Variables ### proxy_set_header GEOIP_COUNTRY_CODE $geoip_country_code; proxy_set_header GEOIP_COUNTRY_CODE3 $geoip_country_code3; proxy_set_header GEOIP_COUNTRY_NAME $geoip_country_name; proxy_set_header GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code; proxy_set_header GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3; proxy_set_header GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name; proxy_set_header GEOIP_REGION $geoip_region; proxy_set_header GEOIP_CITY $geoip_city; proxy_set_header GEOIP_POSTAL_CODE $geoip_postal_code; proxy_set_header GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code; proxy_set_header GEOIP_LATITUDE $geoip_latitude; proxy_set_header GEOIP_LONGITUDE $geoip_longitude;
(Asegúrese de usar la línea include /etc/nginx/proxy.conf; en su configuración de proxy nginx porque, de lo contrario, el backend no puede usar las variables GeoIP).
Ahora recarga nginx...
systemctl reload nginx.service
... para que los cambios surtan efecto.
Reinicie PHP-FPM de la siguiente manera:
systemctl restart php7.0-fpm.service
5 Una breve prueba
Para ver si el módulo GeoIP funciona correctamente, podemos crear un pequeño archivo PHP en nuestro espacio web www.example.com (por ejemplo, /var/www/www.example.com/web):
nano /var/www/www.example.com/web/geoiptest.php
Podemos acceder a las variables GeoIP de la siguiente manera:
$geoip_country_code = getenv(GEOIP_COUNTRY_CODE);
O así:
$geoip_country_code = $_SERVER['GEOIP_COUNTRY_CODE'];
<html> <body> <?php $geoip_country_code = getenv(GEOIP_COUNTRY_CODE); /* $geoip_country_code = $_SERVER['GEOIP_COUNTRY_CODE']; // works as well */ $geoip_country_code3 = getenv(GEOIP_COUNTRY_CODE3); $geoip_country_name = getenv(GEOIP_COUNTRY_NAME); $geoip_city_country_code = getenv(GEOIP_CITY_COUNTRY_CODE); $geoip_city_country_code3 = getenv(GEOIP_CITY_COUNTRY_CODE3); $geoip_city_country_name = getenv(GEOIP_CITY_COUNTRY_NAME); $geoip_region = getenv(GEOIP_REGION); $geoip_city = getenv(GEOIP_CITY); $geoip_postal_code = getenv(GEOIP_POSTAL_CODE); $geoip_city_continent_code = getenv(GEOIP_CITY_CONTINENT_CODE); $geoip_latitude = getenv(GEOIP_LATITUDE); $geoip_longitude = getenv(GEOIP_LONGITUDE); echo 'country_code: '.$geoip_country_code.'<br>'; echo 'country_code3: '.$geoip_country_code3.'<br>'; echo 'country_name: '.$geoip_country_name.'<br>'; echo 'city_country_code: '.$geoip_city_country_code.'<br>'; echo 'city_country_code3: '.$geoip_city_country_code3.'<br>'; echo 'city_country_name: '.$geoip_city_country_name.'<br>'; echo 'region: '.$geoip_region.'<br>'; echo 'city: '.$geoip_city.'<br>'; echo 'postal_code: '.$geoip_postal_code.'<br>'; echo 'city_continent_code: '.$geoip_city_continent_code.'<br>'; echo 'latitude: '.$geoip_latitude.'<br>'; echo 'longitude: '.$geoip_longitude.'<br>'; ?> </body> </html>
Llame a ese archivo en un navegador (http://www.example.com/geoiptest.php), y debería ver GeoIP en funcionamiento (asegúrese de llamar al archivo desde una dirección IP pública, no desde una local) :
También es posible utilizar variables GeoIP directamente en la configuración de nginx, p. de la siguiente manera:
nano /etc/nginx/sites-enabled/www.example.com.vhost
[...] location / { index index.html index.php; try_files /index_$geoip_country_code.html /index.html; } [...]
systemctl reload nginx.service
En este ejemplo, si un visitante proviene de Alemania (código de país:DE) y existe el archivo index_DE.html, entonces se sirve este archivo; de lo contrario, se sirve el archivo index.html predeterminado.
Esto se puede usar para servir contenido en diferentes idiomas, según el origen del usuario.
6 Enlaces
- nginx:http://nginx.org/
- Wiki de nginx:http://wiki.nginx.org/
- Ubuntu:http://www.ubuntu.com/