Revista Tecnología

Redirigir una web a otra URL dependiendo de la IP que conecte [Apache]

Publicado el 09 junio 2014 por Gaspar Fernández Moreno @gaspar_fm
votar

Redirigir una web a otra URL dependiendo de la IP que conecte [Apache]

La necesidad surge en un primer momento cuando, desde diferentes lugares se está desarrollando un sitio web. En ocasiones disponemos de un test.minuevositioweb.com (por ejemplo), pero hay veces que la migración puede resultar difícil, o lenta, dependiendo de nuestras posibilidades; y queremos tener el sitio operativo en la dirección web definitiva tanto para nosotros como para nuestros clientes (que a veces quieren ver cómo va el tema).

Para esto, podemos optar por varias soluciones, por ejemplo modificando la programación del sitio web para detectar la dirección IP del usuario y, si esta no está permitida nos redirigir la conexión a otro lugar.

Aunque también podemos hacer esto mismo con Apache y mod_rewrite (aunque necesitamos acceso a /etc/apache/ para seguir por completo esta guía, por ejemplo podemos hacerlo si montamos un VPS… déjame recomendarte uno (ya puestos, hago publi)), de la siguiente manera:

Editamos el archivo /etc/apache/sites-available/nuestro-sitio o /etc/apache/sites-available/nuestro-sitio.conf (dependiendo de la versión de Apache) lo malo es que no lo podemos poner en .htaccess, aunque sí podremos poner una ristra de IPs en ese archivo, queda mucho mejor con una lista de acceso

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName miweb.com
        ServerAlias www.miweb.com
        DocumentRoot /var/www
       <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteMap    hosts-deny  txt:/home/usuario/access_list
                RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} =NOT-FOUND
                RewriteRule  ^.*$ http://pagina_redirigida.com/ [L]
       </IfModule>
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /home/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
</VirtualHost>

Con especial atención al fragmento de mod_rewrite <IfModule mod_rewrite.c></IfModule>. Ahora sólo tenemos que crear /home/usuario/access_list donde en cada línea debemos poner dos cadenas separadas por un espacio, la primera será la IP y la segunda, lo que queramos. Por ejemplo, a mi me gusta poner la fecha en la que di de alta dicha dirección IP.

Con esta configuración si una IP está dentro de la access_list entrará a la página web directamente, pero si no, irá a http://pagina_redirigida.com/. Por otra parte, podremos actualizar la lista de acceso en cualquier momento sin problema, la lista se recarga a cada acceso que hagamos a la página, por lo que podemos modificar el archivo y añadir las direcciones IP que queramos, cuando queramos.

Por otro lado, estaría interesante disponer de un pequeño script que añadiera direcciones IP, aquí voy a poner sólo un ejemplo, no es para usar en producción, pero es para hacernos una idea. Primero, haremos una pequeña modificación al archivo anterior /etc/apache/sites-available/nuestro-sitio para añadir un script permitido dentro de miweb.com que vamos a llamar addip.php; con lo que el bloque de mod_rewrite, quedará así:

1
2
3
4
5
6
7
8
       <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteCond   %{REQUEST_URI} ^/addip$
                RewriteRule ^/addip$ /addip.php [QSA,L,E]
                RewriteMap    hosts-deny  txt:/home/usuario/access_list
                RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} =NOT-FOUND
                RewriteRule  ^.*$ http://pagina_redirigida.com/ [L]
       </IfModule>

Y el archivo addip.php que colocaremos en el directorio raíz de nuestra web puede ser (es un ejemplo, para hacernos una idea, el siguiente):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?
function getIp()
{
  if ( isset($_SERVER['HTTP_CLIENT_IP']) & ! empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
  } elseif ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) & ! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  } else {
    $ip = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
  }
  $ip = filter_var($ip, FILTER_VALIDATE_IP);
  $ip = ($ip === false) ? '0.0.0.0' : $ip;
  return $ip;
}
function pv($v, $default = false)
{
  return (isset($_POST[$v]))?$_POST[$v]:$default;
}
if ($ip == '0.0.0.0')
   die('No se puede obtener IP');
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
  $pass = pv ('clave');
  if ($pass!='PASSWORD') // Aquí pon tu password
     die("Clave incorrecta");
  if (file_put_contents('/home/usuario/access_list', getIp()' 'time()'_'date('d/m/Y_H:i:s')"\n", FILE_APPEND))
    die ("Lista de acceso actualizada");
  else
    die ("Hubo un problema, habla con el departamento técnico");
} else {
  echo "Tu IP es: "getIp();
?>
  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
        <label for="clave">Introduce la clave</label>
        <input type="text" name="clave" id="rqp" />
        <input type="submit" value="Enviar" />
  </form>
<?php
}
?>

Ahora cuando entramos en http://miweb.com/addip nos preguntará una contraseña que, especificándola, añadirá nuestra IP a la lista de acceso y podremos ver la web que tenemos en construcción. Es interesante que, junto con la dirección IP, acompaño la fecha y la hora, y ya que muchas personas tienen una IP dinámica, podemos hacer periódicamente una limpieza de las IPs permitidas dejando sólo las generadas pasada una fecha dada, así evitamos que alguien ajeno pueda entrar en la web. (Es normal que se renueve una IP de nuestra conexión y al rato esa misma IP la tenga un vecino, dependiendo del proveedor).

Esto también es muy útil cuando un sitio está en mantenimiento, así sólo puede ver el sitio web el equipo de mantenimiento, mientras los usuarios pueden ser redirigidos a una web especial indicando que se está haciendo una tarea de mantenimiento.

Foto: Richard Elzey (Flickr CC-by a 7/6/2014)


Volver a la Portada de Logo Paperblog