Jak propojit Zabbix s Asterisk „out of the box“

V předchozím článku „Zabbix – rozšiřujeme makro hranice“ Popsal jsem, jak získat autorizační relaci a vložit ji do lokálního makra hostitele. V tomto článku vám ukážu, jak propojiti Zabbix s Asteriskem bez externích skriptů a software.

Myšlenka „propojit“ tyto dvě systémy se objevila dávno, a to bez potřeby instalace dodatečného softwaru a skriptů. Rychlé googlení poskytlo mnohé možnosti řešení, ale všechna se shodovala na tom, že je třeba nahrát skripty (v PHP, Bash, Pythonu atd.) na server a bude vám přáno. Chtěl jsem však implementovat monitorování „z krabice“ – bez externích skriptů a instalace dodatečného softwaru na server s monitorováním a PBX.

Strávil jsem tímto čtyři pracovní dny, ale výsledek stál za to. Práce přes rozhraní AMI, nízkoúrovňové detekce, spouštěče, a co je nejdůležitější – připojení k PBX a všechny ostatní nastavení nyní trvá přibližně 15 minut.

Mám Zabbix 4.4 a asi 100 kusů Asterisk verze 13. Některé PBX mají webové rozhraní FreePBX, jiné mají pouze holou konzoli, spoustu subtilností a integraci přes dialplan.

Získáváme data z PBX

První a hlavní úkol, který je třeba vyřešit, je získání dat o peerech a SIP registracích. Pro to existují v PBX rozhraní AGI, AMI, ARI a SSH konzole. Dodatečné moduly jsem z pochopitelných důvodů nezvažoval.

Nejdříve je třeba si objasnit, co jsou tyto AGI, AMI, ARI…

  • AGI – používání skriptů v dialplanu. Obvykle se používá pro řízení hovorů.
  • AMI – dokáže poskytnout všechny potřebné informace, pracuje přes port 5038 podobně jako Telnet. To nám vyhovuje!
  • ARI – moderně, módně, v JSON. Mnoho možností, formát dat ve srozumitelném formátu pro Zabbix, ale pro mě chybí to nejdůležitější: nelze kontrolovat SIP registraci. Další nevýhoda je, že pro peery existují pouze dva stavy online/offline, i když stavů je více a je užitečné je brát v úvahu při diagnostice.
  • SSH – zvládne vše, ale někdy jej neposkytují z „bezpečnostních důvodů“. Důvody mohou být různé, nebudu je rozebírat.

Nicméně, navzdory všem svým nedostatkům ARI pokrývá 90 % všech potřeb pro monitorování.

Zabbix a Telnet – moje zklamání

AMI znám dobře, v minulosti jsem realizoval sledování ztrát v hovorech rozdělených podle vzdálených kanceláří, správu hovorů atd. S Telnetem je také úplně jasné: otevřete připojení, posílejte příkazy a čtěte odpověď. Což jsem udělal, ale výsledek mě zklamal.

Telnet u Zabbixu není takový jako v konzoli Linuxu, je o něco jednodušší a přizpůsobený pro standardní autorizaci typu uživatelské jméno/heslo. Pokud je logika autorizace jiná a není požadavek na pár uživatelské jméno/heslo, dojde k chybě. Po marných pokusech obejít požadavek na autorizaci jsem se podíval na zdrojové kódy modulu Telnet.

Pochopil jsem, že dokud nebude tradiční požadavek na uživatelské jméno s heslem, dál se neposunu. Z důvodu zvědavosti jsem odstranil z kódu vše, co se týkalo autorizace, a znovu sestavil vše. Funguje to! Ale pro požadavky se to nehodí. Jdeme dál…

Vracíme se k hledání

Znovu jsem si přečetl dokumentaci k ARI, provedl další testy — zde nejsou žádné SIP registrace. Existují peerové, hovory a mosty, ale registrace nejsou. V určitém okamžiku jsem se dokonce zamyslel, jestli jsou pro nás SIP registrace skutečně potřebné?

Zajímavé je, že v tomto momentě přišel další požadavek od uživatele s problémem odchozích hovorů. Problém byl v zablokování SIP registrace a řešil se běžným restartováním modulu.

asterisk -rx "sip reload"

Bylo by skvělé přistupovat k AMI přes web: to by vyřešilo všechny problémy, pomyslel jsem si. Začínám kopat tímto směrem a doslova první řádek hledání vede na oficiální dokumentaci Asterisk, která uvádí, že pro mé úkoly je k dispozici možnost webenabled v souboru /etc/asterisk/manager.conf, kterou je třeba nastavit na hodnotu YES v sekci [general]

Poté pomocí běžného webového požadavku typu http://ats:8089/mxml?action=SIPshowregistry získáváme všechny potřebné informace.

Při použití rozhraní FreePBX nelze tuto možnost přes web zapnout, musí se aktivovat přes konzoli úpravami souboru manager.conf. FreePBX ji při změnách konfigurace přes web nemaže.

Kolikrát jsem pracoval s různými integracemi Asterisk, nikdy jsem neviděl, že by se tato funkce někde zmiňovala. Udivilo mě, že nikdo nepopsal tuto metodu interakce s PBX. Dokonce jsem se speciálně snažil najít informace na toto téma: prakticky nic není nebo bylo použito pro zcela jiné úkoly.

WEB AMI — co to je?

Přidání možnosti webenabled do souboru manager.conf otevřelo plný přístup k řízení ATS přes web. Všechny příkazy, které jsou k dispozici přes běžné AMI, jsou nyní také na webu, můžete poslouchat události z ATS přes soket. Princip fungování se nijak neliší od konzolového AMI. Po aktivaci této možnosti se na ATS můžete obrátit na následujících adresách:

https://ats:8089/manager — webová stránka s jednoduchým rozhraním pro testy a ruční odesílání požadavků. Všechny odpovědi jsou formátovány do čitelného HTML vzhledu. Pro monitoring není příliš vhodná.
https://ats:8089/rawman — pouze textový výstup, formát je shodný s konzolovým AMI
https://ats:8089/mxml — pouze textový výstup, ve formátu XML. To nám vyhovuje!

Jak propojit Zabbix s Asterisk „out of the box“

Tady jsem si pomyslel: „To je ono – řešení! Teď už bude vše hotové! Snadné jako facka“, ale radost byla předčasná. K získání potřebných informací stačí použít GET požadavek s potřebnou akcí akce, který v odpovědi vrátí xml se seznamem všech registrací a jejich stavem. To je skvělé, ale potřebujeme autorizaci s uchováním relace v cookie. Když testujete v prohlížeči, o tomto procesu nepřemýšlíte.

Proces autorizace

Nejdříve se obracíme na adresu http://ats:8089/mxml?action=login&username=zabbix&secret=zabbix, v odpovědi nám server pošle cookie s relací autorizace. Takto vypadá HTTP požadavek:

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: cs-CZ,cs;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

Odpověď:

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

Pro práci tam potřebujete mansession_id="6f5de42c", t.j. samotnou cookie autorizace.
Obsah je třeba pouze zkontrolovat na přítomnost odpovědi „Authentication accepted“. Dále, při všech dotazech na server ATS musíme do požadavku přidávat cookie autorizace.

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

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

Jak získat cookie autorizace a používat ji v dalších požadavcích, čtěte zde: „Zabbix – rozšiřování makro hranic»

Pro vytvoření sledovacích prvků v Zabbixu budu používat automatické objevování.

Automatické objevování

Pro automatické objevování registrací a sledování stavů peerů je nutné obrátit se na adresu: https://ats:8089/mxml?action=SIPshowregistry nebo https://ats:8089/mxml?action=SIPpeers

V odpovědi ATC nám vrací XML odpověď:

...









...

V odpovědi je spoustu nečistot, proto je během předzpracování filtrujeme podle šablony. XPath: //response/generic[@host]
Teď začíná to nejzajímavější. Abychom pracovali s detekcí a dynamicky vytvářeli prvky, musí být odpověď ve formátu JSON. XML není podporováno při automatických detekcích.

Pro převod XML na JSON jsem musel trochu experimentovat s automatickou náhradou, vytvořil jsem na to skript v JS.

Jak propojit Zabbix s Asterisk „out of the box“

Zajímavý moment, ve v odpovědi ATC jsou všechny parametry obklopeny jednoduchými uvozovkami, a po aplikaci šablony //response/generic[@host] se mění na dvojité.

Pro vytváření prvků používáme proměnné z odpovědi XML (nyní JSON).

Jak propojit Zabbix s Asterisk „out of the box“

SIP Registry

Pro SIP registrace používáme tři proměnné: uživatelské jméno, host, port. Vyhovovalo mi pojmenování prvku 111111@login.mtt.ru:5060, nenašel jsem situace, kdy bych musel použít všechny pět proměnných.

Hlavní prvek, který získává informace o všech registracích, Asterisk — AMI SIPshowregistry. Každou minutu provádí GET požadavek na https://ats:8089/mxml?action=SIPshowregistry, po čemž se data XML odpovědi předávají všem závislým prvkům k analýze. Prvek pro každou registraci vytvářím závislý na něm. Je to pohodlné, protože aktuální informace získáváme jedním požadavkem, a ne pro každý zvlášť. Tato realizace má však značnou nevýhodu — zátěž na procesor.

Při testování do 100 závislých prvků jsem zatížení nezaznamenal, ale při 1700 prvcích to vyvolalo znatelnou zatěž na procesor po dobu 15 sekund. Mějte to na paměti, pokud máte velké množství závislých prvků.

Jako varianta pro „rozprostření“ zátěže nebo nastavení různé frekvence dotazu na prvek, je možné přesunout logiku zpracování na každý prvek zvlášť.

Informace, které dostanu, neuchovávám v hlavním prvku. Za prvé, nevidím v tom potřebu, a za druhé, pokud je odpověď větší než 64K, tak ji Zabbix zkrátí.

Protože pro závislý prvek používáme úplnou XML odpověď, musíme v předzpracování získat hodnotu tohoto prvku. Skrze XPath to se to provádí takto:
string(//response/generic[@event='RegistryEntry'][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@state)
Pro stavy registrací jsem nepoužil textové stavy, ale převedl je na číselné pomocí JavaScriptu:

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

SIP Peers

Podobně jako u SIP registrací, existuje hlavní prvek Asterisk — AMI SIPshowregistry, ke kterému se přidávají závislé.

Zde se vytvářejí dva závislé prvky:

  • Stav peeru v textové podobě
  • Doba odezvy zařízení — pokud je stav OK, zapíše se čas odpovědi zařízení, jinak se zapíše '-1'

Cesta k prvku je už o něco jednodušší XPath:

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

Pro druhý prvek jsem použil JavaScript, abych oddělil doba odezvy od stavu peeru, protože jsou uchovávány společně:

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

Závěr

Řešení "z krabice" může být složité a ne vždy srozumitelné. Roste flexibilita a přenositelnost mezi různými systémy

Všem příjemnou a snadnou integraci! Šablona a návod k nastavení na GitHub.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster