Giter Site home page Giter Site logo

selivan / https-ssl-cert-check-zabbix Goto Github PK

View Code? Open in Web Editor NEW
282.0 17.0 69.0 90 KB

Script to check validity and expiration of TLS/SSL certificate on hosts. May be used with Zabbix or standalone.

License: Other

Shell 100.00%
zabbix monitoring ssl tls cetrificate expiration validity

https-ssl-cert-check-zabbix's People

Contributors

doug-fitzmaurice-rowden avatar evilhamsterman avatar fgma avatar jeffdesc avatar klepek avatar paskal avatar rupreht avatar selivan avatar tbblake avatar yosijo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

https-ssl-cert-check-zabbix's Issues

"syntax error in expression" random error

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.

Add support Russian domains

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!

ssl_cert_check.zip

idn: not found

Environment

openssl version says: OpenSSL 1.1.1f 31 Mar 2020

Operating System: Ubuntu Server 20.04

Expected Behavior

root@zabbix:~# ./ssl_cert_check.sh expire xxxxxx.com
82

Current Behavior

root@zabbix:~# ./ssl_cert_check.sh expire xxxxxx.com
./ssl_cert_check.sh: line 91: type: idn: not found
82

Always returning 0 on validate

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.

Add basic template.xml file for Zabbix

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()}&lt;1</expression>
                            <name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
                            <priority>DISASTER</priority>
                        </trigger>
                        <trigger>
                            <expression>{last()}&lt;5</expression>
                            <name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
                            <priority>HIGH</priority>
                        </trigger>
                        <trigger>
                            <expression>{last()}&lt;10</expression>
                            <name>SSL Certificate on {HOST.NAME} will expire in {ITEM.LASTVALUE} days</name>
                            <priority>AVERAGE</priority>
                        </trigger>
                        <trigger>
                            <expression>{last()}&lt;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.

Zabbix agent Duplicate user parameter

Environment

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)"

Expected Behavior

When starting up Zabbix-agent2 it should start up normally

Current Behavior

/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"

Little instruction on adding to Zabbix

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.

"integer expression expected" when the certificate is broken

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.

Unsupported Zabbix Item when certificate errors occur (due to stderr)

Environment

openssl version says:

OpenSSL 1.1.1  11 Sep 2018

Operating System: Ubuntu 18.04 (Zabbix)

Expected Behavior

When a certificate error occurs, using Zabbix UserParameter, we should get -65535 as the result in Zabbix

Current Behavior

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.

Details

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.

Multiple sites on one server ( Macros specify domains )

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.

read:errno=104 error returned from domain, but check still possible with the command standalone

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:

| timeout "$check_timeout" openssl s_client -CApath "$ssl_ca_path" -servername "$domain" -verify_hostname "$domain" -connect "$host":"$port" 2>/dev/null )

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)

Getting error when running scripts with no parameters

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:

    • N number of days left before expiration, 0 or negative if expired
    • -65535 failed to get certificate or incorrect parameters
  • valid:

    • 1 valid
    • 0 invalid
    • -65535 failed to get certificate or incorrect parameters
  • json:

    • JSON object with a summary of the result, which can be used by Zabbix (JSONPath)
      * expire_days: the amount of days before the certificate is expired
      * valid: see 'valid' check
      * return_code: the OpenSSL return code
      * return_text: the OpenSSL return text which gives helpful insights
    • JSON object with the error code and message
      * error_code: -65535
      * error_message: The output of the error message

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]#

The script doesn't work on Debian8

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 :/

Environment

openssl version says: OpenSSL 1.0.1t 3 May 2016

Operating System: Debian GNU/Linux 8.10 (jessie)

Expected Behavior

root@yyyyy:/yyy/yyy/yyy# ./ssl_cert_check.sh expire yahoo.fr
136

Current Behavior

root@xxxxxx:/xxx/xxx/xxx# ./ssl_cert_check.sh expire yahoo.fr
-65535
ERROR: Failed to get certificate

Diagnostics

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

Details

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

  • I then tried this:
    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

Unsupported Item key

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

Invalid Date

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

ERROR: Failed to get certificate (website certificate is OK)

Environment

openssl version says:

OpenSSL 1.1.1f  31 Mar 2020

Operating System: Ubuntu Server 20.04

Expected Behavior

Remaining Lifetime of certificate

Current Behavior

-65535
ERROR: Failed to get certificate

Diagnostics

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.

Return failure as JSON also

Expected Behavior

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"}

Current Behavior

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.

Details

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.