We recently started using Let’s Encrypt SSL certificates. These certificates have a validity of only 90 days, and we wanted a way to easily check the expiry dates of all our certificates.

Turns out, it’s really easy to do this with Go.

The crypto/tls Package

The crypto/tls package provides a TLS 1.2 implementation. Among other things, you can use it to establish a TLS connection and examine certificates. Connect to a host, like google.com , is as simple as:

conn , err := tls . Dial ( "tcp" , "google.com:443" , nil )

The Dial succeeds only if the server presents a valid certificate (self-signed certificates will not work). Verifying that the name matches is another step, which can be done like this:

err := conn . VerifyHostname ( "google.com" )

This checks if the given name matches the Common Name or the Subject Alt Names specified in the certificate. And finally, the certificate chain itself is available as conn.ConnectionState().PeerCertificates . The server’s certificate contains the expiry date we are interested in.

Here is a snippet (sans error checking) which can be used to get the expiry date of the certificate of an https site:

conn , _ := tls . Dial ( "tcp" , "google.com:443" , nil ) err := conn . VerifyHostname ( "google.com" ) expiry := conn . ConnectionState () . PeerCertificates [ 0 ] . NotAfter

Not bad for 3 lines of code!

Rolling it into a command-line tool

We threw in error checking, timeouts and a couple of useful tidbits:

Read the list of server names to check for from a file and as command-line arguments

“Humanize” the expiry date with the nifty go-humanize

ASCII art table

and rolled this into a command-line tool we named certchk . Here’s certchk in action:

$ go get github.com/rapidloop/certchk $ certchk Usage: certchk [-f file] servername ... -f file read server names from file $ certchk mail.google.com facebook.com Server | Certificate status ----------------+---------------------------------------------------------------- mail.google.com | valid, expires on 2016-05-31 (2 months from now) facebook.com | valid, expires on 2016-12-30 (9 months from now) $ cat /tmp/names # this is a comment www.netlanders.net www.facebook.com ttybuy.com $ certchk -f /tmp/names mail.google.com Server | Certificate status -------------------+------------------------------------------------------------- www.netlanders.net | x509: certificate signed by unknown authority www.facebook.com | valid, expires on 2016-12-30 (9 months from now) ttybuy.com | x509: certificate is valid for SV100, not ttybuy.com mail.google.com | valid, expires on 2016-05-31 (2 months from now)

That’s it! The code is available on GitHub, and you can go get it with:

$ go get github.com/rapidloop/certchk

Feel free to send us your feedback, suggestions and PRs!