Finding a certificate expiry time

We could find out the certificate expiry time with an openssl command such as this:

$ echo | openssl s_client -connect www.google.com:443 2>/dev/null | openssl x509 -noout -enddate  

Feel free to use any other domain for testing here and later.

We're closing  stdin for the openssl command with echo and passing the retrieved certificate information to another openssl command, x509, to return the date and time when the certificate will expire:

notAfter=Jan 30 08:59:00 2019 GMT 

The resulting string isn't something we could easily parse in Zabbix, though. We could convert it into a UNIX timestamp like this:

$ date -d "$(echo | openssl s_client -connect www.google.com:443 2>/dev/null | openssl x509 -noout -enddate | sed 's/^notAfter=//')" "+%s"  

We're stripping the non-date part with sed and then formatting the date and time as a UNIX timestamp with the date utility:

1546425338

Looks like we have the command ready, but where would we place it? For external checks, a special directory is used. Open zabbix_server.conf and look for the ExternalScripts option. You might see either a specific path or a placeholder:

# ExternalScripts=${datadir}/zabbix/externalscripts

If it's a specific path, that's easy. If it's a placeholder such as the preceding, it references the compile-time data directory. Note that it's not a variable. When compiling from the sources, the ${datadir} path defaults to /usr/local/share/. If you installed from packages, it's likely to be /usr/lib/. In any case, there should be a zabbix/externalscripts/ subdirectory in there. This is where our external check script will have to go. Create a script, zbx_certificate_expiry_time.sh, there with the following contents:

#!/bin/bash
date -d "$(echo | openssl s_client -connect "$1":443 2>/dev/null | openssl x509 -noout -enddate | sed 's/^notAfter=//')" "+%s"

Notice how we replaced the actual website address with a $1 placeholderthis allows us to specify the domain to check as a parameter to this script. Make that file executable:

$ chmod 755 zbx_certificate_expiry_time.sh
$ chown zabbix:zabbix zbx_certificate_expiry_time.sh

And now, for a quick test, type the following:

$ ./zbx_certificate_expiry_time.sh www.google.com
1548838740 

Great, we can pass the domain name to the script and get back the time when the certificate for that domain expires. Now, on to placing this information in Zabbix.

In the frontend, go to Configuration | Hosts, click on Items next to A test host, and click on Create item. Fill in the following:

  • Name: Certificate expiry time on $1
  • Type: External check
  • Key: zbx_certificate_expiry_time.sh[www.google.com]
  • Units: unixtime

We specified the domain to check as a key parameter, and it'll be passed to the script as the first positional parameter, which we then use in the script as $1. If more than one parameter is needed, we would comma-delimit them, the same as for any other item type. The parameters would be properly passed to the script as $1, $2, and so on. If we need no parameters, we would use empty square brackets [], or just leave them off completely. If we wanted to act upon the host information instead of hardcoding the value like we did, we could use some macro; for example, {HOST.HOST}, {HOST.IP}, and {HOST.DNS} are common values. Another useful macro here would be {HOST.CONN}, which would resolve either to the IP or DNS, depending on which one is selected in the interface properties.

When done, click on the Add button at the bottom. Now, check this item in the Latest data page:

The expiry time seems to be collected correctly and the unixtime unit converted the value into a human-readable version. What about a trigger on this item? The easiest solution might be with the fuzzytime() function again. Let's say we want to detect a certificate that will expire in seven days or less. The trigger expression would be as follows:

{A test host:zbx_certificate_expiry_time.sh[www.zabbix.com].fuzzytime(604800)}=0 

The huge value in the trigger function parameters, 604800, is seven days in seconds. Can we make it more readable? Sure we canthis would be exactly the same:

{A test host:zbx_certificate_expiry_time.sh[www.google.com].fuzzytime(7d)}=0 

The trigger would alert with one week left and, from the item values, we could see exactly how much time exactly is left. We discussed triggers in more detail in Chapter 6, Detecting Problems with Triggers.

We're conveniently ignoring the fact that the certificate might not be valid yet. While our trigger would fire if the certificate wasn't valid for a week or more, it would ignore certificates that would only become valid in less than a week.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.171.253