نحوه اتصال Zabbix با Asterisk خارج از جعبه

در مقاله قبلی "Zabbix - گسترش مرزهای کلان" من به شما گفتم که چگونه یک جلسه مجوز را دریافت کنید و آن را به یک ماکرو میزبان محلی جایگزین کنید. در این مقاله به شما خواهم گفت که چگونه Zabbix را با Asterisk بدون اسکریپت و نرم افزار خارجی متصل کنید.

ایده "دوست پیدا کردن" این دو سیستم مدتها پیش و بدون نصب نرم افزار یا اسکریپت اضافی متولد شد. یک جستجوی سریع در گوگل راه‌حل‌های ممکن زیادی را به همراه داشت، همه اینها در این واقعیت خلاصه شد که اسکریپت‌ها (در Pyha، Bash، Python و غیره) را روی سرور آپلود کنید و خوشحال خواهید شد. من می خواستم نظارت را "خارج از جعبه" - بدون اسکریپت های خارجی و نصب نرم افزار اضافی روی سرور با نظارت و PBX اجرا کنم.

من در مجموع 4 روز کاری با این کار صرف کردم، اما نتیجه ارزشش را داشت. کار از طریق رابط AMI، تشخیص سطح پایین، تریگرها و مهمتر از همه، اتصال PBX و سایر تنظیمات اکنون حدود 15 دقیقه طول می کشد.

Zabbix 4.4 موجود است، حدود 100 قطعه از Asterisk نسخه 13. برخی از PBX ها دارای رابط وب FreePBX هستند، برخی با یک کنسول خالی، یکسری ترفندها و یکپارچه سازی از طریق یک پلان شماره گیری.

دریافت اطلاعات از سانترال

اولین و اصلی ترین نکته ای که باید حل شود، به دست آوردن اطلاعات مربوط به همتایان و ثبت نام SIP است. برای این منظور، سانترال دارای رابط های کنسول AGI، AMI، ARI و SSH می باشد. به دلایل واضح، ماژول های اضافی را در نظر نگرفتم.

ابتدا باید بفهمیم این آگی، آمی، آری چیست؟

  • AGI - استفاده از اسکریپت ها در پلان شماره گیری. عمدتا برای مدیریت تماس استفاده می شود.
  • AMI - می تواند تمام اطلاعات لازم را ارائه دهد، از طریق پورت 5038، مشابه Telnet کار می کند. مناسب ماست!
  • ARI - مدرن، مد روز، JSON. احتمالات زیادی وجود دارد، قالب داده برای Zabbix قابل درک است، اما برای من هیچ چیز اصلی وجود ندارد: شما نمی توانید ثبت جرعه را کنترل کنید. یکی دیگر از معایب این است که برای همتایان فقط دو حالت آنلاین/آفلاین وجود دارد، اگرچه حالت های بیشتری وجود دارد و در نظر گرفتن آنها هنگام تشخیص مفید است.
  • SSH می تواند همه کارها را انجام دهد، اما گاهی اوقات به دلایل امنیتی مجاز نیست. ملاحظات ممکن است متفاوت باشد، من وارد آنها نمی شوم.

با این حال، ARI با تمام کاستی هایی که دارد، 90 درصد نیازهای نظارتی را پوشش می دهد.

Zabbix و Telnet - ناامیدی من

من AMI را به خوبی می شناسم؛ زمانی ردیابی ضرر در مکالمات با بخش توسط دفاتر راه دور، مدیریت تماس و غیره را اجرا کردم. با Telnet، همه چیز نیز بسیار واضح است: اتصال را باز کنید، دستورات را ارسال کنید و پاسخ را بخوانید. این کاری بود که من انجام دادم، اما نتیجه ناامیدم کرد.

Telnet در Zabbix مانند کنسول لینوکس نیست، کمی ساده تر است و برای مجوزهای استاندارد مانند ورود / رمز عبور طراحی شده است. اگر منطق مجوز متفاوت باشد، و درخواستی برای جفت ورود/گذرواژه وجود نداشته باشد، خطایی رخ می دهد. پس از تلاش های بیهوده برای دور زدن نیاز مجوز، نگاهی به کد منبع ماژول Telnet مفید بود.

متوجه شدم تا زمانی که درخواست ورود و رمز عبور سنتی وجود نداشته باشد، جلو نمی روم. فقط برای سرگرمی، همه چیز مربوط به مجوز را از کد حذف کردم و همه چیز را دوباره مونتاژ کردم. آثار! اما الزامات را برآورده نمی کند. برو جلو…

بیایید به جستجو برگردیم

من اسناد ARI را دوباره خواندم، آزمایش های اضافی را انجام دادم - اینجا هیچ ثبت جرعه ای وجود ندارد. عید هست، صحبت هست، شلوارک هست، اما ثبت نامی نیست. حتی در مقطعی فکر کردم که آیا واقعاً به ثبت کرکس نیاز داریم؟

در یک تصادف خنده دار، در این لحظه درخواست دیگری از کاربر می رسد، با مشکل در تماس های خروجی. مشکل این بود که ثبت جرعه در حال انجماد بود و به سادگی با راه اندازی مجدد ماژول حل شد.

asterisk -rx "sip reload"

دسترسی به AMI از طریق وب بسیار عالی خواهد بود: فکر کردم که همه مشکلات را حل می کند. من شروع به حفاری در این مسیر می کنم و به معنای واقعی کلمه اولین خط جستجو به اسناد رسمی استریسک منتهی می شود که می گوید گزینه ای برای وظایف من وجود دارد. webenabled در پرونده /etc/asterisk/manager.conf، که باید در قسمت YES تنظیم شود [عمومی]

پس از این، از طریق یک درخواست وب معمولی از فرم http://ats:8089/mxml?action=SIPshowregistry ما تمام اطلاعات لازم را دریافت می کنیم.

هنگام استفاده از رابط FreePBX، نمی توانید این گزینه را از طریق وب فعال کنید، باید آن را از طریق کنسول با ایجاد تغییراتی در فایل manager.conf فعال کنید. هنگامی که تغییرات پیکربندی از طریق وب انجام می شود، FreePBX آن را پاک نمی کند.

من برای مدت طولانی با انواع مختلف ادغام های استریسک کار کرده ام، اما هرگز ندیده ام که این ویژگی در جایی ذکر شود. من تعجب کردم که هیچکس این روش تعامل با PBX را توصیف نمی کند. حتی جستجوی اطلاعات در مورد این موضوع بسیار مفید بود: عملاً هیچ چیز وجود ندارد یا برای کارهای کاملاً متفاوت استفاده شده است.

WEB AMI - چه نوع جانوری؟

افزودن یک گزینه webenabled برای تشکیل پرونده manager.conf دسترسی کامل به مدیریت ATS از طریق وب را فراهم کرد. تمام دستورات موجود از طریق یک AMI معمولی اکنون در وب هستند، می توانید از طریق یک سوکت به رویدادها از PBX گوش دهید. اصل عملکرد هیچ تفاوتی با کنسول 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"، یعنی خود کوکی مجوز.
محتوا را فقط باید برای پاسخ بررسی کنید "احراز هویت پذیرفته شد" در مرحله بعد، برای همه تماس‌ها با سرور PBX، باید یک کوکی مجوز به درخواست اضافه کنیم.

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

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

نحوه دریافت کوکی مجوز و استفاده از آن در سایر درخواست‌ها را در اینجا بخوانید: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: //response/generic[@host]
سپس سرگرمی شروع می شود. برای کار با شناسایی و ایجاد پویا عناصر، پاسخ باید در قالب JSON باشد. XML برای تشخیص خودکار پشتیبانی نمی شود.

برای تبدیل XML به JSON، مجبور شدم کمی با جایگزین خودکار بازی کنم، که برای آن یک اسکریپت در JS ساختم.

نحوه اتصال Zabbix با Asterisk خارج از جعبه

یک نکته جالب: در پاسخ ATS، تمام پارامترها با کوتیشن های تک احاطه شده اند و پس از اعمال الگو //response/generic[@host] آنها با موارد دوگانه جایگزین می شوند.

برای ایجاد عناصر، از متغیرهای پاسخ XML (اکنون JSON) استفاده می‌کنیم.

نحوه اتصال Zabbix با Asterisk خارج از جعبه

رجیستری SIP

برای ثبت جرعه از سه متغیر استفاده می کنیم: نام کاربری, میزبان, بندر. از اسم عنصر خوشحال شدم [ایمیل محافظت شده]: 5060، من هیچ موقعیتی را پیدا نکردم که شما نیاز به استفاده از هر پنج متغیر داشته باشید.

عنصر اصلی که اطلاعات مربوط به همه ثبت نام ها را دریافت می کند، ستاره - AMI SIPshowregistry. یک بار در دقیقه یک درخواست GET می کند https://ats:8089/mxml?action=SIPshowregistry، پس از آن داده های XML پاسخ برای تجزیه به تمام عناصر وابسته ارسال می شود. برای هر ثبت نام یک عنصر وابسته به آن ایجاد می کنم. این راحت است زیرا ما اطلاعات به روز را در یک درخواست دریافت می کنیم و نه برای هر درخواست جداگانه. این پیاده سازی یک اشکال قابل توجه دارد - بار روی پردازنده.

هنگام آزمایش تا 100 عنصر وابسته، متوجه بار نشدم، اما با 1700 عنصر، این بار 15 ثانیه قابل توجهی را روی پردازنده ایجاد کرد. اگر تعداد زیادی عناصر وابسته دارید، این را در نظر داشته باشید.

به عنوان گزینه ای برای "گسترش" بار یا تنظیم فرکانس های مختلف نظرسنجی برای یک عنصر، می توانید منطق پردازش را به طور جداگانه به هر عنصر منتقل کنید.

من اطلاعات دریافتی را در عنصر اصلی ذخیره نمی کنم. اولاً من نیازی به این کار نمی بینم و ثانیاً اگر پاسخ بیش از 64K باشد Zabbix آن را قطع می کند.

از آنجایی که ما از یک پاسخ کامل XML برای عنصر وابسته استفاده می کنیم، باید مقدار این عنصر را در پیش پردازش بدست آوریم. از طریق XPath اینجوری انجام شده:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@ حالت)
برای وضعیت های ثبت نام، من از وضعیت های متنی استفاده نکردم، اما آنها را با استفاده از جاوا اسکریپت به شکل عددی تبدیل کردم:

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

SIP Peers

بر اساس قیاس با ثبت SIP، یک عنصر اصلی از Asterisk - AMI SIPshowregistry وجود دارد که موارد وابسته به آن اضافه می شوند.

این دو عنصر وابسته ایجاد می کند:

  • وضعیت همتا به صورت متنی
  • زمان پاسخگویی دستگاه - اگر وضعیت خوب باشد، زمان پاسخ دستگاه نوشته می شود، در غیر این صورت "-1"

مسیر رسیدن به خود عنصر کمی ساده تر است XPath:

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

برای عنصر دوم از جاوا اسکریپت برای جدا کردن استفاده کردم زمان پاسخ از وضعیت همتا، زیرا با هم ذخیره می شوند:

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

نتیجه

یک راه حل خارج از جعبه می تواند پیچیده باشد و بلافاصله شفاف نباشد. انعطاف پذیری و قابلیت حمل بین سیستم های مختلف را افزایش می دهد

ادغام آسان و شاد برای همه! الگو و دستورالعمل برای راه اندازی GitHub.

منبع: www.habr.com

اضافه کردن نظر