doc:appunti:linux:sa:cacti_122
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
doc:appunti:linux:sa:cacti_122 [2019/07/26 11:33] – [Notifiche] niccolo | doc:appunti:linux:sa:cacti_122 [2022/03/14 18:24] – [Server NSCA] niccolo | ||
---|---|---|---|
Line 17: | Line 17: | ||
Spine accede direttamente al database, controllare i parametri di accesso in **/ | Spine accede direttamente al database, controllare i parametri di accesso in **/ | ||
- | FIXME: L' | + | **ATTENZIONE**: L' |
==== SNMP timeout detected [500 ms], ignoring host ==== | ==== SNMP timeout detected [500 ms], ignoring host ==== | ||
Line 23: | Line 24: | ||
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). | 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; | ||
+ | |||
+ | < | ||
+ | SPINE: Poller[1] ... WARNING: SNMP timeout detected [60000 ms], ignoring host ... | ||
+ | </ | ||
+ | |||
+ | Impostando invece il **poller cmd.php** tali errori scompaiono. | ||
===== Icinga 2 ===== | ===== Icinga 2 ===== | ||
Line 33: | Line 42: | ||
* **Database per Icinga Web 2**. Utilizzato dall' | * **Database per Icinga Web 2**. Utilizzato dall' | ||
- | Si devono installare i seguenti pacchetti: | + | Si devono installare i seguenti pacchetti |
+ | * **postgresql** | ||
* **icinga2** | * **icinga2** | ||
* **icingaweb2** | * **icingaweb2** | ||
Line 129: | Line 139: | ||
=== Monitoring e database IDO === | === Monitoring e database IDO === | ||
+ | |||
+ | Il modulo // | ||
+ | |||
+ | Se la procedura di installazione fallisce (ad esempio perché durante l' | ||
Quando la procedura web configura il **modulo Monitoring** si devono indicare le coordinate del backend IDO creato durante l' | Quando la procedura web configura il **modulo Monitoring** si devono indicare le coordinate del backend IDO creato durante l' | ||
Line 190: | Line 204: | ||
</ | </ | ||
+ | ==== 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 **/ | ||
+ | |||
+ | < | ||
+ | object CheckCommand " | ||
+ | command = [ PluginDir + "/ | ||
+ | arguments = { | ||
+ | " | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Il comando si basa su uno dei plugin standard forniti dal pacchetto **monitoring-plugins-basic**, | ||
+ | |||
+ | Quindi si definisce un servizio di nome **POP3 Service** basato sul comando appena definito; nel file **/ | ||
+ | |||
+ | < | ||
+ | apply Service "POP3 Service" | ||
+ | import " | ||
+ | check_command = " | ||
+ | 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 **/ | ||
+ | |||
+ | < | ||
+ | object Host " | ||
+ | import " | ||
+ | ... | ||
+ | vars.pop_server = " | ||
+ | </ | ||
==== Monitoraggio client remoto via NRPE ==== | ==== Monitoraggio client remoto via NRPE ==== | ||
Line 242: | Line 294: | ||
</ | </ | ||
+ | ==== CheckCommand con parametri opzionali ==== | ||
+ | |||
+ | Si è avuto un caso particolare in cui il **server NRPE versione 2.15** (in esecuzione sull' | ||
+ | |||
+ | < | ||
+ | nrpe[9169]: Error: Could not complete SSL handshake. | ||
+ | </ | ||
+ | |||
+ | È stato necessario avviare il server NRPE con l' | ||
+ | |||
+ | < | ||
+ | object CheckCommand " | ||
+ | command = [ PluginDir + "/ | ||
+ | arguments = { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | È sufficiente definire la variabile opportuna nella sezione host: | ||
+ | |||
+ | < | ||
+ | object Host " | ||
+ | import " | ||
+ | address = " | ||
+ | vars.nrpe_swraid = " | ||
+ | vars.nrpe_no_ssl = true | ||
+ | } | ||
+ | </ | ||
===== Check passivo ===== | ===== 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. | 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. | ||
- | Utilizzeremo una configurazione | + | 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** |
- | Anzitutto | + | * 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:// | ||
+ | |||
+ | Per qusto si deve abilitare l' | ||
Si verifica le //feature// abilitate, si abilita la //command// e si ricarica il servizio: | Si verifica le //feature// abilitate, si abilita la //command// e si ricarica il servizio: | ||
Line 262: | Line 350: | ||
< | < | ||
template Service " | template Service " | ||
- | | + | |
- | check_command = " | + | check_command = " |
- | enable_active_checks = false | + | /* Do active checks to detect missing passive updates. */ |
- | enable_passive_checks = true | + | |
- | check_interval = 1d | + | 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(" | ||
+ | var lastCheck = DateTime(service.last_check).to_string() | ||
+ | return "No check results received. Last result time: " + lastCheck | ||
+ | }} | ||
+ | | ||
+ | | ||
+ | | ||
+ | vars.notification_interval = 1d | ||
} | } | ||
</ | </ | ||
- | Da notare che lo stato viene controllato una sola volta al giorno (**check_interval = 1d**), in caso di problemi | + | Il // |
+ | |||
+ | In condizioni normali viene ricevuto un **check passivo** ogni 24 ore, quindi il check attivo giornaliero (// | ||
- | Quindi si definisce un servizio associato ad un host, ad esempio nel file **/ | + | Per definire il servizio associato ad un host si aggiunge |
< | < | ||
Line 290: | Line 388: | ||
Il timestamp in formato Unix si può ottenere da una shell Unix con il comando **%%date +%s%%**. | 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 **/ | ||
+ | |||
+ | < | ||
+ | [2022-02-22 02:49:04 +0100] information/ | ||
+ | Executing external command: [1645494544] PROCESS_SERVICE_CHECK_RESULT; | ||
+ | Backup Maildir; | ||
+ | rsync Maildir da Santorini a Naxos eseguito con successo. | ||
+ | </ | ||
+ | |||
+ | ==== Ricezione check passivo via REST API ==== | ||
+ | |||
+ | Si verifica che la **[[# | ||
+ | |||
+ | Nel file **/ | ||
+ | |||
+ | < | ||
+ | // Used to submit passive checks results, e.g. from backup scripts. | ||
+ | object ApiUser " | ||
+ | password = " | ||
+ | permissions = [ " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Il client che deve inviare l' | ||
+ | |||
+ | <code bash> | ||
+ | ICINGA2_SERVER=' | ||
+ | ICINGA2_USER=' | ||
+ | ICINGA2_PASSWORD=' | ||
+ | |||
+ | SERVICE_HOST=' | ||
+ | SERVICE_NAME=" | ||
+ | EXIT_STATUS=" | ||
+ | EXIT_MESSAGE=" | ||
+ | |||
+ | curl -k -s -u " | ||
+ | -H ' | ||
+ | -X POST " | ||
+ | -d '{ " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | </ | ||
+ | |||
+ | Un servizio Icinga può essere in uno dei seguenti stati: | ||
+ | |||
+ | ^ 0 | OK | | ||
+ | ^ 1 | WARNING | ||
+ | ^ 2 | CRITICAL | ||
+ | ^ 3 | UNKNOWN | ||
==== Server NSCA ==== | ==== Server NSCA ==== | ||
+ | |||
+ | :!: **ATTENZIONE**: | ||
Nell' | Nell' | ||
Line 367: | Line 518: | ||
Nel nostro caso la mail **%%root@localhost%%** viene inoltrata a chi di dovere tramite **/ | Nel nostro caso la mail **%%root@localhost%%** viene inoltrata a chi di dovere tramite **/ | ||
+ | |||
+ | Nel file **/ | ||
+ | |||
+ | < | ||
+ | apply Notification " | ||
+ | import " | ||
+ | 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 " | ||
+ | import " | ||
+ | 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 " | ||
+ | import " | ||
+ | address = " | ||
+ | ... | ||
+ | vars.notification.mail = { | ||
+ | users = [ " | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Frequenza delle notifiche ==== | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | apply Notification " | ||
+ | ... | ||
+ | interval = 4h | ||
+ | } | ||
+ | |||
+ | apply Notification " | ||
+ | ... | ||
+ | interval = 8h | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Si può personalizzare l' | ||
+ | |||
+ | < | ||
+ | apply Notification " | ||
+ | import " | ||
+ | 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' | ||
+ | |||
+ | < | ||
+ | apply Service " | ||
+ | import " | ||
+ | check_command = " | ||
+ | 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 **/ | ||
+ | |||
+ | < | ||
+ | apply Notification " | ||
+ | import " | ||
+ | users = host.vars.notification.mailcustomer.users | ||
+ | times.begin = 3h | ||
+ | interval = 12h | ||
+ | assign where host.vars.notification.mailcustomer | ||
+ | } | ||
+ | |||
+ | object User " | ||
+ | import " | ||
+ | display_name = "Alert for ADSL 1" | ||
+ | email = " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 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' | ||
+ | |||
+ | < | ||
+ | object Host " | ||
+ | import " | ||
+ | address = " | ||
+ | vars.notification.mailcustomer = { users = [ " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== 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**, | ||
+ | |||
+ | I file che definiscono i servizi sono in **/ | ||
+ | |||
+ | Nel file **/ | ||
+ | |||
+ | Nel file **/ | ||
+ | |||
+ | < | ||
+ | template CheckCommand " | ||
+ | vars.ping_wrta = 160 | ||
+ | vars.ping_wpl = 18 | ||
+ | vars.ping_crta = 320 | ||
+ | vars.ping_cpl = 36 | ||
+ | } | ||
+ | |||
+ | object CheckCommand " | ||
+ | import " | ||
+ | import " | ||
+ | command += [ " | ||
+ | vars.ping_address = " | ||
+ | } | ||
+ | |||
+ | object CheckCommand " | ||
+ | import " | ||
+ | import " | ||
+ | command += [ " | ||
+ | vars.ping_address = " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | poi si modifica il **Service " | ||
+ | |||
+ | < | ||
+ | apply Service " | ||
+ | import " | ||
+ | |||
+ | if (host.vars.ping_slow) { | ||
+ | check_command = " | ||
+ | } else { | ||
+ | check_command = " | ||
+ | } | ||
+ | | ||
+ | assign where host.address | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Per applicare il ping modificato sarà sufficiente definire la variabile **ping_slow** nella definizione di host: | ||
+ | |||
+ | < | ||
+ | object Host " | ||
+ | ... | ||
+ | vars.ping_slow = true | ||
+ | } | ||
+ | </ | ||
+ | ===== Controllo hostalive e IPv6 ===== | ||
+ | |||
+ | Per ogni host viene effettuato un controllo **check_command = hostalive**, | ||
+ | |||
+ | Si tratta di due controlli indipendenti per cui può accadere che il **ping6** sia disabilitato (basta non definire l'// | ||
+ | |||
+ | Per evitare questa situazione si deve sostituire **hostalive** con **hostalive4** nel template // | ||
+ | |||
+ | ===== 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 " | ||
+ | import " | ||
+ | check_command = " | ||
+ | vars.ssh_port = 2222 | ||
+ | assign where (host.address || host.address6) && host.vars.os == " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== 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 " | ||
+ | import " | ||
+ | address = " | ||
+ | vars.http_vhosts[" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Il nome tra parentesi quadre è solo una label utilizzata per identificare il servizio nell' | ||
+ | |||
+ | 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' | ||
+ | |||
+ | Ammettendo che il server web sia configurato opportunamente, | ||
+ | |||
+ | < | ||
+ | object Host " | ||
+ | import " | ||
+ | address = " | ||
+ | vars.http_vhosts[" | ||
+ | http_address = " | ||
+ | http_vhost = " | ||
+ | http_ssl = true | ||
+ | http_sni = true | ||
+ | http_certificate = " | ||
+ | } | ||
+ | vars.http_vhosts[" | ||
+ | http_address = " | ||
+ | http_vhost = " | ||
+ | http_ssl = true | ||
+ | http_sni = true | ||
+ | http_certificate = " | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Each **vars.http_vhosts** section correspond to one command invokation, of this type: | ||
+ | |||
+ | < | ||
+ | check_http -H " | ||
+ | </ | ||
+ | |||
===== Riferimenti Web ===== | ===== Riferimenti Web ===== | ||
Line 372: | Line 759: | ||
* **[[https:// | * **[[https:// | ||
* **[[https:// | * **[[https:// | ||
+ | * **[[https:// |
doc/appunti/linux/sa/cacti_122.txt · Last modified: 2022/10/10 16:27 by niccolo