Як пасябраваць Zabbix з Asterisk «са скрынкі»

У папярэднім артыкуле «Zabbix – пашыраем макра межы» я распавёў як атрымліваць сесію аўтарызацыі і падстаўляць яе ў лакальны макрас хаста. У гэтым артыкуле я распавяду як пасябраваць Zabbix з Asterisk без вонкавых скрыптоў і ПА.

Ідэя "здружыць" гэтыя дзве сістэмы нарадзілася даўно, прычым без усталёўкі дадатковага софту і скрыптоў. Хуткае гугленне выдавала мноства варыянтаў рашэнняў, усё зводзілася да таго, што закіньце скрыпты (на пыху, вежы, пітон і т. п.) на сервер, і будзе вам шчасце. Мне ж хацелася рэалізаваць маніторынг "са скрынкі" – без знешніх скрыптоў і ўстаноўкі дадатковага софту на сервер з маніторынгам і АТС.

Правозіўся я з гэтым у суме 4 працоўныя дні, але вынік каштаваў таго. Праца праз інтэрфейс AMI, нізкаўзроўневыя выяўленне, трыгеры, а галоўнае, на падлучэнне АТС і ўсе астатнія налады зараз сыходзіць хвілін 15.

У наяўнасці заббікс 4.4, каля 100 штук Астэрыскаў 13 версіі. Нейкія АТС ідуць з вэб інтэрфейсам FreePBX, нейкія з голай кансоллю, кучай хітрасцяў і інтэграцыяй праз диалплан.

Атрымліваем дадзеныя з АТС

Першы і асноўны момант, які трэба вырашыць - атрыманне дадзеных аб балях і сип рэгістрацыях. Для гэтага ў АТС існуюць інтэрфейсы AGI, AMI, ARI і SSH кансоль. Дадатковыя модулі па зразумелых прычынах не разглядаў.

Для пачатку трэба разабрацца, што з сябе ўяўляюць гэтыя агі, амі, ары….

  • AGI - выкарыстанне скрыптоў у диалплане. Галоўным чынам выкарыстоўваецца для кіравання выклікамі.
  • AMI – умее аддаваць усю неабходную інфармацыю, працуе праз порт 5038 па аналогіі з Telnet. Нам падыходзіць!
  • ARI - сучасна, модна, JSONна. Шмат магчымасцяў, фармат дадзеных у зразумелым выглядзе для Zabbix, але для мяне няма галоўнага: нельга кантраляваць сип рэгістрацыю. Яшчэ адзін мінус, для баляў ёсць толькі два станы online/offline, хоць станаў больш і іх улічваць карысна пры дыягностыцы.
  • SSH можа ўсё, але часам яго не даюць з-за «меркаванняў бяспекі». Меркаванні могуць быць рознымі, разбіраць іх не буду.

Тым не менш, пры ўсіх сваіх недахопах ARI закрывае 90% усіх запатрабаванняў па маніторынгу.

Zabbix і Telnet – маё расчараванне

AMI ведаю добра, у свой час рэалізоўваў адсочванне страт у гутарках з дзяленнем па выдаленых офісах, кіраванне званкамі і да т.п. З Telnet таксама ўсё лімітава ясна: адчыняй падлучэнне, ішлі каманды і чытай адказ. Што я і зрабіў, але вынік мяне расчараваў.

Telnet у заббікса не такі як у кансолі Linux, ён ледзь прасцейшы і заменчаны пад стандартную аўтарызацыю тыпу лагін/пароль. Калі логіка аўтарызацыі іншая, і няма запыту пары лагін/пароль, вылятае памылка. Пасля марных спроб абыйсці патрабаванне аўтарызацыі палез глядзець зыходнікі модуля Telnet.

Я зразумеў, што пакуль не будзе традыцыйнага запыту лагіна з паролем, далей не прасунуся. Дзеля цікавасці, выкінуў з кода ўсё, што да аўтарызацыі, перасабраў усё. Працуе! Але пад патрабаванні не падыходзіць. Ідзем далей…

Вяртаемся да пошуку

Перачытаў яшчэ раз дакументацыю па ARI, правёў дадатковыя тэсты - няма тут сіп рэгістрацый. Піры ёсць, размовы ёсць, брыджы ёсць, рэгістрацый няма. У нейкі момант нават задумаўся, ці так патрэбны нам сіп рэгістрацыі?

Па пацешным збегу абставінаў, у гэты момант прылятае чарговы запыт ад карыстальніка, з праблемай выходных званкоў. Праблема была ў падвісанні сип рэгістрацыі і вырашалася звычайнай перазагрузкай модуля.

asterisk -rx "sip reload"

Было б выдатна па вэбе звяртацца да AMI: гэта б вырашыла ўсе праблемы, падумаў я. Пачынаю капаць у гэтым кірунку, і літаральна першы радок пошуку вядзе на афіцыйную дакументацыю Asterisk, у якой гаворыцца, што для маіх задач ёсць опцыя. webenabled у файле /etc/asterisk/manager.conf, якую трэба ўсталяваць у значэнне YES, у секцыі [general]

Пасля гэтага, праз звычайны вэб запыт выгляду http://ats:8089/mxml?action=SIPshowregistry атрымліваем усю неабходную інфармацыю.

Пры выкарыстанні інтэрфейсу FreePBX, праз вэб нельга ўключыць дадзеную опцыю, уключаць трэба праз кансоль, уносячы праўкі ў файл manager.conf. FreePBX не сцірае яе пры зменах канфігурацыі праз вэб.

Колькі працаваў з рознага роду інтэграцыямі Asterisk, ніколі не бачыў, каб недзе згадвалася гэтая функцыя. Мяне здзівіла, што ніхто не апісвае гэты метад узаемадзеяння з АТС. Нават спецыяльна палез шукаць інфармацыю па дадзенай тэме: практычна нічога няма ці выкарыстоўвалася для зусім іншых задач.

WEB AMI - што за звер?

Даданне опцыі webenabled у файл manager.conf адкрывала паўнавартасны доступ да кіравання АТСкай праз вэб. Усе каманды, даступныя праз звычайны AMI, зараз ёсць у вэбе, можна слухаць падзеі ад АТС праз сокет. Прынцып працы нічым не адрозніваецца ад кансольнага AMI. Пасля актывацыі дадзенай опцыі, да АТС можна звярнуцца па наступных адрасах:

https://ats:8089/manager - вэб старонка з простым інтэрфейсам, для тэстаў і ручной адпраўкі запытаў. Усе адказы фарматуюцца ў чытэльны HTML выгляд. Для маніторынгу не надта падыходзіць.
https://ats:8089/rawman - толькі тэкставы вывад, фармат аналагічны кансольнаму AMI
https://ats:8089/mxml - толькі тэкставы вывад, у фармаце XML. Нам падыходзіць!

Як пасябраваць Zabbix з Asterisk «са скрынкі»

Тут я было падумаў: «Вось яно - рашэнне! Цяпер усё будзе гатова! Ізі-пізі лямон сквізі», але радавацца было пакуль рана. Для атрымання патрэбнай нам інфармацыі дастаткова выкарыстоўваць GET запыт з патрэбнымі дзеяннем дзеянне, які ў адказ вяртае xml са спісам усіх рэгістрацый і іх станам. Гэта ўсё выдатна, але патрэбна аўтарызацыя з запамінаннем сесіі з кукі. Калі тэстуеш у браўзэры, не задумваешся пра гэты працэс.

Працэс аўтарызацыі

Спачатку мы звяртаемся на адрас http://ats:8089/mxml?action=login&username=zabbix&secret=zabbix, у адказ нам сервер дасылае куку з сесіяй аўтарызацыі. Вось так выглядае 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

Адказ:

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>

Для працы тамака трэба mansession_id="6f5de42c"г.зн. сама кука аўтарызацыі.
Кантэнт трэба толькі праверыць наяўнасць адказу.Authentication accepted». Далей, пры ўсіх зваротах да сервера АТС нам неабходна будзе дадаваць у запыт куку аўтарызацыі.

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

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

Як атрымліваць куку аўтарызацыі і выкарыстоўваць у іншых запытах чытайце тут: «Zabbix – пашыраем макра мяжы»

Для стварэння элементаў адсочвання ў заббіксе буду выкарыстоўваць аўта выяўленне.

Аўта выяўленне

Для аўто выяўлення рэгістрацый і адсочвання станаў баляў неабходна звяртацца да адрасу: https://ats:8089/mxml?action=SIPshowregistry або https://ats:8089/mxml?action=SIPpeers

У адказ АТС вяртае нам 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>

У адказе шмат смецця, таму ў прэпрацэсінгу мы яго фільтруем па шаблоне. XPath: //response/generic[@host]
Далей пачынаецца самае цікавае. Каб працаваць з выяўленнем і дынамічна ствараць элементы, трэба, каб адказ быў у JSON фармаце. XML пры аўта выяўленнях не падтрымліваецца.

Для пераўтварэння XML у JSON прыйшлося крыху пагуляцца з аўта заменай, для чаго я зрабіў скрыпт на JS

Як пасябраваць Zabbix з Asterisk «са скрынкі»

Цікавы момант, у адказе АТС усе параметры апраўляюцца адзінарнымі двукоссямі, а пасля прымянення шаблону //response/generic[@host] яны замяняюцца на падвойныя.

Для стварэння элементаў выкарыстоўваем зменныя з XML адказу (цяпер JSON).

Як пасябраваць Zabbix з Asterisk «са скрынкі»

SIP Registry

Для сіп рэгістрацый выкарыстоўваем тры зменныя: імя карыстальніка, гаспадар, порт. Мяне задавальняла назва элемента [электронная пошта абаронена]: 5060, Сітуацый калі трэба выкарыстоўваць усе пяць зменных я не знайшоў.

Галоўны элемент, які атрымлівае інфармацыю аб усіх рэгістрацыях, Asterisk - AMI SIPshowregistry. Раз у хвіліну ён звяртаецца GET запытам да https://ats:8089/mxml?action=SIPshowregistry, пасля чаго дадзеныя XML адказу перадаюцца ўсім залежным элементам для аналізу. Элемент па кожнай рэгістрацыі ствараю залежнымі ад яго. Гэта зручна, бо актуальную інфармацыю мы атрымліваем за адзін запыт, а не для кожнага асобна. У дадзенай рэалізацыі ёсць істотны мінус - нагрузка на працэсар.

Пры тэсціраванні да 100 залежных элементаў, нагрузку не заўважыў, але пры 1700 элементаў, гэта давала прыкметную 15 секундную нагрузку на працэсар. Майце гэта на ўвазе, калі ў вас вялікая колькасць залежных элементаў.

Як варыянт для «размазвання» нагрузкі ці ўсталёўкі рознай частаты апытання элемента, можна вынесці логіку апрацоўкі ў кожны элемент асобна.

Атрыманую інфармацыю я не захоўваю ў галоўным элеменце. Па-першае, не бачу ў гэтым неабходнасці, а па-другое, калі адказ больш за 64К, то заббікс яго абразае.

Паколькі для залежнага элемента ў нас выкарыстоўваецца поўны XML адказ, нам трэба ў прэпрацэсінг атрымаць значэнне дадзенага элемента. Праз XPath гэта робіцца так:
string(//response/generic[@event=«RegistryEntry»]][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@ state)
Для статутаў рэгістрацый не стаў выкарыстоўваць тэкставыя статуты, а перавёў іх у лікавы выгляд з дапамогай JavaScript:

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

SIP Peers

Па аналогіі з сип рэгістрацыямі, ёсць галоўны элемент Asterisk - AMI SIPshowregistry, да якога дадаюцца залежныя.

Тут ствараюцца два залежныя элементы:

  • Статус балю ў тэкставым выглядзе
  • Час водгуку прылады - калі статус ОК, то пішацца час адказу прылады, інакш "-1"

Сам шлях да элемента ўжо крыху прасцей XPath:

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

Для другога элемента выкарыстоўваў JavaScript, каб аддзяліць час водгуку ад статусу балю, паколькі захоўваюцца яны разам:

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

Заключэнне

Рашэнне са скрынкі можа быць складаным і не адразу зразумелым. Узрастае гнуткасць і пераноснасць паміж рознымі сістэмамі

Усім прыемнай і лёгкай інтэграцыі! Шаблон і інструкцыя па наладзе на GitHub.

Крыніца: habr.com

Дадаць каментар