selivan / https-ssl-cert-check-zabbix Goto Github PK
View Code? Open in Web Editor NEWScript to check validity and expiration of TLS/SSL certificate on hosts. May be used with Zabbix or standalone.
License: Other
Script to check validity and expiration of TLS/SSL certificate on hosts. May be used with Zabbix or standalone.
License: Other
Hi! Thank you for this script! It's exactly what I searched for. But it keeps to show the error at random time in my situation when I try to check validity of monitored service's SSL certificate. The errors looks like this:
./ssl_cert_check.sh: line 85: [[: 0 0 0: syntax error in expression (error token is "0 0") 0
I would like to check it without the script if needed, but I can't give an access to that service, because it's internal. Anyway, thank you.
Hello!
I modyfied your script ssl_cert_check.sh. Added:
# Convert Russian domains for example яндекс.рф to xn--d1acpjx3f.xn--p1ai (Punycode)
# If domain in English it return English domain
# You should install idn (apt install idn)
# Convert variables host and domain
host=`echo "$host" | idn`
domain=`echo "$domain" | idn`
Now it works fine!
Full script attached!
Hello. What are the variables $1-4 in userparams for? Thanks.
line 58: syntax error: unexpected "("
openssl version
says: OpenSSL 1.1.1f 31 Mar 2020
Operating System: Ubuntu Server 20.04
root@zabbix:~# ./ssl_cert_check.sh expire xxxxxx.com
82
root@zabbix:~# ./ssl_cert_check.sh expire xxxxxx.com
./ssl_cert_check.sh: line 91: type: idn: not found
82
Hello,
When doing validate
it always returns 0—expire
seems to be working fine. Even on google.com, etc. I've debugged with bash -x
and the return code is 20:
Verify return code: 20 (unable to get local issuer certificate)
Full log here: https://pastebin.com/AssESEf3
Any suggestion on what might I be doing wrong? Bug maybe?
Thank you in advance.
Here is a basic template.xml
file which can be used as an example for someone who'd like to use this project for Zabbix.
It basically checks whether the SSL Certificate on the machine with its DNS Hostname is valid or not, and whether or not it will soon expire.
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>5.0</version>
<date>2020-06-23T18:35:19Z</date>
<groups>
<group>
<name>SSL Cert Hostname 443 port</name>
</group>
<group>
<name>Templates</name>
</group>
</groups>
<templates>
<template>
<template>Template App SSL Certificate DNS Hostname 443</template>
<name>Template App SSL Certificate DNS Hostname 443</name>
<groups>
<group>
<name>SSL Cert Hostname 443 port</name>
</group>
<group>
<name>Templates</name>
</group>
</groups>
<applications>
<application>
<name>SSL</name>
</application>
</applications>
<items>
<item>
<name>SSL Certificate Expire</name>
<key>ssl_cert_check_expire[{HOST.DNS},443]</key>
<delay>900</delay>
<value_type>FLOAT</value_type>
<applications>
<application>
<name>SSL</name>
</application>
</applications>
<triggers>
<trigger>
<expression>{last()}<1</expression>
<name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
<priority>DISASTER</priority>
</trigger>
<trigger>
<expression>{last()}<5</expression>
<name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
<priority>HIGH</priority>
</trigger>
<trigger>
<expression>{last()}<10</expression>
<name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
<priority>AVERAGE</priority>
</trigger>
<trigger>
<expression>{last()}<20</expression>
<name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
<priority>WARNING</priority>
</trigger>
</triggers>
</item>
<item>
<name>SSL Certificate Valid</name>
<key>ssl_cert_check_valid[{HOST.DNS},443]</key>
<delay>900</delay>
<value_type>FLOAT</value_type>
<applications>
<application>
<name>SSL</name>
</application>
</applications>
<triggers>
<trigger>
<expression>{last()}=0</expression>
<name>SSL Certificate on {HOST.NAME} is not valid</name>
<priority>DISASTER</priority>
</trigger>
</triggers>
</item>
</items>
</template>
</templates>
</zabbix_export>
I guess this could be useful to some people.
openssl version
says: OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
Operating System: Ubuntu VERSION="22.04.4 LTS (Jammy Jellyfish)"
When starting up Zabbix-agent2 it should start up normally
/var/log/syslog prints
"zabbix_agent2[19344]: zabbix_agent2 [19344]: ERROR: cannot initialize user parameters: cannot register user parameter "ssl_cert_list[*],/bin/cat /etc/zabbix/zabbix_agentd.d/ssl_cert_list.json": duplicate user parameter"
Getting this error from log: discovery rule "ssl_cert_list" became not supported: Unsupported item key
My userparameters file is updated as per #42
Zabbix version 6.0.21
Greetings!
It appears your instructions are incomplete - it does not detail adding this as a template into Zabbix. Nor does it provide instruction on what the $1, $2, $3 and $4 mean in your userparameters example.
I encourage trying a little harder in getting this to work with Zabbix completely, with integrations to add hosts to monitor from within the web interface rather than the script.
It's a great script! Just very much incomplete when it comes to integration. I would hope a project like this being in the Zabbix website as a recommended and popular solution be made FOR Zabbix rather than have the "option" for Zabbix.
Hi again!
I found new error while checking corevalue.net domain.
*redirected*
$ ./ssl_cert_check.sh valid 62.216.162.10 443 corevalue.net
1
*redirected*
$ ./ssl_cert_check.sh valid 81.173.210.91 443 corevalue.net
1
*without redirect*
$ ./ssl_cert_check.sh valid 160.153.162.141 443 corevalue.net
./ssl_cert_check.sh: line 85: [: : integer expression expected
0
That site has it's own bad certificate, but user will be redirected to another site with valid certificate. I tried to check it with some online services, but that services doesn't show a problem because they are checking it after redirecting. Please, have a look.
For what exactly is the $3 needed here?
The zabbix expression for expire would be {my-server:ssl_cert_check_expire[example.com,443].last()}<10
openssl version
says:
OpenSSL 1.1.1 11 Sep 2018
Operating System: Ubuntu 18.04 (Zabbix)
When a certificate error occurs, using Zabbix UserParameter, we should get -65535 as the result in Zabbix
When a certificate error occurs, using Zabbix UserParameter, we get an unsupported item in Zabbix due to the stderr message.
As stated at https://www.zabbix.com/documentation/3.0/manual/config/items/userparameters, The return value of the command is standard output together with standard error.
. This means we need a way to run ssl_cert_check.sh
without errors on stderr breaking the code.
We need an extra flag for ssl_cert_check.sh
when used with Zabbix so that we don't cause unsupported item errors, but can still get a meaningful message when run manually.
Hello, this is not like a bug, but maybe it is possible to create, that in Macros you can specify domains witch needs to be monitored for SSL expireation since some people use 1 server and host 3-4 websites with SSL.
Thanks.
So there's a problem with one domain, I cannot share the domain but at the end, the exit code is 104. The error code at the end of the output with the openssl command is:
read:errno=104
The line i'm referencing:
The command still returns the output and can be parsed to get the expiration date. Of course it failes in the original script, since the if statement is checking that the exit code is 0 and the output is not saved. I have no idea if it's connected to the domain or maybe internal firewall rules.
I was thinking of checking if the string is (not empty) and ( exit code is 0 or 104)
When I run the script with no parameters, it spits out a bash error before the usage text:
./ssl_cert_check.sh: line 14: ,: command not found
e.g.
[root@XXXX ~/https-ssl-cert-check-zabbix]# ./ssl_cert_check.sh
-65535
./ssl_cert_check.sh: line 14: ,: command not found
Usage: ssl_cert_check.sh expire|valid|json hostname|ip [port[/starttls protocol]] [domain for TLS SNI] [check_timeout] [tls_version|tls_auto,[self_signed_ok]] [ s_client_option1 ] [ ... ] [ s_client_optionN ]
Script checks SSL certificate expiration and validity for HTTPS.
[port] is optional, default is 443
[starttls protocol] is optional. Use protocol-specific message to switch to TLS communication. See "man s_client" for supported protocols, like: smtp, ftp, ldap
[domain for TLS SNI] is optional, default is hostname
[check_timeout] is optional, default is 5 seconds
[tls_version|tls_auto,[self_signed_ok]] predefined options comma () separated, flag is optional. Set what is needed, no order of parameters is present of the available options below.
[tls_version] is optional, no default is set. This will auto negotiate the TLS protocol and choose the TLS version itself. Override the TLS version as you need: tls1, tls1_1, tls1_2, tls1_3. See either the TLS Version Options section for the TLS options or use "man s_client" for supported TLS options.
[self_signed_ok] is optional. When this flag is set all self-signed certificates will be seen as 'valid'. It will allow OpenSSL return codes 18, 19, 20 and 21. See the 'Diagnostics' section at https://www.openssl.org/docs/man1.0.2/man1/verify.html.
[tls_auto] means auto negotiating TLS protocol. That is the default, this option is used as separator if you want to speficy additional s_client options after it.
[ s_client_option1 ] [ ... ] [ s_client_optionN ] is optional. But all other parameters are required to be set. Everything you append after all parameters will be added/appended on the OpenSSL s_client command. See all s_client options at https://www.openssl.org/docs/man1.0.2/man1/s_client.html.
Output:
expire:
valid:
json:
Return code is always 0, otherwise zabbix agent fails to get item value and triggers would not work. Note: error messages are not printed when running not on a terninal, so that script result from zabbix is always a correct integer.
[root@XXXX ~/https-ssl-cert-check-zabbix]#
Hi,
1st of all, you script is exactly what I was looking for, it works like a charm on debian 9 and 10.
But I have some debian 8 and older servers, and on these ones, the script refuses to work :/
openssl version
says: OpenSSL 1.0.1t 3 May 2016
Operating System: Debian GNU/Linux 8.10 (jessie)
root@yyyyy:/yyy/yyy/yyy# ./ssl_cert_check.sh expire yahoo.fr
136
root@xxxxxx:/xxx/xxx/xxx# ./ssl_cert_check.sh expire yahoo.fr
-65535
ERROR: Failed to get certificate
I use yahoo.fr for the example. IRL, I use my real domain.
On my Debian 9 server, the script works, and the openssl version is: OpenSSL 1.1.0l 10 Sep 2019
On my Debian 8 server, the script doesn't work and the openssl version is: OpenSSL 1.0.1t 3 May 2016
On the debian 8 server, I tried this:
root@demo:/var/lib/zabbix# bash -x ./ssl_cert_check.sh expire yahoo.fr
=> The result is:
+ default_check_timeout=5
+ error_code=-65535
+ check_type=expire
+ host=yahoo.fr
+ port=443
+ domain=yahoo.fr
+ check_timeout=5
+ starttls=
+ starttls_proto=
+ IFS=/
+ split=($port)
+ '[' 1 -gt 1 ']'
+ for util in timeout openssl date
+ type timeout
+ for util in timeout openssl date
+ type openssl
+ for util in timeout openssl date
+ type date
+ grep -qi busybox
+ date --version
+ '[' 2 -lt 2 ']'
+ '[' expire = expire ']'
+ [[ 443 =~ ^[0-9]+$ ]]
+ '[' 443 -ge 1 ']'
+ '[' 443 -le 65535 ']'
+ '[' '!' -z '' ']'
+ [[ 5 =~ ^[0-9]+$ ]]
++ timeout 5 openssl s_client -servername yahoo.fr -verify_hostname yahoo.fr -connect yahoo.fr:443
++ echo
+ output=
+ error 'Failed to get certificate'
+ echo -65535
-65535
+ '[' -t 1 ']'
+ echo 'ERROR: Failed to get certificate'
ERROR: Failed to get certificate
+ exit 0
openssl s_client -servername yahoo.fr -verify_hostname yahoo.fr -connect yahoo.fr:443
And I got this result:
unknown option -verify_hostname
usage: s_client args
My opinion is that the old versions of openssl doesn't support this option, and this causes the script to fail.
Maybe it would be possible to modify the script in a way that would be backwards compatible with the old ways.
Thanks a lot
Mathieu
Hi thanks for your nice code.
i do anything like your instruction
i have almost 100 url to check ssl
i have copy and modify ssl_cert_list into /etc/zabbix/scripts/ssl_cert_list
but in discovery i have red alarm with error unsupported item key.
i most change Key : "ssl_cert_list" ?
my zabbix version is 6.2.3
Hello,
We are using Zabbix Server Container based on the official Zabbix Container Image: zabbix/zabbix-server-pgsql:alpine-5.0-latest.
We are getting following openssl error, while using the "expire" parameter.
OpenSSL Version is 1.1.1g 21 Apr 2020
date: invalid date 'Sep 11 12:00:00 2020 GMT'
-65535
ERROR: Failed to get expire date
Thank you for your help in advance.
Cheers,
Marc
openssl version
says:
OpenSSL 1.1.1f 31 Mar 2020
Operating System: Ubuntu Server 20.04
Remaining Lifetime of certificate
-65535
ERROR: Failed to get certificate
Test results from https://www.whynopadlock.com
Tested URL
XXX
Test completed
Tue, Mar 7, 2023 11:57 AM Eastern Time (GMT -5)
Results URL
SSL Connection - Pass
SSL Certificate Info
Certificate Issuer
Let's Encrypt
Certificate Type
R3
Issued On
2023-03-05
Force HTTPS
Your webserver is forcing the use of SSL.
Valid Certificate
Your SSL Certificate is installed correctly.
Domain Matching
Your SSL certificate matches your domain name!
Protected Domains:
XXX (10 domains)
Signature
Your SSL certificate is using a sha256WithRSAEncryption signature!
Expiration Date
Your SSL certificate is current. Your SSL certificate expires in 87 days. (2023-06-03)
Mixed Content - Pass
You have no mixed content.
When running the script in JSON mode I'd expect errors to also be returned in JSON. I'd expect a return like
{ "error": -65536, "message": "Failed to get certificate"}
The error is returned as a number on one line and the error message on the other. Since the script always returns 0 there's no way to see if failed before trying to parse the data. So you have to try and parse it one way then if that fails parse it another way.
If the error message was also returned as JSON it would make parsing easier as you can still ingest the JSON and check for the existence of an error key.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.