Monitor For Expiring SSL/TLS Certs with Nagios

Monitor For Expiring SSL/TLS Certs with Nagios

We’ve all been there. Your SSL/TLS certificate on your webserver, mail server, or <insert service name here> has expired and your users are miffed!!! Expiring SSL/TLS certificates have been a problem as long as I can remember and that was at a point when SSL certs could last for several years. Now we have Let’s Encrypt (@letsencrypt) in the fray of SSL/TLS certs and their certs only last a maximum of 90 days. Do you really think expiring certs won’t continue to be a problem as more of us use their certificates? By the way, that last comment is in no way meant as a knock on Let’s Encrypt. I personally love Let’s Encrypt and would love to see everyone use them if they don’t need additional features found in higher end certs — extended or organization validation. The Let’s Encrypt folks also have a nice little write-up here on why the 90-day limitation is in place for those curious.

22May2018 – Originally posted
20July2018 – Added countdown restart image
27July2018 – Changed download to latest release Github one-liner

The point of the conversation is that while Let’s Encrypt certs *should* automagically refresh every 90 days and/or we *should* recognize expiring certs ahead of time, there is a time and a place where something fails and they don’t. And I’ve personally been on the receiving end of both scenarios… Hence, this plugin recommendation. 😉 Fortunately, if you have Nagios or Nagios XI, you can monitor the expiration of SSL/TLS certs rather easily.

Setup the plugin

First, the built-in check_http script provided with Nagios and Nagios XI can check for expiring certs on non-http ports. For example, the command below works just fine and it even has server name indication (SNI) support.

./check_http -H --ssl -p465 --sni -C 90,14
 WARNING - Certificate '' expires in 88 day(s) (Mon 13 Aug 2018 05:03:00 PM CDT).

I use a different plugin for a number of reasons. First, the check_http doesn’t provide graphing for “days until expiration” which I think would be helpful in troubleshooting. What I mean by that is the cert expiration *should* decrement one day at a time unless someone applied the wrong cert to a service. Second, the check_ssl_cert plugin has the capability to check against SSL Labs, which is way cool and something I’ll talk about more in depth at a different time. Third, the default command for the check_http check in Nagios XI uses the “-I” instead of the “-H” which provides some unexpected results as shown below. Yes, I know I could change the commands.cfg to reflect that change, but I don’t want a future upgrade to potentially break it.

# ./check_http -I -C 90,14 -p993 --sni
 OK - Certificate '*' will expire on Thu 09 May 2019 09:29:00 AM CDT.
# ./check_http -H -C 90,14 -p993 --sni
 WARNING - Certificate '' expires in 88 day(s) (Mon 13 Aug 2018 05:03:00 PM CDT).

So, without further ado, the check_ssl_cert plugin (and release notes) may be found on the following page — The author has a donation page there as well so please donate to him if you use this plugin in your production environment. The author updates the plugin on a regular basis, however, the commands below should work regardless of future updates.

To download the plugin, first change directory to /tmp on your Nagios box and then run the following curl, cut, tr, wget “one-liner” from the command line. Yes, copy/paste that entire command in the gray box.

cd /tmp
curl -s \
| grep "browser_download_url.*bz2" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi -

Next, we’ll extract the files from the archive and move it to the main Nagios plugins directory.

tar jxf check_ssl_cert-*.tar.bz2
mv /tmp/check_ssl_cert-*/check_ssl_cert /usr/local/nagios/libexec

Change directory to the Nagios plugins directory and modify the user/group.

cd /usr/local/nagios/libexec/
chown apache:nagios check_ssl_cert

Last, verify the file is there and the permissions are correct.

ls -l check_ssl*
-- Output --
-rwxr-xr-x 1 apache nagios 75011 Apr 29 11:37 check_ssl_cert

Testing the plugin from the command line

Now, let’s test the plugin. To run it against on port 443, type the command below. The ‘-w’ means Nagios will provide a warning if the certificate expires in less than 4 days and a critical if the expiration is less than 2 days. If you receive a message similar to the one below, congrats! So far, so good!

./check_ssl_cert -H -p 443 -w 4 -c 2
-- Output --
SSL_CERT OK - x509 certificate '*' from 'Google Internet Authority G3' valid until Jul 17 09:27:00 2018 GMT (expires in 61 days)|days=61;4;2;;

If you are using a shared hosting server, you must use the “sni” argument as shown below. Note: If you don’t specify an SNI option and you use a shared hosting server, you will end up checking the wrong server! You’ve been warned!

./check_ssl_cert -H -p 443 --sni -w 4 -c 2
-- Output -- 
SSL_CERT OK - x509 certificate '' from 'Let's Encrypt Authority X3' valid until Aug 13 16:03:04 2018 GMT (expires in 88 days)|days=88;4;2;;

If that output is a little too verbose, you can also add the “–terse” to the end so it cuts down on the output. Without the terse switch, your Nagios output will undoubtedly end up on a second line within the Nagios web interface.

./check_ssl_cert -H -p 443 --sni -w 4 -c 2 --terse
-- Output -- 
SSL_CERT OK (expires in 87 days)|days=87;4;2;;

If you want to monitor SSL/TLS certificates on other ports such as IMAP (993), POP (995), or SMTP (465), the syntax is identical to the example above. I monitor each service separately because even though the various services share the same certificate, is possible (and highly likely) for the services to have different configuration files that point to different certificates, i.e. one might get updated and another doesn’t.

./check_ssl_cert -H -p 993 --sni -w 4 -c 2
-- Output -- 
SSL_CERT OK - x509 certificate '' from 'Let's Encrypt Authority X3' valid until Aug 13 16:03:04 2018 GMT (expires in 88 days)|days=88;4;2;;

Adding command in Nagios XI

Before we create service, we first need to add the command if this is your first time using check_ssl_cert. So go to Configure -> Core Config Manager -> Commands (in the left hand pane) and then click “Add New.”

Add Nagios XI Command

-- Command Name --
-- Command Line --
$USER1$/check_ssl_cert -H $HOSTADDRESS$ $ARG1$

Make the changes seen in the picture above. I use the plugin name for the command name to avoid confusion. The “command line” and “command name” can be copied and pasted to avoid typos. Don’t forget to hit ‘Save’ at the bottom. When you are taken back to the “Commands” screen, also click on “Apply Configuration.”

Adding the service in Nagios XI

I tend to create either an HTTP check or even just a generic network device (ping) so I have a host to work with. From there, you can just copy the service in the Core Config Manager. If you copied an existing service for the same host, simply change the config and description name and put a check in “active.” Then, select the newly created check_ssl_cert command from the dropdown and add the following into the $ARG1$ field. If you don’t need SNI, omit the “–sni” and the hostname following it. Don’t forget if you need a different port such as IMAPS (993), you can change it here as previously seen when testing from the command line.

-p 443 --sni -w 4 -c 2 --terse


Check SSL Cert Service in Nagios XI

Before you exit the service management area, I would also changr the “check interval” to something more reasonable via the “check settings” tab (below). Your certificate expiration shouldn’t change every 5 minutes so there really isn’t a need to check it every 5 minutes. You could wait a full day (1440 minutes), but I personally check every half a day, i.e. 720. Granted, “extra” SSL checks aren’t going to cause high loads on your server, but they are unnecessary nonetheless. After making your changes, don’t forget to hit “Save” followed by “Apply Configuration” on the “Services” page.

Nagios XI check interval

Final view in Nagios

Here is a host where I’m monitoring SSL/TLS cert expirations for numerous services — HTTP, IMAP, POP, and SMTP. The graph below that is the cert expiration going down one day at a time… Here’s to no more expired certs!

SSL & TLS Certificate Checks in Nagios XI
SSL & TLS Certificate Checks in Nagios XI
SSL Cert Expiration - One Day At A Time
SSL/TLS Cert Expiration in Nagios – One Day At A Time
SSL TLS expiration countdown in Nagios
SSL/TLS Cert Expiration in Nagios – Countdown restart

9 thoughts on “Monitor For Expiring SSL/TLS Certs with Nagios

  1. hi man … i need some help with snmpd checking … where ca i find the MIBs for switches… hp and 3com… i will thank any help

  2. Hi how can this be applied using the services.cfg file? I tried:
    define service {
    use generic-service
    host_name host
    service_description SSL
    check_command check_ssl_cert


    1. Can you successfully run it from the command line? For Core (and graphically on XI), don’t forget that you would need to add it to the commands.cfg. Good luck!

      define command{
      command_name check_ssl_cert
      command_line $USER1$/check_ssl_cert -H $HOSTADDRESS$ $ARG1$
      define service{
      use generic-service
      service_description SSL
      check_command check_ssl_cert!-H
      -p –sni -w 4 -c 2 –terse
      notifications_enabled 1

  3. Hi,
    Is there a Nagios XI built in check or Nagios plugin that allows me to check certificate expiry dates from the certificate stores on my domain servers?

  4. hi men, I have downloaded the plugin and tried to use it against my website but it throws me an error when delivering the information, the error that appears is:

    ./check_ssl_cert -H -p 443
    SSL_CERT CRITICAL No certificate returned

    Do you have any idea why I can’t extract the information?

    1. Hey Ismael! Not accounting for the www re-direct tends to be the most common issue. That said, I tested against www and the primary domain and both worked for me which means there might be something else going on with Nagios. Hope that helps!
      # ./check_ssl_cert -H -p 443
      SSL_CERT OK – x509 certificate ‘*’ ( from ‘DigiCert SHA2 Secure Server CA’ valid until Aug 5 12:00:00 2022 GMT (expires in 421 days)|days_chain_elem1=421;20;15;; days_chain_elem2=636;20;15;;
      # ./check_ssl_cert -H -p 443
      SSL_CERT OK – x509 certificate ‘*’ ( from ‘DigiCert SHA2 Secure Server CA’ valid until Aug 5 12:00:00 2022 GMT (expires in 421 days)|days_chain_elem1=421;20;15;; days_chain_elem2=636;20;15;;

Leave a Reply

Your email address will not be published. Required fields are marked *