Nell'articolo precedente Ho spiegato come ottenere una sessione di autorizzazione e inserirla in un macro locale dell'host. In questo articolo spiegherò come integrare Zabbix con Asterisk senza script o software esterni.
L'idea di ‘integrare’ questi due sistemi è emersa tempo fa, senza la necessità di installare software o script aggiuntivi. Una rapida ricerca su Google restituiva una miriade di soluzioni, tutte basate sull'idea di caricare script (in PHP, Bash, Python, ecc.) sul server, e sarete a posto. Tuttavia, volevo realizzare un monitoraggio ‘fuori dalla scatola’ — senza script esterni e senza installare software aggiuntivi sul server di monitoraggio e sull'ATS.
Ci ho lavorato per un totale di 4 giorni lavorativi, ma il risultato ne è valsa la pena. Lavoro tramite l'interfaccia AMI, rilevamento a basso livello, trigger, e soprattutto, ora ci vogliono solo circa 15 minuti per connettere l'ATS e tutte le altre impostazioni.
Disponiamo di Zabbix 4.4, circa 100 unità di Asterisk versione 13. Alcuni ATS hanno interfaccia web FreePBX, altri una console pura, con un sacco di astuzie e integrazione tramite il dialplan.
Otteniamo dati dall'ATS
Il primo e principale aspetto da affrontare è l'ottenimento di dati sui peer e sulle registrazioni SIP. A tal fine, nell'ATS sono presenti interfacce AGI, AMI, ARI e console SSH. Non ho considerato moduli aggiuntivi per motivi ovvi.
Prima di tutto, dobbiamo capire cosa siano questi AGI, AMI, ARI....
- AGI — utilizzo di script nel dialplan. È principalmente usato per gestire le chiamate.
- AMI — fornisce tutte le informazioni necessarie, funziona attraverso la porta 5038 in analogia con Telnet. Fa al caso nostro!
- ARI — moderno, alla moda, in formato JSON. Molte possibilità, formato dati in una forma comprensibile per Zabbix, ma manca di una cosa fondamentale: non permette di controllare la registrazione SIP. Un altro svantaggio è che per i peer esistono solo due stati online/offline, benché ci siano più stati e considerarli è utile per la diagnosi.
- SSH — può fare di tutto, ma a volte non è concesso per ‘motivi di sicurezza’. I motivi possono essere vari, non li analizzerò.
Tuttavia, nonostante i suoi difetti, ARI copre il 90% di tutte le esigenze di monitoraggio.
Zabbix e Telnet — la mia delusione
Conosco bene AMI, in passato ho implementato il monitoraggio delle perdite nelle conversazioni condivisione per uffici remoti, gestione delle chiamate e simili. Con Telnet è tutto chiaro: apri la connessione, invia comandi e leggi la risposta. E così ho fatto, ma il risultato mi ha deluso.
Il Telnet di Zabbix non è come quello nella console di Linux, è un po' più semplice e progettato per l'autenticazione standard tipo login/password. Se la logica di autenticazione è diversa e non c'è richiesta di coppia login/password, si verifica un errore. Dopo tentativi infruttuosi di eludere il requisito di autenticazione, ho dato un'occhiata al codice sorgente del modulo Telnet.
Ho capito che finché non ci fosse una richiesta tradizionale di login e password, non sarei andato oltre. Per curiosità, ho rimosso dal codice tutto ciò che riguardava l'autenticazione, ricompilato tutto. Funziona! Ma non soddisfa i requisiti. Procediamo...
Torniamo a cercare
Ho riletto la documentazione su ARI e ho condotto ulteriori test: qui non ci sono registrazioni SIP. Ci sono peer, ci sono chiamate, ci sono bridge, ma non ci sono registrazioni. A un certo punto mi sono persino chiesto se ci servissero davvero le registrazioni SIP.
Per una strana coincidenza, in quel momento arriva un altro ticket dall'utente riguardo ai problemi con le chiamate in uscita. Il problema era nel blocco della registrazione SIP e si risolveva con un semplice riavvio del modulo.
asterisk -rx "sip reload"Sarebbe fantastico accedere a AMI tramite web: risolverebbe tutti i problemi, ho pensato. Inizio a scavare in questa direzione, e la prima riga di ricerca mi porta alla documentazione ufficiale di Asterisk, dove si dice che per i miei scopi c'è un'opzione webenabled nel file /etc/asterisk/manager.conf, che deve essere impostata su YES, nella sezione [general]
Dopo di che, attraverso una richiesta web normale del tipo ottieni tutte le informazioni necessarie.
Utilizzando l'interfaccia FreePBX, non è possibile abilitare questa opzione tramite web, deve essere attivata tramite console, apportando modifiche al file manager.conf. FreePBX non la rimuove quando si modificano le configurazioni tramite web.
Per quanto ho lavorato con vari tipi di integrazioni Asterisk, non ho mai visto questa funzione menzionata da nessuna parte. Sono rimasto sorpreso che nessuno descriva questo metodo di interazione con il PBX. Ho persino cercato informazioni specifiche su questo argomento: praticamente non c'era nulla o veniva utilizzato per scopi completamente diversi.
WEB AMI — che cos'è?
Aggiunta dell'opzione webenabled nel file manager.conf ha aperto un accesso completo alla gestione dell'ATS tramite web. Tutti i comandi disponibili attraverso il consueto AMI sono ora presenti nel web, è possibile ascoltare gli eventi dall'ATS tramite socket. Il principio di funzionamento non differisce da quello dell'AMI console. Dopo l'attivazione di questa opzione, è possibile accedere all'ATS tramite i seguenti indirizzi:
— pagina web con interfaccia semplice, per test e invio manuale delle richieste. Tutte le risposte sono formattate in un formato HTML leggibile. Non è molto adatta per il monitoraggio.
— solo output di testo, formato simile all'AMI console
— solo output di testo, in formato XML. Fa per noi!

Qui ho pensato: «Ecco, è la soluzione! Adesso tutto sarà pronto! Facile facile», ma era ancora presto per gioire. Per ottenere le informazioni di cui abbiamo bisogno, basta utilizzare una richiesta GET con l'azione necessaria action, che restituisce in risposta xml con l'elenco di tutte le registrazioni e il loro stato. Tutto ciò è fantastico, ma è necessaria un'autenticazione con memorizzazione della sessione dai cookie. Quando si testa nel browser, non ci si pensa a questo processo.
Processo di autorizzazione
All'inizio ci rivolgiamo all'indirizzo , in risposta il server ci invia un cookie con la sessione di autenticazione. Ecco come appare la richiesta HTTP:
https://ats:8089/mxml?action=login&username=zabbix&secret=zabbix
Host: ats:8089
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1Risposta:
GET: HTTP/1.1 200 OK
Server: Asterisk/13.29.2
Date: Thu, 18 Jun 2020 17:41:19 GMT
Cache-Control: no-cache, no-store
Content-type: text/xml
Set-Cookie: mansession_id="6f5de42c"; Version=1; Max-Age=600
Pragma: SuppressEvents
Content-Length: 146 Per lavorare è necessario mansession_id="6f5de42c", cioè il cookie di autenticazione stesso.
Il contenuto deve solo verificare la presenza della risposta «Authentication accepted». Successivamente, in tutte le richieste al server dell'ATS sarà necessario aggiungere il cookie di autenticazione nella richiesta.
https://ats:8089/mxml?action=SIPpeers
Host: ats:8089
Connection: close
Cookie: mansession_id="6f5de42c"Come ottenere il cookie di autenticazione e utilizzarlo in altre richieste leggi qui: «»
Per creare gli elementi di monitoraggio in Zabbix utilizzerò l'auto scoperta.
Auto scoperta
Per l'auto scoperta delle registrazioni e il monitoraggio dello stato dei peer, è necessario rivolgersi all'indirizzo: o
In risposta, l'ATS ci restituisce una risposta XML:
...
... Nella risposta c'è molta spazzatura, quindi nella pre-elaborazione la filtriamo secondo un modello XPath: //response/generic[@host]
Ora inizia la parte più interessante. Per lavorare con il rilevamento e generare dinamicamente elementi, è necessario che la risposta sia in formato JSON. XML non è supportato per le auto-scoperte.
Per convertire XML in JSON ho dovuto giocare un po' con la sostituzione automatica, per questo ho scritto uno script in JS

Un punto interessante, nella risposta dell'ATS tutti i parametri sono racchiusi tra virgolette singole, e dopo l'applicazione del modello //response/generic[@host] vengono sostituiti con doppie.
Per creare elementi utilizziamo le variabili dalla risposta XML (ora JSON).

SIP Registry
Per le registrazioni SIP utilizziamo tre variabili: username, host, port. Mi piaceva il nome dell'elemento 111111@login.mtt.ru:5060, non ho trovato situazioni in cui fosse necessario utilizzare tutte e cinque le variabili.
L'elemento principale che riceve informazioni su tutte le registrazioni, Asterisk — AMI SIPshowregistry. Una volta al minuto effettua una richiesta GET a , dopodiché i dati della risposta XML vengono trasmessi a tutti gli elementi dipendenti per l'analisi. Creo elementi per ogni registrazione dipendenti da questo. È conveniente, poiché otteniamo le informazioni aggiornate con una sola richiesta, e non per ciascuna separatamente. Questa implementazione ha un significativo svantaggio: il carico sul processore.
Durante il test fino a 100 elementi dipendenti, non ho notato alcun carico, ma con 1700 elementi, ciò comportava un carico significativo di 15 secondi sul processore. Tenetelo a mente se avete un numero elevato di elementi dipendenti.
Come opzione per "distribuire" il carico o impostare una frequenza di polling diversa per l'elemento, è possibile separare la logica di elaborazione in ogni singolo elemento.
Non memorizzo le informazioni ricevute nel principale elemento. In primo luogo, non vedo la necessità, e in secondo luogo, se la risposta supera 64K, Zabbix la tronca.
Poiché per l'elemento dipendente utilizziamo la risposta XML completa, dobbiamo nel pre-processing ottenere il valore di questo elemento. Attraverso XPath si fa in questo modo:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@state)
Per gli stati delle registrazioni non ho utilizzato stati testuali, ma li ho convertiti in forma numerica tramite JavaScript:
switch(value) {
case 'Registered':
return 1;
case 'Unregistered':
return 0;
default:
return -1;
}
SIP Peers
Analogamente alle registrazioni SIP, c'è l'elemento principale Asterisk — AMI SIPshowregistry, al quale vengono aggiunti elementi dipendenti.
Qui vengono creati due elementi dipendenti:
- Stato del peer in formato testuale
- Il tempo di risposta del dispositivo — se lo stato è OK, viene riportato il tempo di risposta del dispositivo, altrimenti «-1»
Il percorso verso l'elemento è già un po' più semplice XPath:
string(//response/generic[@objectname="{#SIP_PEER_OBEJECTNAME}"]/@status)
Per il secondo elemento ho utilizzato JavaScript per separare il tempo di risposta dallo stato del peer, poiché sono memorizzati insieme:
if(value.substring(0,2) == 'OK'){
return value.match(/(d+)/gm);
}
else {
return -1;
}Conclusione
La soluzione «pronta all'uso» può essere complessa e non immediatamente comprensibile. Aumenta la flessibilità e la portabilità tra diversi sistemi.
A tutti una piacevole e semplice integrazione! Modello e istruzioni per la configurazione su .
Fonte: habr.com
