Experimental TLS/SSL certificate command-line checker
docker run josebovet/tlschecker:1.1.0 jpbd.dev
If you are utilizing M1 or higher, please add the option --platform linux/x86_64.
docker run --platform linux/x86_64 josebovet/tlschecker:1.1.0 jpbd.dev
Linux
curl -LO https://github.com/jbovet/tlschecker/releases/download/v1.1.0/tlschecker-linux.zip
unzip tlschecker-linux.zip
chmod 755 tlschecker
sudo install tlschecker /usr/local/bin/tlschecker
Osx
curl -LO https://github.com/jbovet/tlschecker/releases/download/v1.1.0/tlschecker-macos.zip
unzip tlschecker-macos.zip
chmod 755 tlschecker
sudo install tlschecker /usr/local/bin/tlschecker
➜ tlschecker --help
Basic usage:
➜ tlschecker --check-revocation x.com revoked.badssl.com jpbd.dev expired.badssl.com
Using custom ports:
➜ tlschecker example.com:8443 secure-service.internal:9443
You can specify the port in three ways:
- Using hostname:port format:
example.com:8443
- Using a full URL:
https://example.com:8443
- Using the default port (443) by just specifying the hostname:
example.com
TLSChecker supports comprehensive certificate revocation checking via both OCSP (Online Certificate Status Protocol) and CRL (Certificate Revocation List). These features allow you to verify if a certificate has been revoked by its issuing Certificate Authority.
To enable revocation checking, use the --check-revocation
flag:
➜ tlschecker --check-revocation jpbd.dev
When you enable revocation checking, TLSChecker will:
- First check certificate status via OCSP, which provides real-time revocation information
- If OCSP doesn't provide a definitive answer, fall back to CRL checking
- Report the certificate as revoked if either method indicates revocation
The revocation status will be displayed in the output:
- Valid: Certificate is not revoked (confirmed by OCSP or CRL)
- Revoked: Certificate has been revoked (with reason if available)
- Unknown: Revocation status couldn't be determined
- Not Checked: Revocation status was not checked (default when not using the flag)
Example with a revoked certificate:
➜ tlschecker --check-revocation revoked.badssl.com
OCSP (Online Certificate Status Protocol):
- Real-time check with the certificate authority
- Faster and more up-to-date than CRLs
- May not be supported by all certificate authorities
CRL (Certificate Revocation List):
- Downloads and checks the CA's published list of revoked certificates
- More widely supported than OCSP
- Lists may be larger and less frequently updated
Note: Revocation checking requires network connections to OCSP responders and CRL distribution points, which adds some latency to the checks.
When using Prometheus integration, the revocation status is included in the metrics:
tlschecker --prometheus --prometheus-address http://localhost:9091 --check-revocation example.com
A tlschecker_revocation_status
metric is exported with the following values:
- 0 = Not checked
- 1 = Good (not revoked)
- 2 = Unknown
- 3 = Revoked
Additionally, a revoked
label is added to all metrics with a boolean value indicating whether the certificate is revoked.
If you encounter connection problems, here are some common error messages and solutions:
-
"Cannot resolve hostname"
- Check that the hostname is spelled correctly
- Verify your network and DNS configuration
- Try using an IP address instead if DNS resolution is not available
-
"Connection refused"
- Verify the host is running a TLS service on the specified port
- Check if a firewall might be blocking the connection
- Confirm the service is publicly accessible
-
"TLS handshake failed"
- The server might be using an unsupported TLS version
- There might be an issue with the server's certificate configuration
- Your network might be intercepting the TLS connection
JSON output:
➜ tlschecker jpbd.dev -o json
[
{
"cipher": {
"name": "TLS_AES_128_GCM_SHA256",
"version": "TLSv1.3"
},
"certificate": {
"hostname": "jpbd.dev",
"subject": {
"country_or_region": "None",
"state_or_province": "None",
"locality": "None",
"organization_unit": "None",
"organization": "None",
"common_name": "jpbd.dev"
},
"issued": {
"country_or_region": "US",
"organization": "Let's Encrypt",
"common_name": "E1"
},
"valid_from": "Jul 31 07:41:38 2023 GMT",
"valid_to": "Oct 29 07:41:37 2023 GMT",
"validity_days": 79,
"validity_hours": 1896,
"is_expired": false,
"cert_sn": "417275593632489451472716682020094135372872",
"cert_ver": "2",
"cert_alg": "ecdsa-with-SHA384",
"sans": [
"*.jpbd.dev",
"jpbd.dev"
],
"chain": [
{
"subject": "jpbd.dev",
"issuer": "E1",
"valid_from": "Jul 31 07:41:38 2023 GMT",
"valid_to": "Oct 29 07:41:37 2023 GMT",
"signature_algorithm": "ecdsa-with-SHA384"
},
{
"subject": "E1",
"issuer": "ISRG Root X2",
"valid_from": "Sep 4 00:00:00 2020 GMT",
"valid_to": "Sep 15 16:00:00 2025 GMT",
"signature_algorithm": "ecdsa-with-SHA384"
},
{
"subject": "ISRG Root X2",
"issuer": "ISRG Root X1",
"valid_from": "Sep 4 00:00:00 2020 GMT",
"valid_to": "Sep 15 16:00:00 2025 GMT",
"signature_algorithm": "sha256WithRSAEncryption"
},
{
"subject": "ISRG Root X1",
"issuer": "DST Root CA X3",
"valid_from": "Jan 20 19:14:03 2021 GMT",
"valid_to": "Sep 30 18:14:03 2024 GMT",
"signature_algorithm": "sha256WithRSAEncryption"
}
],
"revocation_status": "NotChecked"
}
}
]
Text output:
➜ tlschecker jpbd.dev -o text
--------------------------------------
Hostname: jpbd.dev
Issued domain: jpbd.dev
Subject Name :
Country or Region: None
State or Province: None
Locality: None
Organizational Unit: None
Organization: None
Common Name: jpbd.dev
Issuer Name:
Country or Region: US
Organization: Let's Encrypt
Common Name: E1
Valid from: Jul 31 07:41:38 2023 GMT
Valid to: Oct 29 07:41:37 2023 GMT
Days left: 79
Hours left: 1896
Expired: false
Certificate version: 2
Certificate algorithm: ecdsa-with-SHA384
Certificate S/N: 417275593632489451472716682020094135372872
Revocation Status: Not Checked
Subject Alternative Names:
DNS Name: *.jpbd.dev
DNS Name: jpbd.dev
Additional Certificates (if supplied):
Chain #1
Subject: "jpbd.dev"
Valid from: "Jul 31 07:41:38 2023 GMT"
Valid until: "Oct 29 07:41:37 2023 GMT"
Issuer: "E1"
Signature algorithm: "ecdsa-with-SHA384"
Chain #2
Subject: "E1"
Valid from: "Sep 4 00:00:00 2020 GMT"
Valid until: "Sep 15 16:00:00 2025 GMT"
Issuer: "ISRG Root X2"
Signature algorithm: "ecdsa-with-SHA384"
Chain #3
Subject: "ISRG Root X2"
Valid from: "Sep 4 00:00:00 2020 GMT"
Valid until: "Sep 15 16:00:00 2025 GMT"
Issuer: "ISRG Root X1"
Signature algorithm: "sha256WithRSAEncryption"
Chain #4
Subject: "ISRG Root X1"
Valid from: "Jan 20 19:14:03 2021 GMT"
Valid until: "Sep 30 18:14:03 2024 GMT"
Issuer: "DST Root CA X3"
Signature algorithm: "sha256WithRSAEncryption"