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 上下載.

來源: www.habr.com

添加評論