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 linuxincluded.com --ssl -p465 --sni -C 90,14 WARNING - Certificate 'linuxincluded.com' 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 linuxincluded.com -C 90,14 -p993 --sni OK - Certificate '*.sgcpanel.com' will expire on Thu 09 May 2019 09:29:00 AM CDT. # ./check_http -H linuxincluded.com -C 90,14 -p993 --sni WARNING - Certificate 'linuxincluded.com' 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 — https://github.com/matteocorti/check_ssl_cert/releases. 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 https://api.github.com/repos/matteocorti/check_ssl_cert/releases/latest \ | 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 google.com 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 google.com -p 443 -w 4 -c 2 -- Output -- SSL_CERT OK - x509 certificate '*.google.com' 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 linuxincluded.com -p 443 --sni linuxincluded.com -w 4 -c 2 -- Output -- SSL_CERT OK - x509 certificate 'linuxincluded.com' 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 linuxincluded.com -p 443 --sni linuxincluded.com -w 4 -c 2 --terse -- Output -- SSL_CERT OK linuxincluded.com (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 linuxincluded.com -p 993 --sni linuxincluded.com -w 4 -c 2 -- Output -- SSL_CERT OK - x509 certificate 'linuxincluded.com' 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.”
-- Command Name -- check_ssl_cert -- 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.
$ARG1$ -p 443 --sni linuxincluded.com -w 4 -c 2 --terse
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.
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!
Dallas Haselhorst has worked as an IT and information security consultant for over 20 years. During that time, he has owned his own businesses and worked with companies in numerous industries. Dallas holds several industry certifications and when not working or tinkering in tech, he may be found attempting to mold his daughters into card carrying nerds and organizing BSidesKC.