miércoles, 30 de mayo de 2012

Enviar y recibir correo desde nuestro GNU Shell con fetchmail y ssmtp

En este ultimo par de días, me ha tocado realizar algunas pruebas de correo electrónico, por lo que creo que tengo un poco de información agrupada aquí que les puede servir para manejar básicamente un correo electrónico desde nuestro shell (en mi caso mis pruebas son con bash).

Para enviar correo electrónico usamos el protocolo smtp, por lo tanto requerimos un servidor que ofrezca este servicio. Por otro lado, en cuanto a la recepción de correo nos apoyamos de los servidores pop. Conocer un poco mas de estos detalles es importante a la hora de comenzar nuestro trabajo de configurar un cliente de correo cualquiera que este sea. En nuestra practica vamos a configurar una cuenta de Gmal. A continuación les dejo un muy breve listado con algunos servidores.


Propietario Servidor Protocolo Cifrado Puerto
Gmail imap.googlemail.com imap ssl 993
Gmail pop.googlemail.com pop3 ssl 995
Gmail smtp.googlemail.com smtp ssl 465
Yahoo imap.mail.yahoo.com imap ssl 993
Yahoo pop.mail.yahoo.com pop3 ssl 995
Yahoo smtp.mail.yahoo.com smtp ssl 465
Hotmail pop3.live.com pop3 ssl/tls 995
Hotmail smtp.live.com smtp starttls 587


1. Enviar correo
En el envió de correo vamos ocupar instalar un agente de envió: ssmtp. Es un paquete muy básico y simple: ssmtp. Primero hacemos la instalación y luego modificamos su archivo de configuración.

user@localhost:~$ sudo apt-get install ssmtp
user@localhost:~$ sudo vim /etc/ssmtp/ssmtp.conf


En la configuración tenemos que especificar correo electrónico, contraseña para identificarnos, servidor smtp, tipo de cifrado, etc. A continuación les muestro parcialmente mi archivo ssmtp.conf.

root=martingmail@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=martingmail
AuthPass=xxxxxxxxxx
UseSTARTTLS=YES
FromLineOverride=YES
rewriteDomain=
hostname=martingmail@gmail.com


Una vez configurado los datos de la cuenta, asociamos el correo con una cuenta local de nuestro sistema en el archivo /etc/ssmtp/revaliases, eso lo hacemos colocando la siguiente linea "martin:martingmail@gmail.com:smtp.gmail.com:587".

Si nuestra configuracion y atutentificacion es correcta ya podemos enviar correos con mail command.

#Envio de correo, con redaccion interactiva
mail -s "Mi primer correo" miamigo@sudominio.org
#Envio de correo con redaccion desde el mismo shell
echo "Hola" | mail -s "Mi primer correo" miamigo@sudominio.org
cat miarchivo.txt | mail -s "Mi primer correo" miamigo@sudominio.org
#Enviar correo con archivo adjunto
uuencode ~/mifoto.png mifoto.png | mail -s "Mi foto" milindaamiga@sudominio.org
#Enviar correo con archivo adjunto y texto
( cat declaraciondeamor.txt ; uuencode ~/mifoto.png mifoto.png ) | mail -s "Mi foto" milindaamiga@sudominio.org


Para el caso donde adjuntamos archivos el comando uuencode lo encontramos en el paquete sharutils, por lo que tendríamos que instalarlo también.

2. Recibir correo
Fetchmail es un programa que nos ayuda a traer los nuestros correos de un mail server remoto, por lo tanto es el que no va a traer los correos de nuestro buzón gmail. El siguiente paso es instalar fechtmail y configurar su archivo:

user@localhost:~$ sudo apt-get install fetchmail
user@localhost:~$ sudo vim ~/fetchmailrc


El siguiente es mi archivo de configuración parcial (¿Por que parciales?, por que no puedo mostrar mis datos personales)

#Cada 600 segundos actualizar
set daemon 600
set logfile fetchmail.log
poll pop.googlemail.com proto POP3
user "martingmail@gmail.com" pass "xxxxxxxxx" is "martin"
ssl
mda "/usr/bin/procmail -f %F -d %T"


Ya configurado esto, podemos leer los correos con el mail command, y hacer las operaciones básicas que este nos ofrece, principalmente la redacción y respuesta de correos. El uso de comandos internos del mail command, no lo voy a tratar aquí ya que es un tema muy extenso y no lo domino ampliamente, por lo que en ese aspecto les tocara investigar.

viernes, 11 de mayo de 2012

OTRS y Nagios/Centreon

Como les había comentado antes, había estado trabajando un poco en OTRS para el control de servicios dentro de una unidad organizacional. Por simple curiosidad se me ocurrió agregar dos características al monitoreo para que se generen gráficas estadistas del los servicios que se realizan.

¿Por que construir un propio plugin y no usar los mecanismos que otrs nos ofrece para integrarse con Nagios? Primeramente por cuestiones de facilidad de implementación, la documentación de estos mecanismos no son muy claros (al menos para mi), sobre todo por que otrs ha cambiado entre versiones. La otra razón es por que los mecanismos de otrs tienen la limitante de trabajar únicamente en un entorno donde conviven en un mismo servidor Otrs/Nagios.

El script es muy básico, para este post, soporta  únicamente el monitoreo de tickets abiertos y tickets creados por día:

#!/bin/bash

dbHostname="127.0.0.1"
dbUser="otrsguest"
dbPasswd="qwerty"
dbName="otrs"
dbWhere=""

WARNING=10
CRITICAL=15
TYPE=""

# Plugin return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

function report {
        val=`mysql -h $dbHostname -u $dbUser -p$dbPasswd --database=$dbName --execute="select count(*) as open from ticket $dbWhere" | awk 'BEGIN{FS="\n"; RS="\n\n";}{print $2}'`
        if [ "$val" -le "$WARNING"  ]; then
                echo "Tickets $TYPE: $val [ OK ] | value=$val"
                exit $STATE_OK
        else
                if [ "$val" -le "$CRITICAL" ]; then
                        echo "Tickets $TYPE: $val [ WARNING ] | value=$val"
                        exit $STATE_WARNING
                else
                        echo "Tickets $TYPE: $val [ CRITICAL ] | value=$val"
                        exit $STATE_CRITICAL
                fi
        fi
}

function phelp {
        echo -e "Usage: $0 -t  -w  -c  | -h"
        echo -e "  -t Tipo de tickets a consultar"
        echo -e "  -c Valor critico"
        echo -e "  -w Valor warning"
        echo -e "  -h Help, this message.\n"
}

while getopts t:w:c:h OPT
do
        case $OPT in
                t) TYPE="$OPTARG" ;;
                w) WARNING="$OPTARG" ;;
                c) CRITICAL="$OPTARG" ;;
                h)
                        phelp
                        exit $STATE_UNKNOWN
                ;;
        esac
done


if [ "$TYPE" = "abiertos" ]; then
        dbWhere="where ticket_state_id='4'"
        report
else
        if [ "$TYPE" = "creados" ]; then
                date=`date +"%Y-%m-%d"`
                dbWhere="where create_time like '$date%'"
                report
        else
                echo "Carecteristica a monitorear desconocida. Conocidas: abiertos, creados"
                exit $STATE_UNKNOWN
        fi
fi


La siguiente gráfica nos representa la actividad de tickets abiertos para los últimos dos días.
 La siguiente gráfica nos representa la actividad de tickets creados por día, en los últimos tres días.

lunes, 7 de mayo de 2012

Construcción de Plugin Nagios/Centreon para HP Printer

Hace unas horas termine un script en bash para monitorear los consumibles de unas impresoras HP, la idea de agregarlas a centreon es para darnos conocer en buen momento cuando uno de los consumibles se están por terminar así como un histórico (usando las graficas) de cuanto se esta consumiendo. A posteriori, este script se tendría que poder usar en cualquier impresora HP con SNMP activado, los modelos de impresoras que tenemos son las siguientes:
  • HP LaserJet 4700 Color
  • HP LaserJet 4600 Color
  • HP LaserJet 4250
Requerimientos del script:
  • awk
  • snmpwalk
  • A nivel de red, acceso al segmento de las impresoras.
  • bash
  • etc.
#!/bin/bash
# Martin Barriga 2012

# Default options
COMMUNITY="public"
HOSTNAME="127.0.0.1"
CONSUMMABLE="black"
WARNING=20
CRITICAL=10
SNMPVERSION=2c
SHEETCOUNT="0"
sheetcount=""

#used MIBs
MAINMIB="mib-2.43.11.1.1.6.1"
SHEETMIB="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1"

# Plugin return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

# Option processing
function phelp {
  echo -e "Usage: $0 -H  -C  -v  -o  -w  -c   [ -l | -s ] | -h "
  echo -e "  -H IP Addres HP Printer"
  echo -e "  -C SNMP Community. Default 'public'"
  echo -e "  -v SNMP Version. Default '2c'"
  echo -e "  -o Color Tonner: black, cyan, magenta, yellow, transfer, fuser. Default 'black'"
  echo -e "  -w Warning Value. Default '80'"
  echo -e "  -c Critical Value. Default '90'"
  echo -e "  -l List consumible support."
  echo -e "  -s Print with sheet count available."
  echo -e "  -h Help, this message.\n"
}

function list {
        allinfo=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $MAINMIB`;
        echo "$allinfo" | ( while read line; do
                echo $line | cut -d "\"" -f2;
        done )
}

function withsheetcount {
        index=`echo "$1" | cut -d "." -f8`;
        count=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $SHEETMIB.$index | cut -d " " -f4`;
        sheetcount=", Sheet Available: $count";
}

while getopts H:C:v:o:w:c:slh OPT
do
  case $OPT in
    H) HOSTNAME="$OPTARG" ;;
    C) COMMUNITY="$OPTARG" ;;
    v) SNMPVERSION="$OPTARG" ;;
    o) CONSUMMABLE="$OPTARG" ;;
    w) WARNING=$OPTARG ;;
    c) CRITICAL=$OPTARG ;;
    s) SHEETCOUNT="1" ;;
    l)
       list
       exit $STATE_UNKNOWN
    ;;
    h)
       phelp
       exit $STATE_UNKNOWN
    ;;
    #V)
    #  print_version
    #  exit $STATE_UNKNOWN
    #  ;;
   esac
done

info=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $MAINMIB | grep -i $CONSUMMABLE`
if [ "$info" != "" ]; then
        name=`echo "$info" | cut -d "\"" -f 2`;
        mib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3`;
        newmib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3 | awk -F. -v OFS=. '{$6=8}1'`;
        size=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $newmib | cut -d " " -f4`;
        newmib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3 | awk -F. -v OFS=. '{$6=9}1'`;
        value=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $newmib | cut -d " " -f4`;
        let porcent=($value*100)/$size;

        #If sheet count is required
        if [ "$SHEETCOUNT" = "1" ]; then
                withsheetcount $mib
        fi

        if [ "$porcent" -le "$CRITICAL" ]; then
                echo "$name: Status: $value/$size $porcent% available [ CRITICAL ] | size=$size used=$value";
                exit $STATE_CRITICAL;
        else
                if [ "$porcent" -le "$WARNING" ]; then
                        echo "$name: Status: $value/$size $porcent% available [ WARNING ] | size=$size used=$value";
                        exit $STATE_WARNING;
                else
                        echo "$name: Status: $value/$size $porcent% available [ OK ] | size=$size used=$value";
                        exit $STATE_OK;
                fi
        fi
else
        echo "No se encuentra consumible $CONSUMMABLE en $HOSTNAME [ UNKNOW ]"
        exit $STATE_UNKNOWN
fi