Publi

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.

Listado de IPs a pelo en .htaccess

Bueno, lo malo del método anterior es, como ya dije que no se puede hacer desde .htaccess, y por eso, muchas veces, en las que no tenemos acceso a los archivos del virtualhost no podemos aplicarlo. Lo bueno es que la lista de direcciones IP puede ser más o menos larga y puede ser modificada en cualquier momento, sin tener que mediar nosotros.

Bueno, aquí pongo también cómo podemos hacerlo desde .htaccess, aunque tendremos que poner las IPs “a pelo”:

1
2
3
4
5
6
7
8
9
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REMOTE_ADDR} !^www.xxx.yyy.zzz$
    RewriteCond %{REMOTE_ADDR} !^aaa.bbb.ccc.ddd$
    RewriteCond %{REMOTE_ADDR} !^eee.fff.ggg.hhh$
    RewriteCond %{REQUEST_FILENAME} !mi-logo.png
    RewriteCond %{REQUEST_FILENAME} !temp.html
    RewriteRule .* http://midominio.com/temp.html [R=307,L]
</IfModule>

En este caso, www.xxx.yyy.zzz, aaa.bbb.ccc.ddd y eee.fff.ggg.hhh son las IPs permitidas en la web, y son las que podrán entrar, mientras que todas las demás verán la web http://midominio.com/temp.html (con una redirección temporal, un 307), adicionalmente será también visible el logo de la compañía, para poner una página temporal más o menos bonita.

Como vemos, todas las condiciones son AND, por lo que si se cumple una sola de ellas, ya no veremos la página temp.html

Actualizaciones

14/8/2014 – Añadida solución desde .htaccess

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

También podría interesarte....

There are 5 comments left Ir a comentario

  1. Pingback: El 2014 para Poesía Binaria | Poesía Binaria /

  2. Francisco /
    Usando Mozilla Firefox Mozilla Firefox 46.0 en Windows Windows 7

    Hola,
    Como hago lo mismo pero para bloquear un listado de ip.
    Si quisiera bloquear un listado de ip que esten en un archivo o redireccionarlos a un pagina que les diga que estan bloqueados

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 46.0 en Ubuntu Linux Ubuntu Linux

      Hola!

      Así a bote pronto se me ocurre que cojas la línea que dice
      RewriteCond ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} =NOT-FOUND
      y le pongas !=NOT-FOUND . Es decir, que la condición se aplique cuando las encuentre.

  3. Davila /
    Usando Google Chrome Google Chrome 50.0.2661.102 en Windows Windows NT

    Buen post, como podría redireccionar una URL especifica (no todo el sitio) a otra excepto mi ip.

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 46.0 en Ubuntu Linux Ubuntu Linux

      Puedes jugar con el RewriteCond ^.*$ y poner la URL de la web que quieres redireccionar.

Leave a Reply