Wie Zabbix problemlos mit Asterisk zusammenarbeitet

Im vorherigen Artikel «Zabbix – Makro-Grenzen erweitern» Ich habe erzĂ€hlt, wie man eine Autorisierungssitzung erhĂ€lt und diese in das lokale Host-Makro einfĂŒgt. In diesem Artikel werde ich erklĂ€ren, wie man Zabbix ohne externe Skripte und Software mit Asterisk verbindet.

Die Idee, diese beiden Systeme zu integrieren, entstand schon vor einiger Zeit, ohne dass zusĂ€tzliche Software oder Skripte installiert werden mussten. Eine schnelle Google-Suche lieferte viele LösungsvorschlĂ€ge, aber alle liefen darauf hinaus, dass man Skripte (in PHP, Bash, Python usw.) auf den Server laden sollte, um glĂŒcklich zu sein. Ich wollte jedoch das Monitoring 'out of the box' umsetzen – ohne externe Skripte und ohne zusĂ€tzliche Software auf dem Überwachungs- und Telefonserver.

Ich habe insgesamt 4 Arbeitstage damit verbracht, aber das Ergebnis war es wert. Die Arbeit ĂŒber die AMI-Schnittstelle, die Low-Level-Erkennung, Trigger und vor allem braucht man jetzt nur noch etwa 15 Minuten fĂŒr die Verbindung mit der Telefonanlage und alle anderen Einstellungen.

Vorhanden ist Zabbix 4.4, mit etwa 100 Asterisk 13 Systemen. Einige Telefonanlagen verfĂŒgen ĂŒber die Web-OberflĂ€che FreePBX, andere haben nur eine einfache Konsole, zahlreiche Tricks und Integrationen ĂŒber den Dialplan.

Daten aus der Telefonanlage abrufen

Der erste und wichtigste Punkt, der geklĂ€rt werden muss, ist der Zugriff auf Daten zu Peers und SIP-Registrierungen. HierfĂŒr bietet die Telefonanlagen verschiedene Schnittstellen wie AGI, AMI, ARI und die SSH-Konsole. ZusĂ€tzliche Module habe ich aus offensichtlichen GrĂŒnden nicht betrachtet.

ZunÀchst gilt es, zu verstehen, was diese AGI, AMI, ARI ... wirklich sind.

  • AGI – die Nutzung von Skripten im Dialplan. HauptsĂ€chlich wird es zur Steuerung von Anrufen verwendet.
  • AMI – liefert alle notwendigen Informationen und arbeitet ĂŒber den Port 5038 analog zu Telnet. Das passt uns!
  • ARI – modern, trendig, JSON-basiert. Bietet viele Möglichkeiten, die Datenformate sind verstĂ€ndlich fĂŒr Zabbix, aber es fehlt mir das Entscheidende: Die Kontrolle ĂŒber SIP-Registrierungen ist nicht möglich. Ein weiterer Nachteil ist, dass es fĂŒr Peers nur zwei ZustĂ€nde gibt: online/offline, obwohl es mehr ZustĂ€nde gibt, die zur Diagnose nĂŒtzlich wĂ€ren.
  • SSH – kann alles, wird aber manchmal aufgrund von "SicherheitsĂŒberlegungen" nicht gewĂ€hrt. Die GrĂŒnde können unterschiedlich sein, ich möchte sie nicht weiter analysieren.

Dennoch deckt ARI mit all seinen MĂ€ngeln 90 % aller BedĂŒrfnisse im Monitoring ab.

Zabbix und Telnet – meine EnttĂ€uschung.

Ich kenne AMI gut, zu meiner Zeit habe ich die Verlustverfolgung in GesprĂ€chen mit Remote-BĂŒros, das Anrufmanagement usw. implementiert. Auch bei Telnet ist alles klar: Verbindung öffnen, Befehle senden und Antwort lesen. Das habe ich auch gemacht, aber das Ergebnis hat mich enttĂ€uscht.

Telnet in Zabbix ist nicht dasselbe wie in der Linux-Konsole, es ist etwas einfacher und auf die Standard-Authentifizierung mit Benutzername/Passwort ausgelegt. Ist die Authentifizierungslogik anders und wird kein Benutzername/Passwort-Paar angefragt, erscheint ein Fehler. Nach erfolglosen Versuchen, die Authentifizierungsanforderung zu umgehen, habe ich beschlossen, die Quelldateien des Telnet-Moduls anzusehen.

Ich habe verstanden, dass ich ohne die traditionelle Anfrage nach Benutzername und Passwort nicht weiterkomme. Aus Interesse habe ich alles, was mit Authentifizierung zu tun hat, aus dem Code entfernt und alles neu kompiliert. Es funktioniert! Aber es entspricht nicht den Anforderungen. Weiter geht's...

ZurĂŒck zur Suche

Ich habe die Dokumentation zu ARI nochmals durchgelesen und zusĂ€tzliche Tests durchgefĂŒhrt — es gibt hier keine SIP-Registrierungen. Es gibt Peers, es gibt GesprĂ€che, es gibt Bridges, aber keine Registrierungen. Irgendwann habe ich sogar darĂŒber nachgedacht, wie wichtig uns SIP-Registrierungen wirklich sind?

Durch einen lustigen Zufall kommt gerade in diesem Moment eine Anfrage von einem Benutzer herein, der ein Problem mit ausgehenden Anrufen hat. Das Problem lag an einem HÀngenbleiben der SIP-Registrierung und konnte durch einen einfachen Neustart des Moduls gelöst werden.

asterisk -rx "sip reload"

Es wĂ€re großartig, ĂŒber das Web auf das AMI zuzugreifen: das wĂŒrde alle Probleme lösen, dachte ich. Also begann ich, in diese Richtung zu forschen, und die erste Suchzeile fĂŒhrte mich zur offiziellen Dokumentation von Asterisk, wo stand, dass fĂŒr meine BedĂŒrfnisse eine Option verfĂŒgbar ist webenabled in der Datei /etc/asterisk/manager.conf, die auf YES gesetzt werden muss, im Abschnitt [general]

Danach erhalten wir ĂŒber eine normale Webanfrage des Typs http://ats:8089/mxml?action=SIPshowregistry alle notwendigen Informationen.

Bei der Verwendung der FreePBX-OberflĂ€che kann diese Option ĂŒber das Web nicht aktiviert werden; sie muss ĂŒber die Konsole eingeschaltet werden, indem Änderungen in der Datei manager.conf vorgenommen werden. FreePBX löscht sie nicht bei Änderungen der Konfiguration ĂŒber das Web.

So viel ich mit verschiedenen Arten von Asterisk-Integrationen gearbeitet habe, habe ich nie gesehen, dass diese Funktion irgendwo erwĂ€hnt wird. Es hat mich ĂŒberrascht, dass niemand diese Interaktionsmethode mit der Telefonanlage beschreibt. Ich habe sogar gezielt nach Informationen zu diesem Thema gesucht: es gibt praktisch nichts oder es wurde fĂŒr völlig andere Aufgaben verwendet.

WEB AMI – was ist das fĂŒr ein Ding?

Option hinzufĂŒgen webenabled in die Datei manager.conf öffnet den vollstĂ€ndigen Zugriff zur Verwaltung der Telefonanlage ĂŒber das Web. Alle Kommandos, die normalerweise ĂŒber das klassische AMI verfĂŒgbar sind, können jetzt im Web genutzt werden, man kann Ereignisse von der Telefonanlage ĂŒber einen Socket hören. Das Prinzip ist das gleiche wie beim Konsolen-AM.

https://ats:8089/manager – eine Webseite mit einer einfachen BenutzeroberflĂ€che, geeignet fĂŒr Tests und manuelles Senden von Anfragen. Alle Antworten werden in lesbarem HTML-Format angezeigt. Nicht ideal fĂŒr Monitoring.
https://ats:8089/rawman – nur Textausgabe, das Format Ă€hnelt dem des Konsolen-AMI.
https://ats:8089/mxml – nur Textausgabe im XML-Format. Das passt uns!

Wie Zabbix problemlos mit Asterisk zusammenarbeitet

Hier dachte ich: „Das ist es – die Lösung! Jetzt wird alles bereit sein! Ganz einfach“, aber ich hatte noch zu frĂŒh Freude. Um die benötigten Informationen zu erhalten, genĂŒgt es, eine GET-Anfrage mit der entsprechenden Aktion zu verwenden. Aktion, die als Antwort ein XML mit einer Liste aller Registrierungen und deren Status zurĂŒckgibt. Das klingt alles gut, aber es ist eine Autorisierung erforderlich, die eine Sitzung aus Cookies speichert. Wenn man im Browser testet, denkt man nicht ĂŒber diesen Prozess nach.

Der Autorisierungsprozess

ZunÀchst wenden wir uns an die Adresse http://ats:8089/mxml?action=login&username=zabbix&secret=zabbix, auf die der Server uns ein Cookie mit der Autorisierungssitzung zusendet. So sieht die HTTP-Anfrage aus:

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: de-DE,de;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

Antwort:

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

FĂŒr die Arbeit dort benötigen Sie mansession_id="6f5de42c", das heißt das Cookie fĂŒr die Autorisierung.
Der Inhalt muss nur auf das Vorhandensein der Antwort „Authentifizierung akzeptiert“ ĂŒberprĂŒft werden. Bei allen Anfragen an den Asterisk-Server mĂŒssen wir den Authorization-Cookie zur Anfrage hinzufĂŒgen.

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

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

Wie man den Authorization-Cookie erhĂ€lt und in anderen Anfragen verwendet, lesen Sie hier: „Zabbix — die Grenzen von Makros erweitern»

Zur Erstellung von Tracking-Elementen in Zabbix werde ich die Auto-Entdeckung verwenden.

Auto-Entdeckung

FĂŒr die Auto-Entdeckung von Registrierungen und die Überwachung des Status von Peers muss die folgende Adresse aufgerufen werden: https://ats:8089/mxml?action=SIPshowregistry oder https://ats:8089/mxml?action=SIPpeers

Die Asterisk-Software sendet uns eine XML-Antwort zurĂŒck:

...









...

Im Antworttext finden sich viele irrelevante Informationen, daher filtern wir sie in der Vorverarbeitung nach einem Muster. XPath: //response/generic[@host]
Jetzt wird es wirklich spannend. Um mit der Erkennung zu arbeiten und Elemente dynamisch zu erstellen, muss die Antwort im JSON-Format vorliegen. XML wird bei der automatischen Erkennung nicht unterstĂŒtzt.

Um XML in JSON zu konvertieren, musste ich ein wenig mit automatischen Ersetzungen experimentieren, wofĂŒr ich ein Skript in JS erstellt habe.

Wie Zabbix problemlos mit Asterisk zusammenarbeitet

Ein interessanter Punkt ist, dass im Antworttext der Telefonanlage alle Parameter in einfachen AnfĂŒhrungszeichen stehen, und nach der Anwendung des Musters //response/generic[@host] werden sie durch doppelte AnfĂŒhrungszeichen ersetzt.

FĂŒr die Erstellung der Elemente verwenden wir Variablen aus der XML-Antwort (jetzt JSON).

Wie Zabbix problemlos mit Asterisk zusammenarbeitet

SIP-Registry

FĂŒr SIP-Registrierungen verwenden wir drei Variablen: Benutzername, host, Port. Ich war mit dem Namen des Elements zufrieden. 111111@login.mtt.ru:5060, Situationen, in denen alle fĂŒnf Variablen benötigt werden, habe ich nicht gefunden.

Das Hauptelement, das Informationen ĂŒber alle Registrierungen erhĂ€lt, Asterisk — AMI SIPshowregistry. Einmal pro Minute sendet es eine GET-Anfrage an https://ats:8089/mxml?action=SIPshowregistry, nachdem die XML-Antwortdaten an alle abhĂ€ngigen Elemente zur Analyse ĂŒbergeben werden. Jedes Element fĂŒr jede Registrierung wird von ihm abhĂ€ngig gemacht. Dies ist praktisch, da wir die aktuellen Informationen mit einer einzigen Anfrage erhalten und nicht fĂŒr jedes Element einzeln. Bei dieser Implementierung gibt es jedoch einen wesentlichen Nachteil – die Belastung des Prozessors.

Bei Tests mit bis zu 100 abhĂ€ngigen Elementen habe ich keine merkliche Belastung festgestellt, aber bei 1700 Elementen war dies eine spĂŒrbare 15-sekĂŒndige Belastung fĂŒr den Prozessor. Bitte beachten Sie dies, wenn Sie eine große Anzahl abhĂ€ngiger Elemente haben.

Eine Möglichkeit, die Last zu „verstreuen“ oder eine unterschiedliche Abfragefrequenz fĂŒr jedes Element festzulegen, besteht darin, die Logik der Verarbeitung in jedes Element separat zu verlagern.

Die erhaltenen Informationen speichere ich nicht im Hauptelement. Erstens sehe ich dafĂŒr keine Notwendigkeit und zweitens, wenn die Antwort mehr als 64kB betrĂ€gt, kĂŒrzt Zabbix sie.

Da wir fĂŒr das abhĂ€ngige Element die vollstĂ€ndige XML-Antwort verwenden, mĂŒssen wir im Preprocessing den Wert dieses Elements abrufen. Über XPath so geht das:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@state)
FĂŒr die Registrierungsstatus habe ich keine textbasierten Status verwendet, sondern sie mithilfe von JavaScript in Zahlen umgewandelt:

switch(value) {
  case 'Registriert':
    return 1;
  case 'Nicht registriert':
    return 0;
  default:
    return -1;
}

SIP-Teilnehmer

Analog zu den SIP-Registrierungen gibt es das Hauptelement Asterisk — AMI SIPshowregistry, zu dem abhĂ€ngige Elemente hinzugefĂŒgt werden.

Hier werden zwei abhÀngige Elemente erstellt:

  • Der Status des Teilnehmers im Textformat
  • Die Antwortzeit des GerĂ€ts — wenn der Status OK ist, wird die Antwortzeit des GerĂ€ts angezeigt, andernfalls „-1“

Der Pfad zum Element ist bereits etwas einfacher XPath:

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

FĂŒr das zweite Element habe ich JavaScript verwendet, um die Antwortzeit vom Status des Teilnehmers zu trennen, da sie zusammen gespeichert werden:

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

Fazit

Eine "Out-of-the-Box"-Lösung kann komplex und nicht sofort verstÀndlich sein. Die FlexibilitÀt und PortabilitÀt zwischen verschiedenen Systemen steigt.

Ich wĂŒnsche allen eine angenehme und einfache Integration! Vorlage und Anleitung zur Einrichtung auf GitHub.

Quelle: habr.com

Erwerben Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server đŸ”„ Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster