Cum să conectați Zabbix cu Asterisk din cutie

Într-un articol precedent „Zabbix – extinderea granițelor macro” V-am spus cum să primiți o sesiune de autorizare și să o înlocuiți într-o macrocomandă gazdă locală. În acest articol vă voi spune cum să conectați Zabbix cu Asterisk fără scripturi și software extern.

Ideea de a „împrieteni” aceste două sisteme s-a născut cu mult timp în urmă, fără a instala software sau scripturi suplimentare. O căutare rapidă pe Google a dat multe soluții posibile, totul s-a rezumat la faptul că încărcați scripturile (în Pyha, Bash, Python etc.) pe server și veți fi fericit. Am vrut să implementez monitorizarea „din cutie” - fără scripturi externe și să instalez software suplimentar pe server cu monitorizare și PBX.

Am petrecut în total 4 zile lucrătoare cu asta, dar rezultatul a meritat. Lucrul prin interfața AMI, detectarea la nivel scăzut, declanșatoarele și, cel mai important, conectarea PBX-ului și a tuturor celorlalte setări durează acum aproximativ 15 minute.

Este disponibil Zabbix 4.4, aproximativ 100 de bucăți din Asterisk versiunea 13. Unele PBX vin cu interfața web FreePBX, altele cu o consolă goală, o grămadă de trucuri și integrare printr-un plan de apelare.

Primirea datelor de la PBX

Primul și principalul punct care trebuie rezolvat este obținerea de date despre colegi și înregistrările SIP. În acest scop, PBX-ul are interfețe de consolă AGI, AMI, ARI și SSH. Din motive evidente, nu am luat în considerare module suplimentare.

Mai întâi trebuie să ne dăm seama ce sunt acești agi, ami, ari...

  • AGI - folosind scripturi în dialplan. Folosit în principal pentru gestionarea apelurilor.
  • AMI - poate furniza toate informațiile necesare, funcționează prin portul 5038, similar cu Telnet. Ni se potrivește!
  • ARI - modern, la modă, JSON. Există multe posibilități, formatul de date este de înțeles pentru Zabbix, dar pentru mine nu există un lucru principal: nu poți controla înregistrarea sip. Un alt dezavantaj este că pentru semeni există doar două stări online/offline, deși există mai multe stări și este util să ținem cont de ele la diagnosticare.
  • SSH poate face totul, dar uneori nu este permis din „motive de securitate”. Considerațiile pot fi diferite, nu voi intra în ele.

Cu toate acestea, cu toate deficiențele sale, ARI acoperă 90% din toate nevoile de monitorizare.

Zabbix și Telnet - dezamăgirea mea

Cunosc bine AMI; la un moment dat am implementat urmărirea pierderilor în conversațiile cu divizarea prin birouri la distanță, gestionarea apelurilor etc. Cu Telnet, totul este și foarte clar: deschideți conexiunea, trimiteți comenzile și citiți răspunsul. Așa am făcut, dar rezultatul m-a dezamăgit.

Telnet în Zabbix nu este același ca în consola Linux, este puțin mai simplu și adaptat pentru autorizarea standard, cum ar fi autentificare/parola. Dacă logica de autorizare este diferită și nu există nicio solicitare pentru o pereche de autentificare/parolă, apare o eroare. După încercări zadarnice de a ocoli cerința de autorizare, a fost util să ne uităm la codul sursă al modulului Telnet.

Mi-am dat seama că până nu există o cerere tradițională de autentificare și parolă, nu voi merge mai departe. Doar pentru distracție, am eliminat tot ce ține de autorizare din cod și am reasamblat totul. Lucrări! Dar nu îndeplinește cerințele. Daţi-i drumul…

Să revenim la căutare

Am recitit documentația ARI din nou, am efectuat teste suplimentare - nu există înregistrări sip aici. Sunt sărbători, sunt conversații, sunt pantaloni, dar nu există înscrieri. La un moment dat chiar m-am gândit, chiar avem nevoie de înregistrarea vulturii?

Printr-o coincidență amuzantă, în acest moment sosește o altă solicitare de la utilizator, cu o problemă cu apelurile efectuate. Problema a fost că înregistrarea sip era înghețată și a fost rezolvată prin simpla repornire a modulului.

asterisk -rx "sip reload"

Ar fi grozav să accesezi AMI prin web: asta ar rezolva toate problemele, m-am gândit. Încep să sap în această direcție și, literalmente, prima linie de căutare duce la documentația oficială Asterisk, care spune că există o opțiune pentru sarcinile mele activat web în dosar /etc/asterisk/manager.conf, care trebuie setat la YES, în secțiune [general]

După aceasta, printr-o solicitare web obișnuită a formularului http://ats:8089/mxml?action=SIPshowregistry obținem toate informațiile necesare.

Când utilizați interfața FreePBX, nu puteți activa această opțiune prin web; trebuie să o activați prin consolă făcând modificări în fișierul manager.conf. FreePBX nu îl șterge atunci când modificările de configurare sunt făcute prin web.

Am lucrat cu diverse tipuri de integrări Asterisk de mult timp, dar nu am văzut niciodată această caracteristică menționată nicăieri. Am fost surprins că nimeni nu descrie această metodă de interacțiune cu PBX. A fost chiar deosebit de util să cauți informații despre acest subiect: practic nu există nimic sau a fost folosit pentru sarcini complet diferite.

WEB AMI - ce fel de fiară?

Adăugarea unei opțiuni activat web la dosar manager.conf a oferit acces deplin la managementul ATS prin web. Toate comenzile disponibile printr-un AMI obișnuit sunt acum pe web, puteți asculta evenimente de la PBX printr-o priză. Principiul de funcționare nu este diferit de AMI-ul consolei. După activarea acestei opțiuni, puteți contacta PBX-ul la următoarele adrese:

https://ats:8089/manager — o pagină web cu o interfață simplă pentru testarea și trimiterea manuală a cererilor. Toate răspunsurile sunt formatate în HTML care poate fi citit. Nu prea potrivit pentru monitorizare.
https://ats:8089/rawman — numai ieșire text, format similar cu AMI de consolă
https://ats:8089/mxml - numai ieșire text, în format XML. Ni se potrivește!

Cum să conectați Zabbix cu Asterisk din cutie

Apoi m-am gândit: „Aceasta este soluția! Acum totul va fi gata! Lemon squeezey, ușor de pipăit”, dar era prea devreme să ne bucurăm. Pentru a obține informațiile de care avem nevoie, este suficient să folosim o cerere GET cu acțiunea necesară acțiune, care, ca răspuns, returnează xml cu o listă a tuturor înregistrărilor și starea acestora. Toate acestea sunt grozave, dar aveți nevoie de autorizație pentru a vă aminti sesiunea din cookie. Când testați în browser, nu vă gândiți la acest proces.

Procesul de autorizare

Mai întâi ne adresam adresei http://ats:8089/mxml?action=login&username=zabbix&secret=zabbix, ca răspuns, serverul ne trimite un cookie cu sesiunea de autorizare. Iată cum arată o solicitare 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: ru-RU,ru;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: 1

Raspuns:

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

<ajax-response>
<response type="object" id="unknown">
<generic response="Success" message="Authentication accepted"/>
</response>
</ajax-response>

Pentru a lucra acolo ai nevoie mansession_id="6f5de42c„, adică cookie-ul de autorizare în sine.
Conținut pe care trebuie doar să verifici răspunsul "Autentificarea acceptată" Apoi, pentru toate apelurile către serverul PBX, va trebui să adăugăm un cookie de autorizare la cerere.

https://ats:8089/mxml?action=SIPpeers

Host: ats:8089
Connection: close
Cookie: mansession_id="6f5de42c"

Citiți cum să obțineți un cookie de autorizare și să îl utilizați în alte solicitări aici: „Zabbix - extinderea granițelor macro»

Pentru a crea elemente de urmărire în Zabbix, voi folosi detectarea automată.

Detectare automată

Pentru a detecta automat înregistrările și a urmări stările peer, trebuie să contactați următoarea adresă: https://ats:8089/mxml?action=SIPshowregistry sau https://ats:8089/mxml?action=SIPpeers

Ca răspuns, PBX-ul ne returnează un răspuns XML:

<ajax-response>
<response type="object" id="unknown">
<generic response="Success" eventlist="start" message="Registrations will follow"/>
</response>
...
<response type="object" id="unknown">
<generic event="RegistryEntry" host="login.mtt.ru" port="5060" username="111111" domain="login.mtt.ru" domainport="5060" refresh="105" state="Registered" registrationtime="1592502142"/>
</response>
<response type="object" id="unknown">
<generic event="RegistryEntry" host="voip.uiscom.ru" port="5060" username="222222" domain="voip.uiscom.ru" domainport="5060" refresh="105" state="Registered" registrationtime="1592502142"/>
</response>
<response type="object" id="unknown">
<generic event="RegistryEntry" host="voip.uiscom.ru" port="5060" username="333333" domain="voip.uiscom.ru" domainport="5060" refresh="105" state="Registered" registrationtime="1592502142"/>
</response>
...
</ajax-response>

Există o mulțime de gunoi în răspuns, așa că în preprocesare îl filtrăm după șablon XPath: //răspuns/generic[@gazdă]
Apoi începe distracția. Pentru a lucra cu detectarea și pentru a crea elemente dinamice, răspunsul trebuie să fie în format JSON. XML nu este acceptat pentru detectările automate.

Pentru a converti XML în JSON, a trebuit să mă joc puțin cu înlocuirea automată, pentru care am făcut un script în JS

Cum să conectați Zabbix cu Asterisk din cutie

Un punct interesant: în răspunsul ATS, toți parametrii sunt înconjurați de ghilimele simple, iar după aplicarea șablonului //răspuns/generic[@gazdă] sunt înlocuite cu cele duble.

Pentru a crea elemente, folosim variabile din răspunsul XML (acum JSON).

Cum să conectați Zabbix cu Asterisk din cutie

Registrul SIP

Pentru înregistrările sip folosim trei variabile: nume de utilizator, gazdă, port. Am fost mulțumit de numele elementului [e-mail protejat]: 5060, nu am găsit nicio situație în care trebuie să utilizați toate cele cinci variabile.

Elementul principal care primește informații despre toate înregistrările, Asterisk - AMI SIPshowregistry. O dată pe minut face o solicitare GET către https://ats:8089/mxml?action=SIPshowregistry, după care datele XML ale răspunsului sunt transmise tuturor elementelor dependente pentru analizare. Pentru fiecare înregistrare creez un element dependent de acesta. Acest lucru este convenabil deoarece primim informații actualizate într-o singură solicitare, și nu pentru fiecare solicitare separat. Această implementare are un dezavantaj semnificativ - sarcina pe procesor.

Când am testat până la 100 de elemente dependente, nu am observat încărcarea, dar cu 1700 de elemente, acest lucru a dat o încărcare vizibilă de 15 secunde pe procesor. Țineți cont de acest lucru dacă aveți un număr mare de elemente dependente.

Ca o opțiune de „împrăștiere” a sarcinii sau de a seta diferite frecvențe de interogare pentru un element, puteți muta logica de procesare la fiecare element separat.

Nu stochez informațiile primite în elementul principal. În primul rând, nu văd necesitatea acestui lucru și, în al doilea rând, dacă răspunsul este mai mare de 64K, atunci Zabbix îl întrerupe.

Deoarece folosim un răspuns XML complet pentru elementul dependent, trebuie să obținem valoarea acestui element în preprocesare. Prin XPath se face astfel:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@ stat)
Pentru stările de înregistrare, nu am folosit stări text, ci le-am convertit în formă numerică folosind JavaScript:

switch(value) {
  case 'Registered':
    return 1;
  case 'Unregistered':
    return 0;
  default:
    return -1;
}

SIP Peers

Prin analogie cu înregistrările SIP, există un element principal al Asterisk - AMI SIPshowregistry, la care se adaugă cele dependente.

Acest lucru creează două elemente dependente:

  • Statutul de peer sub formă de text
  • Timpul de răspuns al dispozitivului - dacă starea este OK, atunci timpul de răspuns al dispozitivului este scris, în caz contrar „-1”

Calea către elementul în sine este puțin mai simplă XPath:

șir(//response/generic[@objectname="{#SIP_PEER_OBEJECTNAME}"]/@status)

Pentru al doilea element am folosit JavaScript pentru a separa timp de raspuns din statutul de peer, deoarece sunt stocate împreună:

if(value.substring(0,2) == 'OK'){
	return value.match(/(d+)/gm);
}
else {
	return -1;
}

Concluzie

O soluție ieșită din cutie poate fi complexă și nu clară imediat. Crește flexibilitatea și portabilitatea între diferite sisteme

Integrare fericită și ușoară tuturor! Șablon și instrucțiuni de configurare GitHub.

Sursa: www.habr.com

Adauga un comentariu