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
368 stars 132 forks source link

validate certificate chain of local certificate #325

Closed crigertg closed 2 years ago

crigertg commented 3 years ago

Is your feature request related to a problem? Please describe.

We want to validate our crt files (certificate + intermediate). This turns out to be surprisingly difficult.

Describe the solution you'd like

At the moment the -f parameter is supported. The certificates in this file are checked for ocsp and expiration. It would be great if the chain could be validated too.

Describe alternatives you've considered

We seriously thought about build pipelines installing the certificate in a container and check it via check_ssl_cert. But this seems to be a bit of overengineering.

Additional context

I'm happy to help. But at the moment I'm not sure where to start in the script. I think the crt file containing the signed certificate and the intermediates have to be seperated to check it via openssl. Is this even a desired feature?

matteocorti commented 3 years ago

Do you have an example that I could use to test?

matteocorti commented 3 years ago

I'm a little puzzled: at the moment all the elemnents in the supplied chain are checked. Maybe I'm missing the point

crigertg commented 2 years ago

Hi. Sorry for the late reply.

I try to make up an example:

When deploying a certificate for nginx usually a file containing the certificate chain is deployed. If one of the intermediate certificates is missing there is a problem (which would be alerted via our nagios checks using check_ssl_cert). But I would like to prevent the deployment of a certificate with a missing intermediate certificate. I thought I could check the certificate with the -f parameter but it seems that there is no verification if the chain is complete.

Looking at the SSL certificate of google.com (fetched certificate via openssl s_client -showcerts -servername google.com -connect google.com:443) you can see the chain elements. I would expected that if I store these elements in a file and execute a check with -f it's fine. If I remove the chain elements the check should fail.

I hope that helps :sweat_smile:

matteocorti commented 2 years ago

Thank I get your point. I'll see what I can do.

matteocorti commented 2 years ago

Should work. There are three new tests in the test suite. I also added an additional option --ignore-incomplete-chain to skip the test (if someone wants to test without the chain). The check is also skipped if a user specifies to skip a chain element from the check with --skip-element

crigertg commented 2 years ago

Thank you very much for your effort! Definitely sponsoring a beer or a coffee!

It works if a wrong element is inserted into the chain but not if an element is missing. I've done some digging and found a way to check this but I'm missing a way to plug it in check_ssl_cert yet (not enough time to dig deep into the script).

Coming back to the google.com certificate example. Having three files:

Then this could be tested like this:

missing intermediate

$ openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt google_only.crt
CN = *.google.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error google_only.crt: verification failed

wrong intermediate

$ openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt -untrusted starfield_intermediate.crt  google_only.crt
CN = *.google.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error google_only.crt: verification failed

correct intermediate

$ openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt -untrusted google_intermediate.crt  google_only.crt
google_only.crt: OK

Is this helpful for you? At the moment I lack the time implementing this in check_ssl_cert. :cry:

I've attached the sample files used for testing.

ssl_sample.tar.gz

matteocorti commented 2 years ago

Thanks for the coffee :-) I'll take a look (with my tests a missing element should trigger a critical)

matteocorti commented 2 years ago

I can reproduce the problem with google-only: there is only one element (the plugin compares with the previous element)

matteocorti commented 2 years ago

Now I see the problem. The plugin only verifies certificates fetched online. I should implement a verify step for files.

crigertg commented 2 years ago

Yes! That's the thing we're looking for. So we can run the script on certificates before they get deployed in a CI/CD pipeline.

If you find a way to implement it properly in the already existing flow of the certificate it would be really great.

matteocorti commented 2 years ago

I committed a fix that seems to work. Can you please test?

matteocorti commented 2 years ago

I had to release a new version with the fix as some other checks were not working anymore. Let me know if 2.10.1 solves your problem. If not please reopen the issue.

crigertg commented 2 years ago

I'm still having issues. But i have figured out a way to fix it.

I will provide a PR as soon.