Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Using curl to Check an SSL Certificate's Expiration Date and Details

blog/cards/using-curl-to-check-an-ssl-certificate-expiration-date-and-details.jpg

This is a quick and dependable way to make sure your load balancer or web server is serving the correct certificate.

Quick Jump: Demo Video

I found myself recently wanting to get an SSL certificate’s expiration date for a specific domain name. Running curl https://example.com -vI will show you that info.

If a cert is already expired you’ll get a connection error but if you want to know more details about the expired certificate you can add in the -k flag such as -vkI. That will allow curl to make an insecure connection. You can test that on: curl https://expired.badssl.com/ -vkI

The video below goes into more detail around this and provides tips on how to parse out the date along with when you might want to do such a thing.

Demo Video

Timestamps

  • 0:08 – Assembling our curl command
  • 0:43 – Taking a look at the certificate’s details
  • 1:28 – Parsing out the expiration date with grep and cut
  • 4:10 – Getting similar information in a browser
  • 4:59 – Burning the vI or Iv flags into muscle memory
  • 5:35 – Why? Your load balancer might support multiple certs

Commands

Get the connection and SSL certificate details for a domain name:

$ curl https://example.com -vI

*   Trying 93.184.216.34:443...
* TCP_NODELAY set
* Connected to example.com (93.184.216.34) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=Los Angeles; O=Verizon Digital Media Services, Inc.; CN=www.example.org
*  start date: Dec 10 00:00:00 2021 GMT
*  expire date: Dec  9 23:59:59 2022 GMT
*  subjectAltName: host "example.com" matched cert's "example.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55e5562eb7c0)
> HEAD / HTTP/2
> Host: example.com
> user-agent: curl/7.68.0
> accept: */*

Optionally grep / cut just the SSL certificate’s expiration date:

$ curl https://example.com -vI --stderr - | grep "expire date"

*  expire date: Dec  9 23:59:59 2022 GMT

# Alternatively this will do the same thing as the above:
$ curl https://example.com -vI 2>&1 | grep "expire date"

# Additionally, parse out just the date:
curl https://example.com -vI --stderr - | grep "expire date" | cut -d":" -f 2-

Dec  9 23:59:59 2022 GMT

We have to redirect stderr to stdout because curl writes all of its output to stderr. Without doing this we’ll end up seeing all of the output from curl and no matches from grep.

Will you be using this for anything? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments