17 junio 2013

Monitorización de temperatura de UTMs NetASQ desde Nagios



Me sucede con gran frecuencia, que mis clientes me sorprenden pidiéndome soluciones para sus sistemas, que escapan a lo que las propias herramientas permiten hacer. En este caso, un responsable de seguridad y sistemas, que tiene como objetivo el correcto funcionamiento y monitorización de un parque importante de dispositivos UTM NetASQ, que no siempre están en un CPD con condiciones óptimas de refrigeración, me indicó que quería poder adelantarse al verano, controlando la temperatura de todos estos equipos. A bote pronto, se me ocurrió que lo más normal sería obtener este dato por SNMP, o quizá, algún proceso del sistema operativo del propio NetASQ, lo guardaría de forma periódica en un fichero,… pero como andaba liado de tiempo, abrí un ticket en soporte. "Hola, he visto que en el Dashboard de gestión de estos equipos aparece la temperatura y quisiera que me dijeseis cómo poder acceder a él para monitorizarlo desde Nagios remotamente. ¿Se puede hacer por SNMP?". Respuesta de soporte: "Hola, lamentamos informarle que no es posible acceder a este dato por SNMP" Vaya… y yo que le he dicho al cliente que lo diese por hecho ¿y ahora qué hacemos?





Investigando qué hace el Dashboard por debajo, para el widget de la temperatura,.. y tirando de Tamper Data una vez más, ví que hacía una llamada a un procedimiento RPC llamado "MONITOR STATS". Hablando de este tema con el director técnico de NetASQ en España, me indicó que existía un a herramienta ejecutable desde un terminal, que permite inyectarle comandos y devuelve un resultado.

Se puede hacer en modo "una_sola_línea" mediante una sintaxis algo así como: nsrpc -c fichero_comando usuario:contraseña@IP_NetASQ, de manera que ejecutará lo que tenga dentro el "fichero_comando".

La plataforma desde la que iba a hacer estas pruebas es Nagios montado sobre Linux, por lo que el comando nsrpc no existía, aparte que implicaría tener que abrir el puerto TCP/1300 (por donde acepta las conexiones un NetASQ), para las peticiones desde la máquina Nagios, modificar políticas de seguridad en un montón (más de 80) equipos, así que… hubo que pensar en algo, con lo que ya tenía, que era acceso SSH desde la IP del Nagios.

Se me ocurrió que mediante comandos SSH, podría ejecutar todo lo necesario y extraer en remoto el valor que quería: la temperatura actual del equipo.

Como variables, establezco el usuario y contraseña SSH ($user/$pass), así como el $host al que me conecto, y creo en /tmp el fichero "comando" con el contenido a ejecutar

sshpass -p $pass ssh $user\@$host -o StrictHostKeyChecking=no "echo MONITOR STAT > /tmp/comando"

Lo siguiente es ejecutarlo en remoto, dejando el resultado de la ejecución en /tmp/comando en el sistema remoto ($internal_ip es la IP del equipo desde la que está permitido implícitamente que responda por RPC):

sshpass -p $pass ssh $user\@$host -o StrictHostKeyChecking=no "nsrpc -c /tmp/comando $user:$pass\@$internal_ip > /tmp/output"


Veréis que he incluido la opción "-o StrictHostKeyChecking=no" en el comando SSH. Esto es porque desde la máquina Nagios, hay equipos a los que nunca nos hemos conectado, por lo que para saltarnos la aceptación del certificado, "confiamos" donde nos estamos conectando.

Lo siguiente es "traerme" el contenido de la salida del comando anterior. Podría hacerlo con "scp", pero era aún más rápido hacerme un cat del fichero y guardarlo en una variable "$devuelve"

my $devuelve=`sshpass -p $pass ssh $user\@$host -o StrictHostKeyChecking=no "cat /tmp/output"`;


Después borro los rastros que haya dejado en el sistema remoto

sshpass -p $pass ssh $user@$host -o StrictHostKeyChecking=no "rm -rf /tmp/output /tmp/comando";

Ahora queda procesar el contenido de $devuelve para extraer únicamente la temperatura y tomar decisiones. Hasta ahora muy bien en modo BASH, pero hay que integrarlo con Nagios, y hacer que reciba entradas y devuelva resultados en el formato parseable por el sistema de monitorización.

Directamente, decidí hacerlo en Perl, con el menor número de módulos posibles (para evitar "ensuciar" el sistema Nagios), por lo que pido disculpas por la mezcla de llamadas a "system" dentro del código. El script es tan sencillo como las siguientes líneas:  




En la configuración de Nagios, hay que modificar el fichero /etc/nagios/objects/commands.cfg y añadir lo siguiente:


define command{
        command_name    check_temp_netasq
         command_line    $USER1$/check_temp_netasq -H $HOSTADDRESS$ $ARG1$
        }


Y luego en el fichero correspondiente al host con la configuración Nagios, indicaremos la llamada al comando con los parámetros -w y -c, siendo respectivamente la temperatura a partir de la cual queremos que cambie el estado a Warning y a Critical:


define service{
        use                             generic-service         ; Name of service template to use
        host_name                       FQDN_or_IP_Address_NetASQ_device 
        service_description             NetASQ_Temp
        check_command                   check_temp_netasq!-w 45 -c 50
        notifications_enabled           1
        }


Bueno, pues esto así, tal cual… si se ejecuta desde línea de comandos, funciona estupendamente. Si se comprueban los valores de ejecución del comando con un "echo $?", devuelve 0, 1 ó 2, dependiendo de lo que suceda con la temperatura, pero desde Nagios, da un error en la ejecución del plugin con el mensaje "service check did not exit properly". Investigando el error, encontré un link muy interesante  que dice que los exit de los plugins hechos en Perl, han de hacerse importando la variable %ERRORS y saliendo con exit $ERRORS{'OK'}, en vez de con exit 0… sustituyendo OK por WARNING o CRITICAL para los otros valores. 

Sin embargo, después de pegarme un buen rato con ello, no hubo manera, y me sigue dando los mismos errores. ¿Solución? Según encontré aquí, poner en medio un subprograma en BASH que recoja bien los valores y los envíe de vuelta a Nagios. Este programita check_debug.sh deja logs en un fichero, pero se puede eliminar esa parte para que no ocupe de más, y simplemente nos haga el trabajo del parsing correcto de valores.


#!/bin/bash
RESULT=`$* 2>&1`
EXITCODE=$?
echo $RESULT 
exit $EXITCODE


En este caso, la definición del comando en Nagios se haría así: 

define command{
   command_name    check_temp_netasq
   command_line    $USER1$/check_debug.sh $USER1$/check_temp_netasq -H $HOSTADDRESS$ $ARG1$
        }


Como véis es un script muy sencillo, y sé que por esto no me van a dar el premio a "programador del año", pero os puedo decir que así funciona correctamente y si a uno solo de nuestros lectores le sirve para su instalación, habrá merecido la pena compartirlo.... y si no, pues por parte de Securízame, otro cliente satisfecho!!!

5 comments :

Miguel A. Arroyo dijo...

Muy bueno Lorenzo, curioso el currillo ;-)

F1lth dijo...

Buena esa idea de usar ssh,

En cuanto a Perl y Nagios, yo tuve algun problemilla tambien en su dia con la devolucion de valores de ejecucion. Me acuerdo que lo solvente usando el interprete de perl del sistema en lugar del interprete de Nagios, de tal forma que el comando quedaria algo asi:

define command{
command_name check_temp_netasq
command_line /usr/bin/perl $USER1$/check_temp_netasq -H $HOSTADDRESS$ $ARG1$
}

Un saludo!


F1lth

Lorenzo_Martinez dijo...

Muchas gracias por el aporte. Eso también lo leí como posible problema, pero tampoco me funcionó usar la versión de perl del SO en vez de la de Nagios :(

CarloX dijo...

Y que todavia haya gente con sus monitores hp y sus infovistas... madre de dios :-)

angelhc dijo...

Genial!, yo ahora ando con zabbix pero trabajé bastante con nagios hace tiempo. Me gusta ver temas de monitorización en este site.
Gracias por el aporte.