News Ticker

Configurare Nagios per ricevere Trap SNMP

nagios Per sua stessa natura, Nagios funziona generalmente in maniera "attiva", andando ad eseguire lui stesso i check verso gli host remoti, tramite script già forniti o custom, oppure interrogando direttamente un demone NRPE presente sulla macchina remota, e che in genere esegue check locali. Nagios, però, può essere configurato per eseguire dei check "passivi", ovvero fare in modo che un check che giri, possa essere messo in stati particolari da programmi estetrni. Questo è quello che normalmente succede quando si lavora sull'interfaccia web e si imposta, per esempio, un Acknowledge su un servizio, o si disabilitano le notifiche. La cosa interessante che andremo a fare in questo tutorial è un'ulteriore step. In pratica faremo in modo che non solo il server su cui gira Nagios possa ricevere delle trap SNMP, ma che Nagios stesso reagisca, in maniera predeterminata, a queste trap.

Facciamo un'esempio pratico (sarà poi quello utilizzato nel tutorial, e che è stato personalmente testato da me): un bilanciatore hardware F5 è stato configurato per lanciare delle trap verso una macchina Nagios. Questo bilanciatore invia non solo trap relative al suo stato, ma anche delle trap che indicano lo stato di un host reale bilanciato.
In pratica, quello che si otterrà è il seguente flusso di eventi:

  1. L'host reale ha qualche problema, e va in down (fisicamente, o anche il solo servizio bilanciato dall'F5)
  2. Il bilanciatore se ne accorge, disabilita il reale dal pool legato al VIP (Virtual IP)
  3. Il bilanciatore manda una trap verso il server su cui gira Nagios, identificando che un particolare host va in down
  4. Il server cattura la trap, la interpreta, ed inietta direttamente in Nagios un comando
  5. Nagios mette un particolare servizio in stato CRITICO, scatenando anche le notifiche del caso

In questo caso vediamo che non ci sono latenze dovute al timeslice di check di Nagios, ma la notifica è immediata alla verifica del problema.

Prima di entrare nel vivo del tutorial, tengo a precisare non verrà trattata l'installazione e/o la configurazione di Nagios (se non per quanto riguarda le parti relative al tutorial stesso), e l'ambiente su cui è stato testato il tutto gira attualmente con questo OS/questi software:

  • Debian GNU/Linux 6.0
  • Nagios3 presente sui repository Debian (Nagios 3.2.1-2)

Quindi farò riferimento ai path di default di questo sistema.
Bando alle ciance, andiamo ad incominciare 🙂

 

Configurare il sistema per ricevere le trap SNMP

Il primo passo è quello di far si che il nostro server (sul quale già sta girando Nagios) possa ricevere delle trap SNMP.
Niente di più semplice, dovreste avere già installato il pacchetto snmpd, nel caso in cui non lo fosse, un semplice

# apt-get install snmpd

vi risolverà il problema.
Questo pacchetto contiene un demone in grado di ricevere delle trap snmp. Per configurarlo editate il file /etc/default/snmpd aggiungendo/modificando le seguenti variabili:

TRAPDRUN=yes
TRAPDOPTS='-On -u snmptt -p /var/run/snmptrapd.pid'

Facendola breve diciamo di far partire il demone per le trap (TRAPDRUN=yes) e lo facciamo lanciare con le seguenti opzioni:

  • -On     Fa si che il demone usi gli OID in formato numerico, ed evita che il traduttore debba eseguire la traduzione dal formato testuale a quello numerico
  • -u snmptt     Fa girare il demone con l'utente snmptt
  • -p /var/run/snmptrapd.pid     Definisce il PIDfile in cui andare a scrivere il pid del processo

Andiamo quindi a definire cosa il demone snmptrapd deve fare alla ricezione di una trap. Modifichiamo quindi il file
/etc/snmp/snmptrapd.conf inserendo le seguenti direttive alla fine:

disableAuthorization yes
traphandle default /usr/sbin/smptt

In questo caso, diciamo al demone di disattivare l'autenticazione per l'invio delle trap (per questo tutorial useremo il metodo KISS: Keep It Simple and Stupid), e diciamo al demone di prendere tutte le trap e girarle al software /usr/sbin/smptt (di cui parleremo a breve).
Aspettiamo a riavviare il demone poiché dobbiamo prima assicurarci di aver installato SNMPTT.

 

Configurare il traduttore di trap SNMPTT

Il traduttore è una parte fondamentale. E' quel software che si occupa, una volta ricevuta la trap, di interpretarla, tradurla e scriverla da qualche parte.
La traduzione viene fatta utilizzando dei file .MIB che altro non sono che dizionari contenenti un riferimento TRAP -> MESSAGGIO.
Praticamente tutti i produttori di hardware che emettono trap SNMP forniscono i file .MIB necessari alla traduzione, e la F5 non è da meno.

Intanto installiamo il traduttore:

# apt-get install snmptt

Una volta installato, andiamo a modificare il file di configurazione /etc/snmp/snmptt.ini con i seguenti parametri:

mode = standalone          # Questo perché viene invocato da snmptrapd e non deve girare come demone
dns_enable = 0             # Evitiamo che risolva l'hostname per ogni trap che gli arriva
strip_domain = 0           # Diciamogli di non rimuovere il dominio dall'eventuale hostname
net_snmp_perl_enable = 1   # Può utilizzare il perl la traduzione
translate_value_oids = 1   # Traduce gli OID in formato testuale leggibile breve
translate_enterprise_oid_format = 1   # come sopra
translate_trap_oid_format = 1         # come sopra
translate_varname_oid_format = 1      # come sopra
log_enable = 1             # Abilita il logging delle trap
syslog_enable = 1          # Abilita il logging delle trap sul syslog
syslog_level = info        # Definisce il livello di logging per le trap su syslog

A questo punto portiamo sulla macchina i vari files .MIB relativi all'hardware che andrà a scatenare le trap e traduciamo questi file in formato comprensibile con snmptt. Nulla di più semplice:

# mkdir /etc/snmp/mibs    # In questa directory metteremo tutti i mib tradotti
# snmpttconvertmib --in=F5-BIGIP-COMMON.mib --out=F5-BIGIP-COMMON.conf
# mv F5-BIGIP-COMMON.conf /etc/snmp/mibs/

 

Lanciamo il comando per tutti i MIB che ci fornisce il produttore.
A questo punto, riapriamo il file di configurazione di snmptt (/etc/snmp/snmptt.ini) e terminiamo la configurazione aggiungendo/modificando alla fine:

snmptt_conf_files = <<END
/etc/snmp/snmptt.conf
/etc/snmp/mibs/F5-BIGIP-COMMON.conf
END

Riga per riga, andiamo a mettere tutti i file .conf che abbiamo generato con smpttconvertmib. A questo punto possiamo restartare il demone SNMPD (così da far partire il gestore di trap) e verificare che sia effettivamente partito:

# /etc/init.d/snmpd restart
# cat /var/run/snmptrapd.pid
7464

Perfetto, mettiamoci in tali sul file del syslog (per default il /var/log/messages) e dovremmo iniziare a veder passare le trap:

# tail -f /var/log/messages
Sep 20 11:23:40 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.29 Normal "Status Events" 192.168.0.1 - The system is in an unusable situation. AUDIT - user admin - RAW: httpd(mod_auth_pam): user=admin(admin) partition=[All] level=Administrator tty=1 host=10.10.0.1 attempts=1 start=\"Tue Sep 20 11:03:00 2011\" end=\"Tue Sep 20 11:23:30 2011\".

Ottimo, riceviamo le trap, ora dobbiamo trovare il modo di dire a Nagios che questa trap ha un significato, dirgli quale, e di scatenare un evento… procediamo 😀

 

Catturare le trap

Ci viene in aiuto un'ottimo tool di nome SEC. Questo tool, in maniera generale, permette di analizzare live il contenuto di un file (quindi resta in ascolto ed analizza i nuovi contenuti) e di eseguire determinate operazioni a verificarsi di particolari eventi.
Nel nostro caso, lo metteremo in ascolto sul file in cui vengono slogate le trap /var/log/messages e, con il match su di una particolare RegExp, viene lanciato uno script con determinati parametri.
SEC è uno script in perl, ma ne esiste comunque una versione pacchettizzata per debian, dunque:

# apt-get install sec

Una volta installato, andiamo a modificare il file di configurazione /etc/sec.conf, inserendo i seguenti parametri:

type=Single
ptype=RegExp
pattern=.*(Normal|INFORMATIONAL|MINOR|WARNING|SEVERE|MAJOR|CRITICAL)\ \"Status Events\"\ (\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)\ \-\ (A service is detected (UP|DOWN)\.\ Pool\ member\ (\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)(.*)|(.*))
desc=snmptrap received from $2
action=shellcmd /usr/lib/nagios/eventhandlers/snmptraphandling.sh $2 $1 "$3" $4 $5

In pratica viene detto a SEC di eseguire la "action" quando un testo fa match con la regular expression definita in pattern. Senza stare li a parlare di regular expression (potremmo andare avanti per giorni e giorni), se arriva una trap SNMP con il seguente testo:

Sep 20 11:23:40 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.29 Normal "Status Events" 192.168.0.1 - The system is in an unusable situation. AUDIT - user admin - RAW: httpd(mod_auth_pam): user=admin(admin) partition=[All] level=Administrator tty=1 host=10.10.0.1 attempts=1 start=\"Tue Sep 20 11:03:00 2011\" end=\"Tue Sep 20 11:23:30 2011\".

otteniamo in output le seguenti variabili:

$1 = Normal
$2 = 192.168.0.1
$3 = The system is in an unusable situation. AUDIT - user admin - RAW: httpd(mod_auth_pam): user=admin(admin) partition=[All] level=Administrator tty=1 host=10.10.0.1 attempts=1 start=\"Tue Sep 20 11:03:00 2011\" end=\"Tue Sep 20 11:23:30
$4 =
$5 =

Come vediamo le ultime due variabili sono vuote. Nel caso, invece, ci arrivi una trap formata in quest'altra maniera (che indica lo stato UP/DOWN di un server fisico controllato dal bilanciatore):

Sep 20 11:47:33 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.10 Normal "Status Events" 192.168.0.1 - A service is detected DOWN. Pool member 192.168.0.100:18009 monitor status down. 192.168.0.100 18009

otteniamo, invece, in output le seguenti variabili:

$1 = Normal
$2 = 192.168.0.1
$3 = A service is detected DOWN. Pool member
$4 = DOWN
$5 = 192.168.0.100

In quest'altro caso le ultime due variabili sono valorizzate ed identificano, rispettivamente, lo stato del reale (UP o DOWN) ed il reale in question (192.168.0.100).

Ovviamente, questa RegExp è stata costruita in funzione di come SNMPTT, con i MIB forniti da F5, traduce le trap. Hardware differente, con MIB differenti, tradurranno le trap in maniera differente, e sarà quindi necessario andare a trovare una RegExp funzionante per quella casistica.

Ne approfitto per segnalare il link http://gskinner.com/RegExr/ veramente molto comodo per scrivere e testare le RegExp.

Quindi, abbiamo intercettato le trap con SEC, ed eseguiamo questo script /usr/lib/nagios/eventhandlers/snmptraphandling.sh passandogli le 5 variabili ottenute dalla RegExp, siano esse valorizzate o meno. Ma cosa fa questo script?

 

snmptraphandling.sh

Ho scritto personalmente questo script, basandomi su un'idea di Francois Meehan, autore di uno script python simile ma meno specializzato.

Potete scaricarlo da qui: snmptraphandling.zip

Questa versione in bash accetta in ingresso le seguenti variabili (nel seguente ordine):

HOST: Obbligatoria, identifica l'host che ha inviato la trap
SEVERITY: Obbligatoria, identifica il "peso" della trap (Normal, critical, etc.) così come viene definita da F5
"DATA": Obbligatoria dentro i doppi apici. Contiene un testo che identifica meglio la trap, una descrizione
UP|DOWN: Opzionale, identifica lo stato di un reale
ALARMEDHOST: Opzionale, identifica l'host al quale viene applicata la variabile precedente.

Intanto lo script definisce, a seconda della SEVERITY, che valori applicare al Nagios.
Inoltre, nel caso vengano specificate anche le ultime due variabili, esegue operazioni differenti per scatenare allarmi specifici.

Ma come dialoga con Nagios? Semplicissimo, costruisce un comando ad-hoc interpretabile da Nagios, e lo inetta nel file

/var/lib/nagios3/rw/nagios.cmd

Questo file è specializzato per inviare segnali a Nagios e fargli eseguire operazioni particolari.

In pratica, all'arrivo di una trap viene scatenato un evento indirizzato all'host $HOST, per un servizio chiamato:

snmp_trap_handling_$HOST-…. Nel caso in cui non siano specificate le ultime 2 variabili
snmp_trap_handling_$ALARMED_HOST Nel caso in cui siano specificate le ultime 2 variabili.

Ma prendiamo in mano un'esempio completo, così da essere più chiari.
Ci arriva dal bilanciatore, per esempio, una trap SNMP che ci identifica che un'host è andato giù; all'interno del file
/var/log/messages verrà scritto (da SNMPTT) il seguente messaggio:

Sep 20 11:47:33 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.10 Normal "Status Events" 192.168.0.1 - A service is detected DOWN. Pool member 192.168.0.100:18009 monitor status down. 192.168.0.100 18009

SEC vedrà che questo testo fa match con la RegExp che gli abbiamo applicato, e lancerà questo comando:

/usr/lib/nagios/eventhandlers/snmptraphandling.sh 192.168.0.1 Normal \
"A service is detected DOWN. Pool member" DOWN 192.168.0.100

Lo script prenderà questi valori, li andrà ad elaborare (per esempio, cercando nelle configurazioni di nagios, andrà a tradurre 192.168.0.1 con bil-f5, che altro non è che il nome dell'host specificato in nagios) ed inietterà il seguente testo nel file
/var/lib/nagios3/rw/nagios.cmd:

[1316513822] PROCESS_SERVICE_CHECK_RESULT;bil-f5;snmp_trap_handling_192.168.0.100;2;A service is detected DOWN. Pool member 192.168.0.100:18009 monitor status down. 192.168.0.100

Questo testo fa si che il servizio "snmp_trap_handling_192.168.0.100" venga applicato lo stato 2, ovvero il CRITICAL per Nagios.

Configurare Nagios

Per configurare il Nagios, andremo a creare 3 strutture nuove: la prima è un servizio template che funziona in passivo e che viene usato per creare qualsiasi servizio relativo alle trap snmp; la seconda è l'host che identifica il bilanciatore; la terza è il servizio vero e proprio che verrà messo in critical o meno all'arrivo della trap.
Quindi:

define service {
name generic-snmptrap
active_checks_enabled 1
passive_checks_enabled 1 ; Passive service checks are enabled
is_volatile 1
initial_state o
check_period never
notification_interval 120
notification_options w,u,c,r
notification_period 24x7
check_command return-ok
max_check_attempts 1
check_freshness 0
stalking_options o,w,u,c
register 0 ; Not register. Its just a template
}

Notiamo alcune configurazioni particolari:

passive_checks_enabled 1 Determina che il servizio risponde a check passivi

active_checks_enabled 1 Attiva anche i check attivi. Questo è stato fatto solo perché personalmente trovo che
Nagios debba sempre mostrare uno stato completamente verde. Disattivando i
check attivi, nel TacticalOverview di Nagios avremmo un host segnalato in rosso.

check_period never Non vengono mai schedati check per questo servizio (questo perché il servizio
risponde a delle trap e non esegue direttamente i check)

check_command return-ok Attivando i check attivi, è necessario definite un check_command. Ho usato
return-ok che è un check standard di Nagios che ritorna sempre un stato OK

stalking_options o,w,u,c Questo serve per evitare che mille trap dello stesso tipo vadano a saturare il
Nagios

A questo punto definiamo l'host:

define host{
use generic-host
host_name bil-f5
alias bil-f5
address 192.168.0.1
}

ed infine il servizio:

define service{
use generic-snmptrap
host_name bil-f5
service_description snmp_trap_handling_192.168.0.100
}

Vediamo quindi che, il match che esegue il Nagios, è sulla descrizione del servizio.

 

Conclusioni

Abbiamo infine visto il giro del fumo. Sembrano tante parole ed il tutto molto complicato, ma vi assicuro che, una volta implementato, va tutto liscio come l'olio.

Buon lavoro 🙂

  • Cristiano

    Ho seguito la guida ma quando faccio
    # tail -f /var/log/messages
    non vedo passare alcun trap e quindi mi sono fermato qui con la guida...
    Come mai?

    Uso Ubuntu con Nagios 3.4.1
    Grazie

  • Ciao Cristiano,

    l'unico dubbio che mi viene è che la tua Ubuntu non stia loggando nel file /var/log/messages. Prova a buttare un'occhio al /var/log/syslog per vedere se le trap sono finite li, in ogni caso trovi specifiche sul file/device di log del tuo sistema nel file /etc/rsyslog.conf.

  • Cristiano

    Grazie per l'immediata risposta.
    Immagino tu volessi dire /etc/"S"yslog.conf 😉

    Ho vari file di log dove sono finite delle trap snmptt ma mai quelle di Nagios! Sono del tipo
    Dec 11 16:50:00 nomemacchinamia snmptt-sys[0]: Loading /etc/snmp/mibs/CISCO-PRODUCTS-MIB.conf
    Dec 11 16:50:00 nomemacchinamia snmptt-sys[0]: Finished loading 5 lines from /etc/snmp/mibs/CISCO-PRODUCTS-MIB.conf

  • Ciao Cristiano,
    nono, intendevo proprio rsyslog. A parte di modifiche manuali (e non conosco la versione di Ubuntu che stai utilizzando), il demone di syslog di default del sistema di Canonical è rsyslog.

    Quei log che mi hai segnalato indicano che snmptt ha caricato correttamente i mibs, e che /dovrebbe/ ricevere le trap.

    Prova a verificare nel file /etc/snmp/snmptt.ini alla riga log_file cosa c'è. Personalmente ho /var/log/snmptt/snmptt.log, ed in quel file mi ritrovo tutte le trap (oltre che nel messages come da tutorial).

    Ciao

  • Cristiano

    Ho bisogno di aiuto in generale, magari è necessario un contatto in privato.
    Sono quindi andato avanti e installato sec. Innanzitutto non mi ha creato il file /etc/sec.conf (lo faccio io a mano?) e poi non ho confidenza con gli script e quindi sono piantato con snmphandling.zip

  • Cristiano

    Ciao Matteo, avevo del casino tra syslog"d" e rsyslog.
    In pratica rsyslog (syslog avanzato), quello di default di Ubuntu, spedisce i log nel file /var/log/messages, mentre syslogd (vecchio syslog) si sovrapponeva e modificava sta cosa, creandomi delle modifiche che non avevo previsto.
    Il tutorial è quindi perfettamente funzionante, grande!
    Ho capito il funzionamento di sec e adesso farò pratica con le regex. Ho inoltre migliorato le mie Nagios conoscenze, cercherò poi di capire bene il tuo script..

  • [root@nagios etc]# /usr/local/nagios/libexec/check_nrpe -H 172.16.1.248 CHECK_NRPE: Socket timeout after 10 seconds.

  • Hi Clyde,

    what is the problem exactly? Can you explain better your situation?

    Thanks
    Matteo

  • The next few fields are completely up to you and what you wish Nagios to output to the trap receiver. In my case, $HOSTNAME$ – The monitored host, $SERVICEDESC$ – service description, $SERVICESTATEID$ – the Nagios state id like 0 for OK, 1 – for warning etc…and $SERVICEOUTPUT$ – The additional info field from the plug-in is sufficient. You may add more if you like where you deem necessary.

  • Eric Zorzi

    Ciao Matteo,
    ho un problema quando eseguo:
    snmpttconvertmib --in=F5-BIGIP-COMMON.mib --out=F5-BIGIP-COMMON.conf
    mi da il seguente errore:
    root@ettore:/etc/snmp# snmpttconvertmib --in=F5-BIGIP-COMMON.mib --out=F5-BIGIP-COMMON.conf

    ***** Processing MIB file *****

    snmptranslate version: NET-SNMP version: 5.4.3
    severity: Normal

    File to load is: ./F5-BIGIP-COMMON.mib
    File to APPEND TO: ./F5-BIGIP-COMMON.conf

    MIBS environment var: ./F5-BIGIP-COMMON.mib
    Cannot open input file: File o directory non esistente at /usr/sbin/snmpttconvertmib line 185.

    Come lo risolvo?
    Grazie in anticipo!

  • Ciao Eric,

    probabilmente non trova il file F5-BIGIP-COMMON.mib nella directory in cui ti trovi. Se l'hai messo in un'altro path, prova a specificarlo per intero:

    # snmpttconvertmib –in=/patch/completo/F5-BIGIP-COMMON.mib –out=F5-BIGIP-COMMON.conf

    Fammi sapere,
    Ciao

  • Luciano82

    Ciao Matteo e grazie per il tutorial,
    io ho installato tutto fino alla sezione "sec " poiche non vedo arrivare le trap da un router Cisco , di sotto un po'di logs:

    root@Luciano:/var/log/snmptt# tail -f /var/log/syslog
    Jun 12 12:54:29 Luciano snmptt-sys[0]: Loading /etc/snmp/snmptt.conf
    Jun 12 12:54:29 Luciano snmptt-sys[0]: Finished loading 64 lines from /etc/snmp/snmptt.conf
    Jun 12 12:54:29 Luciano snmptt-sys[0]: Loading /etc/snmp/mibs/OLD-CISCO-TS-MIB.conf
    Jun 12 12:54:29 Luciano snmptt-sys[0]: Finished loading 5 lines from /etc/snmp/mibs/OLD-CISCO-TS-MIB.conf
    Jun 12 12:54:29 Luciano snmptt-sys[0]: Changing to UID: snmptt (119)

    Hai esperienze in merito con i Cisco per potermi dare un consiglio ?

    Ciao e grazie

    Luciano

  • Raffaele

    Salve,
    io ho configurato il syslog per un catalyst 2950 di Cisco.
    Arrivano le trap di UP/Down delle interfaccie sul /var/log/syslog.
    Come faccio a dire a snmptt di andare a pescarle e metterle nel /var/log/messages come da tutorial?

  • @Luciano: Prego! Dai log di snmptt pare che i MIB siano stati caricati correttamente. Hai provato a guardare nel /var/log/messages, magari le trap arrivano li. In ogni caso, butta un'occhio alle opzioni 'syslog_enable', 'enable_log' e 'log_file' nella configurazione di snmptt: dovrebbero chiariti dove finiscono le trap. Purtroppo son supposizioni poichè esperienza diretta con trap provenienti da Cisco non ne ho.

    @Raffaele: Anche nel tuo caso, probabilmente è attiva l'opzione per utilizzare il syslog (syslog_enable). Prova a controllare il contenuto delle opzioni 'enable_log' e 'log_file', magari a disattivare il syslog, così da scegliere dove far finire le trap snmp.

    Ciao a tutti
    Matteo

  • Ciao Matteo,

    ho da chiederti una cosa. Per esigenze del sistema integrato Hp Proliant Management Homepage, temo che le mie trap siano loggate in var/log/syslog. Come posso fare per dire a snmptt di leggere le trap da li invece che da /var/log/message? è possibile? Altrimenti cosa mi consiglieresti di fare? grazie in anticipo.

  • Ciao,
    sto seguendo la tua guida, però quando devo convertire i MIB file mi compare questo messaggio "Cannot adopt OID in INNO-MIB: voiceIfEntry ::= { voiceIfTable 1 }" (per tutte le trap nel file)
    Total translations: 8
    Successful translations: 0
    Failed translations: 8
    Ho dimenticato qualche pasaggio o è un problema dei MIB files?
    Grazie,
    Luca

  • Ciao Luca,
    tendenzialmente errori di questo tipo si hanno proprio quando il MIB non ha una corrispondenza esatta, quindi la traduzione fallisce. Poova a controllare i dati che hai nel MIB sulla base di quel che vedi nel file delle trap.

  • Errore (manca una "n"):
    traphandle default /usr/sbin/smptt -> traphandle default /usr/sbin/snmptt