Cómo restringir el acceso a una web según el país del visitante

Una persona hizo esta pregunta en un grupo de desarrolladores de Facebook y me atacó la curiosidad.

Para empezar, se me ocurren dos formas de atacar el problema, dependiendo de tus conocimientos, hosting que estés usando, etc… En cualquiera de los casos, lo mejor que podremos hacer será filtrar el tráfico en base a la dirección IP desde la que nos están visitando (Cada país tiene un rango de direcciones IP asignadas, con lo cual, suele ser una medida suficientemente buena).

De lo que se trata en definitiva es de verificar si la IP del visitante está dentro de las IPs permitidas y, en caso contrario redireccionarlo a algún otro lado o mostrarle algún mensaje especial.

Probablemente sea más fácil tener una lista de IPs prohibidas que permitidas (Suelen ser menos las primeras que las segundas).

Comencemos por la que va a funcionar en todos lados:

Filtrar por IP usando PHP

PHP tiene algunas herramientas útiles para saber cuál es la IP del visitante:

La primera es ver el contenido de la variable $_SERVER["REMOTE_ADDR"].

Salvo que la petición se haya realizado mediante un servidor proxy, este dato alcanzará para saber desde dónde nos están visitando.

Una vez obtenida esta información, podemos usar algún listado de vinculación de IPs a países (uno que ya tengamos grabado o alguno tipo WebService como http://www.geoplugin.net/json.gp) para obtener la información que buscamos.

Por ejemplo si hacemos una llamada tipo:

echo file_get_contents('http://www.geoplugin.net/json.gp?ip=186.109.132.47');

Obtendremos algo como:

{
  "geoplugin_request":"186.109.132.47",
  "geoplugin_status":200,
  "geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href='http:\/\/www.maxmind.com'>http:\/\/www.maxmind.com<\/a>.",
  "geoplugin_city":"Buenos Aires",
  "geoplugin_region":"Distrito Federal",
  "geoplugin_areaCode":"0",
  "geoplugin_dmaCode":"0",
  "geoplugin_countryCode":"AR",
  "geoplugin_countryName":"Argentina",
  "geoplugin_continentCode":"SA",
  "geoplugin_latitude":"-34.6033",
  "geoplugin_longitude":"-58.3816",
  "geoplugin_regionCode":"07",
  "geoplugin_regionName":"Distrito Federal",
  "geoplugin_currencyCode":"ARS",
  "geoplugin_currencySymbol":"&#36;",
  "geoplugin_currencySymbol_UTF8":"$",
  "geoplugin_currencyConverter":17.277
}

Y, si pasamos el resultado a través de json_decode obtendremos un arreglo del cual podremos simplemente tomar el índice geoplugin_countryCode y validar si está entre los prohibidos, por ejemplo:

$data = json_decode( file_get_contents('http://www.geoplugin.net/json.gp?ip='.$argv[1]), true );

if ( in_array( $data['geoplugin_countryCode'], [ 'AR', 'UY' ]  )  ) {
        echo 'No se admite gente de '.$data['geoplugin_countryName'];
} else {
        echo 'Los visitantes de '.$data['geoplugin_countryName'].' siempre son bienvenidos :)';
}

Cómo filtrar un visitante que está detrás de un proxy

En ocasiones la IP puede ser escondida detrás de un proxy. Para verificar si estamos ante esa situación debemos ver si existe en el arreglo $_SERVER una clave llamada HTTP_X_FORWARDED_FOR

No cambia demasiado, sólo hay que tomar el valor de $_SERVER['HTTP_X_FORWARDED_FOR'] como dirección IP a validar, el resto de la validación sigue siendo igual.

Filtrar por IP a través del WebServer

Otra posibilidad es realizar el filtro a más bajo nivel, es decir, evitar que una IP no deseada siquiera llegue a ejecutar un archivo php en nuestro servidor.

Para poder hacer esto se requiere tener acceso a la configuración del servidor web (o al menos poder usar archivos de configuración extra).

No es lo más común en entornos de hosting compartido, pero si tenés la posibilidad de hacerlo, puede resultar más eficiente.

El procedimiento exacto dependerá del servidor web con el que estés trabajando.

En el caso de Apache, podés usar el archivo .htaccess o, mejor, hacerlo directo desde la configuración del servidor.

Para ello puede usarse una configuración como la siguiente:

<Directory /var/www/html/>
   Order allow,deny
   Deny from 185
</Directory>

De esta forma, cualquier visitante cuya IP comience con 185 tendrá el acceso negado al directorio /var/www/html/ y sus subdirectorios.

¿Te quedó alguna pregunta? ¡Espero tus comentarios!

mchojrin

Por mchojrin

Ayudo a desarrolladores PHP a acceder mercados y clientes más sofisticados y exigentes

¿Te quedó alguna duda? Publica aca tu pregunta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.