Ինչպես անել, որ Zabbix-ը և Asterisk-ը աշխատեն տուփից դուրս

Մի նախորդ հոդվածում «Zabbix - մակրո սահմանների ընդլայնում» Ես պատմեցի, թե ինչպես ստանալ լիազորման նիստ և այն փոխարինել տեղական հոսթ մակրոյով։ Այս հոդվածում ես ձեզ կասեմ, թե ինչպես կարելի է ընկերներ կազմել Zabbix-ի և Asterisk-ի միջև՝ առանց արտաքին սկրիպտների և ծրագրաշարի։

Այս երկու համակարգերի միջև «ընկերանալու» գաղափարը ծնվել է վաղուց, և առանց լրացուցիչ ծրագրակազմ և սկրիպտներ տեղադրելու։ Google-ում արագ որոնումը բազմաթիվ հնարավոր լուծումներ տվեց, որոնք բոլորը հանգեցրին նրան, որ դուք սերվերի վրա սկրիպտներ եք նետում (Pykh, Bash, Python և այլն), և դուք գոհ կլինեք։ Ես ուզում էի մոնիթորինգ իրականացնել «անմիջապես»՝ առանց արտաքին սկրիպտների և սերվերի վրա լրացուցիչ ծրագրակազմ տեղադրելով՝ մոնիթորինգով և PBX-ով։

Ես դրա վրա ծախսեցի ընդհանուր առմամբ 4 աշխատանքային օր, բայց արդյունքն արժեր դրան։ AMI ինտերֆեյսի, ցածր մակարդակի հայտնաբերման, ակտիվացուցիչների և ամենակարևորը՝ PBX-ի և մնացած բոլոր կարգավորումների միացումը այժմ տևում է մոտ 15 րոպե։

Zabbix 4.4-ը պահեստում է, մոտ 100 հատ Asterisk 13 տարբերակ։ Որոշ PBX-ներ գալիս են FreePBX վեբ ինտերֆեյսով, որոշները՝ մերկ կոնսոլով, մի շարք հնարքներով և ինտեգրացիայով՝ dialplan-ի միջոցով։

Մենք տվյալներ ենք ստանում PBX-ից

Առաջին և հիմնական կետը, որը պետք է լուծվի, հասակակիցների և SIP գրանցումների վերաբերյալ տվյալների ստացումն է։ Այս նպատակով, PBX-ն ունի AGI, AMI, ARI ինտերֆեյսներ և SSH կոնսոլ։ Հասկանալի պատճառներով ես լրացուցիչ մոդուլներ չեմ դիտարկել։

Նախ, մենք պետք է պարզենք, թե ինչ են այս agi-ն, ami-ն, ari-ն…

  • AGI - սկրիպտների օգտագործումը dialplan-ում։ Հիմնականում օգտագործվում է զանգերի կառավարման համար։
  • AMI - կարող է տրամադրել բոլոր անհրաժեշտ տեղեկությունները, աշխատում է 5038 պորտի միջոցով՝ Telnet-ի նման։ Մեզ հարմար է!
  • ARI-ն ժամանակակից է, նորաձև, JSON-ի վրա հիմնված։ Շատ հնարավորություններ, տվյալների ձևաչափը հստակ ձևով Zabbix-ի համար, բայց ինձ համար գլխավորը բացակայում է. դուք չեք կարող վերահսկել SIP գրանցումը։ Մեկ այլ թերություն է այն, որ զույգերն ունեն միայն երկու վիճակ՝ առցանց/անցանց, չնայած կան ավելի շատ վիճակներ, և օգտակար է դրանք հաշվի առնել ախտորոշման ժամանակ։
  • SSH-ը կարող է անել ամեն ինչ, բայց երբեմն այն չի տրամադրվում «անվտանգության նկատառումներից» ելնելով։ Նկատառումները կարող են տարբեր լինել, ես դրանց մեջ չեմ խորանա։

Սակայն, բոլոր թերություններով հանդերձ, ARI-ն ապահովում է մոնիթորինգի բոլոր կարիքների 90%-ը։

Zabbix և Telnet - Իմ հիասթափությունը

Ես լավ գիտեմ AMI-ը, մի ժամանակ ես իրականացրել եմ զանգերի կորուստների հետևում՝ հեռակա գրասենյակների բաժանմամբ, զանգերի կառավարմամբ և այլն: Telnet-ի դեպքում ամեն ինչ նույնպես չափազանց պարզ է. բացել կապը, ուղարկել հրամաններ և կարդալ պատասխանը: Ահա թե ինչ արեցի, բայց արդյունքը հիասթափեցրեց ինձ։

Zabbix-ի Telnet-ը նույնը չէ, ինչ կոնսոլի Telnet-ը։ LinuxԱյն մի փոքր ավելի պարզ է և նախատեսված է մուտքի/գաղտնաբառի ստանդարտ նույնականացման համար: Եթե նույնականացման տրամաբանությունը տարբեր է և մուտքի/գաղտնաբառի զույգ չի պահանջվում, սխալ է առաջանում: Նույնականացման պահանջը շրջանցելու անհաջող փորձերից հետո սկսեցի նայել Telnet մոդուլի սկզբնական կոդը:

Ես հասկացա, որ մինչև ավանդական մուտքանուն և գաղտնաբառի հարցում չլիներ, ես առաջ չէի գնա։ Հետաքրքրության համար ես կոդից հանեցի թույլտվության հետ կապված ամեն ինչ և վերամիավորեցի ամեն ինչ։ Աշխատում է! Բայց դա չի համապատասխանում պահանջներին։ Եկեք շարունակենք...

Վերադառնալ որոնմանը

Ես կրկին կարդացի ARI փաստաթղթերը, անցկացրեցի լրացուցիչ թեստեր. այստեղ SIP գրանցումներ չկան: Կան հասակակիցներ, կան զրույցներ, կան կամուրջներ, բայց գրանցումներ չկան։ Ինչ-որ պահի ես նույնիսկ մտածեցի, թե արդյոք մեզ իսկապես անհրաժեշտ են SIP գրանցումներ։

Զվարճալի զուգադիպությամբ, այս պահին մեկ այլ հարցում է ստացվում օգտատիրոջից, ով ելքային զանգերի հետ կապված խնդիր ունի։ Խնդիրն այն էր, որ SIP գրանցումը կախվում էր և լուծվեց պարզապես մոդուլը վերագործարկելով։

asterisk -rx "sip reload"

Հիանալի կլիներ, եթե հնարավոր լիներ AMI-ին մուտք գործել համացանցի միջոցով. դա կլուծեր բոլոր խնդիրները, մտածեցի ես։ Ես սկսում եմ փորել այս ուղղությամբ, և բառացիորեն առաջին որոնման տողը տանում է դեպի Asterisk-ի պաշտոնական փաստաթղթերը, որտեղ ասվում է, որ իմ առաջադրանքների համար կա տարբերակ։ ցանցին միացված ֆայլում /etc/asterisk/manager.conf, որը պետք է դրվի ԱՅՈ-ի վրա, բաժնում [ընդհանուր]

Դրանից հետո, ձևի կանոնավոր վեբ հարցման միջոցով http://ats:8089/mxml?action=SIPshowregistry մենք ստանում ենք բոլոր անհրաժեշտ տեղեկությունները։

FreePBX ինտերֆեյսն օգտագործելիս այս տարբերակը հնարավոր չէ միացնել վեբի միջոցով։ Այն պետք է միացվի կոնսոլի միջոցով՝ խմբագրելով manager.conf ֆայլը։ FreePBX-ը չի մաքրում այն, երբ կարգավորումը փոխվում է վեբի միջոցով։

Asterisk-ի տարբեր ինտեգրացիաների հետ աշխատելու ողջ ընթացքում ես երբեք ոչ մի տեղ չեմ տեսել այս գործառույթի մասին հիշատակում։ Ես զարմացա, որ ոչ ոք չի նկարագրում PBX-ի հետ փոխազդեցության այս մեթոդը։ Ես նույնիսկ հատուկ գնացի այս թեմայի վերաբերյալ տեղեկատվություն փնտրելու. գործնականում ոչինչ չկա, կամ այն ​​օգտագործվել է բոլորովին այլ խնդիրների համար:

WEB AMI - ի՞նչ տեսակի գազան է սա։

Ընտրանք ավելացնելը ցանցին միացված ներկայացնել manager.conf բացվեց PBX-ի կառավարման լիարժեք հասանելիություն համացանցի միջոցով։ Սովորական AMI-ի միջոցով հասանելի բոլոր հրամանները այժմ համացանցում են, դուք կարող եք լսել PBX-ի իրադարձությունները միակցիչի միջոցով։ Գործողության սկզբունքը ոչնչով չի տարբերվում AMI կոնսոլից։ Այս տարբերակը ակտիվացնելուց հետո կարող եք կապվել PBX-ի հետ հետևյալ հասցեներով՝

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, ի պատասխան սերվերը մեզ ուղարկում է cookie՝ լիազորման սեսիայի հետ միասին։ Ահա թե ինչ տեսք ունի 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>

Այնտեղ աշխատելու համար ձեզ անհրաժեշտ է՝ mansion_id="6f5de42c«, այսինքն՝ հենց ինքնին լիազորման cookie-ն։
Պարունակությունը միայն պետք է ստուգվի պատասխանի առկայության համար։Նույնականացումը ընդունված է«Հաջորդը, PBX սերվերին ուղղված բոլոր հարցումների համար մենք պետք է հարցմանը ավելացնենք թույլտվության cookie։»

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

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

Ինչպես ստանալ թույլտվության cookie-ներ և օգտագործել դրանք այլ հարցումներում, կարդացեք այստեղ՝ «Zabbix - ընդլայնելով մակրո սահմանները»

Zabbix-ում հետևողական տարրեր ստեղծելու համար ես կօգտագործեմ ավտոմատ հայտնաբերում։

Ավտոմատ հայտնաբերում

Գրանցումները ավտոմատ կերպով հայտնաբերելու և հասակակիցների վիճակները հետևելու համար ձեզ անհրաժեշտ է մուտք գործել հետևյալ հասցեին. https://ats:8089/mxml?action=SIPshowregistry կամ https://ats:8089/mxml?action=SIPpeers

Ի պատասխան, PBX-ը մեզ վերադարձնում է 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: //պատասխան/ընդհանուր[@host]
Հիմա սկսվում է ամենահետաքրքիր մասը։ Discovery-ի հետ աշխատելու և տարրեր դինամիկ կերպով ստեղծելու համար պատասխանը պետք է լինի JSON ձևաչափով։ XML-ը չի աջակցվում ավտոմատ հայտնաբերումներում։

XML-ը JSON-ի փոխարկելու համար ես ստիպված էի մի փոքր խաղալ ավտոմատ փոխարինման հետ, որի համար ստեղծեցի JS սկրիպտ։

Ինչպես անել, որ Zabbix-ը և Asterisk-ը աշխատեն տուփից դուրս

Հետաքրքիր կետն այն է, որ ATS պատասխանում բոլոր պարամետրերը շրջանակված են մեկ չակերտների մեջ, և ձևանմուշը կիրառելուց հետո //պատասխան/ընդհանուր[@host] դրանք փոխարինվում են կրկնակիներով։

Էլեմենտներ ստեղծելու համար մենք օգտագործում ենք XML պատասխանից (այժմ՝ JSON) փոփոխականներ։

Ինչպես անել, որ Zabbix-ը և Asterisk-ը աշխատեն տուփից դուրս

SIP գրանցամատյան

SIP գրանցումների համար մենք օգտագործում ենք երեք փոփոխական՝ օգտագործողի անունը, հյուրընկալող, նավահանգիստ. Ես գոհ էի տարրի անունից 111111@login.mtt.ru:5060, Ես չգտա որևէ իրավիճակ, երբ անհրաժեշտ լինի օգտագործել բոլոր հինգ փոփոխականները։

Հիմնական տարրը, որը ստանում է տեղեկատվություն բոլոր գրանցումների մասին, Աստերիսկ - AMI SIPshowregistry. Րոպեն մեկ անգամ այն ​​GET հարցում է կատարում https://ats:8089/mxml?action=SIPshowregistry, որից հետո XML պատասխանի տվյալները փոխանցվում են բոլոր կախյալ տարրերին՝ վերլուծության համար։ Ես ստեղծում եմ տարր յուրաքանչյուր գրանցման համար, որը կախված է դրանից։ Սա հարմար է, քանի որ մենք թարմացված տեղեկատվություն ենք ստանում մեկ հարցման մեջ, այլ ոչ թե յուրաքանչյուրի համար առանձին։ Այս իրականացումն ունի զգալի թերություն՝ պրոցեսորի վրա ծանրաբեռնվածությունը։

Մինչև 100 կախյալ տարր փորձարկելիս ես որևէ բեռ չեմ նկատել, բայց 1700 տարրի դեպքում սա պրոցեսորի վրա նկատելի 15 վայրկյան բեռ է տվել։ Հաշվի առեք սա, եթե ունեք մեծ թվով կախյալ տարրեր։

Որպես բեռը «քսելու» կամ տարրերի տարբեր հարցման հաճախականություն սահմանելու տարբերակ, կարող եք մշակման տրամաբանությունը տեղափոխել յուրաքանչյուր տարրի առանձին:

Ես ստացված տեղեկատվությունը չեմ պահում գլխավոր տարրում։ Նախ, ես դրա անհրաժեշտությունը չեմ տեսնում, և երկրորդ, եթե պատասխանը 64 հազարից ավելի է, ապա Zabbix-ը կտրում է այն։

Քանի որ մենք կախյալ տարրի համար օգտագործում ենք ամբողջական XML պատասխան, մենք պետք է ստանանք այս տարրի արժեքը նախնական մշակման ընթացքում։ Միջոցով XPath դա արվում է այսպես.
տող(//պատասխան/ընդհանուր[@event="RegistryEntry"][@օգտատիրոջ անուն="{#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 գործընկերներ

SIP գրանցումների հետ համեմատությամբ, Asterisk-ի հիմնական տարրը AMI SIPshowregistry-ն է, որին ավելացվում են կախյալներ։

Այստեղ ստեղծվում են երկու կախյալ տարրեր՝

  • Հասակակիցների կարգավիճակը տեքստային տեսքով
  • Սարքի արձագանքման ժամանակը. եթե կարգավիճակը լավ է, ապա գրվում է սարքի արձագանքման ժամանակը, հակառակ դեպքում՝ «-1»:

Էլեմենտին տանող ճանապարհն արդեն մի փոքր ավելի պարզ է XPath:

տող(//պատասխան/ընդհանուր[@objectname="{#SIP_PEER_OBEJECTNAME}"]/@status)

Երկրորդ տարրի համար ես օգտագործեցի JavaScript՝ պատասխան ժամանակ գործընկերոջ կարգավիճակից, քանի որ դրանք պահվում են միասին՝

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

Ամփոփում

Պատրաստի լուծումը կարող է բարդ լինել և անմիջապես պարզ չլինել։ Բարձրացված ճկունություն և փոխադրելիություն տարբեր համակարգերի միջև

Մաղթում եմ բոլորիդ հաճելի և հեշտ ինտեգրում։ Կաղապար և տեղադրման հրահանգներ GitHub.

Source: www.habr.com

Գնեք հուսալի հոստինգ DDoS պաշտպանությամբ կայքերի, VPS VDS սերվերների համար 🔥 Գնեք հուսալի կայքերի հոսթինգ՝ DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster