In questo articolo vedremo i vari step per arrivare all’implementazione di un tool che, per conto nostro, si preoccupi di testare la raggiungibilità dei server e dei servizi di cui siamo amministratori. Partiamo innanzitutto dal presupposto di avere installata una distribuzione Linux, io ho utilizzato una Debian 7.4 (Wheezy). Il nostro obiettivo finale sarà quello di ricevere una email nel caso in cui uno dei nostri server non sia raggiungibile; per fare questo abbiamo bisogno di un paio di strumenti che consentano alla nostra Debian di inviare email. Il primo è un MUA (mail user agent), ovvero un client di posta. Debian è dotata di un MUA di nome Mail che è un client utilizzabile da riga di comando (proprio quello che fa al caso nostro). Il secondo strumento è un MTA (mail transfer agent), il daemon smtp che realmente si prende in carico il compito di inviare il messaggio. Esistono moltissimi MTA, come ad esempio Postfix, SendMail, ecc., io ho scelto Ssmtp perchè in modalità satellite funziona molto bene ed è semplicissimo da configurare.

N.B. Si dice modalità satellite quando un MTA non fa da server smtp ma si occupa soltanto di trasferire il messaggio ad un altro server smtp che poi lo invierà al destinatario. Ho scelto questa modalità perchè il nostro scopo è solo quello di inviare dei messaggi, non di implementare un server di posta.

Per installare Ssmtp su debian utilizziamo il comodissimo APT:

root@ibm:/home/draven#apt-get install ssmtp

Dopo averlo installato lo configuriamo editando il file /etc/ssmtp/ssmtp.conf. Questo file dovrà contenere le informazioni del reale server smtp che utilizzeremo per l’invio, un pò come quando si configura un client di posta elettronica, io ho utilizzato un mio account Gmail e quindi nel .conf ho scritto quanto segue:

root@ibm:/home/draven#nano /etc/ssmtp/ssmtp.conf
 
root=ilmioindirizzo@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=ilmiousername
AuthPass=lamiapassword
UseSTARTTLS=YES
UseTLS=YES
AuthMethod=LOGIN

A questo punto la nostra Debian è in grado di inviare email. Passiamo ora alla creazione dello script che farà i test verso i nostri server. Lo script è in Python, un linguaggio di programmazione che per funzionare ha bisogno di un interprete e, anche qui la Debian ci aiuta perchè l’interprete Python è un pacchetto già installato sulla distribuzione. Il formato degli script python è .py, quindi creiamo un file nella posizione che vogliamo, con il nome che vogliamo e con estensione .py:

root@ibm:/home/draven#nano srvmon.py

All’interno del file che io ho chiamato srvmon.py andiamo a scrivere il nostro tool:

#! /usr/bin/env python
 
from os import system
from urllib2 import urlopen
from socket import socket
from sys import argv
from time import strftime
 
def tcp_test(server_info):
    cpos = server_info.find(':')
    try:
        sock = socket()
        sock.connect((server_info[:cpos], int(server_info[cpos+1:])))
        sock.close
        return True
    except:
        return False
 
def http_test(server_info):
    try:
        data = urlopen(server_info).read()
        return True
    except:
        return False
 
def server_test(test_type, server_info):
    if test_type.lower() == 'tcp':
        return tcp_test(server_info)
    elif test_type.lower() == 'http':
        return http_test(server_info)
 
def send_error(test_type, server_info, email_address):
    subject = '%s: %s %s errore' % (strftime("%d/%m/%Y %H:%M:%S"), test_type.upper(), server_info)
    message = 'Il test di tipo %s verso %s e' fallito, l'host e' down!' % (test_type.upper(), server_info)
    system('echo "%s" | mail -s "%s" %s' % (message, subject, email_address))
 
if __name__ == '__main__':
    if len(argv) != 4:
        print('Numero di argomenti errato.')
    elif not server_test(argv[1], argv[2]):
        send_error(argv[1], argv[2], argv[3])

Analizziamo questo script:

  1. nella prima parte vengono richiamate delle librerie usate all’interno dello script.
  2. il blocco tcp_test è la funzione che si occuperà di effettuare test tcp su una porta e un host passati come parametri.
  3. il blocco http_test è la funzione che si occuperà di effettuare test su protocollo http.
  4. il blocco server_test è la funzione che prende in carico i parametri passati allo script, li controlla e decide che tipo di test effettuare.
  5. il blocco send_error costruisce il messaggio da inviare e invoca il programma mail.
  6. l’ultimo blocco è di controllo, restituisce un errore se i parametri passati allo script non sono esatti, altrimenti richiama la funzione send_error.

A questo punto possiamo provare ad utilizzare manualmente lo script; nel caso in cui voglio effettuare un test tcp verso un host, i parametri da inviare allo script sono i seguenti:

root@ibm:/home/draven#python srvmon.py tcp drav.it:22 miamail@mioisp.it

oppure

root@ibm:/home/draven#python srvmon.py http http://www.drav.it miamail@mioisp.it

Nel primo caso, richiamo lo script e gli passo come parametri:
protocollo = tcp
host = drav.it
porta = 22
email del destinatario della notifica = miamail@mioisp.it

Nel secondo caso, il concetto è lo stesso ma, il test che eseguo è una richiesta http sulla porta 80 verso un host.

Ora quello che realmente ci interessa è automatizzare questo processo, per farlo utilizzeremo cron, una utility che nei sistemi operativi Unix Like si occupa di schedulare e automatizzare dei processi. Per modificare il cron e fargli avviare il nostro script digitiamo:

root@ibm:/home/draven#crontab -e

all’interno di cron inseriamo tante righe quanti sono gli host che vogliamo far controllare al nostro script, in questo modo:

*/5 * * * * python /home/draven/srvmon.py tcp host1:22 miamail@mioisp.it
*/5 * * * * python /home/draven/srvmon.py tcp host2:23 miamail@mioisp.it
*/5 * * * * python /home/draven/srvmon.py tcp host3:25 miamail@mioisp.it
ecc.

Fatto questo il cron avvierà ogni 5 minuti il controllo di tutti gli host che abbiamo inserito e lo script ci invierà una email nel caso in cui il test dell’host fallirà.