📜 ⬆️ ⬇️

Zabbix 3.0.4: Windows Agent with TLS, LLD drives, a simple SMART example and command line only

We assume that the server Zabbix 3.0.4 is installed. For the agent installation scripts, we will use, according to hardcore, only the native Windows command line, without pythons, pearls, etc., i.e. without additional installations to the agent system. Encryption is configurable using PSK.

Let the external IP of the Zabbix server be - 30.0.1.1
Local Zabbix Server IP - 10.3.10.1
Test node address - 30.0.1.3
By forwarding ports here will not be said. The node in the example will listen to 10050, the server - 10051.

Formulation of the problem:

1) Simplify agent installation on Windows systems
2) Configure encryption between the agent and the server.
3) Configure disk detection (names, models, serial numbers, types) using the smartmontools utility, SMART monitoring
4) Create a scalable deployment scenario template.
5) Configure the alert.
6) Use command line only.

Windows agents for some reason do not yet have TLS support, but there are compiled versions that can be downloaded from here . Discussion .
')
Unpack We need only the bin directory. We will not need the default config.

Create a zabbix directory and copy the bin directory from the unpacked agent into it. Next, create in the zabbix directory subdirectories conf, disks, logs, psk, scripts, smartmontools . Immediately make a decision that we will place the zabbix folder in the root of the volume C: \


conf - there will be a config file
disks - disk information in JSON will be generated here
logs
pks - there will be a Z_agent.psk file containing the pre-shared key
scripts
smartmontools - put the SMART program of the same name here

Immediately prepare the PSK keys and data file. Create a pskgen4ik file on the server:

#!/bin/bash echo -n "  ? : " read LIMIT a=1 echo \# > /home/appliance/agent_psk while [ "$a" -le $LIMIT ] do openssl rand -hex 64 >> /home/appliance/agent_psk let "a++" done less /home/appliance/agent_psk 

Save, make executable (chmod + x), run, and copy the result to the data file, I will give an example of Excel for clarity. You can use the database. Something like this:



We will fill in the Host name field after creating the agent config (unless of course there is no already compiled list). We invent and add unique identifiers PSK ID. We save the data file, make a backup, strictly restrict access to it and delete the file "agent_psk". All we have is a data file with keys and identifiers that we will use.

SMART


For information about disks and their SMART use the utility Smartmontools . I take the latest version 6.5. In this version, USB passports are normally defined, and new manifestos for 10k. All fixes in the release .

Download and throw in the folder zabbix \ smartmontools

Acquaintance with the utility.


See the list of connected drives:

 c:\>"Program Files"\smartmontools\bin\smartctl.exe --scan 


The –d switch indicates the type of disk.

We are interested in the / dev / sda disk. So far, he has little to say about except that he is an ATA-type and most likely bootable.

We look information about it:

 c:\>"Program Files"\smartmontools\bin\smartctl.exe -i /dev/sda -d ata 


Already more interesting. As you can see SMART is disabled. Turn it on:

 c:\>"Program Files\smartmontools\bin\smartctl.exe" --smart=on --offlineauto=on --saveauto=on /dev/sda 

We look at the table of attributes SMART .

 c:\>"Program Files"\smartmontools\bin\smartctl.exe -A /dev/sda -d ata 


The smart RAID table will not look, but we can get the health status.

Look SMART Health:

 c:\>"Program Files"\smartmontools\bin\smartctl.exe -H /dev/sda -d ata 


Now, the same needs to be done for the remaining 1000 disks. To create templates for each one is out of the question; moreover, I, for example, still need to get the model and serial number of each disk in the report. Zabbix LLD comes to the rescue.

Since Zabbix has the ability to process data using the JSON protocol provided by its API , we will generate the necessary information from smartmontools to the JSON format and passively transfer to the server.

Start creating scripts. To begin with, we will invent detection macros and determine the data:
Macro {#DISKPORT} - the name of the disk in the system (/ dev / sda, / dev / sdb, etc.),
Macro {#DISKTYPE} - disk type (ata, scsi, sat, csmi, etc.),
Macro {#DISKMODEL} - disk model,
Macro {#DISKSN} - serial number.

Create a DiskInfoGenerationJSON.cmd file in the zabbix \ scripts directory with the following contents:

 @echo off echo @echo off > c:\zabbix\disks\disks.cmd echo echo {"data": >> c:\zabbix\disks\disks.cmd echo echo [ >> c:\zabbix\disks\disks.cmd for /F "tokens=1,3" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^ do (for %%s in ("Device Model" "Product") ^ do (for /F "tokens=2*" %%c in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%s ') ^ do (for %%i in ("Serial Number") do (for /F "tokens=3*" %%k in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%i ') ^ do echo echo {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"},>> c:\zabbix\disks\disks.cmd)))) echo echo {"{#SMARTV}":"Smartctl 6.5"}>> c:\zabbix\disks\disks.cmd echo echo ] >> c:\zabbix\disks\disks.cmd echo echo } >> c:\zabbix\disks\disks.cmd 

Save DiskInfoGenerationJSON.cmd

I didn’t manage to solve the problem of the last comma in a simplified way with the help of cmd (yes, I didn’t start to solve it, because it’s crazy stuff)

 {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"}, 

... which violates JSON syntax. So I just added the line {"{#SMARTV}": "Smartctl 6.5"} , which closes the body without a comma.

When you run the DiskInfoGenerationJSON.cmd file. As a result, we should get the file c: \ zabbix \ disks \ disks.cmd with the following contents:



Create in the zabbix \ scripts directory the file GetSmartAllDisk.cmd with the following contents :

 rem        : for /F "tokens=1" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^ do "C:\Program Files\smartmontools\bin\smartctl.exe" --smart=on --offlineauto=on --saveauto=on %%a 

Save GetSmartAllDisk.cmd

Config generation


The generation will be divided into two parts: connection settings and user parameters.

Creating a config


Analyzing the future agent configuration file:

 LogFile=C:\zabbix\logs\logs.log #   LogFileSize=100 #     Server=30.0.1.1 #    ServerActive=30.0.1.1 #    StartAgents=3 # - - Timeout=30 #   30    Hostname= #    # TLS TLSConnect=psk #    ( ) TLSAccept=psk #    ( ) TLSPSKFile=C:\zabbix\psk\Z_agent.psk #     pre-shared  TLSPSKIdentity= #   

The Hostname = and TLSPSKIdentity = fields in the configuration file are unique for each host. As well as a pre-shared key in the zabbix \ psk \ Z_agent.psk file . Therefore, we define these values ​​in variables.

In the zabbix \ scripts directory, create the AgentConfigGeneration.cmd file:

 @echo off chcp 866 > nul set /P CLIENT="Enter Organization name: " set /P PSKID=" Enter PSKIdentity: " set /P PSKkey="Enter PSKkey: " rem   @echo # zabbix_agent 3.0.1> C:\zabbix\conf\zabbix_agentd.conf @echo. >>C:\zabbix\conf\zabbix_agentd.conf @echo %PSKkey%>>C:\zabbix\psk\Z_agent.psk @echo LogFile=C:\zabbix\logs\logs.log >> C:\zabbix\conf\zabbix_agentd.conf @echo LogFileSize=100 >> C:\zabbix\conf\zabbix_agentd.conf @echo Server=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf @echo ServerActive=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf @echo StartAgents=3 >> C:\zabbix\conf\zabbix_agentd.conf @echo Timeout=30 >> C:\zabbix\conf\zabbix_agentd.conf @echo Hostname=%CLIENT%.%COMPUTERNAME%>> C:\zabbix\conf\zabbix_agentd.conf @echo. >> C:\zabbix\conf\zabbix_agentd.conf @echo ##### TLS ###########>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSConnect=psk>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSAccept=psk>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSPSKFile=C:\zabbix\psk\Z_agent.psk>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSPSKIdentity=%PSKID%>> C:\zabbix\conf\zabbix_agentd.conf @echo. >> C:\zabbix\conf\zabbix_agentd.conf 

It's simple. When you start, enter the name of the organization, for example, Organization1 and get the Hostname in the config in the form of " Organization1 . Hostname". Within the network of one organization, as a rule, the use of identical host names is usually excluded, so we will have unique names. Next, enter the PSK ID from the previously compiled data file and the key. But while we do not run.

Adding custom parameters to the config


In the zabbix \ scripts directory create a file UserParameters.txt , which will contain user parameters (UserParameter = <key>, <shell command>)

 #####  . UserParameter=HDD.discovery,for /F "tokens=*" %a in ('C:\zabbix\disks\disks.cmd') do @echo %a ##### SMART # RAW_VALUE UserParameter=HDD.raw[*], for /F "tokens=10" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a # VALUE UserParameter=HDD.value.[*], for /F "tokens=4" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2^| find "$3"') do @echo %a # WORST UserParameter=HDD.worst.[*], for /F "tokens=5" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a # THRESOLD UserParameter=HDD.thresh.[*], for /F "tokens=6" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a # WHEN_FAILED UserParameter=HDD.when.failed.[*], for /F "tokens=9" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a # HEALTH Status UserParameter=HDD.health.[*], for /F "tokens=6" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -H $1 -d $2 ^| find "test"') do @echo %a 

Save UserParameters.txt . We came up with keys and loops to get data. And at the end of the AgentConfigGeneration.cmd file we add the following line:

 type C:\zabbix\scripts\UserParameters.txt>> C:\zabbix\conf\zabbix_agentd.conf 

We still need to open the port on the host if the firewall is enabled. Create the file OpenLocalPort.cmd

 @echo off set localportname=10050 set rulename=zabbix set dirrname=in set protocolname=TCP set actionname=allow netsh advfirewall firewall add rule name=%rulename% dir=%dirrname% action=%actionname% protocol=%protocolname% localport=%localportname% 

So, we wrote the scripts. Here is what we get:


Now you need to decide on the sequence of launches of this kind:

1) Enter variables
2) Installing smartmontools in silent mode
3) Installing the Zabbix Agent service
4) Config generation with user parameters - AgentConfigGeneration.cmd
5) Disk list generation - DiskInfoGenerationJSON.cmd
6) Enable SMART - GetSmartAllDisk.cmd.cmd
7) Open Port - OpenLocalPort.cmd
8) Start Zabbix Agent service

Create the INSTALL_AGENT.cmd file in the zabbix root directory and combine all the steps of our scripts in it:

 @echo off chcp 866 > nul set /P CLIENT="Client NAME: " set /P PSKID="PSKIdentity: " set /P PSKkey="Enter PSKkey: " cls rem  smartmontools    C:\zabbix\smartmontools\smartmontools-6.5-1.win32-setup.exe /S rem   10050   set localportname=10050 set rulename=zabbix set dirrname=in set protocolname=TCP set actionname=allow netsh advfirewall firewall add rule name=%rulename% dir=%dirrname% action=%actionname% protocol=%protocolname% localport=%localportname% echo "port %localportname% was open on host %hostname%" rem   @echo # zabbix_agent 3.0.1> C:\zabbix\conf\zabbix_agentd.conf @echo. >>C:\zabbix\conf\zabbix_agentd.conf @echo %PSKkey%>C:\zabbix\psk\Z_agent.psk @echo LogFile=C:\zabbix\logs\logs.log >> C:\zabbix\conf\zabbix_agentd.conf @echo LogFileSize=100 >> C:\zabbix\conf\zabbix_agentd.conf @echo Server=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf @echo ServerActive=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf @echo StartAgents=3 >> C:\zabbix\conf\zabbix_agentd.conf @echo Timeout=30 >> C:\zabbix\conf\zabbix_agentd.conf @echo Hostname=%CLIENT%.%COMPUTERNAME%>> C:\zabbix\conf\zabbix_agentd.conf @echo. >> C:\zabbix\conf\zabbix_agentd.conf @echo ##### TLS ###########>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSConnect=psk>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSAccept=psk>> C:\zabbix\conf\zabbix_agentd.conf @echo TLSPSKFile=C:\zabbix\psk\Z_agent.psk >> C:\zabbix\conf\zabbix_agentd.conf @echo TLSPSKIdentity=%PSKID%> C:\zabbix\conf\zabbix_agentd.conf @echo. >> C:\zabbix\conf\zabbix_agentd.conf rem    type C:\zabbix\scripts\UserParameters.txt>> C:\zabb\conf\zabbix_agentd.conf rem    @echo off echo @echo off > c:\zabbix\disks\disks.cmd echo echo {"data": >> c:\zabbix\disks\disks.cmd echo echo [ >> c:\zabbix\disks\disks.cmd for /F "tokens=1,3" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^ do (for %%s in ("Device Model" "Product") ^ do (for /F "tokens=2*" %%c in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%s ') ^ do (for %%i in ("Serial Number") do (for /F "tokens=3*" %%k in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%i ') ^ do echo echo {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"},>> c:\zabbix\disks\disks.cmd)))) echo echo {"{#SMARTV}":"Smartctl 6.5"}>> c:\zabbix\disks\disks.cmd echo echo ] >> c:\zabbix\disks\disks.cmd echo echo } >> c:\zabbix\disks\disks.cmd rem      for /F "tokens=1" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^ do "C:\Program Files\smartmontools\bin\smartctl.exe" --smart=on --offlineauto=on --saveauto=on %%a rem   Zabbix Agent if DEFINED ProgramFiles(x86) (goto :x64) else (goto :x86) :x64 C:\zabbix\bin\win64\zabbix_agentd.exe -i -c C:\zabbix\conf\zabbix_agentd.conf goto :NEXT :x86 C:\zabbix\bin\win32\zabbix_agentd.exe -i -c C:\zabbix\conf\zabbix_agentd.conf goto :NEXT :NEXT rem   Zabbix Agent net start "Zabbix Agent" echo. echo OK! @echo ------------------------------------ @echo Hostname: %CLIENT%.%COMPUTERNAME% @echo ------------------------------------ @echo. Pause 

We pack the zabbix directory into an SFX archive and encrypt it with a password if necessary

Example.


We have a server in the organization "Organization 1". We place zabbix.exe on the server and unpack it in the root of the volume C: \

Run INSTALL_AGENT.cmd on behalf of the Administrator. Enter the name of the Organization without spaces, copy the PSK identifier and key from the data file:


Enter:


Check the log file C: \ zabbix \ logs \ logs.log:


Copy the Hostname “Organization1.SUNSET” into the data file:


And so on with each host. After filling the file, go to the Zabbix office - 10.3.10.1/zabbix - and add groups and nodes from it. In the node encryption settings, mark the PSK and wait online.



We are waiting for a few seconds:


About encryption and restrictions

Lld


Russify the office for a change)

Create a SMART Template and a group of data elements. For example, I created the following groups on smart attributes:


Select the “Discovery Rules” and create the rule:


In the “Key” field, we indicate the user parameter that we have invented from the file C: \ zabbix \ scripts \ UserParameters.txt

 UserParameter=HDD.discovery,for /F "tokens=*" %a in ('C:\zabbix\disks\disks.cmd') do @echo %a 

And in the "Filters" tab, we write our macros from the created file c: \ zabbix \ disks \ disks.cmd and click "Add"



Create "Prototypes of data elements"


For example, I will create two prototypes of the Spin_Retry_Count attribute and add Pre-fail to the data item group: Spin_Retry_Count. The first one will get the VALUE value, the second THRESHOLD from the smart attribute table for each detected disk
Let's look again at the file C: \ zabbix \ scripts \ UserParameters.txt (well, or already created configuration). And let's see what cycles we pull out the data we need:

 UserParameter=HDD.value.[*], for /F "tokens=4" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2^| find "$3"') do @echo %a UserParameter=HDD.thresh.[*], for /F "tokens=6" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a 

As you can see from the script for the keys HDD.value. [*] And HDD.thresh. [*], We need to input three arguments $ 1 - disk (/ dev / *), $ 2 - disk type (ata, sat, etc. ), $ 3 - attribute (in our case Spin_Retry_Count). As a result, the key will receive such a format HDD.value. [$ 1, $ 2, $ 3]. For example, for our disk / dev / sda of type “ata”, it will be HDD.value. [/ Dev / sda, ata, Spin_Retry_Count]. But since we created macros for each detected disk, the key format in the prototype of the data item will be HDD.value. [{# DISKPORT}, {# DISKTYPE}, Spin_Retry_Count] . This key will go through each disk for this attribute.

By the way, we can check the key from the server, using zabbix_get

 root@zabbix:~# zabbix_get -s 30.0.1.3 -k HDD.value.[/dev/sda,ata,Spin_Retry_Count] --tls-connect psk --tls-psk-identity "ZP10001AA" --tls-psk-file /root/Organization1.SUNSET.psk 


And also for Threshold:


So, we create our prototype data for VALUE and use passive checking:



Similarly, we create a prototype for Threshold. As a result, we have:



Create a “Trigger Prototype”. Give the name, for example, for clarity:

SMART: ATTENTION! Drive {#DISKMODEL} ({#DISKPORT} - {#DISKTYPE}). It is expected to fail and / or complete failure of the disk in the next 24 hours! Attribute value worse than critical threshold

In the "Expression" field we write the condition:

 ({SMART:HDD.value.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()}-{SMART:HDD.thresh.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()})<0 

The point is that if the Value is less than the Threshold - you need to issue a problem. Last () - shows the last received value ( for more information about functions). In the field "Description" we write, for example:

 : {#DISKPORT}  : {#DISKTYPE} : {#DISKMODEL}  : {#DISKSN} : Threshold —  :  Value  Threshold —   ;     —   .     ,  SMART,          «Good»  «Bad».  VALUE   THRESH   Pre-fail  -   ,      24 . / Spin_Retry_Count /          ,     .    ,       . 

The importance of putting "Emergency"


We assume that the alert we have configured by EMAIL. If not, then here .

Go to "Settings"> "Actions". Create a report form. Click "Create action"

Name : Problem Reports
Default theme: PROBLEM! [{HOST.NAME}] - {TRIGGER.NAME} ({EVENT.ID})
The default message is:

  ! : {TRIGGER.SEVERITY} : {HOST.NAME}  : {HOST.DESCRIPTION} : {EVENT.DATE} : {EVENT.TIME} {TRIGGER.NAME}  : {TRIGGER.DESCRIPTION}     . : 1. {ITEM.NAME1} = {ITEM.VALUE1}. : {ITEM.KEY1} 2. {ITEM.NAME2} = {ITEM.VALUE2}. : {ITEM.KEY2} {TRIGGER.EXPRESSION} Event ID: {EVENT.ID} 

Fill in the recovery message:
Recovery theme: OK. [{HOST.NAME}]
Recovery Message:

   "{EVENT.ID}"  . : {HOST.NAME}  : {HOST.DESCRIPTION}    : {EVENT.DATE} {EVENT.TIME}    : {EVENT.RECOVERY.DATE} {EVENT.RECOVERY.TIME}   : {TRIGGER.NAME} : {TRIGGER.SEVERITY}  :  : 1. {ITEM.NAME1} = {ITEM.VALUE1}. : {ITEM.KEY1} 2. {ITEM.NAME2} = {ITEM.VALUE2}. : {ITEM.KEY2} URL: {TRIGGER.URL} Event ID: {EVENT.ID} 

Enable "Activate"

Go to the tab "Conditions" and fill in as shown below:


I have indicated only “Extreme” problems for example. Conditions you can set what your heart desires.

Go to the tab “Operations” and add either our group of users, or specify only ourselves. Here, in principle, nothing to comment.


Now I simulate a crash. For example, I have all the attributes in order, so I will change the value in the trigger and put "more than zero"

 ({SMART:HDD.value.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()}-{SMART:HDD.thresh.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()})>0 

I think it is not necessary to explain arithmetic.

We wait for some time and get the problem:


And after a couple of seconds, a message arrives in the mail:


After recovery, we will receive the following message:


If there are mistakes, or something can be done easier, please report! I wrote a topic for a couple of hours with screenshots, it seems I checked it twice successfully.

Download ready template

PS: Especially fire when zabbix sends a message to the supplier asking to bill the new disk or, for example, when the toner in the printer runs out, throws a support ticket for the cartridge refilling, but that's another story ...

Source: https://habr.com/ru/post/309172/


All Articles