Cambiar el estado devuelto por un monitor de Nagios

En algunas ocasiones se puede necesitar que un monitor de Nagios nunca devuelva el estado CRITICAL, considere el estado UNKOWN como WARNING, invierta el estado OK por CRITICAL, etc. A priori se podría pensar en modificar el plugin o jugar con Bash, pero para invertir o cambiar el resultado de un plugin está negate.

Por ejemplo, en el caso de querer utilizar el plugin check_ping para saber si una máquina está en la red o no, pero que en caso de que no lo esté (como que se agote el timeout) el estado devuelto sea WARNING y no CRITICAL. Se llamaría a negate tal que:

  • Se le indique un timeout superior al de check_ping, que en caso de superarse devolvería CRITICAL, porque supondría que el plugin objeto de la comprobación no está funcionando bien.
  • Que sustituya la cadea que representa el estado, que aunque Nagios hace caso del código de salida así el texto devuelto será acorde al número.
  • Se le indique que reemplace el estado CRITICAL por WARNING.
  • Se añada al final el plugin y argumentos cuya salida se quiere invertir según convenga.

Hablando en línea de comandos sería algo así:

# /usr/lib/nagios/plugins/negate -t '20' -s -c WARNING /usr/lib/nagios/plugins/check_ping -H '192.168.1.3' -w '5000.0,80%' -c '10000.0,100%' -p '1' -t '10'
PING WARNING - Packet loss = 100%|rta=10000.000000ms;5000.000000;10000.000000;0.000000 pl=100%;80;100;0
# echo $?
1

En cambio si no se usase negate el plugin devolvería el estado CRITICAL:

# /usr/lib/nagios/plugins/check_ping -H '192.168.1.3' -w '5000.0,80%' -c '10000.0,100%' -p '1' -t '10'
PING CRITICAL - Packet loss = 100%|rta=10000.000000ms;5000.000000;10000.000000;0.000000 pl=100%;80;100;0
# echo $?
2

Fuente → Nagios only create warning for a http service [Server Fault]

Alta disponibilidad de Internet con Linux (i)

En unos firewalls con Linux hay infinitas maneras de intentar conseguir alta disponibilidad de salida a Internet, aunque todas tienen sus inconvenientes. Voy a contar un ejemplo combinando Conntrack, Iptables, Corosync, Pacemaker y un script inspirado en la solución de amperis.

Una de las soluciones que primero se vienen a la cabeza es utilizar un algoritmo de pesos con ip route según la relación de velocidad de los proveedores contratados o nuestras preferencias, configurando una ruta por defecto multicamino. Pero esto pronto empezará a dar problemas en según qué conexiones o aplicaciones al encontrarse que según qué paquetes les llegan por distintas IP públicas, como las páginas de los bancos. Y aunque la lógica de dividir el tráfico entre proveedores también puede hacerse con iptables y el módulo statistic, no se evita el problema del multicamino.

Justo acabo de mencionar a iptables […] (continuar leyendo)

Recargando un servidor de Node.js con WebSocket

Un sencillo servidor corriendo sobre Node.js puede permitir la recarga sin interrupciones, de manera amistosa, algo parecido al reload de Apache u otros demonios en Linux. Para ello sólo es necesario que haya un proceso padre que lance hijos y les envíe señales según sea necesario. Sin embargo el cierre de las conexiones esperando a que estas terminen puede dar algunas complicaciones cuando hay un WebSocket.

La gestión de padre e hijos se puede hacer con el módulo cluster. En este ejemplo el script a lanzar manualmente es master.js. Él a su vez lanzará al script server.js y le pasará las señales SIGHUP para recargar el servidor (terminar amistosamente) o SIGTERM para terminar sin piedad.

master.js:

'use strict';

var cluster = require('cluster');
const path = require('path');

cluster.setupMaster({
  exec: path.join(__dirname, 'server.js')
});

//fork the first process
cluster.fork();

process.on('SIGHUP', function () {
  var new_worker = cluster.fork();
  new_worker.once('listening', function () {
    //stop all other workersS
    for (var id in cluster.workers) {
      if (id === new_worker.id.toString()) continue;
      cluster.workers[id].process.kill('SIGHUP');
    }
  });
}).on('SIGTERM', function () {
  for (var id in cluster.workers) {
    cluster.workers[id].process.kill('SIGTERM');
  }
});

[…] (continuar leyendo)