====== 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]]**