KEMBAR78
Blog de Iván López: Nagios
Mostrando entradas con la etiqueta Nagios. Mostrar todas las entradas
Mostrando entradas con la etiqueta Nagios. Mostrar todas las entradas

lunes, 11 de febrero de 2008

Monitorizando sistemas con Nagios

Nagios es un sistema de código abierto de monitorización de redes, máquinas, servicios, sistemas, filesystems... muy flexible que permite definir distintos tipos de alertas en función de la disponibilidad de los objetos monitorizados.

   En mi anterior trabajo lo instalé y configuré para monitorizar distintos entornos que gestionábamos y también para la monitorización remota de filesystems. He rescatado el pequeño documento que hice en su momento y este es el resultado después de completarlo con explicaciones más detalladas, ejemplos y alguna captura.

   Lo primero que debo aclarar es que está basado en la versión 2.4 de Nagios, siendo la versión estable actual la 2.10. No debería haber muchas diferencias por lo que supongo que todo lo que voy a contar funcionará sin problemas. La máquina en la que monté el servidor Nagios es una Sun Fire 280R con Solaris 8 y obviamente no tenía permisos de root, por lo que la instalación está hecha con un usuario normal (vtprov) siendo su home /internet/vtprov. Además, al ser una máquina con Solaris no hay paquetes de binarios ya compilados, por lo que toca compilar desde el código fuente. El caso de la instalación para Linux debería ser similar.

Instalación
Después de descargar y desempaquetar el .tar generamos el fichero Makefile:
$ ./configure --prefix=PREFIX --with-nagios-user=SOMEUSER --with-nagios-group=SOMEGROUP
Donde: PREFIX es la ruta en donde queremos instalar y que llamaremos $NAGIOS_HOME.
           SOMEUSER es el usuario que ejecutará Nagios.
           SOMEGROUP es el grupo del usuario que ejecutará Nagios.
Después simplemente compilamos:
$ make all

Y finalmente instalamos en la ruta que hayamos configurado anteriormente:
$ make install

   Para comprobar el estado de los servicios, sistemas,... Nagios utiliza diversos plugins programados en C. Es necesario descargar y compilar dichos plugins e instalarlos en Nagios. La utilización de plugins hace que Nagios sea muy potente respecto a los sistemas que puede monitorizar puesto que si no existe ningún plugin que nos interese, siempre es posible crear uno a medida.
   La compilación de los plugins es exáctamente igual a la de Nagios y una vez compilados deben almacenarse en el directorio $NAGIOS_HOME/libexec.

Configuración
   Nagios se configura mediante archivos de texto que se encuentran en $NAGIOS_HOME/etc. Los principales archivos son:
  • nagios.cfg: Es el archivo principal de Nagios. En él, además de diversas opciones de configuración se definen las rutas del resto de archivos de configuración. Podemos elegir si queremos un archivo con toda la configuración o múltiples archivos más pequeños. En mi caso elegí un único archivo.
  • checkcommands.cfg: En este archivo se define el nombre lógico y físico de los comandos de monitorización que se utilizarán así como los parámetros de reciben.
  • misccommands.cfg: Se definen las plantillas que se utilizarán para los emails de notificación.
  • bigger.cfg: Archivo principal en el que se configuran los servicios que se desean monitorizar, notificaciones, comandos para la monitorización, agrupación de servicios,...

  •    A continuación muestro con un poco más de detalle los archivos de configuración y añado ejemplos de configuración. Sólo he seleccionado algunas partes concretas puesto que algunos son muy grandes y tienen muchas opciones. Cada una de ellas viene con una pequeña explicación sobre su utilización.

    nagios.cfg
       Hay que prestar especial atención a la opción check_external_commands puesto que sin habilitarla no podremos comprobar el estado de un servicio que deseemos en un momento determinado, sino que sólo se ejecutará la comprobación según se haya planificado.
    # OBJECT CONFIGURATION FILE(S)

    # Plugin commands (service and host check commands)
    cfg_file=/internet/vtprov/nagios/etc/checkcommands.cfg

    # Misc commands (notification and event handler commands, etc)
    cfg_file=/internet/vtprov/nagios/etc/misccommands.cfg

    # You can split other types of object definitions across several
    # config files if you wish (as done here), or keep them all in a
    # single config file.
    cfg_file=/internet/vtprov/nagios/etc/bigger.cfg

    # NAGIOS USER
    nagios_user=vtprov

    # NAGIOS GROUP
    nagios_group=users

    # EXTERNAL COMMAND OPTION
    # This option allows you to specify whether or not Nagios should check
    # for external commands (in the command file defined below). By default
    # Nagios will *not* check for external commands, just to be on the
    # cautious side. If you want to be able to use the CGI command interface
    # you will have to enable this. Setting this value to 0 disables command
    # checking (the default), other values enable it.

    check_external_commands=1
    [...]

    checkcommands.cfg
       Estos son algunos de los comandos (plugins) que podemos usar para comprobar el estado de los servicios. Por ejemplo, el comando check_http realiza una simple llamada GET a la máquina definida en el parámetro $ARG1$, al puerto $ARG2$ y a la URL $ARG3$. Esta llamada la usábamos para comprobar el estado de diversos servlets que estaban corriendo en distintas instancias de servidores tomcat.
       El comando check_http_wm es una personalización del anterior (fijaos que el command_line es el mismo) pero se conecta con un usuario y password que pasamos como parámetro.
       También muestro el ejemplo del ping y también el comando check_nrpe que veremos posteriormente para ejecutar scripts en máquinas remotas y en función del resultado lanzar o no una alarma.
    define command{
    command_name check_ping
    command_line $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5
    }

    define command{
    command_name check_http
    command_line $USER1$/check_http -H $ARG1$ -p $ARG2$ --url=$ARG3$
    }

    define command{
    command_name check_http_wm
    command_line $USER1$/check_http -H $ARG1$ -p $ARG2$ -a USER:PASSWD
    }

    define command{
    command_name check_nrpe
    command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -p $ARG1$ -c $ARG2$ -a $ARG3$ $ARG4$ $ARG5$
    }

    misccommands.cfg
       En mi caso cambié el command_line que venía por defecto por el que muestro a continuación puesto que así se envía más información en la alerta que nos llega por email.
    # 'notify-by-email' command definition
    define command{
    command_name notify-by-email
    command_line /usr/bin/printf "Subject: ** $NOTIFICATIONTYPE$ alert - $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ ** %b\n\n ***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$" | /usr/bin/mail $CONTACTEMAIL$
    }

    bigger.cfg
       Como ya he comentado este es el archivo de configuración en el que damos de alta todos los servicios que queremos monitorizar. Además, también definimos los periodos de monitorización, usuarios, agrupamos los servicios,...

  • Definición de periodos en los cuales se notifican los cambios de estado de los servicios. En este caso definimos dos: 24x7 y Workhours. Luego, al dar de alta un servicio para monitorizar le asociamos uno de estos periodos, de tal forma que sólo se envían notificaciones si estamos en el periodo definido.
    # '24x7' timeperiod definition
    define timeperiod{
    timeperiod_name 24x7
    alias 24 Hours A Day, 7 Days A Week
    sunday 00:00-24:00
    monday 00:00-24:00
    tuesday 00:00-24:00
    wednesday 00:00-24:00
    thursday 00:00-24:00
    friday 00:00-24:00
    saturday 00:00-24:00
    }

    # 'workhours' timeperiod definition
    define timeperiod {
    timeperiod_name Workhours
    alias "Normal" Working Hours
    monday 08:00-19:00
    tuesday 08:00-19:00
    wednesday 08:00-19:00
    thursday 08:00-19:00
    friday 08:00-15:00
    }

  • Definición de grupos de notificación. Los emails a los que notificar separdados por comas y el periodo de notificación definido anteriormente.
    # 'vt-prov' contact definition
    define contact {
    contact_name vt-prov
    alias Nagios Admin
    service_notification_period 24x7
    host_notification_period 24x7
    service_notification_options w,u,c,r
    host_notification_options d,u,r
    service_notification_commands notify-by-email
    host_notification_commands host-notify-by-email
    email user1@empresa.com,user2@empresa.com
    }

  • Definición de máquinas y agrupación de las mismas.
    # 'host1' host definition
    define host{
    use generic-host
    host_name host1
    alias Servidor host1
    address 172.24.88.169
    check_command check-host-alive
    max_check_attempts 10
    check_period 24x7
    notification_interval 120
    notification_period 24x7
    notification_options d,u,r
    contact_groups vt-prov
    }

    # 'solaris-servers' host group definition
    define hostgroup{
    hostgroup_name solaris-servers
    alias Solaris Servers
    members host1,host2,host4,host6
    }

  • Definición de servicios a monitorizar: Esta es la parte más importante y es donde realmente damos de alta todos los servicios que deseamos monitorizar. Como ejemplo muestro el ping para saber si la máquina está activa, la comprobación de un servicio corriendo en un tomcat y la ocupación de un filesystem:
    Ping
    define service{                             
    use generic-service
    host_name host1
    service_description PING
    is_volatile 0
    check_period 24x7
    max_check_attempts 4
    normal_check_interval 1
    retry_check_interval 1
    contact_groups vt-prov
    notification_interval 120
    notification_period 24x7
    notification_options w,u,c,r
    check_command check_ping!100.0,20%!500.0,60%
    }

    Servlet en Tomcat
    define service{
    use generic-service
    host_name host2
    service_description ENTORNO1 - Servicio2
    is_volatile 0
    check_period 24x7
    max_check_attempts 1
    normal_check_interval 5
    retry_check_interval 1
    contact_groups vt-prov
    notification_interval 10
    notification_period 24x7
    notification_options w,u,c,r
    check_command check_http!host2!10102!/servicio/jsp/autent/login.jsp
    }

    Ocupación Filesystem
    define service{
    use generic-service
    host_name host2
    service_description host2 - /var
    is_volatile 0
    check_period 24x7
    max_check_attempts 1
    normal_check_interval 5
    retry_check_interval 1
    contact_groups vt-prov
    notification_interval 120
    notification_period 24x7
    notification_options w,u,c,r
    check_command check_nrpe!7997!check_disk!7!5!/var
    }

  • Agrupación de servicios en un grupo: De esta forma se actua sobre todo el grupo a la vez. Esto es útil cuando por ejemplo hay una intervención en una máquina o se está actualizando un entorno completo y se quieren deshabilitar todas las alarmas de ese entorno a la vez.
    define servicegroup{
    servicegroup_name ENTORNO1 - TOMCATs
    alias ENTORNO1 - TOMCATs
    members host2,ENTORNO1 - Servicio2,host2,ENTORNO1 - Servicio3,host2,ENTORNO1 - Servicio8
    }

  •    Una vez definidos los servicios que deseamos monitorizar, podemos verificar si el archivo de configuración es correcto o contiene algún error. Desde el directorio $NAGIOS_HOME/bin:
    $ nagios -v ../etc/nagios.cfg
    Nagios 2.4
    Copyright (c) 1999-2006 Ethan Galstad (http://www.nagios.org)
    Last Modified: 05-31-2006
    License: GPL

    Reading configuration data...

    Running pre-flight check on configuration data...

    Checking services...
    Checked 82 services.
    Checking hosts...
    Checked 5 hosts.
    Checking host groups...
    Checked 1 host groups.
    Checking service groups...
    Checked 16 service groups.
    Checking contacts...
    Checked 1 contacts.
    Checking contact groups...
    Checked 1 contact groups.
    Checking service escalations...
    Checked 0 service escalations.
    Checking service dependencies...
    Checked 0 service dependencies.
    Checking host escalations...
    Checked 0 host escalations.
    Checking host dependencies...
    Checked 0 host dependencies.
    Checking commands...
    Checked 26 commands.
    Checking time periods...
    Checked 4 time periods.
    Checking extended host info definitions...
    Checked 0 extended host info definitions.
    Checking extended service info definitions...
    Checked 0 extended service info definitions.
    Checking for circular paths between hosts...
    Checking for circular host and service dependencies...
    Checking global event handlers...
    Checking obsessive compulsive processor commands...
    Checking misc settings...

    Total Warnings: 0
    Total Errors: 0

    Things look okay - No serious problems were detected during the pre-flight check

       Como no hay ningún error podemos arrancar Nagios:
    $ nagios -d ../etc/nagios.cfg

       En este momento se empezarían a monitorizar los sistemas que tengamos definidos y se enviarían notificaciones por email si se han configurado.

    Interfaz Web
       Para poder interactuar con el sistema y ver todo de un modo gráfico es necesario configurar la consola web de Nagios. Para ello es necesario un servidor Apache. Instalamos el servidor y en el archivo httpd.conf añadimos lo siguiente:
    ScriptAlias /nagios/cgi-bin "/internet/vtprov/nagios/sbin/"
    <Directory "/internet/vtprov/nagios/sbin">
    AllowOverride AuthConfig
    Options +ExecCGI
    Order allow,deny
    Allow from all
    </Directory>

    Alias /nagios "/internet/vtprov/nagios/share"
    <Directory "/internet/vtprov/nagios/share">
    Options None
    AllowOverride AuthConfig
    Order allow,deny
    Allow from all
    </Directory>

       Reiniciamos apache y ya nos deberíamos poder conectar a la consola de administración:


    Control de Acceso
       Se pueden definir distintos usuarios para conectarse a Nagios con diferentes permisos y que verán únicamente los servicios en los que se hayan añadido como contacto. Para ello utilizamos las opciones de autenticación que ofrece Apache.
       Creamos el archivo .htaccess en los directorios share y sbin con el siguiente contenido:
    AuthName "Acceso a Nagios"
    AuthType Basic
    AuthUserFile /internet/vtprov/nagios/etc/htpasswd.users
    require valid-user

       Y creamos el archivo de passwords desde el directorio bin de la instalación de Apache añadiendo el usuario nagios.
    $ htpasswd -c /internet/vtprov/nagios/etc/htpasswd.users nagios

       Ahora al conectarnos a Nagios nos aparecerá la típica ventana solicitando nuestro usuario y password.


    Comandos remotos
       Para poder ejecutar scritps en máquinas remotas, como por ejemplo, para comprobar el tamaño de los filesystems de otras máquinas, necesitamos instalar un pequeño servidor en dichas máquinas. Este servidor se llama NRPE (Nagios Remote Plugin Executor). Es necesario descargarlo y compilarlo tal y como hemos hecho con Nagios.

       La configuración es muy sencilla: En cada máquina que queramos monitorizar la ocupación de sus filesystems debemos configurar el archivo nrpe.cfg en el que básicamente hay que indicar el puerto en el que queremos levantar el servidor, el usuario y el grupo que lo ejecutan y activar la opción para permitir recibir comandos remotos con parámetros. El fichero de configuración tiene el siguiente aspecto (como antes, incluyo sólo lo más importante).
    # PORT NUMBER
    server_port=7997

    # SERVER ADDRESS
    server_address=172.24.88.169

    # ALLOWED HOST ADDRESSES
    # This is a comma-delimited list of IP address of hosts that are allowed
    # to talk to the NRPE daemon.
    allowed_hosts=127.0.0.1,172.24.86.11

    # NRPE USER
    nrpe_user=nrpe

    # NRPE GROUP
    nrpe_group=users

    # COMMAND ARGUMENT PROCESSING
    # This option determines whether or not the NRPE daemon will allow clients
    # to specify arguments to commands that are executed. This option only works
    # if the daemon was configured with the --enable-command-args configure script
    # option.
    #
    # *** ENABLING THIS OPTION IS A SECURITY RISK! ***
    # Read the SECURITY file for information on some of the security implications
    # of enabling this variable.
    #
    # Values: 0=do not allow arguments, 1=allow command arguments
    dont_blame_nrpe=1

    # COMMAND DEFINITIONS
    command[check_disk]=/home/user/nrpe/check_disk.sh $ARG1$ $ARG2$ $ARG3$

       Hay que destacar la opción dont_blame_nrpe ya que tal y como se indica activarla puede representar un problema de seguridad porque estamos aceptando parámetros y podría realizarse algún tipo de ataque a la máquina por este medio. En mi caso lo habilité porque el script que comprueba el tamaño del filesystem necesita dichos parámetros y no representaba ningún problema de seguridad.
       Al final también hemos añadido el comando remoto que se ejecutará (check_disk) y la llamada al script con los parámetros necesarios. Este script debe existir en la máquina de la que deseamos monitorizar los filesystems.

       Recordemos que antes definimos la ejecución del script check_disk (para un filesystem y máquina concretos) como:
    check_nrpe!7997!check_disk!7!5!/var
       En esta llamada 7997 es el puerto del nrpe en la máquina remota, check_disk es el nombre lógico del script y 7, 5 y /var son los parámetros del script. Éste comprueba el porcentaje de espacio libre del filesystem que recibe como parámetro y lo compara con los dos umbrales que le pasamos. Si es menor de un 7% genera un warning y si es menor de un 5% genera un error crítico.

       El script check_disk.sh que acabamos de ver y que definíamos anteriormente en el archivo bigger.cfg es el siguiente:
    #!/bin/ksh
    # check_disk.sh: Comprueba el tamaño de un filesystem y
    # devuelve el estado en función de dos umbrales definidos.
    #
    # Iván López Martín

    warning=$1
    critical=$2
    filesystem=$3

    STATE_OK=0
    STATE_WARNING=1
    STATE_CRITICAL=2

    size=`df -k $filesystem | grep $filesystem | awk '{print $4}'`
    sizeMB=`echo "$size/1024" | bc`
    percentage=`df -k $filesystem | grep $filesystem | awk '{print $5}' | sed -e s/%//g`
    freePercentage=`echo "100-$percentage" | bc`

    if [ "$freePercentage" -le "$critical" ]; then
    echo "DISK CRITICAL - free space: "$filesystem" $sizeMB MB"
    return $STATE_CRITICAL
    fi
    if [ "$freePercentage" -le "$warning" ]; then
    echo "DISK WARNING - free space: "$filesystem" $sizeMB MB"
    return $STATE_WARNING
    fi

    echo "DISK OK - free space: "$filesystem" $sizeMB MB"
    return $STATE_OK

       Con los scripts remotos configurados arrancamos el demonio nrpe:
    $ nrpe -c nrpe.cfg -d

       Como veis, me he hecho mi propio script para comprobar remotamente los filesystems de las distintas máquinas. Aunque dije inicialmente que los plugins que vienen con Nagios están escritos en C, se puede utilizar cualquier lenguaje que soporte la máquina para comprobar el estado del servicio que deseemos.

       Este script nos era especialmente útil sobre todo para comprobar la ocupación del filesystem /var. Cuando veíamos que estaba bastante lleno sólo teníamos que enviar un email a administración Unix para que borrasen logs antiguos y nos liberaran algo de espacio.

    Interfaz gráfica
       A continuación muestro una serie de capturas de pantalla de la interfaz gráfica con todos los servicios que teníamos configurados en su momento.
    Servicios
    Máquinas

    Agrupación de servicios
    Opciones de servicios


    Conclusiones
       Lo que más me gusta de Nagios es que es muy sencillo de configurar y que con el simple hecho de dar de alta un servicio, automáticamente ya lo estamos monitorizando.
       En su momento también probé herramientas como Hyperic HQ y aunque visualmente son más bonitas, descubren automáticamente los servicios que hay corriendo en las máquinas,... al final son más engorrosas. En mi caso, en algunas máquinas descubría "demasiados" servicios y había que estar eliminando todos los que no queríamos monitorizar. Además, había que definir una a una las alarmas para cada uno de esos servicios. Al final, después de probarla durante un tiempo la descarté y me quedé con Nagios.