Dans un article précédent Je vous ai expliqué comment recevoir une session d'autorisation et la remplacer par une macro hÎte locale. Dans cet article, je vais vous expliquer comment connecter Zabbix à Asterisk sans scripts ni logiciels externes.
L'idĂ©e de « se faire des amis » entre ces deux systĂšmes est nĂ©e il y a longtemps, sans installer de logiciels ou de scripts supplĂ©mentaires. Une recherche rapide sur Google a donnĂ© de nombreuses solutions possibles, tout se rĂ©sumait au fait de tĂ©lĂ©charger les scripts (en Pyha, Bash, Python, etc.) sur le serveur, et vous serez heureux. Je voulais mettre en Ćuvre une surveillance « prĂȘte Ă l'emploi » - sans scripts externes et sans installer de logiciels supplĂ©mentaires sur le serveur avec surveillance et PBX.
J'ai passé au total 4 jours de travail avec cela, mais le résultat en valait la peine. Travailler via l'interface AMI, la détection de bas niveau, les déclencheurs et, surtout, la connexion du PBX et tous les autres paramÚtres prend désormais environ 15 minutes.
Zabbix 4.4 est disponible, environ 100 piÚces d'Asterisk version 13. Certains PBX sont livrés avec l'interface Web FreePBX, d'autres avec une console nue, de nombreuses astuces et une intégration via un plan de numérotation.
Réception de données du PBX
Le premier et principal point Ă rĂ©soudre est lâobtention de donnĂ©es sur les pairs et les enregistrements SIP. A cet effet, le PBX dispose d'interfaces de console AGI, AMI, ARI et SSH. Pour des raisons Ă©videntes, je n'ai pas envisagĂ© de modules supplĂ©mentaires.
Nous devons d'abord comprendre ce que sont ces agi, ami, ari...
- AGI - utilisation de scripts dans le plan de numérotation. Principalement utilisé pour la gestion des appels.
- AMI - peut fournir toutes les informations nécessaires, fonctionne via le port 5038, similaire à Telnet. Nous convient!
- ARI - moderne, à la mode, JSON. Il existe de nombreuses possibilités, le format des données est compréhensible pour Zabbix, mais pour moi il n'y a pas d'essentiel : vous ne pouvez pas contrÎler l'enregistrement sip. Un autre inconvénient est que pour les pairs, il n'y a que deux états en ligne/hors ligne, bien qu'il y ait plus d'états et qu'il soit utile d'en tenir compte lors du diagnostic.
- SSH peut tout faire, mais parfois il n'est pas autorisĂ© pour des « raisons de sĂ©curitĂ© ». Les considĂ©rations peuvent ĂȘtre diffĂ©rentes, je nâentrerai pas dans les dĂ©tails.
Cependant, malgré toutes ses lacunes, l'ARI couvre 90 % de tous les besoins en matiÚre de suivi.
Zabbix et Telnet - ma déception
Je connais bien AMI, j'ai déjà mis en place le suivi des pertes dans les conversations avec division par bureaux distants, gestion des appels, etc. Avec Telnet, tout est également trÚs clair : ouvrez la connexion, envoyez les commandes et lisez la réponse. C'est ce que j'ai fait, mais le résultat m'a déçu.
Le Telnet de Zabbix n'est pas le mĂȘme que celui de la console. LinuxIl est lĂ©gĂšrement plus simple et conçu pour une authentification standard par identifiant et mot de passe. Si la logique d'authentification est diffĂ©rente et qu'aucun identifiant ni mot de passe n'est fourni, une erreur se produit. AprĂšs avoir tentĂ©, sans succĂšs, de contourner l'authentification, j'ai commencĂ© Ă examiner le code source du module Telnet.
J'ai rĂ©alisĂ© que tant qu'il n'y aura pas une demande traditionnelle de connexion et de mot de passe, je n'irai pas de l'avant. Juste pour m'amuser, j'ai supprimĂ© du code tout ce qui concernait l'autorisation et j'ai tout rĂ©assemblĂ©. Travaux! Mais cela ne rĂ©pond pas aux exigences. PoursuivreâŠ
Revenons Ă la recherche
J'ai relu la documentation ARI, effectuĂ© des tests supplĂ©mentaires - il n'y a pas d'enregistrement sip ici. Il y a des fĂȘtes, il y a des conversations, il y a des culottes, mais il n'y a pas d'inscriptions. Ă un moment donnĂ©, je me suis mĂȘme demandĂ© : avons-nous vraiment besoin dâun enregistrement des vautours ?
Par une drÎle de coïncidence, à ce moment une autre demande arrive de l'utilisateur, avec un problÚme d'appels sortants. Le problÚme était que l'enregistrement SIP était gelé et a été résolu en redémarrant simplement le module.
asterisk -rx "sip reload"Ce serait formidable d'accĂ©der Ă AMI via le Web : cela rĂ©soudrait tous les problĂšmes, pensais-je. Je commence Ă creuser dans cette direction, et littĂ©ralement la premiĂšre ligne de recherche mĂšne Ă la documentation officielle d'Asterisk, qui dit qu'il existe une option pour mes tĂąches Webenabled dans le fichier /etc/asterisk/manager.conf, qui doit ĂȘtre dĂ©fini sur OUI, dans la section [gĂ©nĂ©ral]
AprÚs cela, via une demande Web réguliÚre du formulaire nous obtenons toutes les informations nécessaires.
Lorsque vous utilisez l'interface FreePBX, vous ne pouvez pas activer cette option via le Web, vous devez l'activer via la console en apportant des modifications au fichier manager.conf. FreePBX ne l'efface pas lorsque des modifications de configuration sont apportées via le Web.
Je travaille depuis longtemps avec diffĂ©rents types d'intĂ©grations Asterisk, mais je n'ai jamais vu cette fonctionnalitĂ© mentionnĂ©e nulle part. J'ai Ă©tĂ© surpris que personne ne dĂ©crive cette mĂ©thode d'interaction avec le PBX. Il Ă©tait mĂȘme particuliĂšrement utile de rechercher des informations sur ce sujet : il n'y en a pratiquement rien ou elles ont Ă©tĂ© utilisĂ©es pour des tĂąches complĂštement diffĂ©rentes.
WEB AMI - quel genre de bĂȘte ?
Ajout d'une option Webenabled déposer manager.conf fourni un accÚs complet à la gestion ATS via le Web. Toutes les commandes disponibles via une AMI classique sont désormais sur le Web, vous pouvez écouter les événements du PBX via un socket. Le principe de fonctionnement n'est pas différent de la console AMI. AprÚs avoir activé cette option, vous pouvez contacter le PBX aux adresses suivantes :
â une page Web avec une interface simple pour tester et envoyer manuellement des demandes. Toutes les rĂ©ponses sont formatĂ©es en HTML lisible. Peu adaptĂ© au suivi.
â sortie texte uniquement, format similaire Ă celui de la console AMI
- sortie texte uniquement, au format XML. Nous convient!

Puis jâai pensĂ© : « Câest la solution ! Maintenant, tout sera prĂȘt ! Un jus de citron facile Ă presser », mais il Ă©tait trop tĂŽt pour se rĂ©jouir. Pour obtenir les informations dont nous avons besoin, il suffit d'utiliser une requĂȘte GET avec l'action nĂ©cessaire action, qui renvoie en rĂ©ponse du XML avec une liste de tous les enregistrements et leur statut. Tout cela est trĂšs bien, mais vous avez besoin d'une autorisation pour mĂ©moriser la session Ă partir du cookie. Lorsque vous testez dans le navigateur, vous ne pensez pas Ă ce processus.
Processus d'autorisation
Nous abordons d'abord l'adresse , en rĂ©ponse, le serveur nous envoie un cookie avec la session d'autorisation. Voici Ă quoi ressemble une requĂȘte 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: 1réponse:
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> Pour y travailler, il faut mansession_id="6f5de42c", c'est-Ă -dire le cookie d'autorisation lui-mĂȘme.
Contenu, il vous suffit de vérifier la réponse "Authentification acceptée" Ensuite, pour tous les appels vers le serveur PBX, nous devrons ajouter un cookie d'autorisation à la demande.
https://ats:8089/mxml?action=SIPpeers
Host: ats:8089
Connection: close
Cookie: mansession_id="6f5de42c"Découvrez comment obtenir un cookie d'autorisation et l'utiliser dans d'autres demandes ici : «»
Pour créer des éléments de suivi dans Zabbix, j'utiliserai la détection automatique.
Détection automatique
Pour détecter automatiquement les inscriptions et suivre les états des pairs, vous devez contacter l'adresse suivante : ou
En réponse, le PBX nous renvoie une réponse 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> Il y a beaucoup de déchets dans la réponse, donc lors du prétraitement, nous la filtrons par modÚle XPath: //réponse/générique[@host]
Alors le plaisir commence. Pour travailler avec la dĂ©tection et crĂ©er dynamiquement des Ă©lĂ©ments, la rĂ©ponse doit ĂȘtre au format JSON. XML n'est pas pris en charge pour les dĂ©tections automatiques.
Pour convertir XML en JSON, j'ai dû jouer un peu avec le remplacement automatique, pour lequel j'ai réalisé un script en JS

Un point intéressant : dans la réponse ATS, tous les paramÚtres sont entourés de guillemets simples, et aprÚs application du modÚle //réponse/générique[@host] ils sont remplacés par des doubles.
Pour crĂ©er des Ă©lĂ©ments, nous utilisons des variables de la rĂ©ponse XML (maintenant JSON)â.

Registre SIP
Pour les enregistrements SIP, nous utilisons trois variables : Nom d'utilisateur, hÎte, port. J'étais content du nom de l'élément 111111@login.mtt.ru:5060, je n'ai trouvé aucune situation dans laquelle vous devez utiliser les cinq variables.
L'Ă©lĂ©ment principal qui reçoit des informations sur toutes les inscriptions, AstĂ©risque - AMI SIPshowregistry. Une fois par minute, il effectue une requĂȘte GET pour , aprĂšs quoi les donnĂ©es XML de rĂ©ponse sont transmises Ă tous les Ă©lĂ©ments dĂ©pendants pour analyse. Pour chaque inscription je crĂ©e un Ă©lĂ©ment qui en dĂ©pend. Ceci est pratique car nous recevons des informations Ă jour dans une seule demande, et non pour chaque demande sĂ©parĂ©ment. Cette implĂ©mentation prĂ©sente un inconvĂ©nient important : la charge sur le processeur.
Lors du test jusqu'Ă 100 Ă©lĂ©ments dĂ©pendants, je n'ai pas remarquĂ© la charge, mais avec 1700 15 Ă©lĂ©ments, cela a donnĂ© une charge notable de XNUMX secondes sur le processeur. Gardez cela Ă lâesprit si vous disposez dâun grand nombre dâĂ©lĂ©ments dĂ©pendants.
En guise d'option permettant de « répartir » la charge ou de définir différentes fréquences d'interrogation pour un élément, vous pouvez déplacer la logique de traitement vers chaque élément séparément.
Je ne stocke pas les informations reçues dans l'élément principal. PremiÚrement, je n'en vois pas la nécessité, et deuxiÚmement, si la réponse est supérieure à 64 Ko, alors Zabbix la coupe.
Puisque nous utilisons une réponse XML complÚte pour l'élément dépendant, nous devons obtenir la valeur de cet élément lors du prétraitement. à travers XPath c'est fait comme ça:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@ Ătat)
Pour les statuts d'inscription, je n'ai pas utilisé de statuts textuels, mais je les ai convertis sous forme numérique à l'aide de JavaScript :
switch(value) {
case 'Registered':
return 1;
case 'Unregistered':
return 0;
default:
return -1;
}
Homologues SIP
Par analogie avec les enregistrements SIP, il existe un élément principal d'Asterisk - AMI SIPshowregistry, auquel s'ajoutent les éléments dépendants.
Cela crée deux éléments dépendants :
- Statut des pairs sous forme de texte
- Temps de réponse de l'appareil - si l'état est OK, alors le temps de réponse de l'appareil est écrit, sinon « -1 »
Le chemin vers l'Ă©lĂ©ment lui-mĂȘme est un peu plus simple XPath:
chaĂźne(//response/generic[@objectname="{#SIP_PEER_OBEJECTNAME}"]/@status)
Pour le deuxiÚme élément, j'ai utilisé JavaScript pour séparer temps de réponse du statut de pair, puisqu'ils sont stockés ensemble :
if(value.substring(0,2) == 'OK'){
return value.match(/(d+)/gm);
}
else {
return -1;
}Conclusion
Une solution prĂȘte Ă lâemploi peut ĂȘtre complexe et pas immĂ©diatement claire. Augmente la flexibilitĂ© et la portabilitĂ© entre diffĂ©rents systĂšmes
Bonne et facile intégration à tous ! ModÚle et instructions de configuration .
Source: habr.com
