5. Addon di Nagios

Una delle principali feature di Nagios è la sua estendibilità; nuove funzionalità possono essere aggiunte grazie alla sua architettura a plugin, i comandi esterni o il server web Apache. In questo capitolo, vedremo alcuni dei problemi più frequenti che possono essere risolti con alcuni dei più popolari addon per Nagios.

5.1 NRPE

Ipotizziamo di volere che Nagios tenga d'occhio dei servizi locali su host remoti, come per esempio l'uso dello spazio disco, il carico di sistema o il numero di utenti attualmente loggati. Non si tratta di servizi di rete, quindi non possono essere monitorati direttamente con plugin standard: l'ideale sarebbe qualche sorta di agente da installare sui sistemi remoti e che Nagios possa interrogare periodicamente sullo stato dei servizi locali.

Ebbene, è esattamente ciò che fa il Nagios Remote Plugin Executor (NRPE): consente di eseguire plugin locali su host remoti! È formato da due componenti:

Sia l'agente che il plugin sono inclusi nel seguente package:

In aggiunta, il package dei plugin di Nagios viene installato come dipendenza sull'host monitorato: questo consente all'agente NRPE di usare i plugin standard di Nagios per effettuare i check locali. L'installazione del package crea automaticamente l'utente e il gruppo _nrpe con cui girerà il demone e copierà un file di configurazione nrpe.cfg di esempio in /etc/:

/etc/nrpe.cfg
# La facility di syslog da usare per i log
log_facility=daemon

# Percorso del pid file (ignorato se sotto inetd)
pid_file=/var/run/nrpe.pid

# Indirizzo su cui stare in ascolto (ignorato se sotto inetd)
server_address=172.16.0.170
# Porta su cui aspettare le connessioni (ignorato se sotto inetd)
server_port=5666

# Utente e gruppo con cui dovrebbe girare il demone NRPE (ignorato se sotto
# inetd)
nrpe_user=_nrpe
nrpe_group=_nrpe

# Lista di indirizzi IP o hostname, separati da virgola, abilitati a connettersi
# al demone NRPE (ignorato se sotto inetd)
allowed_hosts=127.0.0.1,172.16.0.164

# Non consentire ai client di specificare gli argomenti dei comandi da eseguire
dont_blame_nrpe=0

# Scommenta la seguente opzione per preporre una stringa a tutti i comandi
#command_prefix=/usr/bin/sudo

# Non loggare i messaggi di debug su syslog
debug=0

# Durata massima (in secondi) dei plugin eseguiti
command_timeout=60

# Le definizioni dei comandi sono nella forma:
#
#   command[<command_name>]=<command_line>
#
# In pratica, quando NRPE riceve la richiesta di eseguire il comando
# 'command_name', eseguira' lo script *locale* specificato da 'command_line'.
# Nota: le macro NON sono ammesse all'interno delle definizioni dei comandi
command[check_users]=/usr/local/libexec/nagios/check_users -w 5 -c 10
command[check_load]=/usr/local/libexec/nagios/check_load -w 15,10,5 -c 30,25,20
command[check_disk1]=/usr/local/libexec/nagios/check_disk -w 20 -c 10 -p /dev/wd0a
command[check_total_procs]=/usr/local/libexec/nagios/check_procs -w 150 -c 200

Per eseguire NRPE come demone standalone, basta eseguire il comando:

# /usr/local/sbin/nrpe -c /etc/nrpe.cfg -d

e aggiungere le seguenti righe nel file /etc/rc.local per avviarlo automaticamente al reboot:

/etc/rc.local/
if [ -x /usr/local/sbin/nrpe ]; then
    echo -n ' nrpe'
    /usr/local/sbin/nrpe -c /etc/nrpe.cfg -d
fi

In alternativa, è possibile eseguire NRPE sotto inetd(8) aggiungendo la seguente riga in /etc/inetd.conf(8):

/etc/inetd.conf
nrpe	stream	tcp	wait	_nrpe:_nrpe	/usr/local/sbin/nrpe	nrpe -c /etc/nrpe.cfg -i

e aggiungendo il servizio nrpe in /etc/services(5):

/etc/services
nrpe	5666/tcp	# Nagios Remote Plugin Executor

e quindi inviando il segnale di hangup al demone inetd(8), per fargli rileggere la propria configurazione:

# pkill -HUP inetd

Ora, sul server Nagios, è possibile eseguire controlli usando NRPE semplicemente definendo comandi come il seguente (occorre naturalmente assicurarsi che il nome del comando passato con l'opzione "-c" abbia una definizione di comando corrispondente nel file nrpe.cfg sull'host remoto!):

/var/www/etc/nagios/commands.cfg
define command {
    command_name    check-disk1-nrpe
    command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_disk1
}

5.2 NSCA

Ora si supponga di voler monitorare l'esito di un processo su un host remoto, come un backup schedulato o un job in crontab. Si tratta sempre di servizi "locali", ma, a differenza dello spazio disco o il carico di sistema, suona probabilmente più logico affidare al job stesso la responsabilità della notifica del suo esito. Questo è il lavoro perfetto per il Nagios Service Check Acceptor (NSCA), che è un demone, che gira sul server Nagios, progettato per accettare i risultati di controlli passivi dai client.

NSCA è simile a NRPE essendo formato da un processo demone e un'applicazione client, ma ora i ruoli sono invertiti: il processo demone gira sul server Nagios mentre gli host remoti usano l'utility send_nsca per comunicare il loro stato al demone. NSCA inoltra quindi i risultati dei check a Nagios tramite i comandi esterni (occorre quindi assicurarsi di aver abilitato i comandi esterni nel file di configurazione principale).

5.2.1 Configurazione del server

NSCA può girare come demone standalone o sotto inetd(8). Per installare i componenti server bisogna aggiungere i seguenti package sul server Nagios:

Quindi, occorre editare il file di configurazione /etc/nsca.cfg:

/etc/nsca.cfg
# Percorso del pid file (ignorato se sotto inetd)
pid_file=/var/run/nrpe.pid

# Indirizzo su cui stare in ascolto (facoltativo)
server_address=172.16.0.164
# Porta su cui aspettare le connessioni
server_port=5667

# Utente e gruppo con cui deve girare il demone NSCA (ignorato se sotto inetd)
nsca_user=_nagios
nsca_group=_nagios

# Directory di chroot(2) per il demone NSCA
nsca_chroot=/var/www/var/nagios/rw

# Non loggare i messaggi di debug su syslog
debug=0

# Percorso del command file (relativo alla directory di chroot)
command_file=nagios.cmd
# File su cui scrivere i risultati dei check se il command file non esiste
alternate_dump_file=nsca.dump

# Non raggruppare le scritture al command file
aggregate_writes=0
# Apri il command file in modalita' scrittura
append_to_file=0

# Eta' massima di un pacchetto (in secondi)
max_packet_age=30

# Password per decriptare i pacchetti in arrivo
password=password
# Metodo di decriptaggio (16 = RIJNDAEL-256). Deve combaciare col metodo di
# criptaggio usato dal client
decryption_method=16

Conviene impostare permessi restrittivi (600) sul file di configurazione per proteggere la password di decriptaggio. Per lanciare NSCA come demone standalone, basta digitare:

# /usr/local/sbin/nsca -c /etc/nsca.cfg

e aggiungere le seguenti righe a /etc/rc.local per avviarlo automaticamente al reboot:

/etc/rc.local
if [ -x /usr/local/sbin/nsca ]; then
    echo -n ' nsca'
    /usr/local/sbin/nsca -c /etc/nsca.cfg
fi

In alternativa, è possibile eseguirlo sotto inetd(8) aggiungendo la seguente riga in /etc/inetd.conf(8):

/etc/inetd.conf
nsca	stream	tcp	wait	_nagios:_nagios	/usr/local/sbin/nsca	nsca -c /etc/nsca.cfg --inetd

e aggiungendo il servizio nsca in /etc/services(5):

/etc/services
nsca	5667/tcp	# Nagios Service Check Acceptor

e inviando il segnale di hangup al demone inetd(8), per fargli rileggere la configurazione:

# pkill -HUP inetd

5.2.2 Configurazione del client

Lato client, dobbiamo installare i seguenti package:

ed editare i parametri di crittografia nel file di configurazione /etc/send_nsca.cfg:

/etc/send_nsca.cfg
# Password da usare per criptare i pacchetti in uscita
password=password
# Metodo crittografico (16 = RIJNDAEL-256)
encryption_method=16

L'utility send_nsca legge i dati da standard input e si aspetta, per quanto rigarda i controlli su servizi, una sequenza, separata da tab, di nome host, descrizione del servizio (cioè il valore della direttiva service_description nella definizione del servizio), return code e output; ad es.:

echo "www1\tbackup\t0\tBackup completed successfully" | /usr/local/libexec/nagios/send_nsca -H nagios.kernel-panic.it

e, per quanto riguarda i controlli su host, una sequenza, separata da tab, di nome host, return code e output; ad es.:

echo "router1\t2\tRouter #1 is down" | /usr/local/libexec/nagios/send_nsca -H nagios.kernel-panic.it

È possibile modificare il delimitatore di default (tab) tramite l'opzione "-d" di send_nsca. Ora, se tutto funziona a dovere, ogni messaggio ricevuto dal demone NSCA dovrebbe produrre una riga come la seguente nel file di log di Nagios:

/var/www/var/log/nagios/nagios.log
[1167325538] EXTERNAL COMMAND: PROCESS_SERVICE_CHECK_RESULT;www1;backup;0;Backup completed successfully

5.3 NagVis e NDO

NagVis è un addon di visualizzazione per Nagios; può essere usato per offrire agli utenti una rappresentazione grafica personalizzata dei dati di Nagios. Richiede l'installazione di PHP e alcune librerie:

Apache è già attivo, quindi dobbiamo solo attivare i moduli php appena installati:

# ln -s /var/www/conf/modules.sample/php5.conf /var/www/conf/modules
# ln -fs /var/www/conf/php5.sample/gd.ini /var/www/conf/php5/gd.ini
# ln -fs /var/www/conf/php5.sample/mysql.ini /var/www/conf/php5/mysql.ini

scommentare la seguente riga in /var/www/conf/httpd.conf:

/var/www/conf/httpd.conf
AddType application/x-httpd-php .php

e riavviare Apache:

# apachectl restart
/usr/sbin/apachectl restart: httpd restarted

5.3.1 Installazione di NDO e MySQL

Prima della versione 1.0, NagVis era in grado di recuperare i dati di Nagios direttamente dall'interfaccia web; ora questa modalità non è più supportata e NagVis si aspetta che i dati di monitoraggio siano mantenuti all'interno di un database MySQL, richiedendo quindi l'installazione dell'addon Nagios Data Output Utils (NDOUTILS).

L'addon NDOUTILS consente di esportare i dati attuali e quelli storicizzati da una o più istanze di Nagios a un database MySQL, fungendo quindi da interfaccia fra Nagios e MySQL. Questo addon è formato da vari componenti, ma a noi ne serviranno solo un paio:

Per prima cosa, dobbiamo installare MySQL; la seguente è la lista dei package richiesti:

Quindi, dobbiamo scaricare, estrarre e compilare il tarball di NDOUTILS:

# tar -zxvf ndoutils-x.x.x.tar.gz
[ ... ]
# cd ndoutils-x.x.x
# ./configure --disable-pgsql --enable-mysql --with-mysql-lib=/usr/local/lib \
>   --with-mysql-inc=/usr/local/include
[ ... ]
# make

Nota: nel caso make fallisse compilando il file dbhandlers.c, prova ad applicare questa patch (valida per la versione 1.4b9) eseguendo il seguente comando dall'esterno del source tree di ndoutils:

# patch -p0 < ndo-openbsd.patch

Ora possiamo avviare MySQL, assegnare una password all'utente root e creare database e utente. Lo script di creazione del database si trova all'interno della directory db/ dell'archivio estratto.

# cp /usr/local/share/mysql/my-medium.cnf /etc/my.cnf
# /usr/local/bin/mysql_install_db
[ ... ]
# mysqld_safe &
Starting mysqld daemon with databases from /var/mysql
# /usr/local/bin/mysql_secure_installation
[ ... ]
Enter current password for root (enter for none): <enter>
[ ... ]
Set root password? [Y/n] Y

New password: root
Re-enter new password: root
[ ... ]
Remove anonymous users? [Y/n] Y
[ ... ]
Disallow root login remotely? [Y/n] Y
[ ... ]
Remove test database and access to it? [Y/n] Y
[ ... ]
Reload privilege tables now? [Y/n] Y

[ ... ]
# mysql -u root -p
password: root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Server version: 5.0.51a-log OpenBSD port: mysql-server-5.0.51a

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database nagios;
Query OK, 1 row affected (0.02 sec)

mysql> use nagios;
Database changed
mysql> \.  db/mysql.sql

[...]
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON nagios.* TO 'ndouser'@'localhost' IDENTIFIED BY 'ndopasswd';
mysql> \q

Adesso dobbiamo copiare manualmente i binari e i file di configurazione:

# cp src/ndomod-3x.o /usr/local/libexec/nagios/ndomod.o
# cp config/ndomod.cfg-sample /var/www/etc/nagios/ndomod.cfg
# cp src/ndo2db-3x /usr/local/sbin/ndo2db
# cp config/ndo2db.cfg-sample /var/www/etc/nagios/ndo2db.cfg

ed editare il file di configurazione di NDOMOD:

/var/www/etc/nagios/ndomod.cfg
instance_name=default
output_type=unixsocket
output=/var/nagios/rw/ndo.sock

output_buffer_items=5000
buffer_file=/var/nagios/rw/ndomod.tmp

file_rotation_interval=14400
file_rotation_timeout=60

reconnect_interval=15
reconnect_warning_interval=15
data_processing_options=-1
config_output_options=3

e il file di configurazione di NDO2DB:

/var/www/etc/nagios/ndo2db.cfg
lock_file=/var/run/nagios/ndo2db.lock

ndo2db_user=_nagios
ndo2db_group=_nagios

socket_type=unix
socket_name=/var/www/var/nagios/rw/ndo.sock

db_servertype=mysql
db_host=localhost
db_port=3306
db_name=nagios
db_prefix=nagios_
db_user=ndouser
db_pass=ndopasswd

max_timedevents_age=1440
max_systemcommands_age=10080
max_servicechecks_age=10080
max_hostchecks_age=10080
max_eventhandlers_age=44640

debug_level=0
debug_verbosity=1
debug_file=/var/www/var/log/nagios/ndo2db.debug
max_debug_file_size=1000000

Quindi dobbiamo dire a Nagios di caricare il modulo NDOMOD all'avvio, aggiungendo questa riga al file di configurazione principale:

/var/www/etc/nagios/nagios.cfg
broker_module=/usr/local/libexec/nagios/ndomod.o config_file=/var/www/etc/nagios/ndomod.cfg

e, finalmente, possiamo lanciare il demone NDO2DB e riavviare Nagios:

# /usr/local/sbin/ndo2db -c /var/www/etc/nagios/ndo2db.cfg
# chmod 770 /var/www/var/nagios/rw/ndo.sock
# pkill nagios
# nagios -d /var/www/etc/nagios/nagios.cfg

Si aggiungano le seguenti righe righe a /etc/rc.local per avviare il demone NDO2DB all'avvio:

/etc/rc.local
if [ -x /usr/local/sbin/ndo2db ]; then
    echo -n ' ndo2db'
    /usr/local/sbin/ndo2db -c /var/www/etc/nagios/ndo2db.cfg
    chmod 770 /var/www/var/nagios/rw/ndo.sock
fi

5.3.2 Configurazione di NagVis

Ora che abbiamo installato tutti i prerequisiti necessari, possiamo scaricare ed estrarre il tarball di NagVis:

# tar -zxvf nagvis-x.x.x.tar.gz -C /var/www/nagios/
[ ... ]
# mv /var/www/nagios/nagvis-x.x.x /var/www/nagios/nagvis
# chown -R www /var/www/nagios/nagvis/{etc,var}

Il seguente è un tipico file di configurazione di NagVis; si veda la documentazione per una descrizione dettagliata di ogni parametro:

/var/www/nagios/nagvis/etc/nagvis.ini.php
; <?php return 1; ?>

[global]
[global]
language               = "en_US"
refreshtime            = 60
dateformat             = "Y-m-d H:i:s"

[defaults]
backend                = "ndomy_1"
; Dimensione di default delle icone (le icone si trovano nella directory
; /var/www/nagios/nagvis/images/iconsets)
icons                  = "std_medium"
recognizeservices      = 1
onlyhardstates         = 0
backgroundcolor        = "#fff"
contextmenu            = 1
eventbackground        = 0
eventhighlight         = 1
eventhighlightduration = 10000
eventhighlightinterval = 500
eventlog               = 0
eventloglevel          = "info"
eventlogheight         = 75
eventloghidden         = 1
eventscroll            = 1
eventsound             = 1
headermenu             = 1
headertemplate         = "default"
hovermenu              = 1
hovertemplate          = "default"
hoverdelay             = 0
hoverchildsshow        = 1
hoverchildslimit       = 10
hoverchildsorder       = "asc"
hoverchildssort        = "s"
icons                  = "std_medium"
onlyhardstates         = 0
recognizeservices      = 1
showinlists            = 1
urltarget              = "_self"
hosturl                = "[htmlcgi]/status.cgi?host=[host_name]"
hostgroupurl           = "[htmlcgi]/status.cgi?hostgroup=[hostgroup_name]"
serviceurl             = "[htmlcgi]/extinfo.cgi?type=2&host=[host_name]&service=[service_description]"
servicegroupurl        = "[htmlcgi]/status.cgi?servicegroup=[servicegroup_name]&style=detail"

[wui]
autoupdatefreq         = 25
maplocktime            = 5
allowedforconfig       = nagiosadmin

[paths]
base                   = "/nagios/nagvis/"
htmlbase               = "/nagios/nagvis"
htmlcgi                = "/cgi-bin/nagios"

[index]
backgroundcolor        = #fff
cellsperrow            = 4
headermenu             = 1
headertemplate         = "default"
showrotations          = 1

[automap]
defaultparams          = "&maxLayers=2"
showinlists            = 0

[worker]
interval               = 10
requestmaxparams       = 0
requestmaxlength       = 1900
updateobjectstates     = 30

[backend_ndomy_1]
backendtype            = "ndomy"
dbhost                 = "127.0.0.1"
dbport                 = 3306
dbname                 = "nagios"
dbuser                 = "ndouser"
dbpass                 = "ndopasswd"
dbprefix               = "nagios_"
dbinstancename         = "default"
maxtimewithoutupdate   = 180
htmlcgi                = "/cgi-bin/nagios"

; In questo esempio, il browser alterna le mappe 'dmz' e 'lan' ogni 15 secondi
; La rotazione viene abilitata accedendo all'URL:
; https://your.nagios.server/nagios/nagvis/index.php?rotation=kp
[rotation_kp]
maps                   = "dmz,lan"
interval               = 15

5.3.3 Definizione delle mappe

Ora dobbiamo creare le immagini che NagVis userà come sfondo per ogni mappa e metterle nella directory /var/www/nagios/nagvis/images/maps. Alcuni esempi sono disponibili qui.

Quando le immagini sono pronte, possiamo dire a NagVis in quali punti delle mappe piazzare gli oggetti, creando ed editando i file di configurazione delle mappe. Ogni mappa deve avere un file di configurazione corrispondente (in /var/www/nagios/nagvis/etc/maps/) con lo stesso nome più l'estensione ".cfg". Di seguito un file di configurazione di esempio; la sintassi è abbastanza semplice, quindi non dovrebbe essere difficile modificare il file per adattarlo ai propri host e servizi (vd. la documentazione per maggiori dettagli).

/var/www/nagios/nagvis/etc/maps/dmz.cfg
# La stanza 'global' imposta  alcuni parametri di default che verranno ereditati
# dagli altri oggetti
define global {
# Lista di utenti autorizzati a vedere questa mappa
    allowed_user=nagiosadmin,operator
# Lista di utenti autorizzati a modificare questa mappa tramite interfaccia web
    allowed_for_config=nagiosadmin
# Iconset di default (se omesso, viene ereditato dal file di configurazione
# principale)
    iconset=std_medium
# Immagine di sfondo
    map_image=dmz.png
}

# Visualizza lo stato del web server 'www1'
define host {
    host_name=www1
# Coordinate dell'host sulla mappa
    x=268
    y=166
# Impostare a '1' se si vuole che lo stato dell'host rifletta anche lo stato
# dei suoi servizi
    recognize_services=0
}

# Visualizza lo stato del servizio 'WWW' sul web server 'www1'
define service {
    host_name=www1
    service_description=WWW
    x=588
    y=165
# Come si vede, le opzioni in 'global' possono essere reimpostate negli oggetti
    iconset=std_small
}

# Visualizza lo stato peggiore degli host del gruppo 'WWW'
define hostgroup {
    hostgroup_name=WWW
    x=298
    y=363
    recognize_services=1
}

# Visualizza lo stato peggiore dei servizi del gruppo 'www-services'
define servicegroup {
    servicegroup_name=www-services
    x=609
    y=363
}

# Visualizza lo stato peggiore degli oggetti presenti in un'altra mappa NagVis
define map {
    map_name=lan
    x=406
    y=323
}

# Disegna un campo di testo sulla mappa
define textbox {
# Text may include HTML
    text="This is the DMZ network"
    x=490
    y=394
    w=117
}

Per consentire all'interfaccia web di modificare la configurazione di NagVis, occorre che tutti i file di configurazione appartengano a, e siano scrivibili da, l'utente www.

# chown www /var/www/nagios/nagvis/nagvis/etc/maps/*.cfg
# chmod 644 /var/www/nagios/nagvis/nagvis/etc/maps/*.cfg