Zabbix - 扩展宏边界

在为客户制定解决方案时,出现了 2 个任务,我想通过常规 Zabbix 功能完美地解决它们。

1任务。 跟踪 Mikrotik 路由器上的当前固件版本。

该任务很容易解决 - 通过将代理添加到 HTTP 模板。 代理从 Mikrotik 网站接收当前版本,触发器将当前版本与当前版本进行比较,并在出现差异时发出警报。

当你有10个路由器时,这样的算法并不重要,但是3000个路由器怎么办? 向服务器发送3000个请求? 当然,这样的方案是可行的,但是 3000 个请求的想法并不适合我,我想找到另一个解决方案。 另外,这种算法还有一个缺点:对方可以统计出来自一个IP的如此多的请求来进行DoS攻击,他们可以简单地禁止它。

2任务。 在不同的 HTTP 代理中使用授权会话。

当代理需要通过 HTTP 从“关闭”页面接收信息时,需要授权 cookie。 为此,通常有一个带有“登录名/密码”对的标准授权表单,并在 cookie 中设置会话 ID。

但有一个问题,无法从一个HTTP代理项访问另一项的数据来替换Header中的这个值。

还有一个“Web脚本”,它还有另一个限制,它不允许您获取内容进行分析和进一步保存。 您只能检查页面上是否存在必要的变量,或者在 Web 脚本步骤之间传递先前接收到的变量。

在对这些任务进行了一些思考之后,我决定使用在监控系统的任何部分中都完全可见的宏:在模板、主机、触发器或项目中。 您还可以通过 Web 界面 API 更新宏。

Zabbix 有良好且详细的 API 文档。 通过api进行数据交换,使用Json数据格式。 详细信息可以参见 官方文档.

获取我们需要的数据并将其记录在宏中的操作顺序如下图所示。

Zabbix - 扩展宏边界

步骤1

第一步可以由单个操作或多个操作组成。 所有的主要逻辑都集中在前面的步骤中,最后3步是主要的。

在我的示例中,第一步是在 PBX 上获取第一个任务的授权 cookie。 对于第二个任务,我获取了 Mikrotik 固件当前版本的编号。

Mikrotik 固件当前版本的 URL

当收到最新的可用固件版本时,Mikrotik 设备本身会访问这些地址。

第一步对于每个案例来说都是完全独立的,其工作逻辑可能有所不同。 这一切都取决于您的任务。

使用 Web 脚本时,请跟踪您需要的响应方法。 新闻头条 HTTP 响应或自身 身体 没有标题的响应?
如果需要授权cookie,则设置响应方法 新闻头条 就像星号的情况一样。

如果您需要数据,例如 mikrotik 服务器响应的情况,请输入 身体 没有标题的响应。

步骤2

让我们继续第二步。 获取授权会话:

POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc

{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
        "user": "Admin"
        "password": "zabbix"
    },
    "id": 1,
    "auth": null
}

jsonrpc 是正在使用的 JSON-RPC 协议的版本;
Zabbix实现JSON-RPC版本2.0;

  • method - 被调用的方法;
  • params - 方法传递的参数;
  • id 是任意请求标识符;
  • auth——用户认证密钥; 因为我们还没有它,所以我们将它设置为 null。

为了使用 API,我创建了一个具有有限权限的单独帐户。 首先,您不需要授予不需要的访问权限。 其次,在5.0版本之前,通过宏设置的密码是可以读取的。 因此,如果您使用Zabbix管理员密码,则admin帐户很容易被盗。

当通过第三方脚本使用 API 并在侧面存储凭证时尤其如此。

从 5.0 版开始,有一个选项可以隐藏宏中保存的密码。

Zabbix - 扩展宏边界

当创建单独的帐户用于通过 API 更新数据时,请务必检查您需要的数据是否可以通过 Web 界面获取以及是否可以更新。 我没有检查,然后很长一段时间我无法理解为什么我需要的宏在API中不可见。

Zabbix - 扩展宏边界

在 API 中获得授权后,我们继续获取宏列表。

步骤3

API 不允许您按名称更新主机宏,您必须首先获取宏 ID。 而且,要获取特定主机的宏列表,您需要知道该主机的ID,这是一个额外的请求。 使用默认宏 {主机 ID} 请求中不允许。 我决定像这样绕过限制:

Zabbix - 扩展宏边界

我使用该主机的 ID 创建了一个本地宏。 从 Web 界面查找主机 ID 非常容易。

包含给定主机上所有宏列表的响应可以通过模式进行过滤:

regex:{"hostmacroid":"([0-9]+)"[A-z0-9,":]+"{$MIKROTIK_VERSION}"

Zabbix - 扩展宏边界

这样,我们就得到了我们需要的宏的ID,其中 MIKROTIK_VERSION 是我们正在寻找的宏的名称。 就我而言,搜索宏 MIKROTIK_VERSION分配给主机的。

请求本身如下所示:

POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc

{
    "jsonrpc":"2.0",
    "method":"usermacro.get",
    "params":{
        "output":"extend",
        "hostids":"{$HOST_ID}"
    },
    "auth":"{sid}",
    "id":1
}

变量 {sid} 在第二步中获得,并且会不断使用,需要使用API​​接口。

最后 4 步 - 更新宏

现在我们知道需要更新的宏 ID、授权 cookie 或路由器的固件版本。 您可以更新宏本身。

POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc

{
    "jsonrpc":"2.0",
    "method":"usermacro.update",
    "params":{
        "hostmacroid":"{hostmacroid}",
        "value":"{mikrotik_version}"
    },
    "auth":"{sid}",
    "id":1
}

{mikrotik_版本} 是第一步得到的值。 在我的示例中,当前 mikrotik 固件的版本
{主机宏} - 该值是在第三步中获得的 - 我们正在更新的宏的 id。

发现

使用标准功能解决问题的方法要复杂得多且时间更长。 特别是如果您了解编程并且可以快速在脚本中添加必要的逻辑。

这种方法的明显优点是解决方案在不同服务器之间的“可移植性”。

对于我个人来说,奇怪的是 HTTP 代理无法访问另一个项目的数据并在请求正文或标头中替换它们[ ZBXNEXT-5993].

完成后的模板可以 在 GitHub 上下载.

来源: habr.com

添加评论