如何开箱即用地将 Zabbix 与 Asterisk 连接

在前面的文章 《Zabbix——拓展宏观边界》 我告诉您如何接收授权会话并将其替换为本地主机宏。 在这篇文章中,我将告诉您如何在没有外部脚本和软件的情况下将 Zabbix 与 Asterisk 连接。

让这两个系统“交朋友”的想法很久以前就诞生了,无需安装额外的软件或脚本。 快速谷歌搜索产生了许多可能的解决方案,这一切都归结为将脚本(Pyha、Bash、Python 等)上传到服务器,您会很高兴。 我想实现“开箱即用”的监控 - 无需外部脚本,也无需在具有监控和 PBX 的服务器上安装其他软件。

我总共花了4个工作日来完成这个任务,但结果是值得的。 通过 AMI 接口、低级别检测、触发器以及最重要的是连接 PBX 和所有其他设置,现在大约需要 15 分钟。

Zabbix 4.4已经可用,Asterisk版本100大约有13个。 有些 PBX 带有 FreePBX Web 界面,有些带有裸控制台、一堆技巧并通过拨号方案进行集成。

从 PBX 接收数据

需要解决的第一个也是要点是获取有关对等点和 SIP 注册的数据。 为此,PBX 具有 AGI、AMI、ARI 和 SSH 控制台接口。 由于显而易见的原因,我没有考虑额外的模块。

首先我们需要弄清楚这些agi、ami、ari是什么......

  • AGI - 在拨号方案中使用脚本。 主要用于通话管理。
  • AMI - 可以提供所有必要的信息,通过端口 5038 工作,类似于 Telnet。 适合我们!
  • ARI——现代、时尚、JSON。 有很多可能性,数据格式对于 Zabbix 来说是可以理解的,但对我来说没有主要的事情:你无法控制 sip 注册。 另一个缺点是,对于同行来说,只有在线/离线两种状态,尽管状态有更多,并且在诊断时将它们考虑在内是有用的。
  • SSH 可以做所有事情,但有时由于“安全原因”而不允许使用。 考虑的因素可能不同,我就不多说了。

然而,尽管存在种种缺点,ARI 仍能满足 90% 的监控需求。

Zabbix 和 Telnet - 我的失望

我很了解 AMI;有一次,我通过远程办公室、呼叫管理等实现了与部门对话中的丢失跟踪。 使用 Telnet,一切都非常清晰:打开连接、发送命令并读取响应。 我就是这么做的,但结果却令我失望。

Zabbix 中的 Telnet 与 Linux 控制台中的不一样,它更简单一些,并且是针对登录/密码等标准授权量身定制的。 如果授权逻辑不同,并且没有请求登录名/密码对,则会发生错误。 在尝试绕过授权要求徒劳之后,查看 Telnet 模块的源代码很有用。

我意识到,除非有传统的登录和密码请求,否则我不会继续前进。 只是为了好玩,我从代码中删除了与授权相关的所有内容并重新组装了所有内容。 作品! 但它不符合要求。 前进…

让我们回到搜索

我再次重新阅读了 ARI 文档,运行了额外的测试 - 这里没有 sip 注册。 有宴会,有谈话,有马裤,但没有登记。 在某些时候我什至想,我们真的需要秃鹫注册吗?

有趣的是,此时用户收到了另一个请求,但出局电话出现了问题。 问题是 sip 注册被冻结,只需重新启动模块即可解决。

asterisk -rx "sip reload"

如果能够通过网络访问 AMI,那就太棒了:我想,这将解决所有问题。 我开始朝这个方向挖掘,从字面上看,第一条搜索线通向官方 Asterisk 文档,该文档说我的任务有一个选项 网络功能 在文件中 /etc/asterisk/manager.conf,需要在部分中设置为 YES [一般]

之后,通过表单的常规网络请求 http://ats:8089/mxml?action=SIPshowregistry 我们得到了所有必要的信息。

使用 FreePBX 界面时,您无法通过 Web 启用此选项;您需要通过控制台更改 manager.conf 文件来启用它。 当通过网络进行配置更改时,FreePBX 不会删除它。

我已经使用各种类型的 Asterisk 集成工作了很长时间,但我从未在任何地方看到过这个功能。 令我惊讶的是,没有人描述这种与 PBX 交互的方法。 查找有关该主题的信息甚至特别有用:几乎没有任何信息,或者它用于完全不同的任务。

WEB AMI - 什么样的野兽?

添加一个选项 网络功能 归档 管理器配置文件 提供通过网络对 ATS 管理的完全访问。 通过常规 AMI 可用的所有命令现在都在网络上,您可以通过套接字侦听来自 PBX 的事件。 操作原理与控制台AMI没有什么不同。 激活此选项后,您可以通过以下地址联系 PBX:

https://ats:8089/manager — 具有简单界面的网页,用于测试和手动发送请求。 所有响应都被格式化为可读的 HTML。 不太适合监控。
https://ats:8089/rawman — 仅文本输出,格式类似于控制台 AMI
https://ats:8089/mxml - 仅文本输出,采用 XML 格式。 适合我们!

如何开箱即用地将 Zabbix 与 Asterisk 连接

然后我想:“这就是解决办法! 现在一切都准备好了! 容易尿尿的柠檬汁”,但现在高兴还为时过早。 要获取我们需要的信息,使用 GET 请求和必要的操作就足够了 行动,作为响应返回 xml,其中包含所有注册及其状态的列表。 这一切都很棒,但是您需要授权才能记住 cookie 中的会话。 当你在浏览器中测试时,你不会考虑这个过程。

授权流程

首先我们解决地址 http://ats:8089/mxml?action=login&username=zabbix&secret=zabbix,作为响应,服务器向我们发送一个带有授权会话的 cookie。 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

答:

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>

在那里工作你需要 mansession_id="6f5de42c”,即授权 cookie 本身。
您只需检查内容即可找到答案”认证已接受” 接下来,对于对 PBX 服务器的所有调用,我们需要向请求添加授权 cookie。

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

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

请阅读如何获取授权 cookie 并在其他请求中使用它:“Zabbix - 扩展宏边界»

为了在 Zabbix 中创建跟踪元素,我将使用自动检测。

自动检测

要自动检测注册并跟踪对等状态,您需要联系以下地址: https://ats:8089/mxml?action=SIPshowregistry или https://ats:8089/mxml?action=SIPpeers

作为响应,PBX 向我们返回一个 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>

响应中存在大量垃圾,因此在预处理时我们通过模板进行过滤 XPath的: //响应/通用[@host]
然后乐趣就开始了。 要使用检测并动态创建元素,响应必须采用 JSON 格式。 自动检测不支持 XML。

要将 XML 转换为 JSON,我必须使用自动替换,为此我用 JS 编写了一个脚本

如何开箱即用地将 Zabbix 与 Asterisk 连接

有趣的一点:在ATS响应中,所有参数都用单引号括起来,并且在应用模板之后 //响应/通用[@host] 它们被双倍取代。

为了创建元素,我们使用 XML 响应(现在是 JSON)中的变量。

如何开箱即用地将 Zabbix 与 Asterisk 连接

SIP注册处

对于 sip 注册,我们使用三个变量: 用户名, 主持人, 端口。 我对元素的名称很满意 [电子邮件保护]:5060,我还没有发现任何需要使用全部五个变量的情况。

接收有关所有注册信息的主要元素, Asterisk - AMI SIPshowregistry。 它每分钟发出一次 GET 请求 https://ats:8089/mxml?action=SIPshowregistry,之后响应 XML 数据将传递到所有依赖元素进行解析。 对于每个注册,我都会创建一个依赖于它的元素。 这很方便,因为我们会在一个请求中收到最新信息,而不是分别收到每个请求的最新信息。 这种实现有一个显着的缺点——处理器的负载。

当测试多达 100 个相关元素时,我没有注意到负载,但对于 1700 个元素,这会给处理器带来明显的 15 秒负载。 如果您有大量依赖元素,请记住这一点。

作为“分散”负载或为元素设置不同轮询频率的选项,您可以将处理逻辑分别移动到每个元素。

我不将收到的信息存储在主元素中。 首先,我认为没有必要这样做,其次,如果响应超过 64K,那么 Zabbix 就会将其切断。

由于我们对依赖元素使用完整的 XML 响应,因此我们需要在预处理中获取该元素的值。 通过 XPath的 这样做是这样的:
string(//response/generic[@event="RegistryEntry"][@username="{#SIP_REGISTRY_USERNAME}"][@host="{#SIP_REGISTRY_HOST}"][@port="{#SIP_REGISTRY_PORT}"]/@状态)
对于注册状态,我没有使用文本状态,而是使用 JavaScript 将它们转换为数字形式:

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

SIP 对等体

与 SIP 注册类比,Asterisk 有一个主要元素 - AMI SIPshowregistry,并添加了依赖项。

这将创建两个依赖元素:

  • 文本形式的对等状态
  • 设备响应时间 - 如果状态正常,则写入设备响应时间,否则“-1”

元素本身的路径稍微简单一些 XPath的:

string(//响应/通用[@objectname="{#SIP_PEER_OBEJECTNAME}"]/@status)

对于第二个元素,我使用 JavaScript 来分隔 响应时间 来自对等状态,因为它们存储在一起:

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

结论

开箱即用的解决方案可能很复杂并且不能立即清晰。 提高不同系统之间的灵活性和可移植性

祝大家集成愉快、轻松! 模板和设置说明 GitHub上.

来源: habr.com

添加评论