matteocorti / check_ssl_cert

A shell script (that can be used as a Nagios/Icinga plugin) to check an SSL/TLS connection.
GNU General Public License v3.0
363 stars 133 forks source link

SCT check not working in some environments #256

Closed esabol closed 3 years ago

esabol commented 3 years ago

Tested google.com using check_ssl_cert-1.141.0, and it doesn't seem to work on my system. Maybe it depends on a specific version of OpenSSL being installed?

% ./check_ssl_cert-1.141.0/check_ssl_cert -H google.com
 --debug   
[DBG] Command line arguments: -H google.com --debug
[DBG] -c specified: 15
[DBG] ROOT_CA =
[DBG] file version: file-5.04
[DBG] magic file from /etc/magic:/usr/share/misc/magic
[DBG] cURL binary needed. SSL Labs = , OCSP = 1, CURL =
[DBG] cURL binary not specified
[DBG] cURL available: /usr/bin/curl
[DBG] curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.44 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
[DBG] Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
[DBG] Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
[DBG] nmap binary not needed. No disallowed protocols
expect available (/usr/bin/expect)
timeout available (/usr/bin/timeout)
[DBG] perl available: /usr/bin/perl
[DBG] date available: /bin/date
[DBG] checking date version
found GNU date with timestamp support: enabling date computations
[DBG] check_ssl_cert version: 1.141.0
[DBG] OpenSSL binary: /usr/bin/openssl
[DBG] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
[DBG] OpenSSL configuration directory: /etc/pki/tls
[DBG] 249 root certificates installed by default
[DBG]  System info: Linux REDACTED 2.6.32-754.31.1.el6.x86_64 #1 SMP Wed Jul 15 04:53:15 CDT 2020 x86_64 x86_64 x86_64 GNU/Linux
[DBG] Date computation: GNU
[DBG] '/usr/bin/openssl s_client' supports '-servername': using -servername google.com
'/usr/bin/openssl s_client' does not support '-name'
'/usr/bin/openssl s_client' does not support '-xmpphost': disabling 'to' attribute
[DBG] temporary file /tmp/j2105t created
[DBG] temporary file /tmp/41BbX9 created
[DBG] temporary file /tmp/0JhuBW created
[DBG] temporary file /tmp/M1Of1R created
[DBG] temporary file /tmp/u5pwbL created
[DBG] temporary file /tmp/WAXq75 created
[DBG] temporary file /tmp/0CAJBU created
downloading certificate to /tmp
[DBG] google.com is not an IP address
[DBG] executing with timeout (120s): printf 'HEAD / HTTP/1.1\nHost: google.com\nUser-Agent: check_ssl_cert/1.141.0\nConnection: close\n\n' | /usr/bin/openssl s_client    -crlf -ign_eof  -connect google.com:443 -servername google.com   -showcerts -verify 6       2> /tmp/41BbX9 1> /tmp/j2105t
[DBG] /usr/bin/timeout 120 /bin/sh -c "printf 'HEAD / HTTP/1.1\nHost: google.com\nUser-Agent: check_ssl_cert/1.141.0\nConnection: close\n\n' | /usr/bin/openssl s_client    -crlf -ign_eof  -connect google.com:443 -servername google.com   -showcerts -verify 6       2> /tmp/41BbX9 1> /tmp/j2105t"
[DBG] storing a copy of the retrieved certificate in google.com.crt
[DBG] Return value of the command = 0
[DBG] storing a copy of the retrieved certificate in /tmp/google.com-443.crt
[DBG] storing a copy of the OpenSSL errors in /tmp/google.com-443.error
Checking TLS renegotiation
parsing the x509 certificate file
[DBG] Skipping 0 element of the chain
[DBG] ISSUERS =
[DBG] issuer= C = US, O = Google Trust Services, CN = GTS CA 1O1\nissuer= OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
[DBG] ISSUERS =
[DBG] O = Google Trust Services
[DBG] CN = GTS CA 1O1
[DBG] O = GlobalSign
[DBG] CN = GlobalSign
[DBG] subject= C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.google.com
[DBG] CN         = *.google.com
[DBG] CA         = O = Google Trust Services
[DBG] CA         = CN = GTS CA 1O1
[DBG] CA         = O = GlobalSign
[DBG] CA         = CN = GlobalSign
[DBG] SERIAL     = BC5C6677444A99240500000000877F51
[DBG] FINGERPRINT= 79:D5:16:07:E2:38:0E:84:51:4F:F2:7B:52:98:9B:9D:01:FC:B1:E8
[DBG] OCSP_URI   = http://ocsp.pki.goog/gts1o1core
[DBG] ISSUER_URI = http://pki.goog/gsr2/GTS1O1.crt
[DBG]     Signature Algorithm: sha256WithRSAEncryption
[DBG] subjectAlternativeName = *.google.com *.android.com *.appengine.google.com *.bdn.dev *.cloud.google.com *.crowdsource.google.com *.datacompute.google.com *.flash.android.com *.g.co *.gcp.gvt2.com *.gcpcdn.gvt1.com *.ggpht.cn *.gkecnapps.cn *.google-analytics.com *.google.ca *.google.cl *.google.co.in *.google.co.jp *.google.co.uk *.google.com.ar *.google.com.au *.google.com.br *.google.com.co *.google.com.mx *.google.com.tr *.google.com.vn *.google.de *.google.es *.google.fr *.google.hu *.google.it *.google.nl *.google.pl *.google.pt *.googleadapis.com *.googleapis.cn *.googlecnapps.cn *.googlecommerce.com *.googlevideo.com *.gstatic.cn *.gstatic.com *.gstaticcnapps.cn *.gvt1.com *.gvt2.com *.metric.gstatic.com *.urchin.com *.url.google.com *.wear.gkecnapps.cn *.youtube-nocookie.com *.youtube.com *.youtubeeducation.com *.youtubekids.com *.yt.be *.ytimg.com android.clients.google.com android.com developer.android.google.cn developers.android.google.cn g.co ggpht.cn gkecnapps.cn goo.gl google-analytics.com google.com googlecnapps.cn googlecommerce.com source.android.google.cn urchin.com www.goo.gl youtu.be youtube.com youtubeeducation.com youtubekids.com yt.be
[DBG] Checking expiration date
[DBG] Number of certificates in CA chain: 2
[DBG] Skipping 0 element of the chain
[DBG] ------------------------------------------------------------------------------
[DBG] Checking expiration date of element 1
[DBG] Validity date on cert element 1 is May 18 15:36:55 2021 GMT
[DBG] Date computations: GNU
[DBG] Computing number of hours until 'May 18 15:36:55 2021 GMT'
[DBG] Hours until May 18 15:36:55 2021 GMT: 1674
[DBG] executing: /usr/bin/openssl x509 -noout -checkend 0 on cert element 1
[DBG] executing: /usr/bin/openssl x509 -noout -checkend 1296000 on cert element 1
[DBG] executing: /usr/bin/openssl x509 -noout -checkend 1728000 on cert element 1
[DBG] ------------------------------------------------------------------------------
[DBG] Checking OCSP status of element 1
[DBG] temporary file /tmp/1yIIpy created
[DBG] Storing the chain element in /tmp/1yIIpy
[DBG] Checking revokation via OCSP
[DBG] Issuer hash: 99bdd351
[DBG] Chain element issuer URI: http://pki.goog/gsr2/GTS1O1.crt
[DBG] OCSP: fetching issuer certificate http://pki.goog/gsr2/GTS1O1.crt to /tmp/WAXq75
[DBG] executing with timeout (120s): /usr/bin/curl    --silent --location \"http://pki.goog/gsr2/GTS1O1.crt\" > /tmp/WAXq75 
[DBG] /usr/bin/timeout 120 /bin/sh -c "/usr/bin/curl    --silent --location \"http://pki.goog/gsr2/GTS1O1.crt\" > /tmp/WAXq75"
[DBG] OCSP: issuer certificate type (1):  data
[DBG] OCSP: issuer certificate type (2):  data
[DBG] OCSP: converting issuer certificate from DER to PEM
[DBG] OCSP: issuer certificate type (3):  ASCII text
[DBG] OCSP: storing a copy of the retrieved issuer certificate to /tmp/GTS1O1.crt
[DBG] OSCP: URI = http://ocsp.pki.goog/gts1o1core
[DBG] OCSP: host = ocsp.pki.goog
[DBG] openssl ocsp supports the -header option
[DBG] /usr/bin/openssl ocsp -header requires 'key value'
[DBG] executing /usr/bin/openssl ocsp -timeout "120" -no_nonce -issuer /tmp/WAXq75 -cert /tmp/1yIIpy  -url http://ocsp.pki.goog/gts1o1core  -header HOST ocsp.pki.goog
[DBG] OCSP: response = Response Verify Failure
[DBG] OCSP: response = 140067399812936:error:27069076:OCSP routines:OCSP_basic_verify:signer certificate not found:ocsp_vfy.c:85:
[DBG] OCSP: response = /tmp/1yIIpy: good
[DBG] OCSP: response =  This Update: Mar  8 18:12:37 2021 GMT
[DBG] OCSP: response =  Next Update: Mar 15 17:12:36 2021 GMT
[DBG] ------------------------------------------------------------------------------
[DBG] Checking expiration date of element 2
[DBG] Validity date on cert element 2 is Dec 15 00:00:42 2021 GMT
[DBG] Date computations: GNU
[DBG] Computing number of hours until 'Dec 15 00:00:42 2021 GMT'
[DBG] Hours until Dec 15 00:00:42 2021 GMT: 6723
[DBG] executing: /usr/bin/openssl x509 -noout -checkend 0 on cert element 2
[DBG] executing: /usr/bin/openssl x509 -noout -checkend 1296000 on cert element 2
[DBG] executing: /usr/bin/openssl x509 -noout -checkend 1728000 on cert element 2
[DBG] ------------------------------------------------------------------------------
[DBG] Checking OCSP status of element 2
[DBG] temporary file /tmp/ogKtdt created
[DBG] Storing the chain element in /tmp/ogKtdt
[DBG] Checking revokation via OCSP
[DBG] Issuer hash: 4a6481c9
[DBG] Chain element issuer URI:
cannot find the CA Issuers in the certificate: disabling OCSP checks on element 2
[DBG] ------------------------------------------------------------------------------
[DBG] Checking Signed Certificate Timestamps (SCTs)
[DBG] CRITICAL >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[DBG] prepend_critical_message: new message    = Cannot find Signed Certificate Timestamps (SCT)
[DBG] prepend_critical_message: HOST           = google.com
[DBG] prepend_critical_message: CN             = *.google.com
[DBG] prepend_critical_message: SNI            =
[DBG] prepend_critical_message: FILE           =
[DBG] prepend_critical_message: SHORTNAME      = SSL_CERT
[DBG] prepend_critical_message: MSG            =
[DBG] prepend_critical_message: CRITICAL_MSG   =
[DBG] prepend_critical_message: ALL_MSG 1      =
[DBG] prepend_critical_message: MSG 2          = SSL_CERT CRITICAL *.google.com: Cannot find Signed Certificate Timestamps (SCT)
[DBG] prepend_critical_message: CRITICAL_MSG 2 = SSL_CERT CRITICAL *.google.com: Cannot find Signed Certificate Timestamps (SCT)
[DBG] prepend_critical_message: ALL_MSG 2      = \n    SSL_CERT CRITICAL *.google.com: Cannot find Signed Certificate Timestamps (SCT)
[DBG] CRITICAL <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
[DBG] cleaning up temporary files
[DBG]
[DBG] /tmp/j2105t  
[DBG] /tmp/41BbX9  
[DBG] /tmp/0JhuBW  
[DBG] /tmp/M1Of1R  
[DBG] /tmp/u5pwbL  
[DBG] /tmp/WAXq75  
[DBG] /tmp/0CAJBU  
[DBG] /tmp/1yIIpy  
[DBG] /tmp/ogKtdt  
[DBG] exiting with CRITICAL
[DBG] ALL_MSG = \n    SSL_CERT CRITICAL *.google.com: Cannot find Signed Certificate Timestamps (SCT)
[DBG] number of errors = 1
SSL_CERT CRITICAL *.google.com: Cannot find Signed Certificate Timestamps (SCT)|days_chain_elem1=69;20;15;; days_chain_elem2=280;20;15;;
matteocorti commented 3 years ago

Was able to reproduce with www.ethz.ch on Travis CI with Ubuntu 14 (Trusty)

matteocorti commented 3 years ago

The problem is here

[DBG] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013

OpenSSL 1.0.1 is no more supported since 2016.

I know that RedHat (you are using RHEL 6 as I see) backports security fixes so as long as RHEL 6 is supported you are fine. But features are not back ported and SCT support was introduced with 1.0.1

The only fixes are

matteocorti commented 3 years ago

I implemented a simple check with man verify which should make it possible to detect if SCTs are supported.

esabol commented 3 years ago

OK, that works. Thanks for all your efforts with this fantastic project!

Can I make just one more request and then I'll get out of your hair? Could you add env GZIP=-q (or env GZIP=--quiet) right before man verify? I have $GZIP set to -v -9 in all of my shells (I can't be the only one?), so I get the following output now when I run check_ssl_cert 1.142.0:

% ./check_ssl_cert-1.142.0/check_ssl_cert -H google.com
/usr/share/man/man1/verify.1ssl.gz:      69.8%
/usr/share/man/man1/verify.1ssl.gz:      69.8%
/usr/share/man/man1/verify.1ssl.gz:      69.8%
SSL_CERT OK - x509 certificate '*.google.com' from 'GTS CA 1O1' valid until May 12 12:27:53 2021 GMT (expires in 62 days)|days_chain_elem1=62;20;15;; days_chain_elem2=279;20;15;;

This change fixed that:

--- check_ssl_cert-1.142.0/check_ssl_cert       2021-03-10 10:10:38.000000000 -0500
+++ check_ssl_cert-1.142.0/check_ssl_cert.modified      2021-03-10 12:20:38.027130000 -0500
@@ -3397,3 +3397,3 @@
         # check if OpenSSL supoort SCTs
-        if man verify | grep -F -q SCT ; then
+        if env GZIP=-q man verify | grep -F -q SCT ; then
% ./check_ssl_cert-1.142.0/check_ssl_cert.modified -H google.com
SSL_CERT OK - x509 certificate '*.google.com' from 'GTS CA 1O1' valid until May 12 12:27:53 2021 GMT (expires in 62 days)|days_chain_elem1=62;20;15;; days_chain_elem2=279;20;15;;
matteocorti commented 3 years ago

Sure Anyway the man check is really a bad hack. But checking the version was not so easy ...

matteocorti commented 3 years ago

I committed the change. Do you need a new release or you can leave with the checked out version from GitHub?

esabol commented 3 years ago

I can wait until your next release. Thanks again!