====== 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 //Configurazione// => //Utenti//. Esiste anche la scorciatoia dal pulsante in alto a destra //Autenticato come admin// => //Cambia 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 //Configuration// => //Settings// => //Poller//; 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 **[[https://icinga.com/docs/icinga2/latest/doc/02-getting-started/|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 **[[https://icinga.com/2016/08/11/analyse-icinga-2-problems-using-the-console-api/|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 **[[https://icinga.com/docs/icinga2/latest/doc/07-agent-based-monitoring/#nrpe|Agent-based Checks, NRPE]]**. La soluzione nativa è **[[https://icinga.com/docs/icinga2/latest/doc/06-distributed-monitoring/#distributed-monitoring|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 **[[https://icinga.com/docs/icingaweb2/latest/modules/monitoring/doc/05-Command-Transports/#use-a-local-command-pipe|external command sent via command pipe]]**, che è direttamente derivata dai **[[nagios_passivo|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 **[[https://icinga.com/docs/icinga2/latest/doc/10-icinga-template-library/#itl-dummy|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:
[] PROCESS_SERVICE_CHECK_RESULT;;;;
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|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 < /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 **24x7**. È 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 **[[https://cwiki.apache.org/confluence/display/httpd/NameBasedSSLVHostsWithSNI|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 **[[http://www.clamav.net/|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 =====
* **[[https://icinga.com/docs/icinga2/latest/doc/03-monitoring-basics/|Icinga 2 Monitoring Basics]]**
* **[[https://icinga.com/docs/icinga2/latest/doc/09-object-types/|Object Types Docs]]**
* **[[https://somoit.net/icinga/icinga-passive-checks-2|Icinga – How to configure passive checks made easy]]**
* **[[https://somoit.net/icinga/icinga2-understanding-checks-notification-types|Icinga2 – Understanding checks and notification types]]**