Scripts

CNM permite al usuario ejecutar sus propios scripts en la misma máquina o en equipos remotos que actúan como proxy. El uso de scripts, permite mejorar los repositorios de métricas y aplicaciones de nuestro sistema.

Un script orientado a proporcionar métricas debe devolver valores numéricos de acuerdo con el formato que veremos a continuación. Si su uso es como aplicación, la salida será texto sin restricciones.

Los scripts se pueden subir directamente al CNM desde la rama de scripts o bien crearlos desde el editor que incluye el CNM, que se despliega cuando hacemos click en el botón de crear script o al hacer doble click sobre un script ya definido.

CREAR SCRIPT DE TIPO MÉTRICA

Vamos a crear un script a modo de ejemplo que obtenga el número de puertos TCP y UDP abiertos en un equipo. Para ello desde la rama de scripts hacemos click en crear script y desplegamos el editor que contiene las siguientes zonas recuadradas en la figura:

 

  • En la parte superior izquierda de la ventana aparece el nombre del script. En este caso el script se llama linux_metric_open_ports.pl
  • En la parte superior derecha aparece el tamaño en bytes y la fecha de última modificación del script.
  • La zona recuadrada en azul contiene los parámetros que va a tener el script. Cada uno de ellos tendrá un tipo, un prefijo opcional a utilizar en la ejecución del comando, una descripción y un posible valor por defecto. Los parámetros pueden ser de tres tipos:
    1. Parámetro de texto en claro: Parámetro estándar definido por el usuario. El valor aparece en el interfaz. 
    2. Parámetro de texto oculto: Parámetro definido por el usuario que por seguridad, una vez introducido su valor, no aparece en el interfaz. Se puede utilizar para campos sensibles como contraseñas o incluso nombres de usuario.
    3. Parámetro de tipo IP: Es un parámetro dinámico cuyo valor es asociado internamente por el sistema utilizando el dato del dispositivo al que se asocie como métrica. En la definición del script no se le asigna ningún valor pero se indica al CNM que existe.
  • La zona recuadrada en verde contiene el tipo de proxy y el tipo de script.
    1. El tipo de proxy se refiere al equipo donde va a ejecutarse el script. En este caso se utiliza un proxy Linux porque se trata de un script perl sobre Linux. Si fuera un script escritp visual basic script (vbs) utilizaríamos un proxy Windows. No confundir esto con el tipo de elemento monitorizado, es decir, desde un proxy linux podemos monitorizar una BBDD instalada en un equipo windows. 
    2. El tipo de script define su rol dentro del sistema (métrica o aplicación). Una métrica requiere que el script devuelva valores numéricos, permite representar gráficamente los datos y generar alertas basadas en monitores. Una aplicación requiere un script que genere datos de texto en su salida y estará disponible en el para ser ejecutada a voluntad o de forma periódica a partir de la definición de una taréa.
  • La zona recuadrada en negro permite ejecutar el script y así validarlo. Para ello hay que introducir los siguientes datos y hacer click en Ejecutar:
    1. En Proxy seleccionado el equipo donde se va a ejecutar.
    2. En el cuadro de texto, se debe completar la cadena completa de ejecución que sea  necesaria. 
  • La zona recuadrada en rojo permite al usuario editar el código del script. Los botones de ventana partida, código y resultado cambian la estructura de la ventana para adaptarse a las diferentes situaciones posibles (volver a la ventana incial, editar el código o ver sólo el resultado de la ejecución).

Una vez entendido el funcionamiento del editor de scripts, ya estamos en disposición de crearlo. Para ello vamos a utilizar los siguientes datos:

  • Tipo de proxy: Linux.
  • Tipo de script: Métrica.
  • Crear un parámetro de tipo IP sin prefijo.
  • El contenido del script será el siguiente:

#!/usr/bin/perl -w
#--------------------------------------------------------------------------------------
# NAME:  linux_metric_open_ports.pl
# DESCRIPTION:
# Obtiene el número de puertos abiertos al exterior.
# CALLING SAMPLE:
# linux_metric_open_ports.pl 1.1.1.1
# INPUT (PARAMS):
# a. IP remota
# OUTPUT (STDOUT):
# <001> Ports Open = 5
# OUTPUT (STDERR):
# Error info, warnings etc... If verbose also debug info.
#
# EXIT CODE:
#  0: OK
#--------------------------------------------------------------------------------------
use strict;
use Time::Local;

if (! exists $ARGV[0]) { die "[ERROR]: Falta parametro host (ip)\n"; }
my $REMOTE=$ARGV[0];

my $cmd1="/bin/echo | /usr/bin/nmap -v -sT $REMOTE 2>&1 | grep -i Discovered | wc -l";
my $res1=`$cmd1`;

my $cmd2="/bin/echo | /usr/bin/nmap -v -sU $REMOTE 2>&1 | grep -i Discovered | wc -l";
my $res2=`$cmd2`;

print "<001>  TCP Ports Open = $res1";
print "<002>  UDP Ports Open = $res2";


exit 0;

El script está programado en Perl y tiene como parámetro de entrada la dirección IP del dispositivo a monitorizar. El resultado se devuelve por la salida estandar y cada valor debe estar en una línea con el siguiente formato:

 

  1. Un tag contenido entre los caracteres < y >. Se recomienda seguir un criterio numérico (001, 002, 003 etc ..)
  2. Breve descripción del dato obtenido.
  3. Un signo =
  4. El valor numérico correspondiente.

 Hay que tener en cuenta que un script puede devolver múltiples valores (esto significa n líneas con datos <001>, <002>, <003>, ....<xyz>) y el mismo script puede servir para definir múltiples métricas.

Para validar el script introducimos los datos del proxy local (localhost:22), rellenamos la línea de comandos con una IP accesible (192.168.1.1) y al hacer click en Ejecutar obtenemos los siguiente valores:

<001>  TCP Ports Open = 7
<002>  UDP Ports Open = 0

Una vez validado el script. lo guardamos con el nombre linux_metric_open_ports.pl. A partir de este momento, aparecerá en el listado de scripts y se podrá localizar facilmente  filtrando por nombre o tipo de script (métrica de usuario en este caso). 

Los tags son necesarios para que el CNM sea capaz de seleccionar los valores de acuerdo con la definición que se haga de las métricas. Si al definir la métrica  sólo nos interesara el valor de los puertos TCP abiertos, utilizaríamos  la etiqueta <001> en la definición de la misma.

 CREAR SCRIPT DE TIPO APLICACIÓN

Vamos a crear un script a modo de ejemplo que obtenga los paquetes de software instalados en un servidor Linux Debian. Para ello desde la rama de scripts hacemos click en crear script y desplegamos el editor.

 

  • En la parte superior izquierda  aparece el nombre del script. En este caso el script se llama linux_app_sw_installed.pl
  • En la parte superior derecha aparece el tamaño en bytes y la fecha de última modificación del script.
  • En la zona del recuadro azul se definen los parámetros que va a tener el script. En este caso creamos los siguientes parámetros:
    • Un parámetro de tipo IP, con prefijo -n  y con descripción Host. No le ponemos ningún valor prederminado.
    • Un parámetro de tipo texto oculto, con prefijo -u  y con descripción User. No le ponemos ningún valor prederminado. Este va a ser el usuario que se utilice al realizar la autenticación por ssh al equipo destino.
    • Un parámetro de tipo texto oculto, con prefijo -p  y con descripción Password. No le ponemos ningún valor prederminado. Este va a ser la contraseña que se utilice al realizar la autenticación por ssh al equipo destino.
    • Un parámetro de tipo texto claro, con prefijo -a  y con descripción Patrón. No le ponemos ningún valor prederminado. Este va a ser, en caso de querer usarlo, el patrón de búsqueda que se le va a aplicar al listado de los paquetes.
  • En la zona verde se define el tipo de proxy y el tipo de script. En nuestro caso:
    • Tipo de proxy: Linux.
    • Tipo de script: Aplicación.
  • La zona negra está destinada a probar desde este interfaz el script. Proxy seleccionado indica el equipo que ejecutará el script en las pruebas, el cuadro de texto sirve para poner los parámetros que queramos utilizar y por último, ejecutar se encarga de lanzar la ejecución del código que hay en la zona roja, utilizando los parámetros del cuadro de texto en el proxy indicado.
  • La zona roja permite al usuario almacenar, editar y visualizar el código del script. Los botones de ventana partidacódigo y resultado cambian la estructura de la ventana para ayudar al usuario a realizar tareas como mostrar la ventana incial, editar el código o mostrar sólo el resultado de la ejecución de prueba.
  • El contenido del script será el siguiente:
#!/usr/bin/perl -w
#--------------------------------------------------------------------------------------
# NAME:  linux_app_sw_installed.pl
#
# DESCRIPTION:
# Obtiene el numero de ficheros que existen en un determinado directorio.
#
# CALLING SAMPLE:
# linux_app_sw_installed.pl -n 1.1.1.1 [-a pattern] [-v]
# linux_app_sw_installed.pl -n 1.1.1.1 -u user -p pwd [-a pattern] [-v]
# linux_app_sw_installed.pl -n 1.1.1.1 -u user -k -p passphrase [-a pattern] [-v]
# linux_app_sw_installed.pl -h  : Ayuda
#
# INPUT (PARAMS):
# a. -n  :  IP remota
# b. -a  :  Patron de busqueda en los paquetes
# c. -u  :  Usuario (ssh)
# d. -k:Usa autenticacion por clave publica
# e. -p  :  Clave|Passphrase (ssh)
#
# OUTPUT (STDOUT):
# List of Packages (pattern=.):
# ...
# OUTPUT (STDERR):
# Error info, warnings etc... If verbose also debug info.
#
# EXIT CODE:
#  0: OK
# -1: System error
# >0: Script error
#--------------------------------------------------------------------------------------
use lib '/opt/crawler/bin/';
use strict;
use Getopt::Std;
use Net::OpenSSH;
use Stdout;

#--------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------
my @fpth = split ('/',$0,10);
my @fname = split ('\.',$fpth[$#fpth],10);
my $VERSION="1.0";

my $USAGE = <<USAGE;
ssh2cmd. $VERSION

$fpth[$#fpth] -n IP [-a pattern] [-w xml] [-v]
$fpth[$#fpth] -n IP -u user -p pwd [-a pattern] [-w xml] [-v]
$fpth[$#fpth] -n IP -u user -k -p passphrase [-a pattern] [-w xml] [-v]
$fpth[$#fpth] -h  : Ayuda

-nIP remota/local
-uuser
-kIndica si usa clave autenticacion por clave publica
-ppwd
-k (Usa autenticacion basada en PK)
-aPatron de busqueda en los paquetes
USAGE

#--------------------------------------------------------------------------------------
my %SSH_OPTS =(
   'port'        => 22,
   'master_opts' => [-o => "StrictHostKeyChecking=no"],
);

my $local_ip = my_ip();
my $local=0;
my ($ip,$PK,$pattern)=('',undef,'.');

#--------------------------------------------------------------------------------------
my %opts=();
getopts("hn:u:p:a:k",\%opts);

if ($opts{h}) { die $USAGE;}
$ip=$opts{n} || die $USAGE;

if ($opts{a}) { $pattern=$opts{a}; }

if ( ($ip eq 'localhost') || ($ip eq '127.0.0.1') || ($ip eq $local_ip) ) { $local=1; }

if (! $local) {
   $SSH_OPTS{'user'} = $opts{u} || die $USAGE;
   if (exists $opts{k}) { 
      $PK=1;
      $SSH_OPTS{'passphrase'} = $opts{p};
      $SSH_OPTS{'key_path'}   = '/home/cnm/.ssh/id_rsa';
   }
   elsif (exists $opts{p}) {
      $SSH_OPTS{'password'} = $opts{p};
   }
   else {
      die $USAGE;
   }
}


#--------------------------------------------------------------------------------------
# SE PROCESA EL COMANDO
#--------------------------------------------------------------------------------------
my $CMD1 = <<END1;
/usr/bin/dpkg -al|/bin/grep '^ii'| /bin/grep $pattern |awk '{print \$2"-----------"\$3;}'
END1
#--------------------------------------------------------------------------------------
#print  $CMD1;
my @cmds=($CMD1);
my ($stdout, $stderr, $exit) = ('', '', 0);
my $ssh;

if (! $local) { 
  $ssh = Net::OpenSSH->new($ip, %SSH_OPTS);
  $ssh->error and die "Can't ssh to $ip: " . $ssh->error;
}

foreach my $cmd (@cmds) {

   if (! $local) {
      ($stdout, $stderr) = $ssh->capture2($cmd);
   }
   else { 
      $stdout = `$cmd`;
   }
   chomp $stdout;

   print "List of Packages: (pattern=$pattern) \n$stdout";
   if ($stderr ne '') {
      print STDERR "stderr=$stderr\n";
      exit;
   }
}


#--------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------
# FUNCIONES AUXILIARES
#--------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------
sub my_ip {

   my $r=`/sbin/ifconfig eth0`;
   $r=~/inet\s+addr\:(\d+\.\d+\.\d+\.\d+)\s+/;
   return $1;
}

Como se puede observar, el script está programado en Perl y lo que hace es recibir como parámetros de entrada la dirección ip del dispositivo del que se quiere obtener el listado de paquetes, el usuario y la contraseña con la que el proxy realizará la autenticación ssh y, por último, un parámetro que es opcional y filtra el listado de paquetes.

  • Probamos el script contra un equipo de nuestra red para comprobar si todo funciona correctamente, para lo cuál introducimos una ip de nuestra red,el usuario y la contraseña con la que se realizará la autenticación y el patrón en el cuadro de texto de parámetros de prueba y damos a ejecutar. En nuestro caso hemos puesto en el cuadro de texto de parámetros de prueba -n 10.2.254.223 -u user -p pass -a apt y al dar a ejecutar, ha devuelto el resultado:
    List of Packages: (pattern=apt)
    apt-----------0.8.10.3
    apt-listchanges-----------2.85.7
    apt-utils-----------0.8.10.3
    aptitude-----------0.6.3-3.2
    laptop-detect-----------0.13.7
    libpcap0.8-----------1.1.1-2
    python-apt-----------0.7.100.1
    python-apt-common-----------0.7.100.1

    De esta forma vemos que el script funciona correctamente. En caso de no hacerlo, en el cuadro de resultado indicaría el problema.
  • Guardar el script con el nombre linux_app_sw_installed.pl

Una vez guardado el script podemos encontrarlo en el listado de scripts filtrando por tipo de script, que sea aplicación de usuario. Aquí la norma que se sigue es que si es una métrica el icono es una gráfica y si es una aplicación es un recuadro y, si es de sistema el color de fondo es blanco y si es de usuario el color es amarillo. Por lo tanto tenemos que seleccionar un recuadro amarillo. Al hacerlo debemos encontrar el script que acabamos de crear, linux_app_sw_installed.pl.

CREDENCIALES

En general, los scripts definidos en el sistema necesitaran credenciales de acceso a los equipos remotos. CNM permite definir las credenciales necesarias para ello en la rama de configuración en la solapa de Credenciales.