Enviar notificaciones vía email con Nagios

Nagios

Una de las funciones más interesantes de Nagios es la notificación de los eventos de la red. Una avería en una línea no es difícil de detectar, suelen ser los usuarios los primeros en quejarse. Pero una caída de un servicio que en ese momento no se está usando es más complida de ver. Para no tener que estar todo el día mirando el monitor del Nagios, existe la opción de crear contactos y que se les notifiquen los eventos de la manera que se elija (email, SMS, …). Obviamente la herramienta más común para estas notificaciones será el correo, ya que no todas las empresas disponen de una pasarela de envío de SMS o similar. Para poder enviarlas nos hará falta un servidor de correo, bien en nuestra propia red como en internet. Paso a relataros como he solucionado yo el tema sin usar un servidor de correo en el equipo del Nagios.

Para empezar, en el fichero de configuración de contactos se deben crear los perfiles de los usuarios a los que se debe avisar, así como los grupos a los que pertenecen.

#definimos un contacto predefinido, para no tener que declarar todas las opciones de cada usuario
define contact{
name contacto-basico
service_notification_period laboral
host_notification_period laboral
service_notification_options w,u,c,r,f,s
host_notification_options d,u,r,f,s
service_notification_commands notify-service-by-email
host_notification_commands notificar-host
register 0
}

#definimos el grupo admins, al que pertenece el contacto dani
define contactgroup{
contactgroup_name admins
alias Administradores
members dani
}

#definimos el contacto dani, con un alias y una direccion de email
define contact{
contact_name dani
use contacto-basico
alias Dani
email dani@ejemplo.es
}

Una vez editados los contactos, nos hace falta añadir el comando al fichero oportuno para que Nagios sepa donde buscarlo. Además configuramos la sintaxis con la que se invocará desde Nagios. En éste caso pasamos varias variables predefinidas en el sistema.

#definimos el comando notificar-host
define command{
command_name notificar-host
command_line /tmp/correo.pl $CONTACTEMAIL$ $NOTIFICATIONTYPE$ $HOSTNAME$ $HOSTSTATE$ $HOSTADDRESS$
}

Por último, debemos crear “correo.pl”, que en éste caso es un script en Perl que nos permitirá el envío de correos. Cambiaremos los parámetros para adaptarlo a nuestras necesidades y lo guardaremos en “/tmp”, como hemos definido en el fichero anterior.

#!/usr/bin/perl
use Net::SMTP;
$destinatario=$ARGV[0];
$tipo=$ARGV[1];
$host=$ARGV[2];
$estado=$ARGV[3];
$ip=$ARGV[4];
$smtp= Net::SMTP-> new ("smtp.ejemplo.es");
$smtp->mail("nagios\@ejemplo.es");
$smtp->to("$destinatario");
$smtp->data();
$smtp->datasend("To: $destinatario\n");
$smtp->datasend("Subject: NAGIOS - $tipo: $host con estado $estado\n");
$smtp->datasend("Notificacion de tipo: $tipo\n");
$smtp->datasend("Equipo: $host ($ip)\n");
$smtp->datasend("Estado actual: $estado\n");
$smtp->datasend();
$smtp->quit;

Una vez configurado todo esto, ya dispondremos de notificaciones vía email. He partido de la suposición de que Nagios está funcionando y configurado y que esto es un añadido, de forma que no haya que configurar nada más. La mejor opción para aprender a configurar Nagios es partir de los ficheros de ejemplo y modificarlos de acuerdo a vuestras necesidades.

EDITO

Para los que necesiten una versión que funcione en con un servidor que requiera autentificación:

#!/usr/bin/perl
use Net::SMTP;
$destinatario=$ARGV[0];
$tipo=$ARGV[1];
$host=$ARGV[2];
$estado=$ARGV[3];
$ip=$ARGV[4];
$smtp= Net::SMTP->new('smtp.ejemplo.com');
$smtp->auth('usuario', 'contraseña');
$smtp->mail('nagios@ejemplo.com');
$smtp->to(”$destinatario”);
$smtp->data();
$smtp->datasend(”To: $destinatario\n”);
$smtp->datasend(”Subject: NAGIOS – $tipo: $host con estado $estado\n”);
$smtp->datasend(”\n”);
$smtp->datasend(”Notificacion de tipo: $tipo\n”);
$smtp->datasend(”Equipo: $host ($ip)\n”);
$smtp->datasend(”Estado actual: $estado\n”);
$smtp->datasend();
$smtp->quit;

Ahora mismo estoy probándolo y no me ha dado problemas. En caso de que queráis hacer un debug, podeis cambiar la línea del servidor por la siguiente:

$smtp= Net::SMTP->new(’smtp.ejemplo.com’, Debug => 1);

Y luego probar el script usando:

./nombre_script.pl dirección_de_correo_de_prueba error equipo estado ip

118 thoughts on “Enviar notificaciones vía email con Nagios

  1. Hola buenas a todos, quería felicitar a Dani por su gran aportación, me está ayudando a conseguir mi objetivo de notificación de mail de Nagios y a Arregi por optimizarlo, lo cual probaré una vez que termine de funcionar correctamente.

    Me falla algo de la configuración y no sé exactamente que puede ser. He creado los contactos en contacts.cfg y el comando en commands.cfg y ninguno de los ficheros da error al reiniciar el servicio de Nagios. También he probado a lanzar el script de forma independiente y funciona correctamente.

    **Actualmente tengo servidores OFF por tanto debería mandar correo o sólo cuando surja algún cambio en alguno de ellos? No puedo dedicarme a apagar y encender dichos servidores para probarlo…

    También voy a comentar a continuación la duda que tenía Saenz para monitorizar la RAM de las máquinas, encontré un script que me funciona.

    Gracias de antemano, saludos.

  2. Este es el script que utilizo para chequear la RAM. No olvide añadir los permisos necesarios sobre el fichero. Personalmente no tube que modificar nada de él.

    Saludos.

    —-SCRIPT CHEQUEAR RAM—-

    #!/bin/sh
    # check_mem.sh
    # Determine memory usage percentage on Linux servers.
    # Original write for RHEL3 for PC1 Project – jlightner 05-Jul-2005
    #
    # Modified for RHEL5 on mailservers.
    # -Some of the escapes previously required for RHEL3′s ksh not needed on RHEL5.
    # -Changed comparisons to allow for decimal rather than integer values.
    #

    # Usage: check_mem.sh WARNING CRITICAL
    # Where WARNING and CRITICAL are the integer only portions of the
    # percentage for the level desired.
    # (i.e. 85% Warning & 95% Critical should be input only as “85 95″.)

    # Define Levels based on input
    #
    WARNLEVEL=$1
    CRITLEVEL=$2

    # Setup standard Nagios/NRPE return codes
    #
    UNKNOWN_STATE=3
    CRITICAL_STATE=2
    WARNING_STATE=1
    OK_STATE=0

    # Give full paths to commands – Nagios can’t determine location otherwise
    #
    BC=/usr/bin/bc
    GREP=/bin/grep
    AWK=/bin/awk
    FREE=/usr/bin/free
    TAIL=/usr/bin/tail
    HEAD=/usr/bin/head

    # Get memory information from the “free” command – output of top two lines
    # looks like:
    # total used free shared buffers cached
    # Mem: 8248768 6944444 1304324 0 246164 5647524
    # The set command will get everything from the second line and put it into
    # posiional variables $1 through $7.
    #
    set `$FREE |$HEAD -2 |$TAIL -1`

    # Now give variable names to the positional variables we set above
    #
    MEMTOTAL=$2
    MEMUSED=$3
    MEMFREE=$4
    MEMBUFFERS=$6
    MEMCACHED=$7

    # Do calculations based on what we got from free using the variables defined
    #
    REALMEMUSED=`echo $MEMUSED – $MEMBUFFERS – $MEMCACHED | $BC`
    USEPCT=`echo “scale=3; $REALMEMUSED / $MEMTOTAL * 100″ |$BC -l`
    #USEPCT=`echo scale=3 “n” $REALMEMUSED / $MEMTOTAL * 100 |$BC -l |$AWK -F. ‘{print $1}’`

    # Compare the Used percentage to the Warning and Critical levels input at
    # command line. Issue message and set return code as appropriate for each
    # level. Nagios web page will use these to determine alarm level and message.
    #
    #if [ `echo "5.0 > 5" |bc` -eq 1 ]
    #then echo it is greater
    #else echo it is not greater
    #fi
    if [ `echo "$USEPCT > $CRITLEVEL" |bc` -eq 1 ]
    then echo “CRITICAL – Memory usage is ${USEPCT}%”
    exit ${CRITICAL_STATE}
    elif [ `echo "$USEPCT > $WARNLEVEL" |bc` -eq 1 ]
    then echo “WARNING – Memory usage is ${USEPCT}%”
    exit ${WARNING_STATE}
    elif [ `echo "$USEPCT < $WARNLEVEL" |bc` -eq 1 ]
    then echo "OK – Memory usage is ${USEPCT}%"
    exit ${OK_STATE}
    else echo "Unable to determine memory usage."
    exit ${UNKNOWN_STATE}
    fi
    echo "Unable to determine memory usage."
    exit ${UNKNOWN_STATE}

  3. Bueno creo que he solucionado mi problema!!

    Estaba todo bien configurado y lo he podido probar al crear el script de servicios que dejó Arregi. Ya que si podía hacer funcionar o quitar servicios he probado y manda correo cuando hay algún cambio. Debido a que no puedo modificar el estado de los servidores espero que funcione igual jejeje

    **Mi última duda es respecto al tiempo de espera que Nagios tiene hasta notificar el correo, creo personalmente que es demasiado y me gustaría poder modificarlo, como dijiste Dani esto es ‘editable’ pero no sé cómo conseguirlo, si pudieras echarme una mano te lo agradecería.

    Gracias a todos de nuevo. Saludos!

  4. Lo primero Luis, gracias por tu colaboración, seguro que a más de uno le interesa lo de la memoria.

    Sobre tu duda, asumo que tu lo que quieres es que desde el momento en el que se registra el primer fallo hasta que se envía el correo transcurra menos tiempo. El tema es por los cambios de estado. Cuando un equipo cae, se produce una primera alarma. Como puede ser que el equipo a veces no responda a la primera, Nagios tiene una opción para que se detecten estos cambios “fantasma”, con lo que normalmente espera X comprobaciones más antes de cambiar de estado. El parámetro es max_check_attempts, que marca las veces que desde el primer fallo se vuelve a comprobar antes de dar la alarma. Yo te diría que ojo con esto, que a veces interesa que no salte a la primera de cambio.

  5. GENIAL ESO DEL MAX_CHECK-ATTEMPTS, Y CON RESPECTO AL SCRIPT DE LA RAM TE PREGUNTO LUIS, COMO CORREO ESE SCRIPT O COMO LO INCLUYO A LA CONFIGURACION. METO UN ARCHIVO LLAMADO MEM_RAM O COMO SE EN ALGUNA CARPETA Y DESDE NAGIOS.CONF LO LLAMO O SI ME PUDIERAS DAR LOS PASOS UN POCO MAS COMO PARA TONTOS JAJAJA

  6. Dani, donde puedo cambiar ese parámetro?? en mi fichero de configuracion de nagios??

    En nagios.cfg los paramétros parecidos que tengo son:

    max_check_result_reaper_time
    max_check_result_file_age

    No tengo ninguno que se llame exactamente así

    Saenz ese script lo tengo creado con el nombre check_mem y lo tengo con persmisos de ejecucion en la ruta /usr/local/nagios/libexec q es el directorio q contiene todos los scripts ‘EN CADA UNO DE LOS CLIENTES A MONITORIZAR’. Puede que también sea necesario añadir al usuario nagios como propietario de dicho script.

    Luego desde tu fichero de servicios del SERVIDOR Nagios donde tienes definidos todos los servicios de cada cliente:

    define service{
    use generic-service
    host_name Cliente1 service_description # Memoria RAM
    check_command check_nrpe!check_mem
    }

    Y en el cliente también tienes que configurar como los otros en el demonio NRPE, en la ruta /usr/local/nagios/etc/nrpe.cfg

    command[check_mem]=/usr/local/nagios/libexec/check_mem 85 95

    Reinicias los servicios y listo!

  7. El parámetro lo cambias en las definiciones, creo que en mi caso, estaba en una definición de un grupo de servidores.

  8. Luis casi casi tengo listo eso jajaja. pero digamos que me perdi en eso de:

    “Y en el cliente también tienes que configurar como los otros en el demonio NRPE, en la ruta /usr/local/nagios/etc/nrpe.cfg”

    Yo no tengo ningun archivo que se llame nrpe.cfg …. que es? a partir de ahi no entendi lo que dijiste. :( . ni lo de:

    command[check_mem]=/usr/local/nagios/libexec/check_mem 85 95

    me colaboras

  9. pueden explicarme com cingifuro las notificaiones por correo ya tengo creados mis grupos y contacto pero aplico lo que me dicen y no he logrado nada,,, estoy desde cero.

  10. Hola Juan

    Por lo que dices voy a asumir que tienes Nagios configurado y funcionando y que los ficheros los has creado correctamente. ¿Has reiniciado el servicio para que reconozca las nuevas configuraciones que has introducido?

  11. Hola lo que yo quiero es que las notificaciones tarden un poco más pero no se que valor le pongo al max_check_attempts o si le pongo así

    service_description PING
    check_command check_ping!200.0,20%!600.0,60%
    normal_check_interval 5
    retry_check_interval 1
    max_check_attempts ¿este es un valor bajo?
    notification_interval ¿este es alto?
    Por que luego solo los servicios se caen por la red que los contiene (falla de internet) algo así como el cuento de Pedro y el Lobo..

    saludos.

  12. Si lo que quieres es que antes de enviar la notificación realice más de una comprobación, la variable que lo marca es max_check_attempts. Dale el valor acorde con la cantidad de veces que desees que Nagios compruebe el estado antes de que se produzca una alarma.

    Para éste tipo de dudas, tienes en la documentación de Nagios todas las variables de cada tipo de objeto: http://nagios.sourceforge.net/docs/3_0/objectdefinitions.html

  13. tengo una duda el scrpit de perl que colocas como muestra lo debo crear en el terminal root en un archivo especifico de nagios.

  14. Hola Juan Carlos, como bien pone en el artículo, debes crear el script en una carpeta a tu elección (/tmp en el ejemplo), da igual como lo crees, mientras se pueda ejecutar.

  15. Hola Juan Carlos,

    Si ejecuto tu script desde bash funciona perfecto:

    mail.pl cuenta@dominio.com notificacion nombreservidor OK 192.168.1.1

    Pero cuando lo configuro dentro de commands.cfg no lo envia y en syslog veo esto:
    [1327594478] **ePN failed to compile /usr/local/nagios/libexec/mail.pl: “Global symbol “$destinatario” requires explicit package name at (eval 1) line 4,
    Global symbol “$tipo” requires explicit package name at (eval 1) line 12.
    Global symbol “$host” requires explicit package name at (eval 1) line 13.
    Global symbol “$estado” requires explicit package name at (eval 1) line 14.
    Global symbol “$ip” requires explicit package name at (eval 1) line 15.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 16.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 17.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 18.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 19.
    Global symbol “$destinatario” requires explicit package name at (eval 1) line 19.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 20.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 21.
    Global symbol “$destinatario” requires explicit package name at (eval 1) line 21.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 22.
    Global symbol “$tipo” requires explicit package name at (eval 1) line 22.
    Global symbol “$host” requires explicit package name at (eval 1) line 22.
    Global symbol “$estado” requires explicit package name at (eval 1) line 22.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 23.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 24.
    Global symbol “$tipo” requires explicit package name at (eval 1) line 24.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 25.
    Global symbol “$host” requires explicit package name at (eval 1) line 25.
    Global symbol “$ip” requires explicit package name at (eval 1) line 25.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 26.
    Global symbol “$estado” requires explicit package name at (eval 1) line 26.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 27.
    Global symbol “$smtp” requires explicit package name at (eval 1) line 28.” at /usr/local/nagios/bin/p1.pl line 248.

    Parece que al script perl no le llegan las variables de Nagios

    Que puede ser?
    Gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>