在为客户制定解决方案时,出现了 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数据格式。 详细信息可以参见
获取我们需要的数据并将其记录在宏中的操作顺序如下图所示。
步骤1
第一步可以由单个操作或多个操作组成。 所有的主要逻辑都集中在前面的步骤中,最后3步是主要的。
在我的示例中,第一步是在 PBX 上获取第一个任务的授权 cookie。 对于第二个任务,我获取了 Mikrotik 固件当前版本的编号。
Mikrotik 固件当前版本的 URL
Upgrade.mikrotik.com/routeros/LATEST.6 - 当前稳定版本的 URL 地址Upgrade.mikrotik.com/routeros/LATEST.6fix — 当前 LTS 版本的 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 版开始,有一个选项可以隐藏宏中保存的密码。
当创建单独的帐户用于通过 API 更新数据时,请务必检查您需要的数据是否可以通过 Web 界面获取以及是否可以更新。 我没有检查,然后很长一段时间我无法理解为什么我需要的宏在API中不可见。
在 API 中获得授权后,我们继续获取宏列表。
步骤3
API 不允许您按名称更新主机宏,您必须首先获取宏 ID。 而且,要获取特定主机的宏列表,您需要知道该主机的ID,这是一个额外的请求。 使用默认宏 {主机 ID} 请求中不允许。 我决定像这样绕过限制:
我使用该主机的 ID 创建了一个本地宏。 从 Web 界面查找主机 ID 非常容易。
包含给定主机上所有宏列表的响应可以通过模式进行过滤:
regex:{"hostmacroid":"([0-9]+)"[A-z0-9,":]+"{$MIKROTIK_VERSION}"
这样,我们就得到了我们需要的宏的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 代理无法访问另一个项目的数据并在请求正文或标头中替换它们[
完成后的模板可以
来源: habr.com