I usually use remote active checks by executing SNMP queries or SSH commands. But there are systems and values that cannot be monitored this way.

The passive checks have allowed me to check anything that I cannot check remotely via SNMP or SSH. But I did not want any agent (NSC++, NPA…) installed on the monitored system. That problem can also be avoided.

Contents

Enable passive checks in Nagios

From the official doc:

In order to enable passive checks in Nagios, you'll need to do the following:

If you want to disable processing of passive checks on a global basis, set the accept_passive_service_checks directive to 0.
If you would like to disable passive checks for just a few hosts or services, use the passive_checks_enabled directive in the host and/or service definitions to do so.

Or if you use Centreon like me:

Configuration / Nagios / nagios.cfg / Checks options

Nagios Centreon Enable Passive Checks


And in the host/service definition:

Nagios Centreon Enable Service Passive Checks

Passive check results format and procedure

Again from the official doc:

External applications can submit passive service check results to Nagios by writing a PROCESS_SERVICE_CHECK_RESULT external command to the external command file.
The format of the command is as follows:

[] PROCESS_SERVICE_CHECK_RESULT;<host_name>;<svc_description>;<return_code>;<plugin_output>

where…

  • timestamp is the time in time_t format (seconds since the UNIX epoch) that the service check was perfomed (or submitted). Please note the single space after the right bracket.
  • host_name is the short name of the host associated with the service in the service definition
  • svc_description is the description of the service as specified in the service definition
  • return_code is the return code of the check (0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN)
  • plugin_output is the text output of the service check (i.e. the plugin output)

In my Centreon Nagios, the external is /var/lib/nagios3/rw/nagios.cmd. So, to send PROCESS_SERVICE_CHECK_RESULT command manually to my TESTSERVICE service:

# echo "[`date +%s`] PROCESS_SERVICE_CHECK_RESULT;TESTHOST;TESTSERVICE;1;This is my warning message" >> /var/lib/nagios3/rw/nagios.cmd
Nagios Centreon WARNING Result Passive Check
# echo "[`date +%s`] PROCESS_SERVICE_CHECK_RESULT;TESTHOST;TESTSERVICE;2;This is my critical message" >> /var/lib/nagios3/rw/nagios.cmd
Nagios Centreon CRITICAL Result Passive Check
# echo "[`date +%s`] PROCESS_SERVICE_CHECK_RESULT;TESTHOST;TESTSERVICE;3;This is my unknown message" >> /var/lib/nagios3/rw/nagios.cmd
Nagios Centreon UNKNOWN Result Passive Check
# echo "[`date +%s`] PROCESS_SERVICE_CHECK_RESULT;TESTHOST;TESTSERVICE;0;This is my OK message" >> /var/lib/nagios3/rw/nagios.cmd
Nagios Centreon OK Result Passive Check

Ok, we have performed a passive check by writing to the external command file. And we have been able to do it because we are executing the command locally on the Nagios host. But our target is sending passive checks results remotely!

Configure service to receive passive checks results

One of the simplest ways to achieve this is explained in my previous post (Linux – Create custom inetd service).

That newly configured service could use this simple script:

#!/bin/bash

read MESSAGE
echo $MESSAGE >> /var/lib/nagios3/rw/nagios.cmd

If you have followed the steps explained on that previous post, now you should be able to send passive checks results remotely.

Configuring script to send passive checks results on the monitored host

Now, sending a message over a TCP connection is an easy task using any scripting or programming language.

For example, using Powershell I am going to configure a useless scripts that monitors the number of files in a folder.

  • Less than 5 = OK.
  • Between 5 and 8 = Warning
  • More than 8 = Critical

Analyze the status of our target

A section of the script will analyze the status of the parameters, services or targets of the monitored host:

$FOLDER = Get-ChildItem ("D:\SCRIPTS\NAGIOS\NUMBERFILES\MONITOREDFOLDER")
$NUM = $FOLDER.Count

If ($NUM -lt 5)
{
    Write-Host "OK: $NUM files"    
}
ElseIf ($NUM -gt 8)
{
    Write-Host "CRITICAL: $NUM files"
}
Else
{
    Write-Host "WARNING: $NUM files"
}
Powershell count files

Generate the passive check message

$FOLDER = Get-ChildItem ("D:\SCRIPTS\NAGIOS\NUMBERFILES\MONITOREDFOLDER")
$NUM = $FOLDER.Count

$DATETIMESTAMP = "{0:G}" -f [int][double]::Parse((Get-Date -UFormat %s))

If ($NUM -lt 5)
{
    Write-Host "[$DATETIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;SERVER1;NUMFILES;0;OK: $NUM files"    
}
ElseIf ($NUM -gt 8)
{
    Write-Host "[$DATETIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;SERVER1;NUMFILES;2;CRITICAL: $NUM files"    
}
Else
{
    Write-Host "[$DATETIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;SERVER1;NUMFILES;1;WARNING: $NUM files"    
}

Note the sentence used to generate the timestamp

Send the passive check result to the Nagios server

To send the result we can use the netcat tool simply copying it in a folder to refer to it on the script.

Nagios Netcat


Supposing we configured the service that receives the passive checks results for example on the 3333 port:

$FOLDER = Get-ChildItem ("D:\SCRIPTS\NAGIOS\NUMBERFILES\MONITOREDFOLDER")
$NUM = $FOLDER.Count

$DATETIMESTAMP = "{0:G}" -f [int][double]::Parse((Get-Date -UFormat %s))

If ($NUM -lt 5)
{
    $MSG = "[$DATETIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;SERVER1;NUMFILES;0;OK: $NUM files"    
}
ElseIf ($NUM -gt 8)
{
    $MSG = "[$DATETIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;SERVER1;NUMFILES;2;CRITICAL: $NUM files"    
}
Else
{
    $MSG = "[$DATETIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;SERVER1;NUMFILES;1;WARNING: $NUM files"    
}

$MSG | D:\SCRIPTS\NAGIOS\nc.exe NAGIOS_SERVER 3333

And it is done! Now we have our Nagios server configured to receive passive checks remotely and our monitored system to send the results.

To monitor it simply task-schedule the script to be executed every some minutes!