Using curl to Check an SSL Certificate's Expiration Date and Details
This is a quick and dependable way to make sure your load balancer or web server is serving the correct certificate.
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
References Links
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.