User Tools

Site Tools


doc:appunti:linux:sa:cacti_122

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:linux:sa:cacti_122 [2019/09/03 11:53] – [Configurazione web] niccolodoc:appunti:linux:sa:cacti_122 [2022/10/10 16:27] (current) – [Monitoraggio servizio CLAMD] niccolo
Line 294: Line 294:
 </file> </file>
  
 +==== 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:
 +
 +<code>
 +nrpe[9169]: Error: Could not complete SSL handshake.
 +</code>
 +
 +È 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**.
 +
 +<file>
 +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$" }
 +    }
 +}
 +</file>
 +
 +È sufficiente definire la variabile opportuna nella sezione host:
 +
 +<file>
 +object Host "Server" {
 +  import "generic-host"
 +  address = "server.rigacci.org"
 +  vars.nrpe_swraid = "check_swraid"
 +  vars.nrpe_no_ssl = true
 +}
 +</file>
 ===== Check passivo ===== ===== Check passivo =====
  
Line 330: Line 361:
         return "No check results received. Last result time: " + lastCheck         return "No check results received. Last result time: " + lastCheck
     }}     }}
-    check_interval = 1d  /* This determines the freshness of the check. */ +    check_interval = 1d +1h  /* This determines the freshness of the check. */ 
-    retry_interval = 1h  /* Execute the active check if freshness is due. */ +    retry_interval = 1h      /* Execute the active check if freshness is due. */ 
-    max_check_attempts = 3  /* Retry the active check some times, before notification. */+    max_check_attempts = 3   /* Retry the active check some times, before notification. */
     vars.notification_interval = 1d       vars.notification_interval = 1d  
 } }
Line 339: Line 370:
 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. 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//) 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**.+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: Per definire il servizio associato ad un host si aggiunge ad esempio nel file **/etc/icinga2/conf.d/services.conf** o analogo:
Line 357: 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 **/var/log/icinga2/icinga2.log**:
 +
 +<code>
 +[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.
 +</code>
 +
 +==== 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**:
 +
 +<file>
 +// Used to submit passive checks results, e.g. from backup scripts.
 +object ApiUser "passive-check" {
 +  password = "MyUserSecret"
 +  permissions = [ "actions/process-check-result" ]
 +}
 +</file>
 +
 +Il client che deve inviare l'esito del check passivo può utilizzare ad esempio **curl**, con autenticazione su protocollo https:
 +
 +<code bash>
 +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
 +</code>
 +
 +Un servizio Icinga può essere in uno dei seguenti stati:
 +
 +^  0 | OK        |
 +^  1 | WARNING   |
 +^  2 | CRITICAL  |
 +^  3 | UNKNOWN   |
  
 ==== Server NSCA ==== ==== 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**. 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**.
Line 515: Line 599:
 } }
 </file> </file>
 +===== 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:
 +
 +<file>
 +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"
 +}
 +</file>
 +
 +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:
 +
 +<file>
 +object Host "ADSL_1"     {
 +    import "generic-host"
 +    address = "185.121.12.106"
 +    vars.notification.mailcustomer = { users = [ "dsl_user_1" ] }
 +}
 +</file>
 +
 ===== Modifica servizi predefiniti ===== ===== Modifica servizi predefiniti =====
  
Line 570: Line 684:
   ...   ...
   vars.ping_slow = true   vars.ping_slow = true
 +}
 +</file>
 +===== 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:
 +
 +<file>
 +apply Service "ssh_alt" {
 +  import "generic-service"
 +  check_command = "ssh"
 +  vars.ssh_port = 2222
 +  assign where (host.address || host.address6) && host.vars.os == "LinuxAlt"
 +}
 +</file>
 +
 +===== VirtualHost con SSL =====
 +
 +Per monitorare il funzionamento basico di un server web è sufficiente definire una variabile **vars.http_vhosts** in una sezione **object Host**:
 +
 +<file>
 +object Host "ServerName" {
 +  import "generic-host"
 +  address = "servername.rigacci.org"
 +  vars.http_vhosts["www.rigacci.org"] = { }
 +}
 +</file>
 +
 +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:
 +
 +<file>
 +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"
 +  }
 +}
 +</file>
 +
 +Each **vars.http_vhosts** section correspond to one command invokation, of this type:
 +
 +<code>
 +check_http -H "www.first_domain.tld" -I "servername.rigacci.org" -S --sni -C "24,14"
 +</code>
 +
 +===== 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:
 +
 +<file>
 +# Listen also on TCP localhost, to allow running status check.
 +TCPSocket 3310
 +TCPAddr 127.0.0.1
 +</file>
 +
 +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**:
 +
 +<file>
 +command[check_clamd]=/usr/lib/nagios/plugins/check_clamd -H localhost
 +</file>
 +
 +Sul server Icinga2 si deve definire il **servizio** aggiungendo in **/etc/icinga2/conf.d/local/services.conf** la seguente sezione:
 +
 +<file>
 +apply Service "CLAMD Service" {
 +    import "generic-service"
 +    check_command = "mail_check_nrpe_clamd"
 +    assign where host.vars.nrpe_clamd
 +}
 +</file>
 +
 +Quindi si aggiunge il comando aggiungendo in **/etc/icinga2/conf.d/local/commands.conf** la seguente sezione:
 +
 +<file>
 +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$" }
 +    }
 +}
 +</file>
 +
 +Infine nella sezione **host** relativa all'host da monitorare (potrebbe essere nel file **/etc/icinga2/conf.d/hosts.conf**), si aggiunge la riga:
 +
 +<file>
 +object Host "clamav-hostname" {
 +  ...
 +  vars.nrpe_clamd = true
 +  ...
 } }
 </file> </file>
doc/appunti/linux/sa/cacti_122.1567504431.txt.gz · Last modified: 2019/09/03 11:53 by niccolo