In het vorige artikel Ik legde uit hoe je een autorisatiesessie kunt verkrijgen en deze in de lokale hostmacro kunt invoegen. In dit artikel zal ik beschrijven hoe je Zabbix met Asterisk kunt laten werken zonder externe scripts en software.
Het idee om deze twee systemen te laten samenwerken stamt al een tijd geleden, zonder dat er extra software of scripts geïnstalleerd hoeven te worden. Een snelle zoekopdracht op Google gaf tal van oplossingen, die allemaal neerkomen op het uploaden van scripts (in PHP, Bash, Python, enz.) naar de server, en het zou allemaal goedkomen. Ik wilde echter monitoring 'out of the box' realiseren — zonder externe scripts of extra software op de monitoring- en telefoonserver.
Ik heb hier in totaal vier werkdagen mee geworsteld, maar het resultaat was het waard. Werken via de AMI-interface, low-level detectie, triggers, en het belangrijkste, de verbinding met de telefooncentrale en alle andere instellingen kost nu nog maar 15 minuten.
Ik heb Zabbix 4.4, met ongeveer 100 Asterisk servers van versie 13. Sommige telefooncentrales hebben een webinterface zoals FreePBX, andere komen met een blote console, vol met trucjes en integratie via het belplan.
Gegevens ophalen uit de telefooncentrale
De eerste en belangrijkste kwestie die moet worden opgelost, is het verkrijgen van gegevens over peers en SIP-registraties. Hiervoor zijn er in de telefooncentrale de interfaces AGI, AMI, ARI en de SSH-console. Extra modules heb ik om voor de hand liggende redenen niet bekeken.
Eerst moeten we begrijpen wat deze AGI, AMI en ARI zijn.
- AGI — het gebruik van scripts in het belplan. Dit wordt voornamelijk gebruikt voor het beheer van oproepen.
- AMI — kan alle benodigde informatie geven, werkt via poort 5038, vergelijkbaar met Telnet. Dit is wat we nodig hebben!
- ARI — modern, trendy, JSON-gebaseerd. Veel mogelijkheden, gegevensformaten zijn begrijpelijk voor Zabbix, maar voor mij mist het belangrijkste: je kunt de SIP-registratie niet controleren. Een ander nadeel is dat er voor peers maar twee toestanden zijn: online/offline, terwijl er meer toestanden zijn die nuttig zijn voor diagnostiek.
- SSH — kan alles, maar soms wordt het niet gegeven vanwege 'veiligheidsredenen'. De redenen kunnen variëren, ik zal ze niet verder toelichten.
Niettemin, met al zijn tekortkomingen dekt ARI 90% van alle behoeften voor monitoring.
Zabbix en Telnet — mijn teleurstelling
Ik ken AMI goed, ik heb ooit het volgen van verliezen bij gesprekken gerealiseerd met een verdeling naar externe kantoren, het beheer van oproepen, enzovoort. Met Telnet is ook alles duidelijk: maak verbinding, stuur commando's en lees het antwoord. Dat heb ik gedaan, maar het resultaat teleurstelde me.
Telnet van Zabbix is niet zoals in de Linux-console; het is iets eenvoudiger en is gericht op standaardautorisatie zoals gebruikersnaam/wachtwoord. Als de autorisatielogica anders is en er geen paar gebruikersnaam/wachtwoord wordt opgevraagd, krijg je een foutmelding. Na tevergeefse pogingen om de autorisatievereiste te omzeilen, ben ik de broncode van de Telnet-module gaan bekijken.
Ik begreep dat ik niet verder zou komen zonder de traditionele verzoek om een gebruikersnaam met wachtwoord. Uit nieuwsgierigheid heb ik alles wat met autorisatie te maken had uit de code verwijderd en alles opnieuw samengesteld. Het werkt! Maar het voldoet niet aan de vereisten. Laten we verder gaan...
Laten we terugkeren naar de zoektocht
Ik heb de documentatie van ARI nogmaals doorgenomen en extra tests uitgevoerd — er zijn geen SIP-registraties. Er zijn peers, er zijn gesprekken, er zijn bridges, maar geen registraties. Op een gegeven moment vroeg ik me zelfs af hoe noodzakelijk SIP-registraties voor ons zijn.
Bij een grappige samenloop van omstandigheden komt er op dat moment opnieuw een verzoek van een gebruiker binnen, over problemen met uitgaande oproepen. Het probleem zat in het vastlopen van de SIP-registratie en kon worden opgelost met een gewone herstart van de module.
asterisk -rx "sip reload"Het zou geweldig zijn om via het web toegang te krijgen tot AMI: dat zou al mijn problemen oplossen, dacht ik. Ik begin in die richting te graven, en letterlijk de eerste regel van mijn zoektocht leidt naar de officiële documentatie van Asterisk waarin staat dat er voor mijn taken een optie is webenabled in het bestand /etc/asterisk/manager.conf, die moet worden ingesteld op de waarde YES, in de sectie [general]
Daarna, via een normale webverzoek zoals ontvangen we alle benodigde informatie.
Bij gebruik van de FreePBX-interface kan deze optie niet via het web worden ingeschakeld; je moet het via de console inschakelen door wijzigingen aan te brengen in het bestand manager.conf. FreePBX verwijdert het niet bij configuratiewijzigingen via het web.
Zolang ik met verschillende soorten Asterisk-integraties heb gewerkt, heb ik nog nooit gezien dat deze functie ergens werd genoemd. Het verbaasde me dat niemand deze methode voor interactie met de PABX beschrijft. Ik heb zelfs speciaal gezocht naar informatie over dit onderwerp: er is praktisch niets of het werd voor totaal andere taken gebruikt.
WEB AMI — wat is dat voor iets?
Toevoegen van de optie webenabled naar bestand manager.conf bied volledige toegang tot het beheren van de Asterisk via het web. Alle commando's die beschikbaar zijn via de gewone AMI zijn nu ook via het web toegankelijk, je kunt gebeurtenissen van de Asterisk via een socket beluisteren. Het principe is niet anders dan dat van de console AMI. Na het activeren van deze optie kan je de Asterisk benaderen via de volgende adressen:
— webpagina met een eenvoudige interface voor testen en het handmatig verzenden van verzoeken. Alle antwoorden worden op een leesbare HTML-manier geformatteerd. Niet zo geschikt voor monitoring.
— alleen tekstoutput, het formaat is vergelijkbaar met dat van de console AMI
— alleen tekstoutput, in XML-formaat. Dat is geschikt voor ons!

Hier dacht ik bij mezelf: "Dat is het – de oplossing! Nu zal alles klaar zijn! Eenvoudig als een peulenschil", maar het was te vroeg om te juichen. Voor de informatie die we nodig hebben, is het voldoende om een GET-verzoek te gebruiken met de gewenste actie actie, dat als antwoord xml retourneert met een lijst van alle registraties en hun status. Dit is allemaal geweldig, maar autorisatie met sessie-opslag in cookies is vereist. Wanneer je in de browser test, denk je hier niet over na.
Het autorisatieproces
In het begin benaderen we het adres , waarop de server ons een cookie met de autorisatiesessie toestuurt. Zo ziet het HTTP-verzoek eruit:
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: nl-NL,nl;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: 1Antwoord:
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 Voor gebruik daar is nodig mansession_id="6f5de42c", dat is de cookie van de autorisatie.
De inhoud moet slechts worden gecontroleerd op de aanwezigheid van het antwoord "Authentication accepted". Verder, bij alle verzoeken aan de Asterisk-server moeten we de autorisatiecookie aan de verzoeken toevoegen.
https://ats:8089/mxml?action=SIPpeers
Host: ats:8089
Connection: close
Cookie: mansession_id="6f5de42c"Hoe de autorisatiecookie te verkrijgen en te gebruiken in andere verzoeken lees je hier: "»
Voor het creëren van trackingelementen in Zabbix zal ik gebruik maken van autodetectie.
Autodetectie
Voor autodetectie van registraties en het volgen van de status van peers moet je het volgende adres benaderen: of
Als antwoord stuurt de Asterisk ons een XML-antwoor:
...
... In de response is veel rommel, daarom filteren we het in de preprocessie volgens een sjabloon. XPath: //response/generic[@host]
Daarna begint het interessantste. Om te werken met detectie en dynamisch elementen te creëren, moet de response in JSON-formaat zijn. XML wordt niet ondersteund bij auto-detectie.
Voor de conversie van XML naar JSON moest ik een beetje spelen met auto-replace, hiervoor heb ik een script in JS gemaakt.

Een interessant punt is dat in de response van de PBX alle parameters met enkele aanhalingstekens zijn omgeven, en na toepassing van het sjabloon //response/generic[@host] worden ze vervangen door dubbele aanhalingstekens.
Voor het creëren van elementen gebruiken we variabelen uit de XML-response (nu JSON).

SIP Registratie
Voor SIP-registraties gebruiken we drie variabelen: username, host, port. Ik was tevreden met de naam van het element 111111@login.mtt.ru:5060, situaties waarbij we alle vijf variabelen moesten gebruiken heb ik niet gevonden.
Het belangrijkste element dat informatie over alle registraties ontvangt, Asterisk — AMI SIPshowregistry. Elke minuut doet het een GET-verzoek naar , waarna de gegevens van de XML-respons aan alle afhankelijke elementen worden doorgegeven voor analyse. Het element voor elke registratie maak ik afhankelijk van dit element. Dit is handig, omdat we actuele informatie met één verzoek krijgen, en niet voor elke afzonderlijk. Deze implementatie heeft echter een aanzienlijke nadelen — belasting op de processor.
Bij het testen tot 100 afhankelijke elementen merkte ik geen belasting op, maar bij 1700 elementen gaf dit een merkbare belasting van 15 seconden op de processor. Houd hier rekening mee als je een groot aantal afhankelijke elementen hebt.
Als een optie voor het 'uitspreiden' van de belasting of het instellen van een verschillende frequentie voor het vragen van elementen, kan de logica van de verwerking in elk element apart worden geplaatst.
Ik sla de ontvangen informatie niet op in het hoofdonderdeel. Ten eerste zie ik daar geen noodzaak voor, en ten tweede, als het antwoord meer dan 64K is, snijdt Zabbix het af.
Aangezien we voor het afhankelijke element een volledige XML-respons gebruiken, moeten we in de preprocessing de waarde van dit element verkrijgen. Via XPath zo doe je dat:
string(//response/generic[@event='RegistryEntry' and @username='{#SIP_REGISTRY_USERNAME}' and @host='{#SIP_REGISTRY_HOST}' and @port='{#SIP_REGISTRY_PORT}']/@state)
Voor de statussen van registraties heb ik ervoor gekozen om geen tekststatussen te gebruiken, maar deze om te zetten naar numerieke waarden met JavaScript:
switch(value) {
case 'Registered':
return 1;
case 'Unregistered':
return 0;
default:
return -1;
}
SIP Peers
Op dezelfde manier als bij de SIP-registraties, is er een hoofdonderdeel Asterisk — AMI SIPshowregistry, waar afhankelijkheden aan worden toegevoegd.
Hier worden twee afhankelijke elementen aangemaakt:
- De status van de peer in tekstvorm
- De responstijd van het apparaat — als de status OK is, wordt de responstijd van het apparaat genoteerd, anders '-1'
De weg naar het element is al iets eenvoudiger XPath:
string(//response/generic[@objectname='{#SIP_PEER_OBEJECTNAME']}/@status)
Voor het tweede element gebruikte ik JavaScript om te scheiden de responstijd van de status van de peer, omdat ze samen zijn opgeslagen:
if(value.substring(0,2) == 'OK'){
return value.match(/(\d+)/gm);
}
else {
return -1;
}Conclusie
Een out-of-the-box oplossing kan complex zijn en niet onmiddellijk duidelijk. De flexibiliteit en draagbaarheid tussen verschillende systemen neemt toe.
Iedereen veel plezier en een gemakkelijke integratie! Sjabloon en instructies voor de configuratie op .
Bron: habr.com
