Bagaimana menghubungkan Zabbix dengan Asterisk secara langsung

Dalam artikel sebelumnya "Zabbix - memperluas batasan makro" Saya sudah memberi tahu Anda cara menerima sesi otorisasi dan menggantinya dengan makro host lokal. Pada artikel ini saya akan memberi tahu Anda cara menghubungkan Zabbix dengan Asterisk tanpa skrip dan software eksternal.

Ide untuk “berteman” dengan kedua sistem ini lahir sejak lama, tanpa menginstal software atau skrip tambahan. Googling cepat menghasilkan banyak solusi yang mungkin, semuanya bermuara pada fakta bahwa mengunggah skrip (dalam Pyha, Bash, Python, dll.) ke server, dan Anda akan senang. Saya ingin menerapkan pemantauan “out of the box” - tanpa skrip eksternal dan menginstal perangkat lunak tambahan di server dengan pemantauan dan PBX.

Saya menghabiskan total 4 hari kerja dengan ini, tapi hasilnya sepadan. Bekerja melalui antarmuka AMI, deteksi tingkat rendah, pemicu, dan yang terpenting, menghubungkan PBX dan semua pengaturan lainnya kini membutuhkan waktu sekitar 15 menit.

Tersedia Zabbix 4.4, sekitar 100 buah Asterisk versi 13. Beberapa PBX hadir dengan antarmuka web FreePBX, beberapa dengan konsol kosong, banyak trik dan integrasi melalui dialplan.

Menerima data dari PBX

Poin pertama dan utama yang perlu diselesaikan adalah perolehan data tentang peer dan registrasi SIP. Untuk tujuan ini, PBX memiliki antarmuka konsol AGI, AMI, ARI dan SSH. Untuk alasan yang jelas, saya tidak mempertimbangkan modul tambahan.

Pertama kita perlu mencari tahu apa itu agi, ami, ari...

  • AGI - menggunakan skrip di dialplan. Terutama digunakan untuk manajemen panggilan.
  • AMI - dapat memberikan semua informasi yang diperlukan, bekerja melalui port 5038, mirip dengan Telnet. Cocok untuk kita!
  • ARI - modern, modis, JSON. Ada banyak kemungkinan, format datanya bisa dimengerti oleh Zabbix, tapi bagi saya tidak ada yang utama: Anda tidak bisa mengontrol registrasi sip. Kerugian lainnya adalah untuk peer hanya terdapat dua status online/offline, meskipun terdapat lebih banyak status dan berguna untuk mempertimbangkannya saat mendiagnosis.
  • SSH bisa melakukan apa saja, tapi terkadang tidak diperbolehkan karena “alasan keamanan”. Pertimbangannya mungkin berbeda, saya tidak akan membahasnya.

Namun, dengan segala kekurangannya, ISPA mencakup 90% dari seluruh kebutuhan pemantauan.

Zabbix dan Telnet - kekecewaan saya

Saya mengenal AMI dengan baik; pada suatu waktu saya menerapkan pelacakan kerugian dalam percakapan dengan divisi berdasarkan kantor jarak jauh, manajemen panggilan, dll. Dengan Telnet, semuanya juga sangat jelas: buka koneksi, kirim perintah, dan baca responsnya. Itu yang saya lakukan, tetapi hasilnya mengecewakan saya.

Telnet di Zabbix tidak sama dengan di konsol Linux, ini sedikit lebih sederhana dan disesuaikan untuk otorisasi standar seperti login/password. Jika logika otorisasi berbeda, dan tidak ada permintaan untuk pasangan login/kata sandi, terjadi kesalahan. Setelah upaya sia-sia untuk melewati persyaratan otorisasi, ada gunanya melihat kode sumber modul Telnet.

Saya menyadari bahwa sampai ada permintaan login dan kata sandi tradisional, saya tidak akan melanjutkan. Hanya untuk bersenang-senang, saya menghapus segala sesuatu yang berhubungan dengan otorisasi dari kode dan memasang kembali semuanya. Berhasil! Tapi itu tidak memenuhi persyaratan. Teruskan…

Mari kita kembali ke pencarian

Saya membaca kembali dokumentasi ARI, menjalankan tes tambahan - tidak ada registrasi sip di sini. Ada pesta, ada bincang-bincang, ada pesta, tapi tidak ada registrasi. Pada titik tertentu saya bahkan berpikir, apakah kita benar-benar memerlukan pendaftaran burung nasar?

Secara kebetulan yang lucu, saat ini permintaan lain datang dari pengguna, dengan masalah dengan panggilan keluar. Masalahnya adalah registrasi sip terhenti dan diselesaikan hanya dengan me-reboot modul.

asterisk -rx "sip reload"

Akan sangat bagus jika mengakses AMI melalui web: itu akan menyelesaikan semua masalah, pikir saya. Saya mulai menggali ke arah ini, dan secara harfiah baris pencarian pertama mengarah ke dokumentasi resmi Asterisk, yang mengatakan bahwa ada opsi untuk tugas saya diaktifkan web dalam file /etc/asterisk/manager.conf, yang perlu disetel ke YES, di bagian tersebut [umum]

Setelah ini, melalui formulir permintaan web biasa http://ats:8089/mxml?action=SIPshowregistry kami mendapatkan semua informasi yang diperlukan.

Saat menggunakan antarmuka FreePBX, Anda tidak dapat mengaktifkan opsi ini melalui web, Anda harus mengaktifkannya melalui konsol dengan membuat perubahan pada file manager.conf. FreePBX tidak menghapusnya ketika perubahan konfigurasi dilakukan melalui web.

Saya telah lama bekerja dengan berbagai macam integrasi Asterisk, tetapi saya belum pernah melihat fitur ini disebutkan di mana pun. Saya terkejut karena tidak ada yang menjelaskan metode interaksi dengan PBX ini. Bahkan sangat berguna untuk mencari informasi tentang topik ini: praktis tidak ada atau digunakan untuk tugas yang sama sekali berbeda.

WEB AMI - binatang apa?

Menambahkan opsi diaktifkan web untuk mengajukan manajer.conf memberikan akses penuh ke manajemen ATS melalui web. Semua perintah yang tersedia melalui AMI biasa kini ada di web, Anda dapat mendengarkan acara dari PBX melalui soket. Prinsip pengoperasiannya tidak berbeda dengan konsol AMI. Setelah mengaktifkan opsi ini, Anda dapat menghubungi PBX di alamat berikut:

https://ats:8089/manager — halaman web dengan antarmuka sederhana untuk menguji dan mengirim permintaan secara manual. Semua tanggapan diformat menjadi HTML yang dapat dibaca. Sangat tidak cocok untuk pemantauan.
https://ats:8089/rawman — hanya keluaran teks, formatnya mirip dengan konsol AMI
https://ats:8089/mxml - keluaran teks saja, dalam format XML. Cocok untuk kita!

Bagaimana menghubungkan Zabbix dengan Asterisk secara langsung

Lalu saya berpikir: “Inilah solusinya! Sekarang semuanya akan siap! Perasan lemon yang enak,” tapi masih terlalu dini untuk bersukacita. Untuk memperoleh informasi yang kita perlukan, cukup menggunakan request GET dengan tindakan yang diperlukan tindakan, yang sebagai tanggapannya mengembalikan xml dengan daftar semua pendaftaran dan statusnya. Ini semua bagus, tetapi Anda memerlukan otorisasi untuk mengingat sesi dari cookie. Saat Anda menguji di browser, Anda tidak memikirkan proses ini.

Proses otorisasi

Pertama kita alamat alamatnya http://ats:8089/mxml?action=login&username=zabbix&secret=zabbix, sebagai tanggapan, server mengirimkan cookie kepada kami dengan sesi otorisasi. Seperti inilah tampilan permintaan 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

Jawaban:

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>

Untuk bekerja di sana Anda perlu mansession_id="6f5de42c", yaitu cookie otorisasi itu sendiri.
Konten Anda hanya perlu memeriksa jawabannya "Otentikasi diterima" Selanjutnya, untuk semua panggilan ke server PBX, kita perlu menambahkan cookie otorisasi ke permintaan tersebut.

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

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

Baca cara mendapatkan cookie otorisasi dan menggunakannya dalam permintaan lain di sini: “Zabbix - memperluas batas makro»

Untuk membuat elemen pelacakan di Zabbix saya akan menggunakan deteksi otomatis.

Deteksi otomatis

Untuk mendeteksi pendaftaran secara otomatis dan melacak status rekan, Anda perlu menghubungi alamat berikut: https://ats:8089/mxml?action=SIPshowregistry или https://ats:8089/mxml?action=SIPpeers

Sebagai tanggapan, PBX mengembalikan tanggapan XML kepada kita:

<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>

Responnya banyak sampah, jadi pada preprocessing kita memfilternya berdasarkan template XPath: //respon/generik[@host]
Kemudian kesenangan dimulai. Untuk bekerja dengan deteksi dan membuat elemen secara dinamis, responsnya harus dalam format JSON. XML tidak didukung untuk deteksi otomatis.

Untuk mengonversi XML ke JSON saya harus bermain-main sedikit dengan penggantian otomatis, yang untuknya saya membuat skrip di JS

Bagaimana menghubungkan Zabbix dengan Asterisk secara langsung

Hal yang menarik: dalam respons ATS, semua parameter diapit oleh tanda kutip tunggal, dan setelah menerapkan template //respon/generik[@host] mereka digantikan oleh yang ganda.

Untuk membuat elemen, kami menggunakan variabel dari respons XML (sekarang JSON)​.

Bagaimana menghubungkan Zabbix dengan Asterisk secara langsung

Registri SIP

Untuk registrasi sip kami menggunakan tiga variabel: nama pengguna, tuan rumah, pelabuhan. Saya senang dengan nama elemennya [email dilindungi]: 5060, Saya belum menemukan situasi di mana Anda perlu menggunakan kelima variabel.

Elemen utama yang menerima informasi tentang semua pendaftaran, Asterisk - Pendaftaran AMI SIPshow. Semenit sekali ia membuat permintaan GET ke https://ats:8089/mxml?action=SIPshowregistry, setelah itu data XML respons diteruskan ke semua elemen dependen untuk diurai. Untuk setiap pendaftaran saya membuat elemen yang bergantung padanya. Ini nyaman karena kami menerima informasi terkini dalam satu permintaan, dan bukan untuk setiap permintaan secara terpisah. Implementasi ini memiliki kelemahan yang signifikan - beban pada prosesor.

Saat menguji hingga 100 elemen dependen, saya tidak melihat bebannya, tetapi dengan 1700 elemen, ini memberikan beban 15 detik yang nyata pada prosesor. Ingatlah hal ini jika Anda memiliki banyak elemen dependen.

Sebagai opsi untuk “menyebarkan” beban atau mengatur frekuensi polling yang berbeda untuk suatu elemen, Anda dapat memindahkan logika pemrosesan ke setiap elemen secara terpisah.

Saya tidak menyimpan informasi yang diterima di elemen utama. Pertama, saya tidak melihat perlunya hal ini, dan kedua, jika responsnya lebih dari 64K, maka Zabbix akan memotongnya.

Karena kita menggunakan respons XML lengkap untuk elemen dependen, kita perlu mendapatkan nilai elemen ini dalam prapemrosesan. Melalui XPath itu dilakukan seperti ini:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@ negara)
Untuk status pendaftaran, saya tidak menggunakan status teks, tetapi mengubahnya menjadi bentuk numerik menggunakan JavaScript:

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

Rekan SIP

Dengan analogi dengan registrasi SIP, ada elemen utama Asterisk - AMI SIPshowregistry, yang ditambahkan elemen dependen.

Ini menciptakan dua elemen dependen:

  • Status rekan dalam bentuk teks
  • Waktu respons perangkat - jika statusnya OK, maka waktu respons perangkat ditulis, jika tidak, “-1”

Jalur menuju elemen itu sendiri sedikit lebih sederhana XPath:

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

Untuk elemen kedua saya menggunakan JavaScript untuk memisahkan waktu respon dari status rekan, karena disimpan bersama:

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

Kesimpulan

Solusi yang out-of-the-box bisa jadi rumit dan tidak langsung jelas. Meningkatkan fleksibilitas dan portabilitas antar sistem yang berbeda

Integrasi yang menyenangkan dan mudah semuanya! Templat dan instruksi untuk pengaturan GitHub.

Sumber: www.habr.com

Tambah komentar