Przy opracowywaniu rozwiązania dla klienta napotkałem 2 zadania, które chciałem rozwiązać w estetyczny sposób za pomocą standardowych funkcji Zabbix.
Zadanie 1. Śledzenie aktualnej wersji oprogramowania na routerach Mikrotik.
Zadanie jest łatwe do rozwiązania — poprzez dodanie do szablonu agenta HTTP. Agent pobiera aktualną wersję z witryny Mikrotik, a wyzwalacz porównuje aktualną wersję z bieżącą i w przypadku różnicy generuje alert.
Gdy masz 10 routerów, taki algorytm nie jest krytyczny, ale co zrobić z 3000 routerów? Wysyłać 3000 zapytań do serwera? Oczywiście, taka opcja działa, ale sama myśl o 3000 zapytaniach mnie nie satysfakcjonowała, chciałem znaleźć inne rozwiązanie. Ponadto, wadą takiego algorytmu jest to, że druga strona może potraktować taką liczbę zapytań z jednego IP jako atak DoS i po prostu zablokować dostęp.
Zadanie 2. Użycie sesji autoryzacyjnej w różnych agentach HTTP.
Gdy za pośrednictwem agenta HTTP potrzebne są informacje z „zamkniętych” stron, potrzebne jest ciasteczko autoryzacji. Zazwyczaj istnieje standardowa forma autoryzacji z parą „login/hasło” i ustawieniem ID sesji w ciasteczku.
Jest jednak problem, nie można z jednego elementu agenta HTTP odwoływać się do danych innego elementu, aby wstawić tę wartość w nagłówku.
Istnieje jeszcze „Skrypt webowy”, który ma inne ograniczenie, nie pozwala na uzyskanie treści do analizy i dalszego zachowania. Można jedynie sprawdzić obecność wymaganych zmiennych na stronach lub przekazywać wcześniej uzyskane zmienne między krokami skryptu webowego.
Po chwilowym zastanowieniu się nad tymi zadaniami zdecydowałem się na użycie makr, które są dobrze widoczne w każdej części systemu monitorowania: w szablonach, hostach, wyzwalaczach czy elementach. Makra można aktualizować za pośrednictwem API interfejsu webowego.
Zabbix ma dobrą i szczegółową dokumentację API. Do wymiany danych za pośrednictwem API używany jest format danych JSON. Szczegóły można przeczytać w .
Kolejność działań potrzebnych do uzyskania wymaganych danych i zapisania ich w makrze przedstawiona jest na schemacie poniżej.

Krok 1
Pierwszy krok może składać się z jednego działania lub wielu działań. W pierwszych krokach zakłada się całą główną logikę, a kluczowe są ostatnie 3 kroki.
W moim przykładzie, w pierwszym kroku wykonywano uzyskanie ciasteczka autoryzacji na ACD dla pierwszego zadania. Dla drugiego zadania uzyskałem numer bieżącej wersji oprogramowania Mikrotik.
URL aktualnych wersji oprogramowania Mikrotik
- — adres URL aktualnej wersji Stable
- — adres URL aktualnej wersji LTS
Te adresy są wykorzystywane przez same urządzenia Mikrotik w celu uzyskania najnowszej dostępnej wersji oprogramowania.
Pierwszy krok jest całkowicie indywidualny dla każdego przypadku i logika jego działania może być różna. Wszystko zależy od twojego zadania.
Podczas pracy ze skryptami webowymi monitoruj, jaka metoda uzyskania odpowiedzi jest potrzebna. Nagłówki Odpowiedź HTTP lub sama treść odpowiedzi bez nagłówków?
Jeśli potrzebne są ciasteczka autoryzacji, to metodę odpowiedzi ustaw Nagłówki jak w przypadku z Asterisk.Jeśli potrzebne są dane, jak w przypadku odpowiedzi serwera mikrotik, ustaw Treść odpowiedzi bez nagłówków.
Krok 2
Przechodzimy do drugiego kroku. Uzyskanie sesji autoryzacji:
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 — wersja protokołu JSON-RPC, która jest używana;
Zabbix implementuje JSON-RPC w wersji 2.0;
- method — metoda, która jest wywoływana;
- params — parametry przekazywane przez metodę;
- id — dowolny identyfikator zapytania;
- auth — klucz autoryzacji użytkownika; ponieważ go jeszcze nie mamy, ustawimy go na null.
Aby pracować z API, utworzyłem osobne konto z ograniczonymi uprawnieniami. Po pierwsze, nie należy dawać dostępu tam, gdzie nie potrzeba. Po drugie, przed wersją 5.0, hasło ustawione przez makro było możliwe do odczytania. W związku z tym, jeśli używasz hasła administratora Zabbix, konto admina jest łatwe do skradzenia.
To szczególnie będzie aktualne, gdy pracujesz z API przez zewnętrzne skrypty i przechowujesz dane logowania po stronie.
Od wersji 5.0 pojawiła się opcja ukrycia hasła zapisanego w makrze.

Gdy tworzysz osobne konto do aktualizacji danych przez API, koniecznie sprawdź, czy potrzebne dane są dostępne przez interfejs webowy i czy możliwe jest ich aktualizowanie. Nie sprawdziłem tego, a potem długo nie mogłem zrozumieć, dlaczego przez API nie widać mojego potrzebnego makra.

Po uzyskaniu autoryzacji w API przechodzimy do uzyskania listy makr.
Krok 3
Interfejs API nie pozwala aktualizować makro hosta po nazwie, najpierw trzeba uzyskać ID makra. Co więcej, aby uzyskać listę makr konkretnego hosta, trzeba znać ID tego hosta, co wiąże się z dodatkowym zapytaniem. Użyj standardowego makra {HOST.ID} w zapytaniu jest niemożliwe. Zdecydowałem się obejść to ograniczenie w ten sposób:

Stworzyłem lokalne makro z ID tego hosta. Identyfikator hosta można łatwo znaleźć w interfejsie internetowym.
Odpowiedź z listą wszystkich makr danego hosta można filtrować według wzoru:
regex:{"hostmacroid":"([0-9]+)"[A-z0-9,":]+"{$MIKROTIK_VERSION}" 
W ten sposób otrzymujemy ID potrzebnego makra, gdzie MIKROTIK_VERSION — to nazwa makra, którego szukamy. W moim przypadku szuka makra MIKROTIK_VERSION, które zostało przypisane do hosta.
Same zapytanie wygląda tak:
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
}
Zmienna {sid} uzyskane na drugim etapie i będzie używane na stałe tam, gdzie trzeba pracować z interfejsem API.
Ostateczny KROK 4 — aktualizacja makra
Teraz już znamy ID makra, które musimy zaktualizować, plik cookie autoryzacji lub wersję oprogramowania routera. Możemy aktualizować samo makro.
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_version} — to wartość uzyskana na pierwszym etapie. W moim przykładzie — wersja aktualnego oprogramowania mikrotik
{hostmacroid} — wartość uzyskana w trzecim etapie — id makra, które aktualizujemy.
Wnioski
Podejście do rozwiązania problemu standardowym funkcjonalnością jest znacznie bardziej skomplikowane i czasochłonne. Szczególnie jeśli znasz programowanie i możesz szybko napisać potrzebną logikę w skrypcie.
Oczywistą zaletą tego podejścia jest "przenośność" rozwiązania pomiędzy różnymi serwerami.
Osobiście uważam za dziwne brak możliwości odwoływania się w agencie HTTP do danych innego elementu i wstawiania ich do ciała zapytania lub nagłówków [ ].
Gotowy szablon można .
Źródło: habr.com
