Mostrando entradas con la etiqueta monitoreo. Mostrar todas las entradas
Mostrando entradas con la etiqueta monitoreo. Mostrar todas las entradas
Nagios: generar gráficos con PNP4Nagios
Hace tiempo que estoy trabajando con Nagios y MRTG, como pudieron observar en Nagios: monitoreo remoto de dispositivos + agentes Linux + agentes Windows, y  Monitoreo de ancho de banda en routers/switches/etc usando MRTG. Ambas herramientas me resultaron excelentes y me ayudan mucho en el monitoreo diario de la infraestructura de red.
Desde hace un tiempo vengo buscando la forma de integrar más gráficos en Nagios, y me pareció interesante utilizar MRTG para hacerlo. Esto es perfectamente posible y hasta comencé a trabajar en ello, pero luego descubrí PNP4Nagios y cambié la perspectiva.

Tal como cita la página oficinal:
PNP es un addon para Nagios que analiza datos de performance (performance data) provistos por los plugins y los almacena en bases de datos RRD.
Oye, eso suena similar a lo que MRTG hace. Pues claro, el acercamiento es similar, almacenar datos en bases de datos RRD y luego graficar a partir de ellos utilizando rrdtool. De forma similar trabajan Ntop y otras herramientas.

PNP4Nagios tiene una interfaz web muy atractiva y simple de usar, permitiendo seleccionar intervalos de tiempo de forma dinámica, navegar fácilmente entre servicios de hosts, y generar reportes en PDF. Tal vez una de las características más interesantes es la posibilidad de definir templates propios para indicarle la forma de evaluar y generar los gráficos. Dado que trabaja directamente con RRDTool, brinda todas las facilidades de graficación que esta herramienta provee.

Cabe destacar que para poder graficar datos, los plugins deben retornar información en el campo performance_data, y no todos los plugins lo hacen. Por suerte, quienes diseñan buenos plugins si entregan datos de performance. Estos datos deben tener un formato especial para que PNP pueda parsearlos y almacenarlos, pero esa discusión la dejaré para algún artículo sobre creación de plugins.
Para saber fácilmente si un plugin entrega datos de performance, pueden ejecutarlo desde la consola y ver si incluye el caracter pipe "|" en el resultado impreso. Todo lo que venga luego del pipe son datos de performance. Por ejemplo:
  $./check_icmp -H 10.6.143.101
  OK - 10.6.143.101: rta 1,593ms, lost 0%|rta=1,593ms;200,000;500,000;0; pl=0%;40;80;; rtmax=4,541ms;;;; rtmin=0,832ms;;;;
Este plugin entrega 4 datos de performance:
  - rta: tiempo de respuesta,
  - pl: porcentaje de pérdida de paquetes,
  - rtmax: tiempo máximo de respuesta,
  - rtmin: tiempo mínimo de respuesta.
 

Integración con Nagios

PNP4Nagios provee varios modos de integrarse con Nagios, cada uno con sus ventajas y desventajas:

  • Synchronous: cada vez que Nagios ejecuta un plugin, luego llama el script process_perfdata.pl para actualizar los valores de la base de datos RRD y el archivo XML correspondiente. La mayor desventaja de esta forma de integración es que Nagios ejecuta process_perfdata.pl cada vez que realiza un check de host o servicio.
  • Bulk: este modo permite realizar múltiples actualizaciones de datos de performance juntos. Nagios escribe en un archivo temporal los datos obtenidos en cada check, y a intervalos definidos, Nagios ejecuta el script process_perfdata.pl.
  • Bulk with NPCD: desde el punto de vista de Nagios, es la mejor opción, dado que se independiza de la ejecución del script process_perfdata.pl. La ejecución de script queda a cargo del demonio NPCD (Nagios Performance C Daemon), el cual monitorea un directorio, donde deben ubicarse los datos de performance, a la espera de que un archivo sea creado. De esta forma, Nagios se encarga de guardar los datos de la ejecución de los plugins en archivos y luego mover los archivos al directorio donde los tomará NPCD.
  • Bulk with NPCD and npcdmod: el flujo de datos es igual a Bulk with NPCD, con la diferencia que simplifica la configuración de Nagios, ya que las definiciones de cómo procesar los datos se dejan al módulo npcdmod. El uso de este módulo se realiza definiendo un broker en la configuración de Nagios. Debe tenerse en cuenta que este modo no funciona con Nagios 4.
  • Gearman: se utiliza el módulo Gearman como agente intermediario entre Nagios y el procesamiento de los datos. Nagios se encarga de generar los datos y mod_gearman (broker para Nagios) se encarga de encolarlos para su procesamiento, utilizando el demonio gearmand. Luego el script process_perfdata.pl escanea esta cola en busca de datos. La mayor ventaja de este modo es que Nagios y PNP4Nagios pueden ejecutarse en máquinas distintas, ya que la conexión de Nagios con Gearman es a través de sockets. Además Gearman funciona con workers y puede tener múltiples workers trabajando a la vez. Este modo es el ideal para instalaciones de Nagios con hosts y servicios.

De las opciones listadas, elegí utilizar el modo Bulk with NPCD y npcdmod, dado lo fácil que es ponerlo en funcionamiento, y las ventajas que provee sobre el modo Synchronous. Si algún día utilizan Nagios 4, deberían utilizar otra opción como Bulk with NPCD o Gearman.


Instalación y Configuración

Instalar PNP4Nagios en debian y derivados es tan simple como ejecutar:
  # apt-get install pnp4nagios rrdtool
Existen paquetes para otras distribuciones como CentOS.
 
Luego de instalarlo, para integrarlo con Nagios utilizando el modo Bulk with NPCD y npcdmod, debe realizarse los siguientes pasos.

Setear la variable RUN en yes, en el archivo /etc/default/npcd, para habilitar en demonio NPCD.
RUN=yes
Editar el archivo /etc/nagios3/nagios.cfg de la siguiente manera:
# Habilita el procesamiento de datos de performance entregados por los plugins de chequeo
process_performance_data=1
# Hacer que Nagios comparta su información con la librería npcdmod
broker_module=/usr/lib/pnp4nagios/npcdmod.o config_file=/etc/pnp4nagios/npcd.cfg
Recargar Nagios:
/etc/init.d/nagios3 reload
Gualá, ya está la integración, eso fue fácil.

Por defecto, PNP4Nagios se habilita en un directorio web distinto al de Nagios. Los gráficos se acceden apuntando a las siguientes direcciones:
http://<nombre servidor>/pnp4nagios/pnp4nagios/graph?host=<nombre del host>
http://<nombre servidor>/pnp4nagios/pnp4nagios/graph?host=<nombre del host>&srv=<descripción del servicio>
Como nombre de host debe utilizarse el nombre que se utilizó para definirlo en Nagios.


Una forma más directa de acceder a los gráficos, es agregar el link como un action_url en la definición de hosts en Nagios. El camino fácil es definir nuevos templates para hosts y servicios, de la siguiente manera:
define host {
 use generic-host
 name pnp-host
 action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_
 register 0
}
define service {
 name pnp-service
 action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
 register 0
}
Luego, para cada host o servicio que se desee ver gráficos, simplemente agregar pnp-host y pnp-service en la definición de hosts.


Pensamientos Finales

A diferencia de MRTG que utiliza consultas SNMP para obtener sus datos, PNP4Nagios utiliza los datos entregados por los plugins de Nagios... los cuales pueden sacar datos por SNMP o de muchas otras maneras. Esta funcionalidad me resultó mucho más abarcativa, y ya que igualmente necesito Nagios y estoy obteniendo datos con sus plugins, por qué no aprovecharlos para generar los gráficos.
Claro que es posible obtener con MRTG datos de otras fuentes que no sea SNMP, MRTG es muy flexible. Sería posible llegar a resultados similares a los obtenidos con Nagios y PNP, pero de una forma más laboriosa. No estoy diciendo que esta solución reemplace MRTG, sino que me parece mucho más completa. La elección de utilizar una u otra es de cada administrador.



Referencias

- PNP4Nagios Documentation
- Archivo /usr/share/doc/pnp4nagios/README.Debian
Obtener uso de CPU y memoria, temperatura y estado de interfaces de dispositivos Cisco, utilizando SNMP
Continuando con la labor de monitorear el estado de dispositivos conectados a la red, decidí profundizar en el control de equipamiento Cisco. Para ello, recurrí al viejo pero muy vigente y útil protocolo SNMP. Los dispositivos Cisco, como la gran mayoría de los dispositivos de red, proveen información detallada a través de SNMP. El problema es que entre tanta información provista, uno se puede marear y perder lo que le interesa conocer.

Dado que no encontré mucha información que detalle cómo monitorear e interpretar la información de los recursos más importantes (si encontré pedazos de información por separado), decidí investigar y armar documentación propia. Distintas páginas de Cisco proveen información, pero dan por asumido que conocemos relativamente bien la información provista. Lo único que me resultó realmente útil es el navegador de objetos SNMP (http://tools.cisco.com/Support/SNMP/do/BrowseOID.do?local=en). En base a este último pude recopilar y armar las consultas que yo requería.

Yendo al grano, con la información provista en este artículo podrán no sólo saber cómo obtener por SNMP información del estado de los recursos del dispositivo, sino también entender los valores obtenidos.

Me centraré en obtener la información listada a continuación, la cual abarca todo lo necesario para conocer el estado de un dispositivo:
- Estado de las interfaces de red del dispositivo.
- Uso de CPU.
- Temperatura del chasis, y/u otra información provista por los sensores que el equipo posea.
- Uso de memoria.
En el artículo me centraré en describir los OIDs necesarios para obtener la información listada. Los ejemplos los haré utilizando snmpwalk como herramienta de consulta. Esta misma información se puede obtener con distintos clientes snmp, snmpwalk es sólo uno de ellos, muy versátil y completo. Una vez que se conocen los OIDs y la información provista, es muy fácil automatizar el monitoreo con herramientas como Nagios, o scripts propios. Dejaré la integración con Nagios para otro artículo :D

Si les interesa el monitoreo de redes, pueden encontrar más información al respecto en mis anteriores artículos:
- Nagios: monitoreo remoto de dispositivos + agentes Linux + agentes Windows
- Monitoreo de ancho de banda en routers/switches/etc usando MRTG
- Armar servidor de logging con rsyslog y configurar dispositivos para logging remoto
- Instalar Zabbix en Debian GNU/Linux

Estado de Interfaces

Hay ciertas interfaces que son muy interesantes para monitorear, dado que ello nos permitirá saber si un equipo importante perdió la conexión. Interfaces de este tipo pueden ser uplinks entre edificios, conexiones a servidores, enlaces a la WAN, etc.

El OID utilizado para ver el estado de las interfaces es el 1.3.6.1.2.1.2.2.1.8 (objeto ifOperStatus), descripto como "The current operational state of the interface". Este OID contiene una entrada por cada interfaz presente en el switch.
Por ejemplo, al realizar un walk en un 2950, obtenemos la siguiente información:
$ snmpwalk -v2c -c public 192.168.1.100 -On  1.3.6.1.2.1.2.2.1.8
.1.3.6.1.2.1.2.2.1.8.1 = INTEGER: up(1)
.1.3.6.1.2.1.2.2.1.8.2 = INTEGER: down(2)
.1.3.6.1.2.1.2.2.1.8.3 = INTEGER: down(2)
...
...
Ok, esto nos da el estado de las interfaces... pero cómo sabemos cuál interfaz es cada una? Para esto existe el OID 1.3.6.1.2.1.2.2.1.2 (objeto ifDescr), que contiene información de la interfaz. En el ejemplo anterior, la consulta de este OID nos dará lo siguiente:
$ snmpwalk -v2c -c public 192.168.1.100 -On  1.3.6.1.2.1.2.2.1.2
.1.3.6.1.2.1.2.2.1.2.1 = STRING: FastEthernet0/1
.1.3.6.1.2.1.2.2.1.2.2 = STRING: FastEthernet0/2
.1.3.6.1.2.1.2.2.1.2.3 = STRING: FastEthernet0/3
...
Ahora si, ya sabemos que el OID 1.3.6.1.2.1.2.2.1.8.1 representa el estado de la interfaz FastEthernet0/1, el 1.3.6.1.2.1.2.2.1.2.3 la Fa0/3, etc. Para cada interfaz que se desee monitorear, deberá consultarse primero la descripción de la misma, así sabemos con cuál OID se relaciona.


Uso de CPU

Cisco almacena distintos valores para el uso de CPU, utilizando distintos períodos de tiempo. Los OIDs son:
  • 1.3.6.1.4.1.9.9.109.1.1.1.1.10 (cpmCPUTotalMonIntervalValue): uso de CPU en el intervalo especificado por 1.3.6.1.4.1.9.9.109.1.1.1.1.9 (cpmCPUMonInterval). El intervalo suele ser 5 segundos, y este OID es el que debe utilizarse en lugar de cpmCPUTotal5sec y cpmCPUTotal5secRev, ya en desuso.
  • 1.3.6.1.4.1.9.9.109.1.1.1.1.7 (cpmCPUTotal1minRev): uso en el último minuto. Anteriormente se utilizaba cpmCPUTotal1min.
  • 1.3.6.1.4.1.9.9.109.1.1.1.1.8 (cpmCPUTotal5minRev): uso en los últimos cinco minutos. Debe utilizarse en lugar de cpmCPUTotal5min.
La empresa recomienda utilizar cpmCPUTotal5minRev, dado que representa la mejor estimación de uso.
Todos estos valores representan porcentaje de uso y van de 0 a 100.

Ejemplo de consulta del valor de carga de CPU en los últimos 5 minutos es el siguiente:
$ snmpwalk -v2c -c public 192.168.1.100 -On  1.3.6.1.4.1.9.9.109.1.1.1.1.8
.1.3.6.1.4.1.9.9.109.1.1.1.1.8.1 = Gauge32: 6
es decir, la carga es de 6%.

En la página How to Collect CPU Utilization on Cisco IOS Devices Using SNMP se explica bien como obtener información del uso de CPU.


Sensores (midiendo temperatura y estado de fans)

Existen varios sensores en los dispositivos que permiten medir diferentes valores, como la temperatura del chasis y el funcionamiento de los fans. Los valores de los sensores se almacenan en el objeto 1.3.6.1.4.1.9.9.91.1.1.1.1.4 (entSensorValue).
Por ejemplo, accediendo los valores de los sensores en un 4500 obtendremos algo así:
$ snmpwalk -v2c -c public 192.168.1.200 -On 1.3.6.1.4.1.9.9.91.1.1.1.1.4
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.9 = INTEGER: 35
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.15 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.18 = INTEGER: 2
Este objeto contiene entradas indexadas según el índice físico de cada entidad (en este caso, el sensor es la entidad). Para saber a qué entidad refiere cada índice, se puede consultar el objeto 1.3.6.1.2.1.47.1.1.1.1.2 (entPhysicalDescr), el cual describe cada entidad física.
En el ejemplo anterior, podemos ver lo siguiente al consultar este objeto:
$ snmpwalk -v2c -c public 192.168.1.200 -On 1.3.6.1.2.1.47.1.1.1.1.2
...
.1.3.6.1.2.1.47.1.1.1.1.2.9 = STRING: "Chassis Temperature Sensor"
...
.1.3.6.1.2.1.47.1.1.1.1.2.15 = STRING: "Power Supply Fan Sensor"
...
.1.3.6.1.2.1.47.1.1.1.1.2.18 = STRING: "Power Supply Fan Sensor"
Es decir, los valores obtenidos anteriormente son la temperatura del chasis y el estado de los fans de las fuentes.
Ahora, qué significan esos valores? en qué unidades están representados? Bueno, para esto necesitamos consultar ooootro objeto, el 1.3.6.1.4.1.9.9.91.1.1.1.1.1 (entSensorType), que nos indica de qué tipo es cada sensor:
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.9 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.15 = INTEGER: 12
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.18 = INTEGER: 12
Cisco tiene predefinidos estos valores en una tabla, la cual se puede encontrar en su página. La tabla indica lo siguiente:
1:other
2:unknown
3:voltsAC
4:voltsDC
5:amperes
6:watts
7:hertz
8:celsius
9:percentRH
10:rpm
11:cmm
12:truthvalue
13:specialEnum
14:dBm
Con esto sabemos que el primer sensor mide grados celsius (valor 8), y los otros dos otorgan un valor booleano (12). Pero qué significan los valores 1 y 2? cuál es verdadero y cuál es falso? Consultando la página de Cisco, encontramos lo siguiente:
other(1): a measure other than those listed below
unknown(2): unknown measurement, or
arbitrary, relative numbers
voltsAC(3): electric potential
voltsDC(4): electric potential
amperes(5): electric current
watts(6): power
hertz(7): frequency
celsius(8): temperature
percentRH(9): percent relative humidity
rpm(10): shaft revolutions per minute
cmm(11),: cubic meters per minute (airflow)
truthvalue(12): value takes { true(1), false(2) }
specialEnum(13): value takes user defined enumerated values
dBm(14): dB relative to 1mW of power
Gracias a esta última información, ahora sabemos que 1 es verdadero, y 2 es falso. Es decir, el Fan 1 funciona bien, mientras que el 2 no.

Juntando todo este meollo de consultas, ahora sabemos lo siguiente:
  • El switch posee 3 sensores.
  • El primero mide la temperatura del chasis, la cual en este momento es de 35º
  • Los otros dos sensores chequean el estado de los fans de las fuentes, estando el primer fan funcionando bien y el segundo no.
 
Uso de Memoria

Es posible ver el uso de memoria de los dispositivos, así como la cantidad de memoria libre, accediendo al objeto 1.3.6.1.4.1.9.9.48 (ciscoMemoryPoolMIB). Cisco divide la memoria en pools, según su uso. Los tipos de pools predefinidos son:
1:  processor memory
2:  i/o memory
3:  pci memory
4:  fast memory
5:  multibus memory
Además, los pools pueden ser categorizados en dinámicos o predefinidos. De los listados anteriormente, sólo el tipo processor debe ser soportado por todos los dispositivos.
Ejemplo de valores obtenidos en un 2950:
$ snmpwalk -v2c -c public 192.168.1.100 -On 1.3.6.1.4.1.9.9.48
.1.3.6.1.4.1.9.9.48.1.1.1.2.1 = STRING: "Processor"
.1.3.6.1.4.1.9.9.48.1.1.1.2.2 = STRING: "I/O"
.1.3.6.1.4.1.9.9.48.1.1.1.3.1 = INTEGER: 2
.1.3.6.1.4.1.9.9.48.1.1.1.3.2 = INTEGER: 0
.1.3.6.1.4.1.9.9.48.1.1.1.4.1 = INTEGER: 1
.1.3.6.1.4.1.9.9.48.1.1.1.4.2 = INTEGER: 1
.1.3.6.1.4.1.9.9.48.1.1.1.5.1 = Gauge32: 2417476
.1.3.6.1.4.1.9.9.48.1.1.1.5.2 = Gauge32: 687872
.1.3.6.1.4.1.9.9.48.1.1.1.6.1 = Gauge32: 1467696
.1.3.6.1.4.1.9.9.48.1.1.1.6.2 = Gauge32: 1492064
.1.3.6.1.4.1.9.9.48.1.1.1.7.1 = Gauge32: 1274620
.1.3.6.1.4.1.9.9.48.1.1.1.7.2 = Gauge32: 1492060
De los valores obtenidos, tenemos que:
  • 1.3.6.1.4.1.9.9.48.1.1.1.2 (ciscoMemoryPoolName) define el nombre del pool. En el ejemplo hay dos pools, Processor e I/O.
  • 1.3.6.1.4.1.9.9.48.1.1.1.5 (ciscoMemoryPoolUsed) muestra el uso de memoria actual de cada pool, expresado en bytes.
  • 1.3.6.1.4.1.9.9.48.1.1.1.6 (ciscoMemoryPoolFree) representa la memoria libre en cada pool, también en bytes.
La memoria total del equipo se puede obtener sumando los bytes libres con los utilizados.
Instalar Zabbix en Debian GNU/Linux
Después de haber leído muchas buenas críticas acerca de Zabbix, decidí instalarlo sobre un debian para probarlo. Dado que no fue una tarea trivial, decidí documentarla para facilitarle la vida a alguien más. Para empezar, salvo un artículo específico, no encontré documentación que explique bien cómo utilizar los paquetes provistos en debian. Debian trae Zabbix en sus repositorios, pero instalar el servicio no es tan directo como instalar los paquetes, requiere varios pasos adicionales. Esto me molestó bastante, dado que se podría automatizar todo este proceso en la misma instalación del paquete. Igualmente, conociendo los pasos, no es una tarea compleja, sólo algo tediosa :P El artículo en el que me basé para la instalación es How To Install Zabbix on Ubuntu & Configure it to Monitor Multiple VPS Servers.


Instalar los paquetes necesarios
Para instalar Zabbix, ejecutar lo siguiente:
# apt-get install apache2 php5-mysql mysql-server zabbix-server-mysql zabbix-frontend-php
Los paquetes de Apache, PHP5 y MySQL sólo son necesarios si aún no los instalaron, se agregan por completitud. Los paquetes de Zabbix crean los archivos del servidor zabbix, y copian los archivos del front-end en /usr/share, pero sólo eso... restan varios pasos. Es posible instalar Zabbix sobre PostgreSQL.


Configuración base de datos

Los paquetes instalados no crean la base de datos, ni el usuario, por lo que hay que hacerlo manualmente. Los siguientes pasos explican cómo hacer este proceso:
  1. Desde MySQL (i.e. logueados con $mysql -u root -p), crear la base de datos, el usuario y asignarle permisos:
    mysql> create database zabbix_db;
    mysql> create user 'zabbix_usr'@'localhost' identified by 'ELpassword';
    mysql> grant all privileges on zabbix_db.* to 'zabbix_usr'@'localhost';
    mysql> flush privileges;
  2. Los valores para el nombre de usuario y base de datos pueden elegirse a gusto. El comando final permite recargar los permisos para que se asignen los nuevos.
  3. Crear las tablas y asignar los valores default provistos por Zabbix. Para esto existen los archivos /usr/share/zabbix-server-mysql/{schema.sql.gz, images.sql.gz, data.sql.gz}. Descomprimirlos y ejecutarlos con MySQL, con destino la base de datos recién creada.
    /usr/share/zabbix-server-mysql$ gunzip schema.sql.gz images.sql.gz data.sql.gz
    $ mysql -u root -p zabbix_db < schema.sql
    $ mysql -u root -p zabbix_db < images.sql
    $ mysql -u root -p zabbix_db < data.sql

Servidor Zabbix

Según la definición de la base de datos, hay que adaptar el archivo de configuración del serivicio Zabbix. Debe editarse el archivo /etc/zabbix/zabbix_server.conf y ajustar los siguientes valores:
DBName=zabbix_db
DBUser=zabbix_usr
DBPassword=ELpassword
Además, dado que por defecto el servicio Zabbix no inicia automáticamente, debe editarse el archivo /etc/default/zabbix-server y dejar la siguiente sentencia:
START=yes
Luego si podremos iniciar el servicio:
# /etc/init.d/zabbix-server start

Front-End Web

Para habilitar el front end web, deben realizarse los siguientes pasos:
  1. Copiar el archivo de configuración de Apache, provisto en el paquete Zabbix, a su lugar correspondiente, para habilitar el acceso web:
    # cp /usr/share/doc/zabbix-frontend-php/examples/apache.conf /etc/apache2/conf-enabled/zabbix.conf
    En versiones anteriores de debian, los archivos de configuración se copian en /etc/apache2/conf.d

  2. Editar el archivo /etc/php5/apache2/php.ini y asignar los siguientes valores a las variables correspondientes, para adaptar la configuración de PHP a los requerimientos de Zabbix
    post_max_size = 16M
    max_execution_time = 300
    max_input_time = 300
    date.timezone = America/Argentina/Buenos_Aires
    donde el timezone dependerá de su ubicación (ver List of Supported Timezones).
  3. Reiniciar el servidor Apache:
    # service apache2 restart
  4. Abrir, desde el navegador, la página de Zabbix. La misma se encuentra en http://<IP del servidor>/zabbix. Esto redirige al wizzard de configuración inicial, donde:
    2- Se chequea que los requisitos para correr Zabbix se cumplan. Si alguno no se cumple, mostrará un fail y no permitirá seguir hasta tanto se corrija.
    3- Solicita se configuren los datos de la base de datos. Si MySQL no aparece entre las opciones, es que les falta el paquete php5-mysql
    4- Permite asignar los valores del servidor Zabbix. Si no cambiaron nada en la configuración del server, dejar los que están por defecto.
    5- Muestra el resultado de la configuración y permite revisar los valores antes de terminar.
    6- Intenta crear el archivo /etc/zabbix/zabbix.conf.php. Si el servicio no tiene permiso para hacerlo (lo cual será así), descargar el archivo y copiarlo manualmente en el directorio correspondiente.
    Una vez creado el archivo, clickear "Retry" y mostrará un mensaje OK. Clickear "Finish" para ir a la página principal.
  5. Ingresar al sistema con el usuario admin y contraseña zabbix.

Fin
Nagios: monitoreo remoto de dispositivos + agentes Linux + agentes Windows
Desde hace un par de semanas vengo trabajando con Nagios para tener, al instante, el estado de los
servicios de la red (i.e. monitoreo).
Existen varias herramientas para este tipo de trabajo, estando entre las mejores (según he leído y por recomendaciones) Cacti y Zabbix. Mi elección de Nagios se debe a su integración con OSSIM, y a que ya había trabajado con ella en otra ocasión y me resultó muy buena. Esto no implica que Nagios sea la mejor herramienta, pero sí una excelente. Una comparación interesante que encontré sobre herramientas de monitoreo libres es Tired of Nagios and Cacti? Try Zabbix, la cual, obviamente se enfoca en Zabbix, pero nombra los pro y los contra de cada herramienta.

Las características que encuentro más importantes en Nagios, son:
- Compatibilidad. Existen agentes tanto para Linux como para Windows que permiten monitorear una gran variedad de recursos.
- Flexibilidad. Se pueden definir comandos nuevos para chequeos que no estén incluidos, o para mejorar alguno existente.
- Extendibilidad. El protocolo de comunicación entre agentes y servidor es abierto y está documentado para que cualquiera pueda desarrollar sus propios agentes. Además, como veremos, es posible utilizar varios protocolos.
- Configuración a través de archivos de texto. Si bien algunos no les gusta, para mi es mucho más rápido definir hosts y servicios a chequear mediante simples archivos de texto, que haciendo muchos clicks en una interfaz web.
- Visualización del estado de la red en una sola pantalla. Es fácil y rápido detectar cuando algo anda mal.
- Intervalos para chequear un host/servicio configurables.
- Reporte de alertas por mail y SMSs.
- Sistema de detección de cambios de estado (flapping). Si un host se detecta caído, al minuto normal, al minuto caído, no está bueno recibir 300 alertas, dado que el host está en un estado inestable. Nagios detecta esto y previene futuras alertas hasta que se estabilice.
- Variedad de plugins predefinidos.
- Hay una gran comunidad detrás, así como mucha documentación.


What's all about?

La idea de este artículo no es hablar de las bondades o puntos bajos de Nagios, sino explicar la forma de armar una configuración básica que permita chequear el estado de hosts y servicios remotamente, así como chequear recursos mediante agentes tanto en Windows como en Linux.
Información de Nagios hay mucha, este artículo pretende aportar una explicación resumida del funcionamiento básico y una configuración que abarca la mayoría de los chequeos típicos. Añadir chequeos no debería ser mayor problema una vez conocida las bases.
Para completar esta información, recomiendo leer la documentación oficial en Nagios Core Documentation.


Definición de objetos

Nagios se configura mediante archivos de texto, los cuales deben tener la extensión .cfg. La configuración se basa en objetos, que son los elementos involucrados en la logística de monitoreo y notificación.
Los objetos básicos son:
  - comandos: definen qué programas ejecutar.
  - servicios: son los recursos a testear (CPU, disco, protocolos de red, etc)
  - hosts: definen los hosts que se van a monitorear.
  - contactos: son las personas a las que se va a notificar cuando ocurre una alerta.
  - tiemeperiods: definen en qué horarios se puede chequear un host y en qué horarios se puede notificar a un contacto.
Estos objetos se pueden agrupar mediante los siguientes objetos:
  - hostgroups: permiten agrupar hosts.
  - servicegroups: agrupan servicios.
  - contactgroups: agrupan contactos.

Como se puede observar en la sección de definición de objetos del manual de Nagios, cada objeto puede tener definidos varios atributos, aunque sólo unos pocos (sobre todo si utilizamos la herencia) son obligatorios. Los objetos se definen mediante la cláusula "define" y sus atributos se encierran entre llaves.
Los atributos que utilizaremos para cada tipo de objeto, y que les servirán para la gran mayoría de los casos, son los siguientes:
  comandos:
    - command_name: nombre del comando (por ej check_http)
    - command_line: la línea de comando que se ejecutará para el chequeo (ejemplo: /usr/lib/nagios/plugins/check_http -I $HOSTADDRESS$ -p $ARG1$)

    Como se puede observar en el ejemplo, existen variables predefinidas que se pueden utilizar como argumentos pasados al programa en la línea de comandos (Nagios las denomina macros). La lista completa de macros se encuentra aquí. En el ejemplo $HOSTADDRESS$ es la dirección del host que se está chequeando. También es posible utilizar variables cuyo valor será reemplazado cuando se llame el comando desde la definición de un servicio (o host), las cuales se denominan a partir de $ARG1$ hasta $ARGN$.
 
  servicios:
    - use: directiva que permite heredar atributos de servicios definidos previamente. Es posible definir un servicio base y luego extenderlo mediante esta directiva. En las definiciones de servicios, se suele heredar de "generic-service".
    - service_description: una breve descripción del servicio.
    - hostgroup_name/host_name: asigna el servicio a un grupo de hosts o a hosts específicos. No es mandatorio utilizar este parámetro, dado que se pueden asignar servicios a hosts desde la misma definición de los hosts. Es posible asignar más de un hostgroup o host separándolos con comas.
    - check_command: el nombre del comando, previamente definido, que se utilizará para chequear el servicio. Algo a tener en cuenta es que cuando se llama al comando, los parámetros se pasan separados con signos de admiración. Estos luego se reemplazarán en $ARG1$... $ARGN$, según se definió en el comando.
    Por ejemplo, en la definición de check_tcp encontramos que el comando ejecutado es el siguiente:
      /usr/lib/nagios/plugins/check_tcp -H $HOSTADDRESS$ -p '$ARG1$' -4
    donde $ARG1$ se reemplazará por el puerto TCP que se desea chequear cuando se llame el comando.
    La forma de llamar el comando es la siguiente:
      check_command check_tcp!50000
    donde 50000 es el parámetro utilizado para el puerto.

    NOTA: si no se hereda la definición de generic-service, deberán definirse otros atributos adicionales que son mandatorios (max_check_attempts, check_interval, retry_interval, check_period, notification_interval, notification_period, contacts, contact_groups).

  hosts:
    - use: al igual que en los servicios, esta directiva permite heredar los atributos de un host previamente definido. El caso más común es heredar la definición de "generic-host"
    - host_name: es lo que el nombre indica, el hostname del host.
    - address: dirección IP del host.
    - alias: una breve descripción de la funcionalidad del host.
    - hostgroups: listado de hostgroups a los que el host pertenece. Este atributo no es mandatorio, además es posible asignar los hosts a un hostgroup desde la misma definición del hostgroup.
    - check_command: tiene la misma utilidad que cuando se define un servicio, con la diferencia que se utiliza para chequear si un host está online. Por defecto se utiliza ping (definido en generic-host) como chequeo, pero se puede reemplazar por otro si es que el host no admite pings.
 
    NOTA: si no se hereda la definición de generic-host, deberán definirse otros atributos adicionales que son mandatorios (max_check_attempts, check_period, notification_interval, notification_period, contacts, contact_groups).
 
  hostgroups:
    - hostgroup_name: el nombre del hostgroup que estamos definiendo.
    - alias: una breve descripción de la funcionalidad del hostgroup.
    - members: listado de hosts, separados por coma, que pertenecen a este hostgroup. Este atributo es opcional.

  contactos:
    - contact_name: nombre del contacto.
    - alias: un alias para el mismo.
    - service_notification_period: indica en qué horarios se puede contactar en caso de caída de servicios.
    - host_notification_period: indica en qué horarios se puede contactar en caso de caída del host.
    - service_notification_options: listado de estados de servicio que deben reportarse. Los estados se definen con letras y se separan con comas: u (UNKNOWN), c (CRITICAL), r (RECOVERY - OK), f (FLAPPING), y n (NONE).
    - host_notification_options: listado de estados de host que deben reportarse. También se definen con letras separadas por coma: d (DOWN), u (UNREACHABLE), r (RECOVERY - UP), f (FLAPPING), s (comienza el downtime programado), n (NONE).
    - service_notification_commands: cómo notificar al contacto en caso de servicio caído (email, sms, etc).
    host_notification_commands: cómo notificar al contacto en caso de host caído (email, sms, etc).
    - email: dirección de email del contacto.
    - contactgroups: grupo al que pertenece el contacto.

 
Agentes Nagios

Una gran parte del monitoreo se puede hacer remotamente. Todo servicio publicado en la red, se puede monitorear sin necesidad de instalar nada en el host monitoreado. Sin embargo hay recursos que no se pueden monitorear remotamente, como por ejemplo:
- espacio libre en disco
- memoria en uso
- carga de CPU
- servicios activos
- cantidad de usuarios logueados
Para ello es necesario instalar agentes. Estos agentes, mediante plugins, chequean el estado de los recursos y envían los datos al servidor Nagios. El tipo de conexión es pull, es decir, el servidor Nagios contacta cada cierto intervalo de tiempo a los agentes, les indica qué comandos ejecutar y obtiene los resultados.
Existen varios protocolos utilizados para la comunicación entre agentes y Nagios:
- NRPE - Nagios Remote plugin Executor. Es el protocolo más utilizado y recomendado por Nagios. Se accede mediante el plugin check_nrpe.
- NSCA - Nagios Service Check Acceptor.
- NSCP: protocolo nativo de NSClient++
- NRDP: reemplazo NSCA.
- Syslog: protocolo estándar para transmisión de logs en Unix.
- SNMP: Simple Network Management Protocol. Protocolo estándar para administración y monitoreo de dispositivos de red.

En este artículo se utilizará el protocolo NRPE, para lo cual se instalarán agentes en Linux y Windows que lo soporten.


Instalación del servidor

Instalar el servidor de Nagios es muy simple, está en los repositorios de la mayoría de las distribuciones.
Por ejemplo, en debian, basta con ejecutar:
  # apt-get install nagios3 nagios-nrpe-plugin

La instalación en debian solicita que se introduzca una clave de administración web (usuario nagiosadmin). Pueden elegir no ingresar clave, e ingresarla después. Lo más cómodo es asignarla en esta instancia, aunque queda a elección. La autenticación de la interfaz web la realiza Apache, así que agregar o quitar usuarios se puede realizar con la utilidad htpasswd. También instalamos aquí los plugins para comunicarnos con los agentes mediante NRPE (ver más adelante).

El servicio de Nagios se ejecutará, por defecto, a nombre del usuario nagios y grupo nagios. Esto es para limitar los privilegios, dado que el sistema no necesita permisos de root para ejecutarse, y sería muy riesgoso.


Si utilizan debian, otros datos interesantes acerca de la instalación son:
  - Los plugins default de Nagios (paquete nagios-plugins) se instalan en /usr/lib/nagios/plugins
  - Los comandos (ver más adelante que son) default están definidos en /etc/nagios-plugins/config
  - Por defecto, nagios carga toda la configuración incluida en /etc/nagios3/conf.d, así que lo más conveniente es incluir los archivos con las definiciones de hosts, servicios, comandos, etc, allí.
  - El archivo de configuración de apache para la interfaz web de Nagios se encuentra en /etc/apache2/conf.d/nagios3.conf
  - Por defecto la interfaz web se accede mediante la URL http:///nagios3. Este alias se puede cambiar en el archivo citado en el punto anterior.
  - El archivo de autenticación para la interfaz se encuentra en /etc/nagios3/htpasswd.users


Arquitectura de ejemplo

Para poder explicar la configuración de Nagios de forma más didáctica, utilizaremos la siguiente arquitectura de red como ejemplo:
En esta simple estructura traté de cubrir los casos más frecuentes, al menos cubre todos los casos con los que me he topado. La red cuenta con:
  - un servidor Nagios que monitoreará todo (192.168.0.100).
  - un servidor Linux (linuxagent - 192.168.0.3) con el agente de Nagios instalado, que posee un servicio Web (puerto 80).
  - un servidor Windows (winagent - 192.168.0.4) con el agente de Nagios instalado, que presta servicio de fileserver (CIFS puerto 445), y Web service en el puerto 81. En este servidor chequearemos que el servicio de Firewall de Windows esté iniciado (MpsSvc).
  - un servidor al cual no se le instaló agente (noagent - 192.168.0.20), pero que presta un servicio no estándar en el puerto 4444.
  - un servidor web colocado en internet (itfreekzone - 10.0.0.10, claro está que la IP no es una IP de internet válida, sólo se usa de ejemplo).
Los hosts de la red interna son alcanzables mediante ping, mientras que el servidor Web de internet no.

Si tienen algún caso que no entre en alguna de estos posibles, dejen su comentario y trato de añadirlo :)


Servidor Linux con agente

Arranquemos con la configuración del monitoreo de un servidor linux para el cual utilizamos un agente. Como se indicó anteriormente, NRPE es el protocolo elegido para la ejecución remota de comandos, así que el agente a instalar debe soportarlo. En debian existe un paquete denominado nagios-nrpe-server.

En el servidor Linux, instalaremos entonces los siguientes paquetes (buscar equivalentes en distribuciones no debian):
  # apt-get --no-install-recommends install nagios-nrpe-server nagios-plugins-basic
El paquete nagios-plugins-basic provee el set básico de plugins para los chequeos.

La configuración del agente NRPE se realiza desde el archivo /etc/nagios/nrpe.cfg. Las variables a tener en cuenta en este archivo son:
server_port=5666 #define en qué puerto (TCP) escuchará el agente. Por defecto es el 5666, pero se puede setear cualquiera.

server_address=192.168.0.3 # indica en qué dirección IP escuchará el agente, en caso que el servidor posea más de una IP.

allowed_hosts=192.168.0.100 # define qué IPs tienen permitido conectarse al agente en busca de datos. Es un parámetro de seguridad mínimo para limitar desde qué máquinas se conectan al agente.

dont_blame_nrpe=0 # mi variable favorita (por su nombre, claro). Esta variable indica si se permite que el agente reciba comandos con parámetros (por ejemplo, en la ejecución "check_disk -w 20%" el parámetro es "-w 20%"). Es muy mala idea permitir que hosts remotos envíen al agente parámetros, dado que podrían utilizarse para explotar alguna vulnerabilidad (qué pasa si se recibe "check_disk -w <muchos bytes...="">" ???). Por ello, se recomienda crear alias de comandos, como por ejemplo "command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -x sda", donde el servidor sólo necesitará llamar "check_disk" (sin parámetros) para obtener los datos de espacio libre y alertas.

command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10 # alias check_user para obtener la cantidad de usuarios logueados y alertar si hay más de 5 logueados al mismo tiempo.
command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20 #alias check_load para obtener la carga de CPU
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -x sda #alias check_disk para obtener el espacio disponible en el disco /dev/sda y alertar si queda menos de 20% de espacio en alguna partición.
Como se ve, los alias son muy importantes, y se pueden agregar tantos como se desee. Estos definen un acceso a información con parámetros predefinidos, de modo que el servidor sólo debe llamar el comando sin parámetros, y disminuir el riesgo (el atributo lo dice, no le eches la culpa a NRPE si se te rompe todo por usar parámetros - dont_blame_nrpe). Sólo listé tres (check_disk, check_load, y check_users) pero podría haber creado todos los que quisiera.

Una vez configurado el agente, reiniciarlo para que tome los cambios:
  # /etc/init.d/nagios-nrpe-server restart


Servidor Windows con Agente

Para monitorear recursos en Windows, existe el demonio NSClient++ (http://www.nsclient.org). El demonio soporta todos los protocolos mencionados anteriormente, pero como comenté, utilizaremos NRPE.
La instalación es muy simple, bajan la última versión del instalador y la ejecutan. Pueden elegir la instalación típica y dar todo next, sin chequear nada, dado que luego reemplazaremos el archivo nsclient.ini con la información que les dejo a continuación. Si desean utilizar las opciones del instalador, verán que permite habilitar algunas cosas, como si utilizar NSCP (check_nt) y/o NRPE (check_nrpe), un password de acceso para el caso de check_nt (el cual no utilizaremos), los hosts que tienen permitido acceder a la información (allowed_hosts), checks WMI, y los check plugins.

Toda la configuración se guarda en el archivo C:\Program Files\NSClient++\nsclient.ini (o C:\Archivos de Programas\NSClient++\nsclient.ini). Si no tildaron nada durante la instalación, verán que está vacío, a excepción de unos comentarios.
NSClient no utiliza el mismo formato de configuración que el visto en el host Linux, es más, varía bastante. Para empezar, la configuración se divide en secciones (formato estándar de los .ini). Por otra parte, los plugins se deben habilitar antes de ser utilizados. Además los plugins se llaman con ejecutables diferentes (CheckCpu. CheckDriveSize, etc), y los alias se definen de otra manera. Para estandarizar, en la configuración utilicé los mismos alias que en el host Linux, así es posible realizar grupos de hosts que incluyan tanto servidores Linux como Windows, y ejecutar los mismos comandos en ambos.
La configuración que utilizaremos será la siguiente:
[/modules]
; habilitamos el uso de NRPE
NRPEServer = 1

; habilitamos plugins a utilizar. Como se ve, los plugins se agrupan por tipo.
CheckSystem=1
CheckDisk=1
CheckExternalScripts=1

; creamos los mismos alias que en la definición del host Linux, y agregamos un alias para chequear servicios
[/settings/external scripts/alias]
check_load=CheckCpu MaxWarn=80 time=5m ; alias para chequear la carga de CPU. Si sobrepasa el 80% en un intervalo de 5 minutos, nos alertará.
check_disk=CheckDriveSize ShowAll MinWarnFree=10% MinCritFree=5% ; alias para chequear el espacio en todos los discos del servidor
check_firewall_service=CheckServiceState MpsSvc; alias para chequear el servicio del firewall de Windows (llamado MpsSvc).

[/settings/default]
; permitimos el acceso al servidor Nagios para las consultas.
allowed hosts = 192.168.0.100

Configuración de los checks en el servidor Nagios

Bien, con los agentes instalados y configurados, volvemos al servidor Nagios. Utilizamos el directorio /etc/nagios3/conf.d para poner nuestra configuración, tal vez adentro de un directorio nuevo, para que quede más ordenado y no se mezcle con el resto.

Observando el directorio conf.d encontramos varias definiciones, como las citadas generic-host y generic-service. También se agrega por defecto la definición de los servicios a chequear en localhost, algo que nos puede servir como ejemplo. En /etc/nagios-plugins/config encontramos la definición de varios comandos, que nos servirán para la mayoría de los casos, aunque habrá algunos que tendremos que definir nosotros.

Para comenzar, definimos un comando nuevo que utilice check_http, pero que nos permita chequear servicios Web en cualquier puerto. En /etc/nagios-plugins/config/http.cfg existen varios comandos predefinidos para llamar a check_http, pero no encontré ninguno que permita hacer un simple check a un puerto diferente al 80. Si quieren ser prolijos, podríamos incluir los comandos en un archivo commands.cfg dentro de nuestro directorio de configuración.
El comando se define de la siguiente manera:
define command {
  command_name check_http_port
  command_line /usr/lib/nagios/plugins/check_http -I $HOSTADDRESS$ -p $ARG1$
}
Cuando se llame el comando, deberá entregarse un puerto como argumento y realizará el chequeo HTTP.

A continuación me parece bien definir un grupo de hosts para agrupar los hosts que tienen instalado el agente, lo denominaremos remote-agent.
define hostgroup {
  hostgroup_name remote-agent
  alias Hosts que tienen el agente de Nagios instalado
}
De esta forma, podemos definir servicios que se chequeen en todos los host que tengan el agente instalado, tan solo agregando los hosts al grupo remote-agent y asignando los servicios al mismo.
Para los checks remotos, debemos utilizar el comando check_nrpe_1arg (/etc/nagios-plugins/config/check_nrpe.cfg), al cual se le entrega como parámetro el nombre del comando a ejecutar en el host remoto. El “1arg” indica que se le entrega un parámetro (el nombre del comando a ejecutar). Los comandos que llamaremos son los alias que definimos en cada host anteriormente.
En los hosts con el agente realizaremos checks de CPU y disco:
#checkear CPU
  define service {
    use generic-service # hereda los atributos de generic-service
    hostgroup_name remote-agent # indicamos que se aplica al hostgroup remote-agent
    service_description Load average # describimos lo que se testea
    check_command check_nrpe_1arg!check_load #llamamos a check_nrpe_1arg y le indicamos que debe ejecutar check_load
  }

  #checkear discos
  define service{
    use                             generic-service # heredamos
    hostgroup_name                  remote-agent # aplicamos al grupo remote-agent
    service_description             Disk Space # describimos lo que testeamos
    check_command                   check_nrpe_1arg!check_disk # indicamos que debe ejecutarse el alias check_disk
  }
Ya tenemos los checks genéricos que haremos en los hosts con agentes.
Dado que el resto de los servicios los chequearemos por host, pasemos a la definición de los hosts.
# host linux con agente
define host {
  use generic-host
  host_name linuxagent
  alias Web Server Linux con agente instalado
  address 192.168.0.3
  hostgroups remote-agent,http-servers
}
Acá aparece el grupo predefinido http-servers. El mismo se encuentra definido en /etc/nagios3/conf.d/hostgroups_nagios2.cfg y nos permite chequear Web servers que escuchen en el puerto 80.
# host windows con agente
define host {
  use generic-host
  host_name winagent
  alias Windows Server, File Server y Web service
  address 192.168.0.4
  hostgroups remote-agent
}

# host sin agente
define host {
  use generic-host
  host_name noagent
  alias Servidor sin agente
  address 192.168.0.20
}

# host en internet
define host {
  use generic-host
  host_name itfreekzone
  alias Web server en internet
  address 10.0.0.10
  hostgroups http-servers
  check_command check_http
  check_interval 5
}
Nótese que en el servidor itfreekzone agregué el atributo check_command. Dado que el firewall no nos permite realizar pings a internet, es necesario encontrar una alternativa para detectar que el host está online, por ello utilicé check_http. También definí un nuevo intervalo de chequeos (por defecto era 1), para incrementar la distancia entre sucesivos checks y así no estar enviando requests continuamente a Internet.

La definición anterior ya nos alcanza para los chequeos en linuxagent e itfreekzone, pero todavía nos queda trabajo por hacer para monitorear al resto. Pasemos a definir los servicios que nos faltan.

Como comenté anteriormente, en winagent deseamos chequear que el servicio MpsSvc está levantado. Agregamos entonces la siguiente definición:
define service {
  use generic-service
  service_description Check Firewall Windows
  check_command check_nrpe_1arg!check_firewall_service
  host_name winagent
}
En la definición se ve que el servicio se aplica solamente al host winagent, y se llama el alias predefinido check_firewall_service.
Ahora, en el host windows, resta chequear CIFS y el Web Service:
define service {
  use generic-service
  service_description Check Web service en puerto 81
  check_command check_http_port!81
  host_name winagent
}

define service {
  use generic-service
  service_description Check CIFS
  check_command check_tcp!445
  host_name winagent
}
Como se observa, para chequear el web service utilizamos el comando que definimos anteriormente (check_http_port), mientras que para chequear CIFS, simplemente realizamos una conexión TCP al puerto 445. Existen plugins específicos para un chequeo más a fondo del servicio CIFS, pero para nuestro ejemplo alcanza.

Qué resta? chequear el serivicio NN en el host noagent. En este caso también utilizaremos check_tcp, nada mágico:
define service {
  use generic-service
  service_description Check Servicio NN
  check_command check_tcp!4444
  host_name noagent
}
Ok, tenemos los hosts y los servicios a chequear. Ahora, a quién y cómo enviamos las alertas?
Por defecto las alertas se envían al grupo admins (ver /etc/nagios3/conf.d/generic-host_nagios2.cfg), el cual las envía por mail al contacto root@localhost (ver /etc/nagios3/conf.d/contacts_nagios2.cfg). Definamos un nuevo contacto que pertenezca al grupo admins, pero al cual se le envíen solamente estados críticos y recoveries:
define contact {
  contact_name demasiadovivo # mi nombre
  alias d3m4s1@d0v1v0 # mi alias
  service_notification_period 24x7 # indico que ante caída de servicios me notifique en cualquier momento de la semana
  host_notification_period 24x7 # indico que ante caída del host me notifique en cualquier momento de la semana
  service_notification_options c,r # solo notificarme servicios en estados críticos (c) y recoveries (r)
  host_notification_options d,r # solo notificarme host caído (d) y recoveries (r)
  service_notification_commands notify-service-by-email # notificarme cambios en los servicios por mail
  host_notification_commands notify-host-by-email # notificarme cambios en el host por mail
  email demasiadovivo@itfreekzone.com # mi dirección de mail
  contactgroups admins # me agrego al grupo de contacto admins.
}
Con esto terminamos la definición. Un restart del servicio Nagios para que tome la nueva configuración y ya estamos:
  # /etc/init.d/nagios3 restart

En caso que algo haya quedado mal definido, Nagios lo indicará con un error y el servicio no iniciará.

Fue difícil? bueno, hasta que aprendemos la terminología, la estructura de objetos y la forma de definir todo, puede que si. Luego es tan simple como agregar definiciones. Por suerte es bastante intuitivo =)


Referencias

- Nagios Core Documentation
- about NSClient++
- Using NSClient++ from nagios with check_nrpe
- Installing Nagios On Debian Lenny And Monitoring A Debian Lenny Server
OSSIM: alertas arpwatch por mail que incluyan MAC origen y destino
Desde hace varias semanas vengo peleando con OSSIM y el plugin que utiliza para parsear logs de arpwatch. En el artículo anterior les conté cómo modifiqué el código de arpwatch para que reporte sólo el cambio de MAC de hosts específicos, y no todos los cambios de MACs. Ahora mi meta era hacer que OSSIM me envíe un mail cada vez que detecte el cambio de MAC de estos hosts.

El envío de este tipo de alertas por mail es muy simple y lo describiré luego. Primero veamos qué información brinda el plugin de arpwatch y entenderán por qué tuve que crear un nuevo plugin.

El plugin original (/etc/ossim/agent/plugins/arpwatch.cfg o /etc/ossim/agent/plugins/arpwatch_eth0.cfg) utiliza el tipo de evento host-mac-event, un tipo de evento que posee un conjunto fijo de atributos y no se pueden agregar, ni quitar, ni modificar, a menos que modifiquemos el código C del servidor OSSIM. Los atributos que brinda este tipo de evento, según la documentación oficial, son:
    host: IP del host que cambio su MAC
    mac: nueva dirección MAC en hexadecmal
    vendor: fabricante de la placa
    sensor
    interface
    date
    plugin_id: el ID del plugin, el cual es siemrpe 1512 (arpwatch)
    plugin_sid: sin importancia ya que el servidor OSSIM asignará el que corresponda
    log: contiene una copia del cambio de MAC
    userdata1: copia de la nueva dirección MAC nueva
    userdata2: copia del nombre fabricante
Si prestan atención, pueden ver que la MAC anterior sólo figura en el atributo log. Cuál es el problema? que el atributo log no se puede utilizar en las acciones (y presupongo que tampoco en las correlaciones, pero no puedo asegurarlo).
Entonces, si no se puede utilizar en las acciones, no es posible enviar mails que incluyan la MAC de origen en ellos, algo que, al menos para mi, es de mucha utilidad.
Supongan que arman una política que les envíe una alerta por mail cada vez que un host importante cambia su MAC. Con el plugin original sólo tendrían la nueva MAC y deberían ir a revisar la larga lista de eventos SIEM para encontrar cual era la MAC anterior y ver la diferencia.


Nuevo plugin para arpwatch

En fin. Para arreglar esto, definí un nuevo plugin para arpwatch, denominado arpwatch_new.cfg (oh si, muy original):
[DEFAULT]
plugin_id=51512

[arpwatch-changed-address]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$4}
mac={$2}
userdata1={$2}
userdata3={$3}
plugin_sid=2
regexp="arpwatch.*?: changed ethernet address (\IPV4) (\MAC) \((\MAC)\) (\S+)"
vendor=unknown

[arpwatch-flipflop]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$4}
mac={$2}
userdata1={$2}
userdata3={$3}
plugin_sid=2
regexp="arpwatch.*?: flip flop (\IPV4) (\MAC) \((\MAC)\) (\S+)"
vendor=unknown

[arpwatch-new-station]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$3}
mac={$2}
plugin_sid=1
regexp="arpwatch.*?: new station (\IPV4) (\MAC) (\S+)"
vendor=unknown

[arpwatch-reused-address]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$4}
mac={$2}
userdata1={$2}
userdata3={$3}
plugin_sid=2
regexp="arpwatch.*?: reused old ethernet address (\IPV4) (\MAC) \((\MAC)\) (\S+)"
vendor=unknown

[config]
create_file=true
enable=yes
interface=eth0
location=/var/log/ossim/arpwatch-new.log
process=/usr/sbin/arpwatch_eth0
restart=no
restart_interval=\_CFG(watchdog,restart_interval)
shutdown=killall %(process)s
source=log
start=yes
startup=%(process)s -d -d -i %(interface)s -f /var/lib/arpwatch/arp-eth0.dat -N >> %(location)s 2>&1 &
stop=yes
type=detector
Como verán, cambié el identificador a 51512 para no colisionar con el anterior (1512) y utilicé el tipo de evento genérico "event", que permite flexibilidad en los atributos a utilizar. Gracias a esto, ahora puedo ver la MAC origen en el atributo userdata3, mientras que la nueva MAC está en userdata1, como antes.
Para habilitar este nuevo plugin, hay que ingresarlo en las tablas plugin y plugin_sid de la base de datos OSSIM. Esto se hace a través del siguiente archivo sql (arpwatch_new.sql):
-- uncomment the following lines to delete old arpwatch plugin
-- DELETE FROM plugin WHERE id = "1512";
-- DELETE FROM plugin_sid WHERE plugin_id="1512";
-- delete old entries of this plugin
DELETE FROM plugin WHERE id = "51512";
DELETE FROM plugin_sid WHERE plugin_id = "51512";

INSERT INTO plugin (id, type, name, description) VALUES (51512, 1, 'arpwatch_new', 'Ethernet/FDDI station monitor daemon');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 1, NULL, NULL, 'arpwatch_new: Mac address New');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 2, NULL, NULL, 'arpwatch_new: Mac address Change');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 3, NULL, NULL, 'arpwatch_new: Mac address Deleted');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 4, NULL, NULL, 'arpwatch_new: Mac address Same');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 5, NULL, NULL, 'arpwatch_new: Mac address Event unknown');
Inluir esto en la base de datos es tan simple como ejectutar:
  cat arpwatch_new.sql | mysql -u root -p ossim

Luego deben modificar la configuración del agente OSSIM para que incluya este plugin, es decir, comentar la línea del plugin de arpwatch anterior y agregar el nuevo en el archivo /etc/ossim/agent/config.cfg, en la sección plugins:
  #arpwatch_eth0=/etc/ossim/agent/plugins/arpwatch_eth0.cfg
  arpwatch_new=/etc/ossim/agent/plugins/arpwatch_new.cfg

Finalmente reinicien los servicios de ossim server y agent:
  /etc/init.d/ossim-server restart
  /etc/init.d/ossim-agent restart
y verifiquen que se encuentre cargado en la  pestaña Collections de la interfaz web.


Reporte de cambios por mail

Con el nuevo plugin ya es posible crear una política que ejecute una acción que envíe mails. Las políticas y las acciones se pueden crear fácilmente desde la interfaz web. Para hacerlo, hay que dirigirse a la opción Intelligence -> Policy & Actions.

Primero crearemos la acción que ejecutará el envío de mail, para luego poder seleccionarla en la política. La acción se crea desde la pestaña Actions y dando al botón New. Una acción puede ser la creación de un ticket, o, como deseamos nosotros, el envío de un mail. Este tipo se elige en el desplegable Type. Es obligatorio colocar una descripción de la acción.
El resto de los campos son muy intuitivos, el originario del mail, el destinatario, el asunto y el mensaje. Se pueden utilizar palabras claves especiales tanto en el contenido como en el asunto del mail, las cuales OSSIM reemplazará por el valor correspondiente. En la parte superior de la acción estan los atributos elegibles, entre los que se cuenta con las IPs de orígen y destino, puertos, protocolos y varios campos más. Para el caso en cuestión, lo importante es que el reporte contenga la IP del host y las MACs anterior y nueva, las cuales se encuentran en los atributos userdata1 y userdata3, según lo definimos en el plugin.

La política se crea de forma bastante intuitiva, en la pestaña Policy, dando New y siguiendo los pasos. Los primeros pasos describen atributos que deben tener los paquetes para que esta política se aplique, como IPs orígen y destino, y Ports destino.
Uno de los pasos relevantes es la definición del "DS Groups", donde se elige el grupo de plugins a tener en cuenta a la hora de analizar los paquetes. OSSIM trae algunos grupos de plugins ya armados, pero para nuestro caso, hay que insertar uno nuevo, dandole al link "Insert new DS Group?". En este punto hay que ingresar un nombre y una descripción, acompañado por el plugin a utilizar, que se selecciona dando en el +

En el listado debería aparecer el nuevo plugin que creamos anteriormente con ID 51512. Una vez seleccionado es posible elegir que tipos de evento, del mencionado plugin, deben tenerse en cuenta. Es así como podemos reportar sólo eventos de cambio de MAC y no cuando se ve un host nuevo. El tipo de evento que nos interesa es el que tiene el identificador 2.
Cuando el grupo DS ya está ingresado, es posible seleccionarlo y continuar con la definición de la política.
El otro paso relevante es la elección de las consecuencias que tiene la política. Es decir, qué acción tomar cuando detectamos un evento que cumple con las características descriptas en la política. Para este caso, elegiremos la acción que creamos anteriormente, y además podríamos elevar la prioridad del evento a 5.


En fin

Con estos cambios ya es posible recibir por mail reportes de cambios de MACs en hosts importantes, que incluyan la MAC anterior y la nueva, gracias a la nueva definición del plugin y la política creada.


Referencias

- OSSIM Sensor - The Agent
- Creating a Custom OSSIM 3 policy
Arpwatch con seguimiento de hosts específicos
Desde que instalé arpwatch en la red de la empresa donde trabajo, me encontré con una necesidad imperiosa. Nuestra red otorga las IPs de las workstations por DHCP, pero en la misma red existen host importantes que tienen IPs fijas.
Arpwatch no se desempeña demasiado bien en redes con DHCP, dado que con este esquema las IPs de las máquinas suelen cambiar cada tanto, generando reportes sin utilidad para quien revisa los logs de seguridad. Entre tantos reportes sin utilidad pueden quedar escondidos reportes que si nos interesan, como por ejemplo ver que la IP de un proxy, gateway, server, cambió su MAC, algo que es en extremo sospechoso y muy importante para detectar intrusos.
De esta manera tenemos una herramienta muy simple y poderosa, pero que al generar tantos reportes molestos, resulta poco útil en este tipo de redes.

Para obtener lo mejor de esta herramienta contaba con dos opciones:
  1) desarrollar un script que parsee los logs buscando sólo las IPs que me interesan,
  2) agregar al código de arpwatch la funcionalidad necesaria para poder filtrar ciertas IPs.

La primera era más rápida y simple, pero la segunda mucho más interesante. Por fin esta semana conté con tiempo libre, así que puse manos a la obra y actualicé el código de arpwatch para que incluya esta funcionalidad. Esta es una de las grandes ventajas de utilizar software libre, si necesitas más funcionalidad, podes agregarla vos mismo!

Por lo que encontré, arpwatch no se actualiza desde 2006, pero hay parches como el de debian, que agregaron cierta funcionalidad. Como ya sabrán, utilizo debian para todo y es la base de una gran porción de distribuciones, así que decidí partir del paquete de debian. Este paquete incluye opciones como ignorar una red entera, o enviar reportes por mail, y pueden verlas marcadas con el prefijo "(Debian)" en la man page.

Yendo al grano, qué provee el código que desarrolle?
  - la posibilidad de reportar cambios de MAC sólo de IPs específicas
  - una nueva opción en la línea de comandos (-H <filename>) para activar esta funcionalidad e indicar el archivo donde se encuentran los hosts a seguir
  - configuración simple del archivo de hosts a seguir:
    - se puede especificar un host según su IP (ej: 192.168.0.2), hostname (mihost.mired.com), o red entera (192.168.0.0/24),
    - es posible dejar líneas en blanco para separar grupos de host visualmente
    - permite la adición de comentarios utilizando el símbolo # al comienzo de cada línea.
  - man page actualizada explicando la nueva funcionalidad.

Si por ejemplo quisiéramos seguir sólo los hosts 192.168.0.2, www.miempresa.com, y la red 192.168.10.0/24, el archivo de hosts (denominado hosts.dat) podría ser:
  #ip interna
  192.168.0.2

  #web de la empresa
  www.miempresa.com

  #red de compras
  192.168.10.0/24

Luego bastaría con ejecutar arpwatch de la siguiente manera:
  # arpwatch -H hosts.dat

La instalación de esta nueva versión debe hacerse de la siguiente manera:
  1) descargar el código de arpwatch original
  2) descargar el parche de debian
  3) descargar mi parche
  4) desomprimir el código original y los parches:
      $ tar -xzvf arpwatch_2.1a15.orig.tar.gz
      $ tar -xzvf arpwatch_2.1a15-1.1.diff.gz
      $ tar -xzvf arpwatch-2.1a15-2-diff.diff.gz
  5) parchar el código original con el parche de debian, parados en el directorio del código original:
      $ cd arpwatch_2.1a15
      $ patch < ../arpwatch_2.1a15-1.1.diff
  6) parchar lo anterior con la extensión que programé:
      $ patch < ../arpwatch-2.1a15-2-diff.diff
  7) compilar:
      $ ./configure
      $ make
  8) instalar:
      $ make install

Algo a tener en cuenta es que deberán tener las fuentes de pcap para poder compilar arpwatch. En debian el paquete se denomina libpcap-dev.

Si tienen alguna duda o encuentran algún fallo en el programa, por favor reportenmelo. Contacté al maintainer del paquete en debian y espero le interese incorporar este parche para ampliar la funcionalidad de esta excelente herramienta.
Espero les resulte tan útil como a mi!

Que tengan un feliz año nuevo y arranquen el 2012 con todo. Recuerden que, según los mayas, será el último =P
Localizar físicamente dispositivos conectados a la red a partir de su IP o MAC
En redes de gran tamaño y con movimiento constante de dispositivos, es complejo saber en qué lugar está conectado cada uno en cada momento. En ocasiones es necesario conocer la ubicación debido a que el dispositivo presenta alguna falla, o bien se está utilizando para realizar tareas indebidas en la red.
Como monitoreador de la red, podemos detectar una IP atacante, y si sabemos dónde está conectada esa máquina, podemos ir a ver quién es.

Por ello creé un procedimiento que permite ubicar dónde está conectado un dispositivo a partir de su dirección IP o MAC. Para lograrlo, debemos tener la red debidamente documentada. Es decir, necesitamos saber cómo es la conexión entre switches y routers (uplinks), y la ubicación física de estos dispositivos.
Si bien el procedimiento está pensado en redes con equipamiento Cisco, debe existir el comando equivalente en otros equipos de red.

Entonces, las herramientas necesarias son:
- Switches con IOS que soporte el comando “show mac-address-table address <dirección>” (o similar).
- Documentación de las conexiones entre switches y routers (i.e. uplinks).
- Documentación de la dirección IP de cada switch/router.
- Documentación de la ubicación física de cada switch/router.
- Documentación de las bocas de red patcheadas a cada switch.
Si se posee la IP, primero es necesario conocer la dirección MAC de la placa de red del dispositivo. Suponiendo que la IP es 192.168.1.10, la MAC se puede obtener haciendo un ping y luego viendo la cache arp con el comando arp (tanto en Windows como en Linux es igual):
$ ping 192.168.1.10
$ arp -a
Con esto se obtiene la dirección MAC asociada, por ejemplo: 00:11:22:33:44:55.
sugerencia: en GNU/Linux se puede utilizar el comando $ arping <IP>
Una vez obtenida la dirección MAC, el procedimiento es el siguiente:
1. Conectarse (ssh o telnet, dependiendo que tipo de conexión acepte) a alguno de los switches de la red. Si se sospecha en que switch puede estar conectado el dispositivo, comenzar con el mismo para ahorrar tiempo de búsqueda. Igualmente el mecanismo funciona aunque se comience desde cualquier otro switch.

2. Ejecutar el comando:
switch #show mac-address-table address 0011.2233.4455
para obtener en que port del switch se encuentra el dispositivo.

3. Utilizar el documento de uplinks para reconocer si el port es un uplink o una conexión directa a una máquina. Si el port no es un uplink ya obtuvimos el switch y port que buscábamos, ir a 5. Sino, ir a 4.

4. Si el port es un uplink, a partir del documento de uplinks y de IPs, obtener la dirección IP del switch al que está conectado. Conectarse a dicho switch y repetir desde el paso 2.

5. Mirar el documento con el mapeo de links -> localización física para saber dónde se encuentra el switch.

6. Ver a que boca de red se encuentra patcheado el port del switch.

7. A partir de la documentación de las bocas de red, obtener en qué lugar del edificio se encuentra el puesto conectado al port del switch.
De esta forma podemos encontrar rápidamente el dispositivo que buscamos. Imaginen que esto en redes con muchos puestos, muchos switches y routers, poder determinar donde se encuentra un dispositivo a partir de una IP es extremadamente útil.
Instalación y configuración de OSSIM (alias "The Perfect Setup")
Después de hacer una introducción a esta interesante herramienta de monitoreo, y ya teniendo en mente los programas que utiliza y qué función desempeña cada uno, podemos comenzar a instalar y configurar el sistema. Para el que se perdió las entregas anteriores, pueden leer el completo review que hice de OSSIM en los siguientes links: Parte I, Parte II, y Parte III.
Si bien la instalación es tan simple como la de cualquier otra distribución, la configuración no lo es tanto. Todo va a depender de la red que estamos monitoreando y de las funciones que deseamos utilizar.
En este artículo voy a plantear la configuración que realicé en el sistema de mi empresa, pero puede que no se adapte a toda red. La realidad es que no existe una receta mágica, y uno se va dando cuenta de lo que necesita alertar y lo que desea obviar una vez que tiene el sistema sniffeando.
Lo que planteo a continuación es una lista de pasos de configuración que realicé, a partir de la observación y la lectura de muchos manuales/artículos/tutoriales. Hace más de dos meses que utilizo OSSIM y todavía queda mucho por aprender. La idea es tener un sistema seguro, que alerte sólo lo que necesitamos.

El artículo inicial lo escribí hace más de un mes, pero como era extremadamente extenso y muchos temas se podían tratar por separado, decidí partirlo en varios artículos genéricos, como el uso de NTP, la activación de HTTPS, la configuración de Snort, las modificaciones a Oinkmaster y las actualizaciones automáticas. En este artículo haré referencia a ellos en el caso que la explicación lo requiera.


Configurar switch para monitorear

Para poder monitorear, primero tenemos que ser capaces de recibir el tráfico que nos interesa. En redes switcheadas, si todo va bien, sólo veremos el tráfico dirigido a la máquina conectada, y el tráfico broadcast. Esto por supuesto no nos sirve si queremos monitorear varios servidores o la red completa.
Por suerte los switchs vienen preparados para realizar monitoreo. No se de otras marcas, pero los Cisco ofrecen dirigir el tráfico de otros ports a un dado port. Es decir, es posible enviar al port donde está conectada nuestra máquina monitor todo el tráfico de otros ports.

Los comandos a ejecutar para realizar esta tarea son muy simples. Debemos definir una sesión de monitoreo, y asignar los ports fuentes y el port destino (nuestra máquina monitor).
Suponiendo que tenemos nuestra máquina monitor en el port GigabitEthernet 0/1, y que deseamos monitorear los ports Gi0/4, Gi0/5 y Fa1/7, los comandos a ejecutar serían:
switch(config)# monitor session 1 destination interface G0/1
switch(config)# monitor session 1 source interface Gi0/4, Gi0/5
switch(config)# monitor session 1 source interface Fa1/7
Listo, ya podemos monitorear =)


Instalando OSSIM

OK, el paso más simple será descargar e instalar OSSIM en la máquina destinada a monitoreo.
La descarga la pueden realizar en la sección download de la página de alienvault. La primer decisión que deberán tomar es si instalar la versión de 32 o la de 64 bits. Mi recomendación es que si tienen un procesador de 64bits, instalen la versión de 64bits. Esta versión aprovechará mejor los recursos, y a pesar de la creencia general, las distribuciones de 64bits no ocasionan problemas. Yo utilizo debian de 64bits hace más de 3 años, y no he tenido ningún inconveniente.

El requerimiento de hardware dependerá de la cantidad de hosts a monitorear, y las herramientas de monitoreo que activen. La gente de alienvault recomienda tener una máquina con un mínimo de 2GB de RAM, y por supuesto, una placa de red de 1 Gbit. No hacen ninguna referencia al procesador o al disco, pero por mi experiencia recomendaría como mínimo un Core 2 Duo o un Athlon X2 de 2GHz, y 500GB de disco (realmente se generan muuuuchos logs). Si bien con 2GB de RAM, y desactivando algunos monitoreos, el sistema puede sobrevivir, les recomiendo que se gasten en tener 4GB, así utilizan menos swap y aceleran el sistema.

Los pasos de la instalación son tan simples como el de cualquier distribución basada en debian. Igualmente pueden encontrar una guía en la misma página de OSSIM.


Pasos iniciales

Una vez terminada la instalación, se encuentran con que el sistema inicia en modo consola. Si bien pueden instalar algún entorno gráfico, no creo que valga la pena, simplemente sobrecargarán al ya sobrecargado sistema (a menos que tengan un server con recursos de sobra). Además el sistema funciona completamente por Web, solamente la configuración inicial requerirá que utilicen la consola.

Como bien dije, las herramientas más importantes se visualizan por Web. Por un lado tienen el OSSIM, y por otro Ntop. Si bien Ntop está (al igual que el resto de las herramientas), embebido en las secciones del OSSIM, pueden accederlo directamente a través del port 3000. Ntop no corre sobre apache, sino que ejecuta su propio servidor Web. Les recomiendo que utilicen esta interfaz porque Ntop trae muchísima información que no es desplegada dentro de OSSIM.

Para el resto de la configuración no necesitan estar sentados frente a la máquina monitor, sino que pueden accederlo remotamente a través de SSH, el cual ya viene instalado y funcionando. Claro está que les recomiendo tener siempre un teclado y monitor a mano, porque cuando configuremos el firewall, puede que perdamos la conexión remota =P


Configurar el firewall

OSSIM por defecto trae una configuración de iptables que nos permite acceder a los servicios más importantes (SSL, HTTP y HTTPS), pero obviamente al no conocer de antemano las IPs que tienen permitido el acceso, utiliza una política permisiva que debemos cambiar.
El script que inicia/detiene/reinicia el firewall es /etc/init.d/ossim-firewall. En este script encontrarán que OSSIM realiza un restore de las reglas ubicadas en /etc/ossim_firewall, así que debemos tocar este último archivo.
En ossim_firewall encontrarán, como les anticipé, que las políticas default son ACCEPT. Antes de cambiar esto, debemos modificar las reglas que nos permiten acceso, porque sino, perderemos la conexión (a quién no le ha pasado alguna vez =)).
Para cada servicio utilizado, debemos agregar las IPs desde las que se lo puede acceder. En nuestro caso, remotamente solo accederemos a través de SSH, HTTP, HTTPS, y Ntop, mientras que permitiremos a MySQL que acceda localmente.
Suponiendo que la IP de la máquina monitor es 192.168.1.30 y que permitimos el acceso desde la IP 192.168.1.2, las reglas deberían quedar como las siguientes:
# permitimos ssh
-A INPUT -s 192.168.1.2 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

# aceptamos que MySQL se conecte localmente
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -s 127.0.0.1 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -s 192.168.1.30 -j ACCEPT

# permitimos HTTP
-A INPUT -s 192.168.1.2 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

# permitimos HTTPS
-A INPUT -s 192.168.1.2 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT

# permitimos Ntop
-A INPUT -s 192.168.1.2 -p tcp -m state --state NEW -m tcp --dport 3000 -j ACCEPT
Ahora que ya sabemos lo que vamos a permitir, rechacemos todo el resto. Para ello, modificamos las políticas default, cambiando las líneas
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
por
:INPUT DROP [0:0]
:FORWARD DROP [0:0]


Habilitar NTP

Si tenemos una red de mediana a grande, probablemente tengamos configurado algún servidor NTP (sobre todo si están en un entorno Windows Active Directory).
Tal como anticipé en la introducción, hace uno días publiqué cómo configurar el sistema como cliente NTP en el artículo Configurar NTP en GNU/Linux. Se aplica exactamente lo mismo en OSSIM.


Habilitando HTTPS


En la instalación default, OSSIM no provee seguridad para acceder a su interfaz Web, simplemente transmite los datos a través de HTTP. Absolutamente todo fluye a través de HTTP, incluso las credenciales de acceso al server. Por ello, el primer paso a realizar es activar HTTPS.
Al igual que en el caso de NTP, hace un tiempo publiqué un artículo que explica cómo habilitar HTTPS en Apache y sobre cómo forzar el uso de SSL. Me remito entonces a tal artículo porque se aplica lo mismo en este caso: Activar HTTPS en Apache + Forzar SSL.


Deshabilitar servicios

Si bien todas las herramientas tiene su utilidad, puede que no necesitemos todas, y si no las necesitamos, es mejor desactivarlas para que no consuman valiosos recursos.
En mi caso, encontré que las herramientas que detectan servicios en la red no eran necesarias, debido a que conozco los dispositivos que se encuentran conectados, y el gasto de recursos que suponían no valía la pena. Por esto, desactivé las herramientas pads y p0f.
Pads me resultó llamativo por el consumo de CPU. Estando pads activado, la utilización de CPU estaba siempre al 100%, con pads encabezando la lista con alrededor de un 97% de utilización. Realmente este alto consumo no justificaba una funcionalidad que puedo realizar con nmap.
P0f no consume tantos recursos pero si genera muchos logs del tipo "se encontró que una máquina tiene el mismo sistema operativo que antes", es decir, mensajes totalmente inútiles que llenan logs y fastidian la vida de la persona que los lee.
A su vez, dado que el administrador de dominio de la red ya cuenta con otras herramientas para monitorear los hosts, también deshabilité el Nagios.

Para desactivar herramientas, primero eliminamos los links desde los diferentes rc* para que no se inicien cada vez que arrancamos el sistema:
# update-rc.d pads remove
# update-rc.d nagios3 remove
También necesitamos eliminar los servicios de la lista de servicios levantados por OSSIM. Esto lo hacemos comentando las líneas correspondientes en /etc/ossim/agent/config.cfg, en la sección [plugins]:
#p0f_eth0=/etc/ossim/agent/plugins/p0f_eth0.cfg
#pads_eth0=/etc/ossim/agent/plugins/pads_eth0.cfg
La anécdota con este último paso es que si no lo realizamos, cada vez que matamos un servicio, OSSIM lo vuelve a revivir! (servicio Highlander como suele llamarlo Javi).

Ahora sí, estando seguros de que nadie revivirá los servicios, los detendremos con su correspondiente script en /etc/init.d, o bien ejecutamos un kill:
# /etc/init.d/pads stop
# /etc/init.d/nagios3 stop
# killall p0f_eth0


Mantener el sistema actualizado

Algo que es extremadamente importante es mantener el sistema actualizado. Esto permite mantener el sistema seguro, parchando vulnerabilidades.
Tal como les expliqué en el artículo Actualizaciones automáticas de seguridad en GNU/Linux, realizar actualizaciones automáticas pueden provocar inestabilidad y por ello es recomendable aplicar automáticamente sólo actualizaciones de seguridad. En el artículo citado les comento cómo hacer esto con la herramienta unattended upgrades.

Además de las actualizaciones de seguridad, también necesitamos mantener actualizadas las reglas de nuestro snort. Los temas relacionados a la configuración de snort los traté en el artículo Customizando Snort (). Particularmente el tema de actualizar reglas lo pueden encontrar rápidamente en la sección "Mantener Snort actualizado" de dicho artículo.

Cuando se actualizan las reglas de snort, si queremos que OSSIM las detecte debemos ejecutar un script en perl que mapea reglas con entradas en la base de datos del OSSIM (ver Install Oinkmaster and update snort rules):
perl /usr/share/ossim/scripts/create_sidmap.pl /etc/snort/rules/
Esto lógicamente hay que ejecutarlo cada vez que se agregan/actualizan/eliminan reglas, es decir, cada vez que Oinkmaster hace su trabajo. Por ello podemos agregar una entrada en cron que cada día actualice la base de atos:
# rebuild the sid database of ossim
perl /usr/share/ossim/scripts/create_sidmap.pl /etc/snort/rules/ 2>&1 | logger -t ossim-snort
Si leen el artículo sobre snort, encontrarán que ya había creado un script para cron que ejecute tareas relacionadas a la actualización de reglas, así que tranquilamente pueden la línea anterior a dicho script.


Acceso a la interfaz Web OSSIM

Cuando utilicen por primera vez la interfaz Web de OSSIM, se encontrarán con que les pide credenciales que ustedes nunca crearon. Pues bien, esta información la pueden encontrar rápidamente en la guía de OSSIM, pero para ahorrarles el trabajo les comento que las credenciales default son admin:admin.
Cuando se logueen por primera vez usando las credenciales anteriores el sistema les pedirá que cambien el password.


Administración de ntop

Luego de instalar OSSIM, ntop ya se encuentra en funcionamiento y podemos ver las estadísticas que arma a partir de los paquetes observados. Pero si quieren ingresar a la sección "Admin", no van a poder porque requiere un password que nunca asignamos. El password lo podemos asignar desde la consola ejecutando el comando:
# ntop -A
En particular, necesité acceder a las preferencias de la sección Admin para setear el path al programa dot, el cual se encarga de graficar la conexión entre nodos. El gráfico lo pueden ver en "IP -> Local -> Network Traffic Map", eso si, si logran entender algo, es un milagro =P


Corregir Nagios

Si decidieron utilizar Nagios, se van a encontrar con un problema. No investigué demasiado, pero alguno de los programas que descubren hosts, los va agregando automáticamente a Nagios para poder realizar el seguimiento. El problema está en que no realiza correctamente la configuración, porque los agrega en un archivo pero no crea la definición del host.
Por ejemplo, el programa descubre un host que escucha en el port 445, entonces agrega el host a hostgroup-services/port_445_Servers.cfg. Ese archivo define grupos de host que escuchan en el port 445. Hasta aca todo bien. Pero como no crea una definición para el host, cuando Nagios intenta leer la configuración, arroja un error del estilo "Error: Could not find any host matching '<IP>' (config file '/etc/nagios3/conf.d/ossim-configs/hostgroup-services/port_445_Servers.cfg', starting on line 1)".
Para que Nagios vuelva a funcionar debemos, o bien quitar de port_445_Servers.cfg la IP del host, o bien crear una definición para el Host. Las definiciones de Hosts están agrupadas en /etc/nagios3/conf.d/ossim-configs/hosts/. Pueden agarrar algún archivo de host ya configurado como base, copiarlo y cambiar la IP. El formato de los archivos que definen hosts es:
define host{
host_name <IP>
address <IP>
use generic-host
}
Deberán generar uno de estos archivos por cada host que tengan en la red. También pueden agregar varias definiciones en un mismo archivo, lo de separarlos es por seguir el funcionamiento de OSSIM.


Desactivar alertas molestas

Como menciono al principio del artículo, OSSIM funciona bien apenas lo instalamos, pero es necesario customizarlo para que nos alerte lo que necesitamos. Las configuraciones default nunca son buenas, y este no es un caso especial. Apenas conecten la máquina a la red para monitorear, van a notar una montaña de alertas con falsos positivos. En mi caso, en dos días monitoreando 8 servidores el log creció 40GB! así no hay disco que aguante. Lo bueno es que uno puede reconocer rápidamente cuáles son los falsos positivos más recurrentes y desactivarlos.

Recuerden que en OSSIM se muestran las alertas de todas las herramientas que corren por debajo, como ser snort, OSSEC, p0f, pads, arpwatch, etc. Por supuesto que el que genera la mayor cantidad de alertas es snort. El segundo en generar alertas molestas es OSSEC. Por ello voy a tratar estas dos herramientas en particular.


Configurar snort

Snort es probablemente la herramienta más importante dentro de OSSIM, pero también la más compleja. Con ella perdi la mayor cantidad de tiempo, monitoreando alertas, buscando y aprendiendo lo que reportaban y desactivando lo que no necesito.

En el artículo Customizando Snort traté todos los temas relacionados a esta herramienta, incluída la desactivación de alertas y la configuración de preprocesadores. Me remito entonces a tal artículo.
Lo único que deben tener en cuenta al leer el artículo es que OSSIM genera un archivo de configuración por cada interfaz de red que utilicemos para monitorear. Por ejemplo, si deseamos monitorear con la interfaz eth0, OSSIM genera y utiliza el archivo de configuración /etc/snort/snort.eth0.conf en lugar del clásico snort.conf. A su vez, como explico también en el artículo de snort, los paquetes snort de debian utilizan las variables configuradas en snort.debian.conf, que en OSSIM están en archivos dependientes de la interfaz (tomando como ejemplo eth0, el archivo se llamará snort.debian.eth0.conf).

Algo que también me llamó la atención es el hecho de tener dos binarios para el snort. Por un lado tenemos el común "snort", y por otro uno llamado "snort_eth0". En el caso de tener más placas de red, tal vez OSSIM habría creado un tercer binario llamado snort_eth1, pero no pude encontrar información al respecto, así que no puedo asegurarlo. No descubrí diferencias entre los binarios snort y snort_eth0, incluso calculé los hashes md5 y dan igual... si alguien tiene idea de cuál es el sentido de tener dos binarios, agradeceré comentarios. La teoría de Javi es que esta distinción entre nombres es para que cuando se listan procesos (por ejemplo usando top), uno pueda ver rápidamente en qué interfaz está escuchando cada proceso de snort.


Personalizar alertas en OSSEC

OSSEC se mostró incordioso con los errores en los logs. Básicamente OSSEC busca expresiones regulares en los logs y cuando detecta patrones extraños, los reporta. También posee otras funcionalidades, pero ésta es la que más se utiliza por default en OSSIM.
Luego de observar un rato los alertas en OSSIM, descubrimos rápidamente el error "Unknown problem somewhere in the system" por destacarse en cantidad de apariciones. Este error para nada descriptivo lo arroja OSSEC cuando detecta la presencia de palabras como error, failure, failed, en los logs, y no existe alguna regla que entienda el error. Esto es, una regla detecta la palabra error, si no existe otra regla que detecte un patrón conocido en esa línea, se arroja el error "Unknown problem somewhere in the system" porque no sabe con qué está lidiando, sólo sabe que es un error.

En el caso de mi monitor, encontré que había muchos errores del tipo "Error reading channel stat information. Missing key" en syslog, y por ello saltaba la alerta. La regla que dispara esta alerta está ubicada en /var/ossec/rules/syslog_rules.xml y tiene el siguiente formato:
<rule id="1002" level="2">
<match>$BAD_WORDS</match>
<options>alert_by_email</options>
<description>Unknown problem somewhere in the system.</description>
</rule>
donde $BAD_WORDS es "core_dumped|failure|error|attack|bad |illegal |denied|refused|unauthorized|fatal|failed|Segmentation Fault|Corrupted". Como no me interesa llenar mi pantalla de monitoreo con este tipo de errores, decidí crear una regla que se abstenga de reportar.

Escribir reglas para OSSEC es relativamente sencillo, posee un poderoso motor de expresiones regulares, así que podemos crear reglas complejas. El formato es XML, así que cualquiera puede adaptarse rápidamente.
Al igual que snort, poseemos un archivo donde agregar reglas definidas por nosotros, el cual es /var/ossec/rules/local_rules.xml.
La regla que definiré no reportará el error si la expresión regular coincide con el error "Error reading channel stat information. Missing key" y el programa que la reporta es nfsen:
<rule id="101002" level="2">
<if_sid>1002</if_sid>
<program_name>^nfsen</program_name>
<regex>Error reading channel stat information. Missing key \s+</regex>
<options>no_email_alert</options>
</rule>
Como observan, el nuevo id es diferente al original. De esta forma, primero matchea la primer regla, pero como hay una regla que dice no alertar estos casos, entonces no lo hace.

Pueden leer más sobre customizar reglas OSSEC en Why does ossec send me so many emails?. Me resultó interesante la frase que citan en el mismo: "To keep ossec useful and yourself sane you need to do some tunning to keep the signal to noise ratio high" =)

Para aprender más sobre OSSEC, vean el FAQ donde pueden encontrar mucha ayuda.


FIN (fin?)

Ya escribí 4 artículos sobre OSSIM (y 5 más que surgieron durante la configuración) y todavía no se si he finalizado o no de analizar esta distribución. Las herramientas que trae son grandiosas, pero requieren de bastante configuración para que se adapten correctamente a nuestras necesidades.
Sin dudas snort es la herramienta más importante y merece un buen estudio, leyendo sus manuales, aprendiendo sobre sus reglas y preprocesadores. Pero así como es de grandiosa es de molesta. Si no está correctamente configurada, tendremos miles de logs inútiles que nos darán un buen dolor de cabeza. Lo bueno es que el código está ahí, ustedes pueden deshabilitar/modificar/agregar reglas de forma muy simple!

Es claro que la configuración que presenté en este artículo está adaptada a las necesidades de mi empresa, pero creo que es lo suficientemente general para adaptarla a la mayoría de las empresas/instituciones, por lo que espero que les sea de mucha utilidad.
Lo que planteo en este artículo tiene muchas horas de investigación, prueba y error, lectura de manuales/blogs/tutoriales/etc. Muchas horas de enojos cuando algo no sale y satisfacción cuando las cosas andan.

Espero haber brindado con esta seguidilla de artículos una especie de guía, algo que yo no tuve, recopilando información y a la vez aportando experiencias y datos que no encontré en ningún lugar.