Nagios Falante
Este artigo ensina como colocar o Nagios para te ligar e avisar em caso de falhas críticas em sua rede. Ele irá funcionar como uma secretária eletrônica ao contrário. Ao invés de esperar a ligação, ele ligará e te avisará.
Parte 4: Alguns scripts e algumas configurações
Primeiramente, tenha certeza que o seu Nagios está
configurado e funcionando corretamente. Para saber como fazer
isso, vá no site oficial e leia os vários tutoriais, HOWTOs e
documentação, que são muito boas.
Site: http://www.nagios.org
Vamos entender o que vai acontecer:
1) O Nagios verifica os serviços e caso necessário, emite os avisos que estão configurados nos arquivos:
Vamos baixar e compilar o mgetty:
ATENÇÃO!!! Não é necessário instalar TODO o pacote mgetty, vamos utilizar apenas a parte de "voice" dele.
Baixe a última versão e descompacte em algum lugar. Depois disso entre no subdiretório "voice" e dê um "make" lá dentro. Simples assim.
Depois de compilar, copie todos os binários do diretório "pvftools" para um lugar qualquer, por exemplo "/usr/local/bin".
Copie também o binário do "vm" (Voice Shell) que fica no diretório "vm", pois é ele quem vai fazer toda a mágica!
Agora vem a parte difícil da coisa:
O Nagios envia notícias em paralelo, ou seja, se um serviço parar e houver mais de uma pessoa configurado no "contacts.conf" e "contacgroups.conf", ele irá tentar ligar para todos ao mesmo tempo... coisa que o modem não permite.
Solução: Criar um "servidor de e-mail" para mensagens de voz. Ou melhor, algum programa que enfilere as mensagens e dispare de modo serial e não paralelo.
Como eu quero facilitar a vida de vocês, vou colocar aqui meus scripts OK?
Nota: Estão todos em shell script, se alguém fizer uma versão melhor, em C por exemplo, me envie OK?
Nota 1: Os arquivos de som DEVEM ser gravados em WAV no formato **22050/16bits/Mono**. Caso não seja nesses parâmetros, o som não sairá correto!!! Depois disso, é necessário converter o arquivo para o formato que seu voice modem entenda (.rmd).
Nota 2: Os programas a seguir recebem 3 arquivos de som, um para o nome do servidor, outro para o nome do serviço e o terceiro para o estado.
O resultado será algo como: "Servidor X, HTTP, Crítico".
Este é o "daemon" do mailmodem. Ele fica em um loop infinito verificando (a cada 2 min) por arquivos no diretório "/var/spool/mailmodem", onde as mensagens serão colocadas.
Site: http://www.nagios.org
Vamos entender o que vai acontecer:
1) O Nagios verifica os serviços e caso necessário, emite os avisos que estão configurados nos arquivos:
- contacts.cfg
- misccommands.cfg
- services.cfg
Vamos baixar e compilar o mgetty:
ATENÇÃO!!! Não é necessário instalar TODO o pacote mgetty, vamos utilizar apenas a parte de "voice" dele.
Baixe a última versão e descompacte em algum lugar. Depois disso entre no subdiretório "voice" e dê um "make" lá dentro. Simples assim.
Depois de compilar, copie todos os binários do diretório "pvftools" para um lugar qualquer, por exemplo "/usr/local/bin".
Copie também o binário do "vm" (Voice Shell) que fica no diretório "vm", pois é ele quem vai fazer toda a mágica!
Agora vem a parte difícil da coisa:
O Nagios envia notícias em paralelo, ou seja, se um serviço parar e houver mais de uma pessoa configurado no "contacts.conf" e "contacgroups.conf", ele irá tentar ligar para todos ao mesmo tempo... coisa que o modem não permite.
Solução: Criar um "servidor de e-mail" para mensagens de voz. Ou melhor, algum programa que enfilere as mensagens e dispare de modo serial e não paralelo.
Como eu quero facilitar a vida de vocês, vou colocar aqui meus scripts OK?
Nota: Estão todos em shell script, se alguém fizer uma versão melhor, em C por exemplo, me envie OK?
Nota 1: Os arquivos de som DEVEM ser gravados em WAV no formato **22050/16bits/Mono**. Caso não seja nesses parâmetros, o som não sairá correto!!! Depois disso, é necessário converter o arquivo para o formato que seu voice modem entenda (.rmd).
Nota 2: Os programas a seguir recebem 3 arquivos de som, um para o nome do servidor, outro para o nome do serviço e o terceiro para o estado.
O resultado será algo como: "Servidor X, HTTP, Crítico".
Este é o "daemon" do mailmodem. Ele fica em um loop infinito verificando (a cada 2 min) por arquivos no diretório "/var/spool/mailmodem", onde as mensagens serão colocadas.
#!/bin/bash
. /etc/mailmodem.conf
DELAY="2m"
while :; do
for message in `find $spool -type f | sort`; do
CONT="`cat $message`"
TEL="`echo $CONT | cut -f1 -d:`"
SOM1="`echo $CONT | cut -f2 -d:`"
SOM2="`echo $CONT | cut -f3 -d:`"
SOM3="`echo $CONT | cut -f4 -d:`"
if [ -z "`ps ax | grep playmodem | grep -v grep`" ]; then
$playmodem $TEL $SOM1 $SOM2 $SOM3
ERROR="$?"
rm $message
fi
if [ "$ERROR" == "0" ]; then
/usr/bin/logger -t MailModem "Send |Tel: $TEL - Som1: $SOM1 - Som2: $SOM2 - Som3: $SOM3| Success"
else
/usr/bin/logger -t MailModem "Send |Tel: $TEL - Som1: $SOM1 - Som2: $SOM2 - Som3: $SOM3| Failed, errnum: $ERROR"
fi
sleep 1s
done
sleep $DELAY
done
exit 0
. /etc/mailmodem.conf
DELAY="2m"
while :; do
for message in `find $spool -type f | sort`; do
CONT="`cat $message`"
TEL="`echo $CONT | cut -f1 -d:`"
SOM1="`echo $CONT | cut -f2 -d:`"
SOM2="`echo $CONT | cut -f3 -d:`"
SOM3="`echo $CONT | cut -f4 -d:`"
if [ -z "`ps ax | grep playmodem | grep -v grep`" ]; then
$playmodem $TEL $SOM1 $SOM2 $SOM3
ERROR="$?"
rm $message
fi
if [ "$ERROR" == "0" ]; then
/usr/bin/logger -t MailModem "Send |Tel: $TEL - Som1: $SOM1 - Som2: $SOM2 - Som3: $SOM3| Success"
else
/usr/bin/logger -t MailModem "Send |Tel: $TEL - Som1: $SOM1 - Som2: $SOM2 - Som3: $SOM3| Failed, errnum: $ERROR"
fi
sleep 1s
done
sleep $DELAY
done
exit 0
Este é o "arquivo de configuração" do mailmodem.sh, que deve ficar no /etc:
# Mail Modem Conf file
# Where the playmodem.sh stay
playmodem="/usr/local/bin/playmodem.sh"
# The place of spool messages
spool="/var/spool/mailmodem"
# Temporary directory
tmp="/tmp"
# The translation file
translation="/etc/nagios/translation.txt"
# Directory of sounds
sounddir="/usr/local/share/sounds"
# Where the playmodem.sh stay
playmodem="/usr/local/bin/playmodem.sh"
# The place of spool messages
spool="/var/spool/mailmodem"
# Temporary directory
tmp="/tmp"
# The translation file
translation="/etc/nagios/translation.txt"
# Directory of sounds
sounddir="/usr/local/share/sounds"
Este é o send_modem.sh. Ele é responsável por colocar as mensagens no diretório "spool" do mailmodem e fazer algumas checagens como a existência dos arquivos de som e fazer umas "traduções" por exemplo.
Estas traduções são o seguinte:
No Nagios você pode definir nomes de serviços com espaços e coisas assim, quando usar o send_modem.sh para enviar as mensagens ele irá passar estes nomes enormes, gerando confusão ou dando problemas mesmo. A tradução serve para trocar os nomes extensos que o Nagios passa como parâmetro por nomes menores, mais genéricos.
#!/bin/bash
. /etc/mailmodem.conf
file="`date +%s%N`"
if [ "$#" != "4" ]; then
echo "Wrong number of paramets"
echo "Usage: $0 tel_number sound1 sound2 sound3"
exit 255
fi
# Telefone
TEL="$1"
# Nome da maquina
P1="$2"
SOM1="`echo $P1 | awk '{print tolower($1)}'`"
# Servico
P2="$3"
SOM2="`grep -i ^\"$P2\" $translation | cut -f2 -d: | awk '{print tolower($0)}'`"
if [ -e "$sounddir/`echo $P2 | tr A-Z a-z`.rmd" ]; then
SOM2="`echo $P2 | tr A-Z a-z`"
else
SOM2="`grep -i "^$P2" $translation | cut -f2 -d: | tr A-Z a-z`"
fi
# Estado
P3="$4"
if [ -e "$sounddir/`echo $P3 | tr A-Z a-z`.rmd" ]; then
SOM3="`echo $P3 | tr A-Z a-z`"
else
SOM3="`grep -i "^$P3" $translation | cut -f2 -d: | tr A-Z a-z`"
fi
if [ -z "$SOM2" ] || [ -z "$SOM3" ]; then
/usr/bin/logger -t MailModem "Wrong sound. Param: $1, $2, $3, $4. Exiting..."
exit 255
fi
test -e $spool/$file || echo -n "$TEL:$SOM1.rmd:$SOM2.rmd:$SOM3.rmd" > $spool/$file
chmod 666 $spool/$file
exit 0
. /etc/mailmodem.conf
file="`date +%s%N`"
if [ "$#" != "4" ]; then
echo "Wrong number of paramets"
echo "Usage: $0 tel_number sound1 sound2 sound3"
exit 255
fi
# Telefone
TEL="$1"
# Nome da maquina
P1="$2"
SOM1="`echo $P1 | awk '{print tolower($1)}'`"
# Servico
P2="$3"
SOM2="`grep -i ^\"$P2\" $translation | cut -f2 -d: | awk '{print tolower($0)}'`"
if [ -e "$sounddir/`echo $P2 | tr A-Z a-z`.rmd" ]; then
SOM2="`echo $P2 | tr A-Z a-z`"
else
SOM2="`grep -i "^$P2" $translation | cut -f2 -d: | tr A-Z a-z`"
fi
# Estado
P3="$4"
if [ -e "$sounddir/`echo $P3 | tr A-Z a-z`.rmd" ]; then
SOM3="`echo $P3 | tr A-Z a-z`"
else
SOM3="`grep -i "^$P3" $translation | cut -f2 -d: | tr A-Z a-z`"
fi
if [ -z "$SOM2" ] || [ -z "$SOM3" ]; then
/usr/bin/logger -t MailModem "Wrong sound. Param: $1, $2, $3, $4. Exiting..."
exit 255
fi
test -e $spool/$file || echo -n "$TEL:$SOM1.rmd:$SOM2.rmd:$SOM3.rmd" > $spool/$file
chmod 666 $spool/$file
exit 0
Aqui um exemplo das traduções. Defina o nome e local no arquivo de configuração do mailmodem (/etc/mailmodem.conf):
#
# Neste arquivo fica a tradução das falas
#
Administracao do Silver Stream:SILVERSTREAM
Servico do SilverStream:SILVERSTREAM
Servico do SyBase:SYBASE
Porta do SyBase:SYBASE
Exchange Informations Service:EXCHANGE
Exchange MTA:EXCHANGE
Exchange Management:EXCHANGE
IMAP4 - Exchange:EXCHANGE
GroupShield:GROUPSHIELD
HTTPS:HTTP
MailScanner Process:SMTP
Postfix Process:SMTP
SQUID Proxy:SQUID
UPS Charge Remaning:BATERIA
PROBLEM:CRITICO
UNKNOWN:CRITICO
RECOVERY:RECUPERADO
# Neste arquivo fica a tradução das falas
#
Administracao do Silver Stream:SILVERSTREAM
Servico do SilverStream:SILVERSTREAM
Servico do SyBase:SYBASE
Porta do SyBase:SYBASE
Exchange Informations Service:EXCHANGE
Exchange MTA:EXCHANGE
Exchange Management:EXCHANGE
IMAP4 - Exchange:EXCHANGE
GroupShield:GROUPSHIELD
HTTPS:HTTP
MailScanner Process:SMTP
Postfix Process:SMTP
SQUID Proxy:SQUID
UPS Charge Remaning:BATERIA
PROBLEM:CRITICO
UNKNOWN:CRITICO
RECOVERY:RECUPERADO
Quando o Nagios passar "Postfix Process", por exemplo, o programa irá "traduzir" para SMTP e procurar um arquivo de som chamado smtp.rmd no diretório de arquivos de som.
Este arquivo que irá tocar os 3 sons através do script do modem "messages.sh":
#!/bin/bash
TEL="$1"
SOM1="$2"
SOM2="$3"
SOM3="$4"
PREFIX="/usr/local"
DIRSOM="$PREFIX/share/sounds"
err=`sudo -u root $PREFIX/bin/vm shell -l cua0 $PREFIX/bin/message.sh $TEL $DIRSOM/$SOM1 $DIRSOM/$SOM2 $DIRSOM/$SOM3`
if [ "$err" == "OK: message sent" ];then
out="0"
mess="OK"
else
out="255"
mess="ERROR"
fi
echo "$mess"
exit $out
TEL="$1"
SOM1="$2"
SOM2="$3"
SOM3="$4"
PREFIX="/usr/local"
DIRSOM="$PREFIX/share/sounds"
err=`sudo -u root $PREFIX/bin/vm shell -l cua0 $PREFIX/bin/message.sh $TEL $DIRSOM/$SOM1 $DIRSOM/$SOM2 $DIRSOM/$SOM3`
if [ "$err" == "OK: message sent" ];then
out="0"
mess="OK"
else
out="255"
mess="ERROR"
fi
echo "$mess"
exit $out
O messages.sh. Observe que este script não é meu, apenas dei uma adaptada para tocar 3 arquivos de som ao invés de 1.
#
# This script calls the given phone number and plays a message.
#
# $1 - phone number to call
# $2 - filename of the message to play (must be a .rmd file, that
# can be played on the modem used for dialout)
#
# $Id: message.sh,v 1.5 1999/12/04 15:07:34 marcs Exp $
#
#
# Define the function to receive an answer from the voice library
#
function receive
{
read -r INPUT <&$VOICE_INPUT;
echo "$INPUT";
}
#
# Define the function to send a command to the voice library
#
function send
{
echo $1 >&$VOICE_OUTPUT;
kill -PIPE $VOICE_PID
}
#
# Check command line options
#
if [ $# -ne 4 ]; then
echo "usage: $0 <phone_number> <filename1> <filename2> <filename3>" >&2
exit 99
fi
#
# Let's see if the voice library is talking to us
#
ANSWER=`receive`
if [ "$ANSWER" != "HELLO SHELL" ]; then
kill -KILL $$
fi
send "HELLO VOICE PROGRAM"
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Enable events
#
send "ENABLE EVENTS"
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Start dialout
#
send "DIAL $1"
ANSWER=`receive`
if [ "$ANSWER" != "DIALING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
echo "ERROR: $ANSWER, aborting"
exit 99
fi
#
# Disable events
#
send "DISABLE EVENTS"
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Now play the message file
#
send "PLAY $2"
ANSWER=`receive`
if [ "$ANSWER" != "PLAYING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
send "PLAY $3"
ANSWER=`receive`
if [ "$ANSWER" != "PLAYING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
send "PLAY $4"
ANSWER=`receive`
if [ "$ANSWER" != "PLAYING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Let's say goodbye
#
send "GOODBYE"
ANSWER=`receive`
if [ "$ANSWER" != "GOODBYE SHELL" ]; then
kill -KILL $$
fi
echo "OK: message sent"
exit 0
# This script calls the given phone number and plays a message.
#
# $1 - phone number to call
# $2 - filename of the message to play (must be a .rmd file, that
# can be played on the modem used for dialout)
#
# $Id: message.sh,v 1.5 1999/12/04 15:07:34 marcs Exp $
#
#
# Define the function to receive an answer from the voice library
#
function receive
{
read -r INPUT <&$VOICE_INPUT;
echo "$INPUT";
}
#
# Define the function to send a command to the voice library
#
function send
{
echo $1 >&$VOICE_OUTPUT;
kill -PIPE $VOICE_PID
}
#
# Check command line options
#
if [ $# -ne 4 ]; then
echo "usage: $0 <phone_number> <filename1> <filename2> <filename3>" >&2
exit 99
fi
#
# Let's see if the voice library is talking to us
#
ANSWER=`receive`
if [ "$ANSWER" != "HELLO SHELL" ]; then
kill -KILL $$
fi
send "HELLO VOICE PROGRAM"
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Enable events
#
send "ENABLE EVENTS"
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Start dialout
#
send "DIAL $1"
ANSWER=`receive`
if [ "$ANSWER" != "DIALING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
echo "ERROR: $ANSWER, aborting"
exit 99
fi
#
# Disable events
#
send "DISABLE EVENTS"
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Now play the message file
#
send "PLAY $2"
ANSWER=`receive`
if [ "$ANSWER" != "PLAYING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
send "PLAY $3"
ANSWER=`receive`
if [ "$ANSWER" != "PLAYING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
send "PLAY $4"
ANSWER=`receive`
if [ "$ANSWER" != "PLAYING" ]; then
kill -KILL $$
fi
ANSWER=`receive`
if [ "$ANSWER" != "READY" ]; then
kill -KILL $$
fi
#
# Let's say goodbye
#
send "GOODBYE"
ANSWER=`receive`
if [ "$ANSWER" != "GOODBYE SHELL" ]; then
kill -KILL $$
fi
echo "OK: message sent"
exit 0
Um pequeno script para converter os arquivos .WAV para .RMD, o convert.sh/ A variável PREFIX deve apontar para o diretório onde os arquivos "pvftools" foram copiados.
Observe a linha onde diz "pvftormd US_Robotics 1". Cada modem possui um formato diferente de tratar som. Verifique o seu e substitua o parâmetro.
Para listar os dispositivos use: "pvftormd -L"
#!/bin/bash
IN="$1"
OUT="`echo $IN | cut -f1 -d.`.rmd"
PREFIX="/usr/local/bin"
$PREFIX/wavtopvf $IN | $PREFIX/pvfspeed -s 8000 | $PREFIX/pvftormd US_Robotics 1 > $OUT
rm $IN
exit 0
IN="$1"
OUT="`echo $IN | cut -f1 -d.`.rmd"
PREFIX="/usr/local/bin"
$PREFIX/wavtopvf $IN | $PREFIX/pvfspeed -s 8000 | $PREFIX/pvftormd US_Robotics 1 > $OUT
rm $IN
exit 0
Excelente artigo! Apesar de não usar o Nagios, achei muito interessante a parte do mgetty. Acabei de configurar uma secretária eletrônica que recebe até fax aqui em casa usando esse tal de mgetty :P, muito bom mesmo.
Inclusive fica aí a sugestão de artigo, falar sobre como implementar um servidor de fax/secretária eletrônica usando o mgetty. Levando em conta que o mgetty também pode literalmente "telefonar" pra você, também pode-se ensinar a implementar um serviço de despertador que nem as companhias telefônicas fazem, ou seja, ligar pra seu telefone em determinado horário pré-agendado. Cruel!!!
Ah se eu tivesse tempo, infelizmente meu "time" hoje em dia é 100% consumido pela manutenção do site, daí tive de sacrificar algo que adoro fazer, que é escrever :)
[]'s