В предишната статия Разказах как да получа сесия за авторизация и да я вградя в локалния макрос на хоста. В тази статия ще опиша как да свържа Zabbix с Asterisk без външни скриптове и софтуер.
Идеята за „свързване“ на тези две системи се роди отдавна, без инсталиране на допълнителен софтуер и скриптове. Бързото търсене в Google показваше много решения, но всички те се свеждаха до това да качите скриптове (на PHP, Bash, Python и т.н.) на сървъра и ще бъдете щастливи. Аз исках да реализирам мониторинг „от кутията“ — без външни скриптове и инсталиране на допълнителен софтуер на сървъра с мониторинга и АТС.
Прекарах общо 4 работни дни с това, но резултатът си заслужава. Работата през интерфейса AMI, ниско ниво на откритие, тригери, а най-важното — свързването на АТС и всички останали настройки сега отнема около 15 минути.
Налице е Zabbix 4.4, около 100 устройства Asterisk от версия 13. Някои АТС идват с уеб интерфейса FreePBX, а други с проста консула, куп хитрости и интеграция чрез диалплан.
Получаване на данни от АТС
Първият и основен момент, който трябва да решите, е получаването на данни за пирс и SIP регистрации. За това в АТС съществуват интерфейси AGI, AMI, ARI и SSH конзола. Допълнителни модули не разглеждах по обясними причини.
За начало, трябва да разберем какво представляват тези AGI, AMI, ARI…
- AGI — използване на скриптове в диалплана. Основно се използва за управление на повикванията.
- AMI — предоставя необходимата информация, работи през порт 5038 аналогично на Telnet. Подходящо е за нас!
- ARI — модерно, стилно, JSON-но. Много възможности, формат на данните в разбираем вид за Zabbix, но за мен липсва основното: не може да контролира SIP регистрацията. Още един недостатък: за пирс има само два състояния online/offline, въпреки че състоянията са повече и е полезно да се вземат предвид при диагностика.
- SSH — може всичко, но понякога не го дават по „съображения за сигурност“. Причините могат да бъдат различни, няма да ги разглеждам.
Въпреки всички свои недостатъци, ARI покрива 90% от нуждите за мониторинг.
Zabbix и Telnet — моето разочарование
Зная AMI, я раньше реализовывал отслеживание потерь в разговорах, деля их по удалённым офисам, управление звонками и тому подобное. С Telnet всё также достаточно просто: открываешь подключение, отправляешь команды и читаешь ответ. Что я и сделал, но результат меня разочаровал.
Telnet в Zabbix отличается от команд в консоли Linux, он немного проще и ориентирован на стандартную авторизацию типа логин/пароль. Если логика авторизации иная и не запрашивается пара логин/пароль, возникает ошибка. После безуспешных попыток обойти требование авторизации я решил изучить исходники модуля Telnet.
Я осознал, что пока не будет традиционного запроса логина с паролем, я не продвинусь дальше. В общем, ради интереса я убрал из кода всё, что касалось авторизации, пересобрал приложение. И оно заработало! Но не подходит под требования. Двигаемся дальше…
Возвращаемся к поиску.
Я снова перечитал документацию по ARI и провёл дополнительные тесты — здесь нет SIP-регистраций. Пиры есть, разговоры есть, бриджи есть, но регистраций нет. В какой-то момент даже задумался, так ли нужны нам SIP-регистрации?
По забавному стечению обстоятельств, в этот момент мне пришёл очередной запрос от пользователя с проблемой исходящих звонков. Проблема заключалась в зависании SIP-регистрации и решалась обычной перезагрузкой модуля.
asterisk -rx "sip reload"Было бы замечательно обращаться к AMI через веб: это решило бы все проблемы, подумал я. Начинаю это исследовать, и буквально первая строка поиска ведёт на официальную документацию Asterisk, где говорится, что для моих задач есть опция webenabled в файла /etc/asterisk/manager.conf, которую нужно установить в значение YES в секции [general]
После этого, через обычный веб-запрос вида получаем всю необходимую информацию.
При использовании интерфейса FreePBX включить данную опцию через веб невозможно, её нужно включать в консоли, внося изменения в файл manager.conf. FreePBX не удаляет её при изменениях конфигурации через веб.
Сколько бы я ни работал с разного рода интеграциями Asterisk, никогда не видел, чтобы эта функция упоминалась. Меня удивило, что никто не описывает этот метод взаимодействия с АТС. Даже специально искал информацию по этой теме: практически ничего нет или использовалось для совершенно других задач.
WEB AMI — что это такое?
Добавление опции webenabled в файла manager.conf отваряше пълен достъп до управлението на АТС през уеб. Всички команди, налични през обикновения AMI, сега са в уеб интерфейса, можете да слушате събития от АТС чрез сокет. Принципът на работа не се различава от конзолния AMI. След активирането на тази опция, до АТС можете да се обърнете на следните адреси:
— уеб страница с прост интерфейс, за тестове и ръчно изпращане на заявки. Всички отговори са форматирани в четим HTML вид. За мониторинг не е много подходящо.
— само текстов изход, форматът е аналогичен на конзолния AMI
— само текстов изход, в XML формат. Подходящо е!

Тук си помислих: „Ето го – решението! Сега всичко ще бъде готово! Лесно, като лимонова кора“, но радостта беше преждевременна. За да получим нужната информация, просто трябва да използваме GET заявка с необходимото действие action, която в отговор връща xml с списък на всички регистрации и тяхното състояние. Всичко изглежда добре, но е необходима авторизация с запаметяване на сесията от бисквитки. Когато тествате в браузъра, не мислите за този процес.
Процес на авторизация
В началото се обръщаме на адреса , в отговор сървърът ни изпраща бисквитка с сесията за авторизация. Ето как изглежда 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: bg-BG,bg;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 За работа там е нужно mansession_id="6f5de42c", т.е. самата бисквитка за авторизация.
Съдържанието просто трябва да провери наличието на отговора „Авторизацията е приета“. След това, при всички обръщения към сървъра на АТС, трябва да добавим бисквитката за авторизация в заявката.
https://ats:8089/mxml?action=SIPpeers
Host: ats:8089
Connection: close
Cookie: mansession_id="6f5de42c"Как да получите бисквитката за авторизация и да я използвате в други заявки, прочетете тук: „»
За създаване на елементи за наблюдение в Забикс ще използвам автоматично откриване.
Автоматично откриване
За автоматично откриване на регистрациите и наблюдение на състоянията на пирчетата е необходимо да се обърнете на адрес: или
В отговор АТС ни връща XML отговор:
...
... В ответе много лишней информации, поэтому на этапе предварительной обработки мы фильтруем её по шаблону. XPath: //response/generic[@host]
Далее начинается самое интересное. Чтобы работать с обнаружением и динамически создавать элементы, ответ должен быть в формате JSON. XML не поддерживается при автообнаружении.
Для преобразования XML в JSON пришлось немного поиграть с автоматической заменой, для чего я написал скрипт на JS.

Интересный момент: в ответе АТС все параметры обрамляются одинарными кавычками, а после применения шаблона //response/generic[@host] они заменяются на двойные.
Для создания элементов используем переменные из XML-ответа (сейчас в JSON).

SIP Registry
Для SIP-регистраций используем три переменные: username, host, port. Меня устраивало название элемента 111111@login.mtt.ru:5060, ситуаций, когда нужно использовать все пять переменных, я не нашел.
Главный элемент, который получает информацию о всех регистрациях, Asterisk — AMI SIPshowregistry. Раз в минуту он отправляет GET-запрос к , после чего данные XML-ответа передаются всем зависимым элементам для анализа. Элемент по каждой регистрации создаю зависимыми от него. Это удобно, так как актуальную информацию мы получаем за один запрос, а не для каждого отдельно. У данной реализации есть существенный минус — нагрузка на процессор.
При тестировании до 100 зависимых элементов, нагрузки не заметил, но при 1700 элементах это давало заметную 15-секундную нагрузку на процессор. Имейте это ввиду, если у вас большое количество зависимых элементов.
Как вариант для «размазывания» нагрузки или установки разной частоты опроса элемента, можно вынести логику обработки в каждый элемент отдельно.
Не съхранявам получената информация в основния елемент. Първо, не виждам необходимост от това, и второ, ако отговорът е по-голям от 64К, Zabbix го реже.
Тъй като за зависимия елемент използваме пълния XML отговор, трябва в предпроцесирането да получим стойността на този елемент. През XPath това се прави така:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@state)
За статусите на регистрация не използвах текстови статуси, а ги преобразувах в числов вид с помощта на JavaScript:
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)
За втория елемент използвах JavaScript, за да отделя времето за отговор от статуса на пира, тъй като те се съхраняват заедно:
if(value.substring(0,2) == 'OK'){
return value.match(/(d+)/gm);
}
else {
return -1;
}Заключение
Решението «извън кутията» може да бъде сложно и не веднага разбираемо. Увеличава гъвкавостта и преносимостта между различни системи.
На всички желая приятна и лесна интеграция! Шаблон и инструкции за настройка на .
Източник: habr.com
