• Publicidad

Redirector para squid

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Redirector para squid

Notapor angelruiz » 2009-06-03 09:12 @425

Primeramente saludarlos y agradecerles por este hermoso trabajo.

He estado revisando diversos redirectores para squid escritos en Perl, entre los cuales conseguí uno que me funciona muy bien pero quiero hacerle modificaciones.

Este script fue escrito por el señor Victor Carceler:

http://iespuigcastellar.xeill.net/Members/vcarceler/temp/welcomeredirector.pl/view

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
#
#       WelcomeRedirector v0.2 (por Victor Carceler)
#
#       Este script es software libre GPL
#
#       Este script es un redirector para Squid (http://www.squid-cache.org/Doc/FAQ/FAQ-15.html)
#       Cuando Squid recibe una petición, se la pasa a WelcomeRedirector y el script retorna
#       la URL que Squid debe retornar al cliente.
#
#       Si es la primera vez que el cliente realiza la petición, o hace más de TIMEOUT segundos
#       desde la última petición, el cliente es dirigido a URL. En caso contrario el cliente
#       obtiene el documento que pidió.
#       NO_REDIRECT_PREFIX indica un prefijo que si se encuentra en la dirección del cliente
#       evitará que sea redirigido (aunque sea la primera conexión).
#
#       Para que Squid utilice este software debe configurar la directiva redirect_program
#       y redirect_children (con valor 1) en squid.conf

my $TIMEOUT = 3600;
my $URL = "http://iespuigcastellar.xeill.net/activitats/xeill";
my $NO_REDIRECT_PREFIX = "192.168";

$|=1;

my %registro;

while (<>) {
        @X = split;
        $url = $X[0];
        $address = $X[1];
        $ident = $X[2];
        $method = $X[3];

        #print "Petición: $url -> $address -> $ident -> $method\n";

        my $registrado = 0;

        # Sólo redirigimos peticiones que no coinciden con NO_REDIRECT_PREFIX
        if ($address !~ /$NO_REDIRECT_PREFIX/) {
                # Tenemos $address registrada ?
                my @ips = keys %registro;
                foreach(@ips) {
                        if ($_ == $address) {
                                if ((time - $registro{$address}) >= $TIMEOUT) {delete $registro{$address};
                                } else {
                                        $registrado = 1;
                                        #print  "Tengo la ip registrada !!!";
                                }
                        }
                }
        } else {
                $registrado = 1; # Nos saltamos la redirección
        }

        if (! $registrado) {
                $url = $URL;
                print "302:$url\n";
                $registro{$address}=time;
        } else {
                print "$url\n";
        }
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4



El script funciona a la perfección...

Ahora bien, lo que quiero hacer son básicamente dos cosas.

1. agregarle un log: que me registre la IP del cliente en cada redirección.
2. que redireccione dependiendo de la IP del cliente. Es decir, quiero crear un archivo txt en el cual tenga una lista de IP:
Código: Seleccionar todo
192.168.50.2
192.168.50.5
con lo cual el script sólo redireccione a los clientes de la lista.

Les comento lo siguiente:

Trabajo en una distro de Linux llamada brazilfw (firewall and router) totalmente gratuita, http://www.brazilfw.com.br; en dicho foro me desempeño como developer (equipo de desarrollo), para el cual he realizado algunos addons en bash. Pero de Perl realmente tengo como 2 días estudiándolo.

Me apena pedirles ayuda tan directamente (bandeja de plata), pero lo que realmente pido es orientación, ideas...

La finalidad de este script es hacer llegar un mensaje a determinado grupo de usuarios de una red (bienvenidas, avisos, etc).

Muy agradecido por sus respuestas.

Angel Ruiz.
Última edición por angelruiz el 2009-07-14 22:58 @999, editado 2 veces en total
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Publicidad

Notapor explorer » 2009-06-04 15:49 @700

Bienvenido a los foros de Perl en Español, angelruiz.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $TIMEOUT = 3600;
my $URL     = "http://iespuigcastellar.xeill.net/activitats/xeill";
my $NO_REDIRECT_PREFIX = "192.168";

$|=1;  # no caché

my %registro;  # memoria de las IP vistas

while (<>) {
    my ($url, $address, $ident, $method) = split;

    #print "Petición: $url -> $address -> $ident -> $method\n";

    my $registrado = 0;

    # Sólo redirigimos peticiones que no coinciden con NO_REDIRECT_PREFIX
    if ($address !~ /$NO_REDIRECT_PREFIX/) {
        # Tenemos $address registrada ?
        foreach( keys %registro) {
            if ($_ eq $address) {
                if ((time - $registro{$address}) >= $TIMEOUT) {
                    delete $registro{$address};
                }
                else {
                    $registrado = 1;
                    #print  "Tengo la ip registrada !!!";
                }
            }
        }
    }
    else {
        $registrado = 1; # Nos saltamos la redirección
    }

    if (! $registrado) {
        print "302:$URL\n";
        $registro{$address} = time;
    }
    else {
        print "$url\n";
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Para lo primero, llevar un registro de actividad, primero tienes que hacer un open() antes del bucle. Dentro del bucle, haces un print() hacia el fichero, guardando la $address. Y luego, después del bucle, haces un close().

Para lo segundo, la redirección ocurre en el último if(), justo donde aparece el print() con el valor 302. Entonces, antes de entrar en el bucle, lees el fichero de IP y las guardas en un arreglo. Luego, en el bucle, en la parte de decidir si redireccionar o no, recorre las IP dentro del arreglo. Si coincide con alguna de ellas, decides si hacerlo o no. Y terminas el bucle inmediatamente.

Inténtalo. Si te atascas, vuelve a preguntar...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor angelruiz » 2009-06-04 16:09 @715

Gracias, explorer...

Estoy tratando de hacer lo segundo, el lo primero no veo problema.

Primero hice open() y luego un array pero al comparar $address con las IP de la lista me toma los primeros bloques del IP como igual a address.

Sigo y te comento.
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Notapor angelruiz » 2009-06-05 14:45 @656

Hola.
Realicé lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/partition/perl/bin/perl
#

my $TIMEOUT = 3600;
my $URL     = "http://iespuigcastellar.xeill.net/activitats/xeill";
my $NO_REDIRECT_PREFIX = "10.250";

#acá leo las IP
$file= "/partition/practicas/misdatos.txt";
open(DATOS, "<$file");
my @lineas = <DATOS>;
chomp @lineas;
close(DATOS);

$|=1;  # no caché

my %registro;  # memoria de las IP vistas

while (<>) {
    my ($url, $address, $ident, $method) = split;

    #print "Petición: $url -> $address -> $ident -> $method\n";

    my $registrado = 0;

    # Sólo redirigimos peticiones que no coinciden con NO_REDIRECT_PREFIX
    if ($address !~ /$NO_REDIRECT_PREFIX/) {
        # Tenemos $address registrada ?
        foreach( keys %registro) {
            if ($_ eq $address) {
                if ((time - $registro{$address}) >= $TIMEOUT) {
                    delete $registro{$address};
                }
                else {
                    $registrado = 1;
                    #print  "Tengo la ip registrada !!!";
                }
            }
        }
    }
    else {
        $registrado = 1; # Nos saltamos la redirección
    }
### tomo las ips de mi txt
foreach $linea (@lineas) {
     
                if ($linea eq $address) {
                $pasa=1;
                } else {
                $pasa=0;
                }
            }
       
       
####
    if ($pasa eq 1) {

    if (! $registrado) {
        print "302:$URL\n";
        $registro{$address} = time;
    }
    else {
        print "$url\n";
    }
}
else {
        print "$url\n";
    }
 
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Me surge el siguiente problema:

Si por consola ingreso:
Código: Seleccionar todo
echo http://www.google.com 192.168.50.40 | ./redirector.pl

el resultado es perfecto.

Pero cuando lo hago desde squid no me redirecciona aunque la IP esté en la lista.

Es decir, cuando compara la IP del usuario con la IP de la lista, los ve diferente.
Me parece que squid no esta leyendo la lista.
Además no sé como testar de otra forma...

Desde ayer estoy probando diferentes formas y no puedo :cry:
Gracias...
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Notapor explorer » 2009-06-06 16:13 @717

Creo que el fallo está aquí:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach $linea (@lineas) {
    if ($linea eq $address) {
        $pasa=1;
    } else {
        $pasa=0;
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Aquí deberías de salir del bucle en cuanto descubrieses que la IP está en la lista. Si no, una posible comparación posterior podría volver a colocar la variable $pasa otra vez a 0.

Algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/partition/perl/bin/perl
#

$| = 1; # no caché

my $TIMEOUT = 3600;
my $URL     = "http://iespuigcastellar.xeill.net/activitats/xeill";
my $NO_REDIRECT_PREFIX = qr(10\.250);

my %registro;                     # memoria de las IP vistas

# Acá leo las IP
$file= "/partition/practicas/misdatos.txt";
open(DATOS, "<$file");
my @lineas = <DATOS>;
chomp @lineas;
close(DATOS);

while (<>) {
    my ($url, $address, $ident, $method) = split;
    #print "Petición: $url -> $address -> $ident -> $method\n";

    # Sólo redirigimos peticiones que no coinciden con NO_REDIRECT_PREFIX
    if ($address !~ /$NO_REDIRECT_PREFIX/) {

        # ¿Tenemos $address registrada?
        my $registrada = 0;           # De momento, no

        for my $ip (keys %registro) {
            next if $ip ne $address;  # Seguir buscando mientras no la encontremos
                                      # Si la encontramos,
            $registrada = 1;          # En principio, decimos que está registrada

            if ((time - $registro{$ip}) >= $TIMEOUT) {  # Pero, ¿demasiado tiempo?
                delete  $registro{$ip};                 # Sí, la olvidamos
                $registrada = 0;                        # Y no está registrada
            }

            last;                     # Se acabó la búsqueda
        }

        if (!$registrada) {             # No está $registrada
            for $linea (@lineas) {      # ¿Es una de nuestras @lineas?
                next if $linea ne $address;   # No, seguimos buscando

                $url = "302:$URL";            # Sí, cambiamos la $url
                $registro{$address} = time;   # La registramos

                last;                         # Y salimos
            }
        }
    }

    print "$url\n";
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

No lo he probado, pero estos son los cambios:
  • Si la $address no es un NO_REDIRECT_PREFIX, entonces miramos por todas las IP guardadas antes. Si encontramos la nuestra, la borramos del registro si ha pasado el tiempo o indicamos que la tenemos $registrada. En ambos casos, terminamos de buscar con la ayuda del last (nueva sentencia que he puesto para acelerar)
  • Si la $address no está registrada (o pasó el tiempo), hay que ver si está en alguna de nuestras @lineas. Si está, cambiamos el $url, registramos la dirección, y paramos el bucle (otro last).
  • Finalmente, sacamos afuera la $url
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor angelruiz » 2009-06-08 23:33 @023

Hola amigos.
EL cambio que me pasastes funciona cuando pruebo manualmente desde consola con el comando:
Código: Seleccionar todo
echo http://www.google.com 192.168.50.3 | ./redirector.pl


El resultado es perfecto.

Pero cuando lo hago desde squid, este no me califica como iguales el ip de la lista versus el ip del cliente que esta navegando.

Incluso hice el codigo sencillo sin redireccion temporal etc. y me sucede lo mismo.. :evil: .

hay una diferencia en la entrada que hace la petición del cliente dentro del script con respecto al comando que hago manualmente (pero no se cual es).

Si me tiran una luz se los agradezco.

Saludos. y Explorer gracias por la ayuda muchas gracias.

Editado: Tambien le agregue para que me registre un log y sucede que cuando pruebo con el comando antes citado funciona pero cuando pruebo con squid nada de nada. no me guarda nada en el log.
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Notapor angelruiz » 2009-06-08 23:59 @041

Creo que dí con la causa :twisted:

Puedo ver cómo squid ve la URL del usuario:
Código: Seleccionar todo
192.168.50.30/-  Fijence (/-)


Por eso no me compara correctamente las IP.

Ahora bien, ¿cómo puedo quitarle el /-?

Gracias
Última edición por angelruiz el 2009-06-09 15:17 @678, editado 1 vez en total
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Notapor angelruiz » 2009-06-09 00:57 @081

Traté de concatenar la variable del array con /- y funciona pero no estoy seguro de si es la forma correcta.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$como = "$linea/-";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Notapor explorer » 2009-06-09 14:27 @643

¿Eso es lo que recibes en $url o en $address?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor angelruiz » 2009-06-09 15:20 @680

en $address
angelruiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2009-06-03 08:33 @398

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 7 invitados