next up previous contents
Siguiente: Salida Subir: Control de acceso Anterior: Control de acceso   Índice General


Conexión

El código fuente del script conexion es muy sencillo:
#!/usr/bin/perl -w

#-----------------------------------------------------------------------
# Script:     conexion
# Version:    1.0
# Argumentos: login id_cola ubicacion
# Descripcion: Llama a la funcion conexion del modulo ControlNocat con
#             los mismos parametros para registrar la entrada en la red
#             en la tabla conexiones.
#-----------------------------------------------------------------------

use lib '/usr/local/nocat/lib/';
use ControlNocat;
use strict;

my $login=$ARGV[0];
my $id_cola=$ARGV[1];
my $ubicacion=$ARGV[2];

open (STDERR,">/dev/null");
&conexion($login,$id_cola,$ubicacion);
close (STDERR);
Este script se invoca desde la pasarela en el momento que un usuario es autenticado y la pasarela acaba de cambiar sus reglas del cortafuegos, esto se realiza en el método permit de la clase gateway. Para invocar el script conexión nos tenemos que conectar por ssh desde la pasarela al servidor. Para realizar esta conexión se ha creado un usuario llamado nocat en el servidor de autenticación que es el propietario del script. El problema es el método para autenticar a la pasarela desde el servidor, no se puede usar el sistema de introducir una clave. Lo que se ha hecho es usar el método con clave pública en ssh. Se generan en la pasarela un par de claves RSA, la clave pública y la clave privada, para hacer eso ejecutamos: ssh-keygen -t rsa Cuando nos pide una clave para proteger la clave privada pulsamos enter dos veces y dejamos la clave privada sin proteger. Esto no presenta problemas ya que se supone que la pasarela está protegida, en caso de que alguien pueda llegar a la clave privada querrá decir que el sistema de protección ya ha fallado. El comando anterior crea el directorio .ssh dentro del directorio home del usuario que lo ejecuta, y dentro de ese directorio está la clave privada (id_rsa) y la clave pública (id_rsa.pub). En nuestro caso hemos creado un usuario nocat también en la pasarela, y será este usuario el que pueda conectarse al servidor sin necesidad de introducir ninguna clave. Nos tenemos que asegurar que sólo pueda leer ese usuario esas claves, para eso tecleamos: chmod 700 /.ssh Una vez hecho esto, creamos en el servidor de autenticación el usuario nocat y copiamos la clave pública generada antes en /home/nocat/.ssh/authorized_keys. En el fichero de configuración (/etc/ssh/sshd_config) debemos tener:
PubkeyAuthentication yes
Una vez que reiniciemos el servicio (/etc/init.d/sshd restart), el usuario nocat de la pasarela podrá conectarse por ssh al servidor sin necesidad de introducir ninguna clave. En principio se invocó el script de conexión directamente desde el proceso gateway de la pasarela, pero se comprobó que se introducía mucho retardo mientras se establecía la conexión y se comprobaba la clave. La solución que se adoptó fue crear un proceso que se ejecuta en background en la pasarela (p_remoto) y atiende peticiones continuamente. Las peticiones tienen el siguiente formato: servidor script [parámetros] El servidor es la dirección del servidor, el script es el nombre del script que se ejecuta remotamente, y una serie de parámetros opcionales. El script lo busca en el directorio /usr/local/nocat/bin del servidor. El modo de funcionamiento es escribir en un archivo FIFO una línea con el formato anterior y el proceso p_remoto se encarga de atender la petición y ejecutar el script deseado. El p_remoto crea un hijo cada vez que tiene que atender una petición, y se queda esperando a que termine. De esta manera, cuando se produce una conexión se libera al proceso gateway de esperar la conexión ssh, permitiéndole continuar con su ejecución normalmente. Pasemos a ver como quedó el método permit de la clase gateway. Introducimos unas líneas de comentarios para indicar el lugar donde se insertaron las líneas.

sub permit {
    my ( $self, $peer, $class ) = @_;
    my $fw = $self->firewall( GatewayAddr => $peer->gateway_ip );
    my $action;

    # Stash the peer object for future use.
    #
    $self->add_peer( $peer );

    # Update its expiration timestamp.
    #
    $peer->timestamp(1);

    # Get *our* notion of what the peer's service class should be.
    #
    $class = $self->classify( $peer, $class );

    my $prior_class = $peer->status;


    if ( $prior_class ne $class ) {
    # Insert the rule for the new class of service...
    #
    $fw->permit( $class, $peer->mac, $peer->ip );

    # *BEFORE* removing the rule for the *old* class of service, if any.
    # This way we don't drop packets for stateful connections in the
    # event of service upgrade.
    #
    if ( $prior_class and $prior_class ne DENY ) {
      $self->log( 5, "Upgrading ", $peer->user,
        " from $prior_class to $class service." );

      $fw->deny( $prior_class, $peer->mac, $peer->ip );
      $action = "Upgrade";
    } else {
      $self->log( 5, "User ", $peer->user, " permitted in class $class
               with rate ",$peer->rate,"Kbit and ceil ", $peer->ceil,"Kbit" );
      $action = PERMIT;


#  Codigo insertado para pasar a p_remoto una peticion que ejecute el script
#   conexion en el servidor y registre la conexion en la tabla conexiones
#
      my $servidor=$self->{AuthServiceAddr};
      my $login=$peer->user;
      my $ubicacion=$self->{Ubicacion};
      my $id=$peer->id_cola;
      open (FIFO,">/home/nocat/param_fifo");
      print FIFO "$servidor conexion $login $id $ubicacion";
      close FIFO;

#  Insertamos clase para la calidad de servicio
#
     $fw->ins_qos($peer->ip, $peer->id_cola, $peer->rate,
                                              $peer->ceil, $peer->prio);
    }
  $peer->status( $class );
#  Guardamos los parametros anteriores
#
    $peer->ceil_anterior( $peer->ceil);
    $peer->rate_anterior( $peer->rate);
  }
  elsif ( $peer->ceil_anterior  ne $peer->ceil or
            $peer->rate_anterior ne $peer->rate)
  {#Si cambian los parametros de conexion
    $self->log(5,"Upgrading ", $peer->user, "from Rate",
    $peer->rate_anterior,"Kbit Ceil", $peer->ceil_anterior,"Kbit to ",
       $peer->rate,"Kbit", $peer->ceil,"Kbit");
    $fw->del_qos($peer->ip, $peer->id_cola);
    $fw->ins_qos($peer->ip, $peer->id_cola, $peer->rate,
                                                $peer->ceil, $peer->prio);
    $peer->ceil_anterior( $peer->ceil);
    $peer->rate_anterior( $peer->rate);

    $action = "Renew";
  }
  else
  {
    $self->log( 5, "User ", $peer->user, " renewed in class $class
          with rate", $peer->rate,"Kbit and ceil", $peer->ceil,"Kbit" );
    $action = "Renew";
  }
  # Tell the parent process about it.
  $self->notify_parent( $action => $peer );
}


next up previous contents
Siguiente: Salida Subir: Control de acceso Anterior: Control de acceso   Índice General
Jesús Martín 2003-09-16
e-REdING. Biblioteca de la Escuela Superior de Ingenieros de Sevilla.


SISTEMA DE CONTROL, TARIFICACIÓN Y ADMINISTRACIÓN DEL ACCESO A INTERNET DESDE REDES HETEROGÉNEAS

: Martín Ruiz, Jesús
: Ingeniería Telecomunicación
Contenido del proyecto: