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)

Listar sólo ficheros ordenados por fecha de modificación

Lo intuitivo sería pensar en usar ls -lt, pero si se quieren evitar directorios, ficheros con un determinado nombre, seguir enlaces simbólicos, que los caracteres de nueva línea nos la puedan jugar,.. find es más fiable que andar filtrando con grep los resultados. Aunque hay que pensar un poco para combinarlo con sort para ordenar los resultados por el primer campo (en tiempo POSIX con parte decimal) y sed para eliminar después el tiempo, que ya no nos sirve.

Algo así:

find -P . -maxdepth 1 -type f -printf '%C@ %p\0' | sort -znrk1 | sed -e 's/^[^ ]* //' -e 's/\x0[^ ]* /\x0/g' | while IFS= read -r -d '' i

OjO a ISF= y -d ”, que permiten dividir las ocurrencias y no zamparse los espacios en blanco que pudiera tener el nombre de un fichero al final.

Actualizar DNS de cPanel desde Bash

Hoy Dyn ha dejado de prestar de manera gratuita su servicio de DNS dinámico. Avisaron con un mes de antelación y yo que ya llevaba tiempo dándole vueltas a cómo poder utilizar un dominio y un hosting propio para eso, me puse a investigar y tuve suerte.

En los foros de cPanel encontré un mensaje con un script en Bash para actualizar desde consola nuestros registros DNS —que por motivos de licencias no puedo reproducir aquí—. Utiliza la api de cPanel para gestionar los dominios y es ideal por ejemplo para crearnos un subdominio y llamar al script periódicamente desde el cron de una máquina con Linux. Incluso una Raspberry Pi con una distribución a medida, al no necesitar de librerías extrañas. Está bien pensado, comprobando en cada ejecución si la IP actual es la misma que la anterior para ahorrar actualizaciones innecesarias y hasta puede mandar un correo electrónico en caso de errores.

La configuración para un ejemplo podría ser:

CONTACT_EMAIL="perico@delospalotes.com"
DOMAIN="delospalotes.com"
SUBDOMAIN="micasa"
CPANEL_SERVER="cpanel.delospalotes.com"
CPANEL_USER="usuario de cpanel"
CPANEL_PASS="contraseña de cpanel"

Y fuera dependencias de servicios de terceros.

Solución al «Argument list too long» en Linux

Cuando se quiere aplicar una operación masiva como copiar, mover y borrar archivos se suelen usar combinaciones de asteriscos y comodines para no ir de uno en uno. Luego Bash se encarga de expandir los nombres. El problema es que entonces se forma un chorizo de comando con demasiados argumentos. La solución pasa por ejecutar el comando en cuestión archivo a archivo, como por ejemplo con find y xargs para borrar:

find . -name "*" -print0 | xargs -0 rm

Pero ojo, que en este caso find es recursivo, así que habría que acotarlo con -maxdepth 1. Además, así también se pueden ejecutar comandos sobre archivos según fechas y otras características.

Vía → Argument list too long error for rm, cp, mv commands @ Stack Overflow.

Obtener la IP de cada interfaz en Perl

Obtener la IP de la máquina no tiene mucho misterio. Pero cuando se trata de servidores con varias interfaces de red, algunas incluso virtuales, la cosa cambia. Y se trata de algo que puede tener muchas aplicaciones, como por ejemplo un script que distinga entre si las copias que se van a realizar son realmente desde/hacia una máquina remota o en local y agilizar el proceso.

La manera más resumida en el caso de Linux es filtrar la salida de ifconfig:

my @IP = (`ifconfig -a` =~ /inet addr:(\S+)/g);

Pero es cierto que algún día los desarrolladores de la distribución de turno pudieran decidir traducir las palabras inet addr por direccion inet o a saber, por lo que ya estarían fastidiando la expresión regular y por tanto el invento. Así que por eso para soluciones más elegantes y multiplataforma, que para eso es Perl, se puede hacer uso de algún módulo como […] (continuar leyendo)

«cron» y el último día de cada mes

El demonio cron facilita las ejecuciones programadas cuando se trata del primer día del mes. Sin embargo para el último día de cada mes hay que usar un poco de ingenio y otras herramientas del sistema. Una manera:

30 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && /ruta/absoluta/al/script 1>/dev/null 2>&1

Que cada día a las 2330 comprobará si se trata del último día del mes:

  1. Obtiene el día del mes.
  2. Obtiene el calendario del mes actual.
    1. Extrae el final de cada línea del calendario.
    2. Se queda con la última de esas líneas.
  3. Si el día actual es igual al último día del mes obtenido, se ejecuta lo que le digamos y las salidas las manda a /dev/null.

Fuente → The UNIX and Linux Forums.