Skip to main content

You are here


Nagios SSL Certificate Expiration Check

So, a while back I demonstrated a way to to set up an automated SSL certificate expiration monitoring solution.
Well, it turns out the check_http Nagios plugin has built-in support to monitor SSL certificate expiration as well. This is accompished using the -C / --certificate options.

Example check on a local expired Let's Encrypt Certificate:

[[email protected] plugins]# ./check_http -t 10 -H -I -C 10
SSL CRITICAL - Certificate '' expired on 2018-07-25 18:39 -0700/PDT.

check_http help doc:

-C, --certificate=INTEGER[,INTEGER]
    Minimum number of days a certificate has to be valid. Port defaults to 443
    (when this option is used the URL is not checked.)

CHECK CERTIFICATE: check_http -H -C 30,14

 When the certificate of '' is valid for more than 30 days,
 a STATE_OK is returned. When the certificate is still valid, but for less than
 30 days, but more than 14 days, a STATE_WARNING is returned.
 A STATE_CRITICAL will be returned when certificate expires in less than 14 days

Awesome Applications: 

Ah Shit - check_http string

After updating the themes of,, I completely forgot to also update the header template files to include once again their respective Google Analytics tracking code. This resulting in almost three months of no stats. When I originally setup the Nagios check_http 's on my sites, I didn't set them to also search for the custom Google Analytics string, which I always use this configuration at work on all http checks.

This can easily be accomplish using the -s|--string option of the check_http plugin.

/usr/local/nagios/libexec/check_http -I -S -t 10 --string UA-12912270-3

So the lesson learned, you should always configure your check_http Nagios service checks to also search for a custom string as part of the check!

Awesome Applications: 

Monitoring TFTPd server

So I just spent the last two hours of my life trying to figure why PXE booting was not working in my home network. Turned out the root cause was my fault completely since, I forgot to add a firewall rule on my dhcp/PXE server to allow incoming UDP connections on port 69.


iptables -A INPUT -p udp -m udp --dport 69 -j ACCEPT

As with just about any other service, this service can be monitored using Nagios. Originally, I had problems using the and check_tftp plugins that are available from on Nagios Exchange repo, mainly because of the way I have setup my machines.

check_tftp This plugin was useless in my environment because this plugin all it does is send out an status command to the TFTP server. Since I'm using the BSD tftp client, all status commands sent to any host will always show up as being connected regardless. This plugin was not opted to work in my environment. Mainly because it uses Net::TFTP, unlike the tftp client application, Net::TFTP does not support specifying a custom reverse connection port (or port ranges). By default, when connecting to a TFTP server, the TFTP server will dynamically choose a random non-standard port to connect back to the client machine and proceed with the TFTP download. My Nagios machine (like all of my machines) are set to drop all incoming packets except for specific ports and related/established connections.

I wrote a simple Nagios plugin that monitors TFTP. All it simply does, is download a non-empty file called test.txt.

#!/usr/bin/perl -w

# Tony Baltazar. root[@]

use strict;
use Getopt::Long;

my %options;
GetOptions(\%options, "host|H:s", "port|p:i", "rport|R:s", "file|f:s", "help");

if ($options{help}) {
	exit 0;
} elsif ($options{host} && $options{port} && $options{file}) {

	my $cmd_str = ( $options{rport} ?  "/usr/bin/tftp -R $options{rport}:$options{rport} $options{host} $options{port} -c get $options{file}" : "/usr/bin/tftp $options{host} $options{port} -c get $options{file}");

	my $cmd = `$cmd_str`;
	if ($? != 0) {
		print "CRITICAL: $cmd";
		system("rm -f /tmp/$options{file}");
		exit 2;
	} else {
		if (! -z "/tmp/$options{file}" ) {
			print "TFTP is ok.\n$cmd";
			exit 0;
		} else {
			print "WARNING: $cmd";
			exit 1;

} else {

sub usage {
print < --port= --file=]

   --host | -H  : TFTP server.
   --port | -p  : TFTP Port.
   --file | -m  : Test file that will be downloaded.
   --help | -h  : This help message.

   --rport | -R : Explicitly force the reverse originating connection's port.


Seeing the plugin in action:
Assuming, we're using port udp 1069 to allow the TFTP server ( to connect to the Nagios monitoring machine.

[[email protected] libexec]# iptables -L -n |grep "Chain INPUT"
Chain INPUT (policy DROP)
[[email protected] libexec]# iptables-save|grep 1069
-A INPUT -s -p udp -m udp --dport 1069 -j ACCEPT

Firewall not allowing TFTP to connect back using port 1066.

[[email protected] libexec]# su - nagios -c '/usr/local/nagios/libexec/ -H -p 69 -R 1066 -f test.txt'
CRITICAL: Transfer timed out.

Downloading a non-existing file from the TFTP server.

[[email protected] tmp]# su - nagios -c '/usr/local/nagios/libexec/ -H -p 69 -R 1069 -f test.txtFAKESHIT'
WARNING: Error code 1: File not found

Successful connection and transfer.

TFTP is ok.


Awesome Applications: 

ZFS on Linux: Nagios check_zfs plugin

To monitor my ZFS pool, of course I'm using Nagios, duh. Nagios Exchange provide a check_zfs plugin written in Perl.

Although the plugin was originally designed for Solaris and FreeBSD systems, I got it to work under my Linux system with very little modification. The code can be found on my SysAdmin-Scripts git repo on GitHub

[[email protected] ~]# su - nagios -c "/usr/local/nagios/libexec/check_zfs backups 3"
OK ZPOOL backups : ONLINE {Size:464G Used:11.1G Avail:453G Cap:2%}


Awesome Applications: 

Installing the Nagios Service Check Acceptor

One of the cool things that Nagios supports is the ability to do passive checks. That is instead of Nagios actively checking a client machine for errors, the client is able to send error notifications to Nagios. This can be accomplished using the Nagios Service Check Acceptor.

Installing plugin is a straight forward process. The following steps were the ones I made to get it working under CentOS 6 (Nagios server) and CentOS 5 (client).

Install dependencies:

yum install libmcrypt libmcrypt-devel

Download latest stable version (I tend to stick with stable versions, unless it's absolutely necessary to run development versions), configure and compile.

tar -xvf nsca-2.7.2.tar.gz
cd nsca-2.7.2
*** Configuration summary for nsca 2.7.2 07-03-2007 ***:

General Options:
NSCA port: 5667
NSCA user: nagios
NSCA group: nagios

make all

Copy xinet.d sample config file and nsca.cfg file.

cp sample-config/nsca.cfg /usr/local/nagios/etc/
cp sample-config/nsca.xinetd /etc/xinetd.d/nsca

Update /etc/xinetd.d/nsca.xinetd/nsca (where is the client IP that will be passively checked)

# default: on
	# description: NSCA
	service nsca
        	flags           = REUSE
	        socket_type     = stream        
        	wait            = no
	        user            = nagios
		group		= nagcmd
        	server          = /usr/local/nagios/bin/nsca
	        server_args     = -c /usr/local/nagios/etc/nsca.cfg --inetd
        	log_on_failure  += USERID
	        disable         = no
		only_from       =

Restart xinet.d

service xinetd restart

Verify that it's running

netstat -anp|grep 5667
tcp 0 0 :::5667 :::* LISTEN 30008/xinetd

Add firewall rule

iptables -A INPUT -p tcp -m tcp --dport 5667 -s -j ACCEPT

Set password and update decryption type in /usr/local/nagios/etc/nsca.cfg

Finally, update the permissions so no one can read the password.

chmod 400 /usr/local/nagios/etc/nsca.cfg
chown nagios.nagios /usr/local/nagios/etc/nsca.cfg

Now lets configure the client machine. The same dependencies also need to be installed on the client system. I also went ahead and download and compiled nsca. (In theory I could of just copied over the send_nsca binary that was compiled on the Nagios server since both are x64 Linux systems).
Once compiled, copy the send_nsca binary and update its permissions.

cp src/send_nsca /usr/local/nagios/bin/
chown nagios.nagios /usr/local/nagios/bin/send_nsca
chmod 4710 /usr/local/nagios/bin/send_nsca

Copy the sample send_nsca.cfg config file and update the encryption settings, this must match those as the nsca server

cp sample-config/send_nsca.cfg /usr/local/nagios/etc/


chown nagios.nagios /usr/local/nagios/etc/send_nsca.cfg
chmod 400 /usr/local/nagios/etc/send_nsca.cfg

Now you can use the following test script to test the settings.

CMD="rubyninja;test;3;UNKNOWN - just an nsca test"
/bin/echo $CMD| /usr/local/nagios/bin/send_nsca -H $nagiosserveriphere -d ';' -c $CFG

In my case:

[[email protected] ~]# su - nagios -c 'bash /usr/local/nagios/libexec/test_nsca'
1 data packet(s) sent to host successfully.

Server successfully received the passive check.

Feb 22 20:46:39 monitor nagios: Warning:  Passive check result was received for service 'test' on host 'rubyninja', but the service could not be found!

Last words, the only problem I ran into was having xinetd load the newly available nsca properly.

xinetd[3499]: Started working: 0 available services
nsca[3615]: Handling the connection...
nsca[3615]: Could not send init packet to client

Fix: The was because the sample nsca.xinetd file had the nagios as the group setting. I simply had to update it to 'nagcmd'.
I suspect this is because of the permissions set on the Nagios command file nagios.cmd, which is the interface for the external commands sent to the Nagios server.


Awesome Applications: 

Custom Nagios mdadm monitoring: check_mdadm-raid

Simple Nagios mdadm monitoring plugin.

#!/usr/bin/env ruby

# Tony Baltazar. root[@]

OK = 0

# Note to self, mdadm exit status:
#0 The array is functioning normally.
#1 The array has at least one failed device.
#2 The array has multiple failed devices such that it is unusable.
#4 There was an error while trying to get information about the device.

raid_device = '/dev/md0'

get_raid_output = %x[sudo mdadm --detail #{raid_device}].lines.to_a

get_raid_status = get_raid_output.grep(/\sState\s:\s/).to_s.match(/:\s(.*)\\n\"\]/)
raid_state = get_raid_status[1].strip

if raid_state.empty?
 print "Unable to get RAID status!"

if /^(clean(, checking)?|active)$/.match(raid_state) 
 print "RAID OK: #{raid_state}"
 exit OK
elsif /degraded/i.match(raid_state)
 print "WARNING RAID: #{raid_state}"
elsif /fail/i.match(raid_state)
 print "CRITICAL RAID: #{raid_state}"
 print "UNKNOWN RAID detected: #{raid_state}"


Awesome Applications: 

Monitoring computer's temperature with lm_sensors



Installing lm-sersors in Ubuntu Server 12.04 is really simple.

sudo apt-get install libsensors4 libsensors4-dev lm-sensors


[email protected]:~$ sudo sensors-detect
# System: Apple Inc. Macmini5,1
# Board: Apple Inc. Mac-8ED6AF5B48C039E1

This program will help you determine which kernel modules you need
to load to use lm_sensors most effectively. It is generally safe
and recommended to accept the default answers to all questions,
unless you know what you're doing.

Some south bridges, CPUs or memory controllers contain embedded sensors.


# Chip drivers



Monitoring programs won't work until the needed modules are
to load them.

Unloading i2c-dev... OK
Unloading i2c-i801... OK
Unloading cpuid... OK

module-init-tools stop/waiting
[email protected]:~$


[email protected]:~$ sensors
Adapter: ISA adapter

Adapter: ISA adapter
Exhaust : 1801 RPM (min = 1800 RPM)
TA0P: +36.0°C
TA0p: +36.0°C
TA1P: +34.8°C
TA1p: +34.8°C
TC0C: +47.0°C
TC0D: +44.8°C
TC0E: +57.5°C
TC0F: +58.5°C
TC0G: +94.0°C
TC0J: +0.8°C
TC0P: +42.5°C
TC0c: +47.0°C
TC0d: +44.8°C
TC0p: +42.5°C
TC1C: +50.0°C
TC1c: +50.0°C
TCFC: +0.2°C
TCGC: +49.0°C
TCGc: +49.0°C
TCPG: +98.0°C
TCSC: +50.0°C
TCSc: +50.0°C
TCTD: +255.5°C
TCXC: +49.5°C


#!/usr/bin/env perl
use strict;
# Tony Baltazar. root[@]

use constant OK => 0;
use constant WARNING => 1;
use constant CRITICAL => 2;
use constant UNKNOWN => 3;


# Sample output

my $counter = 0;
my $output_string;

for my $heat_usage_per_core (@get_current_heat) {
	my $core = $1;
	my $temp = $2;
	if ($temp < $THRESHOLDS{OK}) {

if ($counter == 3 ) {
	print $output_string;
} else {



Awesome Applications: 

Monitoring DHCP server with check_dhcp



To set the setuid permissions, use the command:
chmod u+s yourpluginfile


chown root.root check_dhcp
chmod u+s check_dhcp




Awesome Applications: 

Writing custom Nagios plugins: check_public-ip





ip=`curl -connect-timeout 30 -s`

                echo "IP service monitoring is unavailable."
                exit $STATE_WARNING
                exit $STATE_CRITICAL
                echo "Unknown state detected."
                exit $STATE_UNKNOWN

        echo "Public OK: $ip"
        exit $STATE_OK


Awesome Applications: 

Cron monitoring plugin for Nagios



case "${CRON_CHECK}" in


Awesome Applications: 


Premium Drupal Themes by Adaptivethemes