User Tools

Site Tools


doc:appunti:linux:sa:cacti_122

Cacti e Icinga2 su Debian Buster

Cacti 1.2.2

Password di admin

L'installazione predefinita crea un account admin con la stessa password utilizzata per l'accesso al database MySQL, quindi vedere il file /etc/cacti/debian.php per recuperare la password.

Una volta fatto accesso all'interfaccia di amministrazione (URL predefinito /cacti/) si può cambiare password da ConfigurazioneUtenti. Esiste anche la scorciatoia dal pulsante in alto a destra Autenticato come adminCambia password, ma da quel menu è attiva una restrizione che chiede una password più complessa (carattere non alfabetico, ecc.).

Poller: Spine invece di cmd.php

La raccolta dei dati avviene ogni 5 minuti eseguendo lo script cmd.php; essendo scritto in PHP l'efficienza è scarsa e potrebbe causare problemi se il numero di data source è elevato. Per questo esiste un poller alternativo da installare con il pacchetto cacti-spine, scritto in linguaggio compilato e che supporta il multithread.

Per attivare il poller alternativo è sufficiente fare login come amministratore nell'interfaccia web e quindi cliccare su ConfigurationSettingsPoller; nel menu a tendina Poller type scegliere spine invece di cmd.php.

Spine accede direttamente al database, controllare i parametri di accesso in /etc/cacti/spine.conf.

ATTENZIONE: L'installazione predefinita genera un errore perché il poller eseguito da /etc/cron.d/cacti non ha i permessi per scrivere su /var/log/cacti/poller-error.log. Il proprietario del file era root:root, impostando www-data:www-data con mode 640 pare risolvere. Sembra normale che venga eseguito /usr/share/cacti/site/poller.php anche se si è selezionato Spine.

SNMP timeout detected [500 ms], ignoring host

Soprattutto dopo aver abilitato il poller Spine, capita molto di frequente di trovare l'errore SNMP timeout nei log. In effetti l'impostazione predefinita di 500 ms è davvero stringente: richiede tempi di latenza sulla rete molto brevi e host non troppo carichi. Inoltre pare che Spine sia molto più preciso nel calcolare il timeout, situazioni che non generavano alcun errore con il poller cmd.php, improvvisamente iniziano a generare grafici pieni di lacune e riempiono i file di log con errori SMTP timeout.

Pare che la soluzione sia quella di allungare il SNMP Timeout nella configurazione di ciascun host. Per dispositivi raggiungibili tramite connessione DSL, che possono essere interessati da congestioni di traffico e picchi di carico elevati (utilizzo della CPU prossimo al 100%) può essere necessario portare il timeout anche intorno ai 15000 ms (15 secondi).

FIXME Non è chiaro come mai con il poller Spine gli errori SNMP Timeout sono frequentissimi; un host con linea ADSL congestionata produce un grafico di oggetti SNMP pieno di lacune pressoché illeggibile, anche avendo impostato un SNMP Timeout di 60000 ms: (in /var/log/cacti/cacti.log si legge

SPINE: Poller[1] ... WARNING: SNMP timeout detected [60000 ms], ignoring host ...

Impostando invece il poller cmd.php tali errori scompaiono.

Icinga 2

Istruzioni abbastanza dettagliate sono nella guida Getting Started.

L'installazione di Icinga e Icingaweb prevede l'attivazione di svariate componenti e la creazione di alcuni database di supporto:

  • Database IDO (Icinga Data Output) - È il database utilizzato dal modulo Monitoring di Icinga Web 2 per memorizzare i dati. Tale database viene denominato icinga2 dalla procedura di installazione Debian.
  • Servizio REST API - È l'interfaccia di comunicazione tra Icinga Web 2 e il servizio Icinga2. Deve essere attivata e si deve creare un utente con password per l'accesso, si consiglia di usare il nome icingaweb2.
  • Database per Icinga Web 2. Utilizzato dall'interfaccia web come database di servizio. Non contiene i dati del monitoraggio, ma contiene ad esempio l'elenco degli utenti autorizzati all'accesso. Deve essere creato manualmente e viene popolato dalla procedura di configurazione web. Si consiglia di utilizzare il nome icingaweb.

Si devono installare i seguenti pacchetti (si è scelto PostgreSQL come database di supporto):

  • postgresql
  • icinga2
  • icingaweb2
  • icinga2-ido-pgsql

Se al posto di PostgreSQL si intende usare MySQL come backend, è necessario installare il pacchetto icinga2-ido-mysql.

Installazione pacchetti Debian

Durante l'installazione del pacchetto IDO viene chiesto se attivare ido-pgsql, è necessario rispondere affermativamente.

Tramite procedura guidata da dbconfig-common, viene creato un utente PostgreSQL e un database, entrambi di nome icinga2. Il database verrà inizializzato con tabelle ecc. Le coordinate per l'accesso a questo database sono memorizzate in /etc/icinga2/features-available/ido-pgsql.conf.

Al termine dell'installazione viene abilitata la configurazione /etc/apache2/conf-enabled/icingaweb2.conf pertanto è attivo l'URL /icingaweb2/.

Database IDO (Icinga Data Output)

Il data base IDO serve a Icinga Web 2 come backend per la memorizzazione dei dati, col pacchetto Debian viene installato ma non attivato. Per vedere quali caratteristiche sono attive in Icinga2 da riga di comando si esegue:

# icinga2 feature list
Disabled features: api command compatlog debuglog elasticsearch gelf
                   graphite ido-pgsql influxdb livestatus opentsdb
                   perfdata statusdata syslog
Enabled features: checker mainlog notification

Per attivare la componente ido-pgsql si esegue:

icinga2 feature enable ido-pgsql
systemctl restart icinga2

REST API Interface

Il modulo Icinga Web 2 ha bisogno di una interfaccia di comunicazione con il servizio Icinga2 per inviare comandi, per recuparare informazioni sugli oggetti, ecc. È necessario pertanto attivare la funzionalità api di Icinga2, che la procedura di installazione Debian ha lasciato non attiva:

icinga2 api setup

La configurazione viene salvata in /etc/icinga2/conf.d/api-users.conf, la procedura crea un solo utente con nome root che ha pieni permessi sull'interfaccia API. È consigliato creare un altro utente di nome icingaweb2 che abbia solo i permessi necessari a Icinga Web 2 per il suo funzionamento.

object ApiUser "root" {
  password = "MySecretRoot"
  permissions = [ "*" ]
}

object ApiUser "icingaweb2" {
  password = "MySecretIcingaweb2"
  permissions = [ "status/query", "actions/*", "objects/modify/*", "objects/query/*" ]
}

Dopo questa modifica è necessario riavviare il servizio:

systemctl restart icinga2

Configurazione web

Database di backend

Durante la configurazione web verranno chieste le credenziali per un database che verrà usato da Icinga Web 2; è necessario creare tale database preventivamente e la procedura provvederà a popolarlo come necessario. Queste le istruzioni SQL utilizzate in PostgreSQL:

CREATE USER icingaweb PASSWORD 'MySecret';
CREATE DATABASE icingaweb OWNER icingaweb;

Prima di inziare la configurazione via web bisogna attivare un token di autorizzazione. Va creato sull'host eseguendo sulla riga di comando (da utente root):

icingacli setup config directory --group icingaweb2;
icingacli setup token create;

Il token visualizzato (viene salvato anche nel file /etc/icingaweb2/setup.token) deve essere copiato nella pagina web di configurazione /icingaweb2/setup.

Oltre al modulo principale Monitoring, si è scelto di installare anche Doc.

La procedura verifica che siano installate tutte le componenti PHP necessarie: volendo utilizzare come backend il database PostgreSQL, è necessario aver installato il pacchetto php7.3-pgsql (per il database MySQL è necessario invece il pacchetto php7.3-mysql). Altri pacchetti che potrebbero essere necessari sono: php-imagick, php-gd, ecc. Verificare anche che nel file /etc/php/7.3/apache2/php.ini sia presente una direttiva del tipo:

date.timezone = "Europe/Rome"

Ricordarsi di eseguire systemctl restart apache2 quando si modifica l'installazione di PHP.

Durante la configurazione si è ovviamente scelto di effettuare l'autenticazione su database. Quando si specificano i parametri per l'accesso al database è opportuno anche indicare la codifica dei caratteri UTF-8. In questa fase viene creato anche l'utente amministratore di Icinga2, si suggerisce di chiamarlo admin.

Monitoring e database IDO

Il modulo Monitoring ha bisogno di un database di supporto, che non è lo stesso usato da Icingaweb 2. Durante l'installazione del pacchetto icinga2-ido-pgsql viene infatti creato un database di nome icinga2 a cui si accede tramite le credenziali salvate in /etc/icinga2/features-available/ido-pgsql.conf. La procedura di installazione crea l'utente e il database, inoltre popola quest'ultimo con le tabelle necessarie.

Se la procedura di installazione fallisce (ad esempio perché durante l'esecuzione non è ancora installato il pacchetto postgresql), la soluzione più comoda è rimuovere e reinstallare il pacchetto icinga2-ido-pgsql (il --reconfigure purtroppo non è sufficiente).

Quando la procedura web configura il modulo Monitoring si devono indicare le coordinate del backend IDO creato durante l'installazione del pacchetto Debian icinga2-ido-pgsql. Aprire il file /etc/icinga2/features-available/ido-pgsql.conf per vedere username, password, ecc.

REST API

Infine la procedura web chiede i parametri per il Command Transport, cioè dell'interfaccia API. Immettere il nome utente e la password che sono stati aggiunti nel file /etc/icinga2/conf.d/api-users.conf, cioè l'utente icingaweb2 con le permissions limitate, non l'utente root.

Al termine della procedura, la configurazione viene salvata nel file /etc/icingaweb2/config.ini.

Comandi utili CLI

Elenco completo di tutti gli oggetti definiti nei file di configurazione:

icinga2 object list

Elenco delle feature attive del servizio Icinga 2:

icinga2 feature list

Si può anche usare la Console API, lanciando l'opportuno comando dopo aver dichiarato login e password tramite variabili d'ambiente (sono necessarie le credenziali di root contenute in /etc/icinga2/conf.d/api-users.conf):

#!/bin/sh
export ICINGA2_API_USERNAME=root
export ICINGA2_API_PASSWORD=MySecret
icinga2 console --connect 'https://localhost:5665/'

Ecco ad esempio come leggere il last_check e il next_check di un servizio:

<1> => get_service("Naxos", "Backup Web Sites").last_check
1563877042.745325
<2> => get_service("Naxos", "Backup Web Sites").next_check
1563962558.395343

Per convertire il timestamp Unix in una data comprensibile questo il comando shell:

$ date -d @1563962558.395343
Wed Jul 24 12:02:38 CEST 2019

Monitoraggio

Per attivare il monitoraggio di qualche host bisogna installare i plugin opportuni, Debian mette a disposizione i pacchetti monitoring-plugins-basic e monitoring-plugins-common.

Sintassi colorata con Vim

Per avere la sintassi colorata quando si editano i file di configurazione di Icinga2, si devono installare un paio di pacchetti e abilitare l'add-on. Con questi comandi si attiva solo per l'utente root (quindi nella directory /root/.vim/):

apt-get install vim-addon-manager vim-icinga2
vim-addons install icinga2

Monitoraggio di un servizio TCP/IP standard

In questo esempio aggiungiamo il monitoraggio di un servizio standard POP3 sulla porta 110 TCP.

Per prima cosa si definisce un CheckCommand nel file /etc/icinga2/conf.d/commands.conf (o analogo):

object CheckCommand "mail_check_pop" {
    command = [ PluginDir + "/check_pop" ]
    arguments = {
        "-H" = "$pop_server$"
    }
}

Il comando si basa su uno dei plugin standard forniti dal pacchetto monitoring-plugins-basic, per la precisione si tratta di /usr/lib/nagios/plugins/check_pop. L'unico argomento che viene passato con l'opzione -H è l'indirizzo dell'host, che dovrà essere definito nella variabile $pop_server$.

Quindi si definisce un servizio di nome POP3 Service basato sul comando appena definito; nel file /etc/icinga2/conf.d/services.conf (o analogo) si aggiunge:

apply Service "POP3 Service" {
    import "generic-service"
    check_command = "mail_check_pop"
    check_interval = 5m
    assign where host.vars.pop_server
}

Da notare che il nome del servizio verrà usato nella visualizzazione di IcingaWeb, pertanto si usa qualcosa di descrittivo e comprensibile. Considerato che il template generic-service ha un check_interval di un solo minuto, si è preferito rilassare il controllo ad un intervallo di cinque minuti.

Infine si deve attivare il servizio per l'host desiderato: è sufficiente definire la variabile pop_server che sarà anche usata dal plugin come indirizzo remoto da testare. La definizione degli host è generalmente contenuta nel file /etc/icinga2/conf.d/hosts.conf:

object Host "MyHost" {
  import "generic-host"
  ...
  vars.pop_server = "mail.rigacci.org"

Monitoraggio client remoto via NRPE

Il protocollo NRPE nasce per NAGIOS: sul client remoto da monitorare gira il demone NRPE che sta in ascolto sulla porta 5666, l'interrogazione avviene su tale porta. Con Icinga 2 è possibile utilizzare tale meccanismo sebbene sia deprecato, vedere in proposito Agent-based Checks, NRPE. La soluzione nativa è Icinga 2 client.

Sul server si deve installare il plugin contenuto nel pacchetto Debian nagios-nrpe-plugin, sul client remoto va invece installato il pacchetto nagios-nrpe-server.

Nell'esempio che segue si definisce un servizio Software RAID, da eseguire tramite protocollo NRPE.

Nel file /etc/icinga2/conf.d/commands.conf (o altro file analogo) si definisce un CheckCommand:

object CheckCommand "disk_check_nrpe_swraid" {
    command = [ PluginDir + "/check_nrpe", "--timeout=60:UNKNOWN" ]
    arguments = {
        "-H" = "$address$"
        "-c" = "$nrpe_swraid$"
    }
}

Nel file /etc/icinga2/conf.d/services.conf (o analogo) si definisce il Service:

apply Service "Software RAID" {
    import "generic-service"
    check_command = "disk_check_nrpe_swraid"
    assign where host.vars.nrpe_swraid
}

Il servizio viene applicato a tutti gli host che hanno la variabile nrpe_swraid impostata, tale variabile viene usata per passare al server NRPE il nome del check da eseguire. Questa è la definizione dell'Host nel file /etc/icinga2/conf.d/hosts.conf (o analogo):

object Host "Mail Rigacci.Org" {
  import "generic-host"
  address = "mail.rigacci.org"
  vars.nrpe_swraid = "check_raid"
}

Sul client che esegue il server NRPE si installa il pacchetto nagios-plugins-contrib, che contiene il plugin per verificare il RAID software Linux. Quindi è sufficiente configurare /etc/nagios/nrpe.cfg per consentire le interrogazioni da parte del server Icinga 2:

allowed_hosts=127.0.0.1,52.92.232.192,2001:41d0:206:2232::9396

e definire il comando check_raid nel file /etc/nagios/nrpe_local.cfg:

command[check_raid]=/usr/lib/nagios/plugins/check_raid --plugin=mdstat

CheckCommand con parametri opzionali

Si è avuto un caso particolare in cui il server NRPE versione 2.15 (in esecuzione sull'host da monitorare) non poteva essere interrogato da Icinga 2 a causa di problemi SSL (probabilmente a causa della versione troppo vecchia della libreria SSL). Nei log del server si legge:

nrpe[9169]: Error: Could not complete SSL handshake.

È stato necessario avviare il server NRPE con l'opzione -n per disabilitare SSL. Su Icinga 2 si è modificato il comando che invoca il plugin check_nrpe, in modo che disabiliti SSL (con l'analoga opzione -n), ma solo per gli host che hanno questa limitazione.

object CheckCommand "disk_check_nrpe_swraid" {
    command = [ PluginDir + "/check_nrpe", "--timeout=60:UNKNOWN" ]
    arguments = {
        "-H" = "$address$"
        "-c" = "$nrpe_swraid$"
        "-n" = { set_if = "$nrpe_no_ssl$" }
    }
}

È sufficiente definire la variabile opportuna nella sezione host:

object Host "Server" {
  import "generic-host"
  address = "server.rigacci.org"
  vars.nrpe_swraid = "check_swraid"
  vars.nrpe_no_ssl = true
}

Check passivo

Normalmente Icinga 2 effettua check attivi, cioè interroga l'host remoto per conoscere lo stato di una specifica grandezza ed agire di consegunza. Se l'host remoto è dietro a un firewall o comunque non è possibile conoscerne lo stato con un check diretto, è possibile utilizzare i check passivi, cioè è l'host remoto che informa il server Icinga 2 sul proprio stato.

Nel nostro caso si vuole monitorare l'esecuzione di un backup su un host remoto. Il monitoraggio deve accorgersi non solo di un eventuale errore, ma anche della mancata esecuzione, per questo si utilizza una combinazione di check passivi e attivi.

  • In condizioni normali l'host remoto esegue il backup e notifica Icinga 2 con un check passivo.
  • Se l'host Icinga 2 non riceve il check passivo, esegue un check attivo dummy che restituisce lo stato 3 UNKNOWN.

Il check passivo utilizza il meccanismo external command sent via command pipe, che è direttamente derivata dai check passivi con Nagios3. Probabilmente si tratta di una configurazione deprecabile, soprattutto per l'utilizzo di NSCA (Nagios Service Check Acceptor).

Per qusto si deve abilitare l'opzione external command file; in pratica Icinga 2 inizierà a ricevere input dal named pipe /var/run/icinga2/cmd/icinga2.cmd: ogni eventuale check passivo deve solo aggiungere una riga sulla pipe per informare Icinga dello stato del check.

Si verifica le feature abilitate, si abilita la command e si ricarica il servizio:

icinga2 feature list
icinga2 feature enable command
systemctl reload icinga2

Nel file /etc/icinga2/conf.d/templates.conf (o analogo) si definisce un template per questo tipo di servizio:

template Service "passive-backup-service" {
    import "generic-service"
    check_command = "passive"
    /* Do active checks to detect missing passive updates. */
    enable_active_checks = true
    enable_passive_checks = true
    /* Use a runtime function to retrieve the last check time and more details. */
    vars.dummy_text = {{
        var service = get_service(macro("$host.name$"), macro("$service.name$"))
        var lastCheck = DateTime(service.last_check).to_string()
        return "No check results received. Last result time: " + lastCheck
    }}
    check_interval = 1d +1h  /* This determines the freshness of the check. */
    retry_interval = 1h      /* Execute the active check if freshness is due. */
    max_check_attempts = 3   /* Retry the active check some times, before notification. */
    vars.notification_interval = 1d  
}

Il check_command passive è definito in /usr/share/icinga2/include/command-icinga.conf, si tratta in effetti del comando built-in dummy con il valore di dummy_state impostato a 3 (stato UNKNOWN). Il valore di dummy_text invece utlizza una funziona per recuperare il timestamp dell'ultimo esito positivo del check.

In condizioni normali viene ricevuto un check passivo ogni 24 ore, quindi il check attivo giornaliero (check_interval = 1d + 1h) non viene eseguito. Qualora il check passivo non venga ricevuto, viene eseguito il check attivo dummy e lo stato passa da OK ad UNKNOWN soft. Il check viene ripetuto ogni ora (retry_interval =1h) e al terzo tentativo (max_check_attempts = 3) lo stato passa a UNKNOWN hard.

Per definire il servizio associato ad un host si aggiunge ad esempio nel file /etc/icinga2/conf.d/services.conf o analogo:

apply Service "Backup Maildir" {
  import "passive-backup-service"
  assign where host.name == "Naxos"
}

Per simulare l'invio di un check passivo è sufficiente scrivere una riga di testo sulla pipe. Questo è il formato da utilizzare:

[<timestamp>] PROCESS_SERVICE_CHECK_RESULT;<hostname>;<service>;<ret_code>;<plugin_output>

Il timestamp in formato Unix si può ottenere da una shell Unix con il comando date +%s.

La ricezione di un check passivo viene registrata nel log /var/log/icinga2/icinga2.log:

[2022-02-22 02:49:04 +0100] information/ExternalCommandListener:
    Executing external command: [1645494544] PROCESS_SERVICE_CHECK_RESULT;Naxos;
    Backup Maildir;0;2022-02-22 02:49:03: santorini-naxos-rsync-maildir:
    rsync Maildir da Santorini a Naxos eseguito con successo.

Ricezione check passivo via REST API

Si verifica che la REST API interface sia attiva (è la stessa che viene usata dal modulo Icinga Web 2). Dovrebbe essere in ascolto sulla porta TCP/5665.

Nel file /etc/icinga2/conf.d/api-users.conf si definisce un utente con password che abbia l'autorizzazione ad inviare i risultati dei check. L'unico permesso richiesto è actions/process-check-result:

// Used to submit passive checks results, e.g. from backup scripts.
object ApiUser "passive-check" {
  password = "MyUserSecret"
  permissions = [ "actions/process-check-result" ]
}

Il client che deve inviare l'esito del check passivo può utilizzare ad esempio curl, con autenticazione su protocollo https:

ICINGA2_SERVER='icinga2.rigacci.org'
ICINGA2_USER='passive-check'
ICINGA2_PASSWORD='MyUserSecret'
 
SERVICE_HOST='Naxos'
SERVICE_NAME="Backup Remote Rsync"
EXIT_STATUS="0"
EXIT_MESSAGE="[OK] Rsync to remote storage"
 
curl -k -s -u "${ICINGA2_USER}:${ICINGA2_PASSWORD}" \
    -H 'Accept: application/json' \
    -X POST "https://${ICINGA2_SERVER}:5665/v1/actions/process-check-result" \
    -d '{ "type": "Service",
          "filter": "host.name==\"'"$SERVICE_HOST"'\" && service.name==\"'"$SERVICE_NAME"'\"",
          "exit_status": '"$EXIT_STATUS"',
          "plugin_output": "'"$EXIT_MESSAGE"'" }' > /dev/null

Un servizio Icinga può essere in uno dei seguenti stati:

0 OK
1 WARNING
2 CRITICAL
3 UNKNOWN

Server NSCA

:!: ATTENZIONE: L'utilizzo di NCSA è deprecato, Icinga2 ha la sua interfaccia REST API che può essere protetta con HTTPS e autenticazione. La ricezione dei check passivi va fatta via REST API come spiegato sopra.

Nell'ottica di riutilizzare più possibile la configurazione di un vecchio server Nagios3, si utilizza il Nagios Service Check Acceptor per ricevere le notifiche dei check passivi. Si tratta di un demone che ascolta sulla porta TCP/IP 5667 e riceve le notifiche dai vari client per inoltrarle sulla named pipe monitorata da Icinga 2. Pertanto sullo stesso host dove viene eseguito Icinga si installa il pacchetto nsca.

Sul firewall si deve ovviamente aprire la porta 5667 in ingresso e si impostano questi valori nel file di configurazione /etc/nsca.cfg:

command_file=/var/run/icinga2/cmd/icinga2.cmd
158c158
password=MyNscaSecret
decryption_method=3

ATTENZIONE! Poiché il file di configurazione /etc/nsca.cfg contiene una password (che viene condivisa con tutti i client) è opportuno proteggerlo con mode 0640.

FIXME Pare che lo script start/stop per il servizio nsca non funzioni. Eseguendo il comando systemctl stop nsca si legge nel syslog:

nsca[16127]: Stopping Nagios Service Check Acceptor: nscastart-stop-daemon:
    matching only on non-root pidfile /var/run/nagios/nsca.pid is insecure

e infatti il servizio non viene fermato (non funziona neanche il restart). Bisogna killare il processo e riavviarlo manualmente.

Client NSCA

Sull'host che esegue il servizio con check passivo si deve installare il pacchetto nsca-client. Il file di configurazione /etc/send_nsca.cfg deve contenre configurazioni corrispondenti al server:

password=MyNscaSecret
encryption_method=3

ATTENZIONE! Non solo la password deve essere condivisa tra il server e tutti i client, ma non viene effettuato alcun controllo di accesso o simili. Ogni client può pretendere di inviare check passivi a nome di qualunque altro client. Si deve pertanto usare questa architettura solo se il trust fra server e client è totale.

Un semplice script di shell può essere utilizzato per inviare un check passivo:

#!/bin/sh
 
$hostname='ClientName'
$service='Backup Web Sites'
$ret_code=0
$message='All the DocumentRoot(s) were backed-up successfully.'
 
send_nsca -H icinga2.rigacci.org -c /etc/send_nsca.cfg <<END > /dev/null
$hostname    $service    $ret_code    $message
END

ATTENZIONE

  • $hostname deve corrispondere a un host definito in Icinga 2.
  • $service deve corrispondere a un servizio definito in Icinga 2.
  • $ret_code vale zero se il check ha esito positivo (OK), il valore 1 è per lo stato WARNING, il valore 2 per CRITICAL e il valore 3 per UNKNOWN.
  • Il separatore di campo nel testo da inviare a send_nsca è il TAB, non spazi.
  • Se il messaggio ha un formato errato, viene inviato un pacchetto di lunghezza zero che non produce errori nei log del server.

Notifiche

Per abilitare le notifiche via mail, si deve anzitutto verificare che la feature notification sia attiva; dalla riga di comando si esegue:

icinga2 feature list

Nella configurazione predefinita Debian è definito uno User nel file /etc/icinga2/conf.d/users.conf. Verificare che tale user abbia una email valida rispetto al servizio mail dell'host su cui gira Icinga 2.

object User "icingaadmin" {
  import "generic-user"
  ...
  email = "root@localhost"
}

Nel nostro caso la mail root@localhost viene inoltrata a chi di dovere tramite /etc/aliases e le opportune configurazioni di Postfix.

Nel file /etc/icinga2/conf.d/notifications.conf viene abilitata la notifica per ogni host che abbia definito la host.vars.notification.mail (clausola assign where):

apply Notification "mail-icingaadmin" to Host {
  import "mail-host-notification"
  user_groups = host.vars.notification.mail.groups
  users = host.vars.notification.mail.users
  ...
  assign where host.vars.notification.mail
}

Nello stesso file - con una sintassi praticamente identica - viene abilitata la notifica anche per ogni servizio che abbia definito la host.vars.notification.mail:

apply Notification "mail-icingaadmin" to Service {
  import "mail-service-notification"
  user_groups = host.vars.notification.mail.groups
  users = host.vars.notification.mail.users
  ...
  assign where host.vars.notification.mail
}

Quindi - definendo tale variabile per un host - si ottiene come risultato di ricevere notifiche per tutti gli eventi associati a tale host e per tutti gli eventi legati ai servizi che dipendono dallo stesso. Questa è la sintassi:

object Host "Webserver" {
  import "generic-host"
  address = "www.rigacci.org"
  ...
  vars.notification.mail = {
      users = [ "icingaadmin" ]
  }
}

Frequenza delle notifiche

L'impostazione predefinita Debian è di inviare una notifica ogni 30 minuti, con periodo 24×7. È possibile impostare un valore diverso per le notifiche che riguardano gli host e quelle dei servizi nel file /etc/icinga2/conf.d/notifications.conf:

apply Notification "mail-icingaadmin" to Host {
  ...
  interval = 4h
}

apply Notification "mail-icingaadmin" to Service {
  ...
  interval = 8h
}

Si può personalizzare l'intervallo di notifica in base al servizio, ecco come modificare la Notification “mail-icingaadmin”:

apply Notification "mail-icingaadmin" to Service {
  import "mail-service-notification"
  user_groups = host.vars.notification.mail.groups
  users = host.vars.notification.mail.users
  if (service.vars.notification_interval) {
    interval = service.vars.notification_interval
  } else {
    interval = 12h
  }
  assign where host.vars.notification.mail
}

Come si vede l'intervallo di notifica predefinito è impostato a 12h (due volte al giorno) a meno che non sia stata definita nel servizio la vars.notification_interval. Vediamo quindi la definizione di un servizio che imposta un interval personalizzato:

apply Service "Software RAID" {
    import "generic-service"
    check_command = "disk_check_nrpe_swraid"
    check_interval = 15m
    vars.notification_interval = 1d
    assign where host.vars.nrpe_swraid
}

Notifica custom su Host

Vediamo come predisporre le notifiche per un singolo host inviando una mail ad un determinato indirizzo. Si crea un file (ad esempio /etc/icinga2/conf.d/notification_dsl.conf) in cui si definisce il tipo di notifica e l'utente che deve ricevere la mail:

apply Notification "mail-dsl-users" to Host {
  import "mail-host-notification"
  users = host.vars.notification.mailcustomer.users
  times.begin = 3h
  interval = 12h
  assign where host.vars.notification.mailcustomer
}

object User "dsl_user_1" {
  import "generic-user"
  display_name = "Alert for ADSL 1"
  email = "name@domain.tld"
}

Le notifiche inizieranno solo dopo 3 ore che l'host ha il problema, e verranno ripetute ogni 12 ore. Quindi è sufficiente aggiungere una riga alla definizione dell'host:

object Host "ADSL_1"     {
    import "generic-host"
    address = "185.121.12.106"
    vars.notification.mailcustomer = { users = [ "dsl_user_1" ] }
}

Modifica servizi predefiniti

Potrebbe essere necessario fare delle modifiche ai servizi predefiniti. Ad esempio il servizio ping4 viene applicato ad ogni host che abbia un address, ma i parametri sono un po' troppo stringenti; un host collegato ad una DSL di bassa qualità sarà molto spesso in stato di WARNING o CRITICAL a causa di round-trip o packet loss troppo alti.

I file che definiscono i servizi sono in /usr/share/icinga2/, ma è sconsigliato modificarli perché un eventuale aggiornamento del pacchetto farebbe perdere le modifiche.

Nel file /usr/share/icinga2/include/command-plugins.conf è definito l'object CheckCommand “ping4” che importa la sua configurazione dal template CheckCommand “ping-common”. Il comando ping4 viene applicato a tutti gli host nel file /etc/icinga2/conf.d/services.conf, quando asserisce un apply Service “ping4” con la semplice clausola assign where host.address.

Nel file /etc/icinga2/conf.d/commands.conf si possono definire un template e due comandi nuovi:

template CheckCommand "ping-common-slow" {
    vars.ping_wrta = 160
    vars.ping_wpl = 18
    vars.ping_crta = 320
    vars.ping_cpl = 36
}

object CheckCommand "ping4slow" {
    import "ping-common"
    import "ping-common-slow"
    command += [ "-4" ]
    vars.ping_address = "$address$"
}

object CheckCommand "ping6slow" {
    import "ping-common"
    import "ping-common-slow"
    command += [ "-6" ]
    vars.ping_address = "$address6$"
}

poi si modifica il Service “ping4” nel file /etc/icinga2/conf.d/services.conf (ovviamente si dovrà modificare in maniera analoga anche il ping6):

apply Service "ping4" {
  import "generic-service"

  if (host.vars.ping_slow) {
    check_command = "ping4slow"
  } else {
    check_command = "ping4"
  }
  
  assign where host.address
}

Per applicare il ping modificato sarà sufficiente definire la variabile ping_slow nella definizione di host:

object Host "Naxos" {
  ...
  vars.ping_slow = true
}

Controllo hostalive e IPv6

Per ogni host viene effettuato un controllo check_command = hostalive, poiché così è impostato il template generic-host definito in /etc/icinga2/conf.d/templates.conf. Inoltre vengono effettuati anche i check per i servizi ping4 e ping6 se sono definiti host.address e host.address6 rispettivamente.

Si tratta di due controlli indipendenti per cui può accadere che il ping6 sia disabilitato (basta non definire l'address6 nella configurazione dell'host), ma hostalive tenta comunque un ping6 se risolve il nome con un indirzzo IPv6. Se la connettività IPv6 non è attiva, si ottiene come risultato che l'host risulta DOWN nonostante che risponda al ping4.

Per evitare questa situazione si deve sostituire hostalive con hostalive4 nel template generic-host.

Porta TCP alternativa per servizio standard

Il servizio predefinito ssh viene applicato a tutti gli host che anno vars.os = Linux e si basa ovviamente sulla porta 22 TCP. Per fare il test su una porta alternativa si deve definire un servizio personalizzato:

apply Service "ssh_alt" {
  import "generic-service"
  check_command = "ssh"
  vars.ssh_port = 2222
  assign where (host.address || host.address6) && host.vars.os == "LinuxAlt"
}

VirtualHost con SSL

Per monitorare il funzionamento basico di un server web è sufficiente definire una variabile vars.http_vhosts in una sezione object Host:

object Host "ServerName" {
  import "generic-host"
  address = "servername.rigacci.org"
  vars.http_vhosts["www.rigacci.org"] = { }
}

Il nome tra parentesi quadre è solo una label utilizzata per identificare il servizio nell'interfaccia web, non viene utilizzata né per ottenere l'indirizzo IP del server (a quello serve la variabile address) né tantomeno per identificare un NamedVirtualHost.

Per un moderno server web tuttavia è necessario verificare la scadenza del certificato SSL ed eventualmente verificare diversi VirtualHost che condividono lo stesso indirizzo IP, ma hanno ServerName e certificati SSL diversi.

In teoria non sarebbe possibile verificare il certificato SSL di un VirtualHost basato su nome, perché nella fase iniziale della negoziazione SSL il nome dell'host richiesto non è ancora noto e quindi il server non può sapere quale certificato presentare al client. Tuttavia l'estensione SNI è stata sviluppata apposta per ovviare a questo problema. Vedere in proposito Name Based SSL VHosts With SNI.

Ammettendo che il server web sia configurato opportunamente, ecco un modo per verificare due diversi VirtualHost ospitati sullo stesso server:

object Host "ServerName" {
  import "generic-host"
  address = "servername.rigacci.org"
  vars.http_vhosts["www.first_domain.tld"] = {
    http_address = "$address$"
    http_vhost = "www.first_domain.tld"
    http_ssl = true
    http_sni = true
    http_certificate = "24,14"
  }
  vars.http_vhosts["www.second_domain.tld"] = {
    http_address = "$address$"
    http_vhost = "www.second_domain.tld"
    http_ssl = true
    http_sni = true
    http_certificate = "24,14"
  }
}

Each vars.http_vhosts section correspond to one command invokation, of this type:

check_http -H "www.first_domain.tld" -I "servername.rigacci.org" -S --sni -C "24,14"

Monitoraggio servizio CLAMD

Il programma antivirus ClamAV generalmente viene configurato in Debian come servizio clamav-daemon.service, l'eseguibile clamd è in esecuzione con i parametri configurati in /etc/clamav/clamd.conf. Per attivare il monitoraggio del servizio (si vuole sapere se il demone è in esecuzione) conviene usare il plugin /usr/lib/nagios/plugins/check_clamd fornito dal pacchetto monitoring-plugins-basic, che fa una semplice interrogazione su TCP/IP.

Per impostazione predefinita clamd non si mette in ascolto sulla porta TCP 3310, è necessario aggiungere queste righe alla configurazione:

# Listen also on TCP localhost, to allow running status check.
TCPSocket 3310
TCPAddr 127.0.0.1

Il binding viene fatto solo su localhost in modo da non esporre il servizio antivirus all'esterno; pertanto il plugin Icinga deve essere eseguito in locale e il check da parte di un host remoto avvien tramite NRPE. Per ottenere questo si aggiunge in /etc/nagios/nrpe_local.cfg:

command[check_clamd]=/usr/lib/nagios/plugins/check_clamd -H localhost

Sul server Icinga2 si deve definire il servizio aggiungendo in /etc/icinga2/conf.d/local/services.conf la seguente sezione:

apply Service "CLAMD Service" {
    import "generic-service"
    check_command = "mail_check_nrpe_clamd"
    assign where host.vars.nrpe_clamd
}

Quindi si aggiunge il comando aggiungendo in /etc/icinga2/conf.d/local/commands.conf la seguente sezione:

object CheckCommand "mail_check_nrpe_clamd" {
    command = [ PluginDir + "/check_nrpe", "--timeout=60:UNKNOWN" ]
    arguments = {
        "-H" = "$address$"
        "-c" = "check_clamd"
        "-n" = { set_if = "$nrpe_no_ssl$" }
    }
}

Infine nella sezione host relativa all'host da monitorare (potrebbe essere nel file /etc/icinga2/conf.d/hosts.conf), si aggiunge la riga:

object Host "clamav-hostname" {
  ...
  vars.nrpe_clamd = true
  ...
}

Riferimenti Web

doc/appunti/linux/sa/cacti_122.txt · Last modified: 2022/10/10 16:27 by niccolo