Command Line Tools for SSL Certificate Verification: Fetching Serial Numbers and Checking Heartbleed Vulnerabilities


4 views

After the Heartbleed vulnerability forced widespread certificate reissuance, manually checking each server's SSL certificate through browser interfaces becomes tedious and unreliable. We need an automated way to:

  • Fetch certificate serial numbers
  • Verify installation status
  • Check for proper renewal

The most robust solution uses OpenSSL's s_client command with these key parameters:

echo "" | openssl s_client -showcerts -status -verify 0 \
        -connect example.com:443 2>&1 | \
        grep -E "Verify return|subject=/serial"

This one-liner provides:

  • Certificate validation (-verify 0)
  • Clean output through grep filtering
  • Forced termination (echo "")

curl with Certificate Inspection

curl -vI --ssl-reqd https://example.com \
| grep -E "SSL connection|certificate"

nmap for Bulk Scanning

nmap --script ssl-cert -p 443 server1.example.com server2.example.com

For production environments, consider this bash script that checks multiple domains:

#!/bin/bash
domains=("example.com" "api.example.com" "staging.example.com")

for domain in "${domains[@]}"; do
  echo "Checking $domain..."
  echo | openssl s_client -connect $domain:443 2>&1 | \
    openssl x509 -noout -dates -serial
done

For ongoing monitoring, tools like certspotter or Facebook's certificate transparency monitoring can alert you about new certificates issued for your domains.


After critical vulnerabilities like Heartbleed surface, system administrators face the tedious task of reissuing and verifying SSL certificates across multiple servers. Manual verification through browser interfaces becomes impractical at scale. Here's why command line tools are essential:

  • Batch processing for multiple domains/servers
  • Integration with monitoring systems
  • Historical tracking of certificate changes
  • Automated expiration alerts

The most reliable tool for certificate inspection is OpenSSL, available on virtually all Unix-like systems. Here's an enhanced version of the basic certificate fetching command:

#!/bin/bash
DOMAIN="example.com"
PORT=443

echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:$PORT 2>&1 | \
    openssl x509 -noout -serial -subject -dates -issuer

This script outputs:

  • Certificate serial number
  • Subject details
  • Validity period
  • Issuer information

For complete chain verification, add these OpenSSL options:

openssl s_client -showcerts -verify 5 -connect $DOMAIN:$PORT < /dev/null

Key parameters:

  • -showcerts: Displays entire chain
  • -verify 5: Sets chain verification depth
  • -CAfile: Specify custom CA bundle

For large-scale environments, consider these specialized tools:

1. SSLScan:

sslscan --show-certificate example.com

2. TestSSL.sh:

testssl.sh --csvfile report.csv example.com

3. Python Implementation:

import ssl
import socket

context = ssl.create_default_context()
with socket.create_connection(("example.com", 443)) as sock:
    with context.wrap_socket(sock, server_hostname="example.com") as ssock:
        cert = ssock.getpeercert()

print(cert['serialNumber'])

This Bash function checks expiration dates:

check_cert_expiry() {
    local domain=$1
    local port=${2:-443}
    local expiry_date=$(echo | openssl s_client -servername $domain -connect $domain:$port 2>/dev/null | \
        openssl x509 -noout -enddate | cut -d= -f2)
    local remaining_days=$(( ($(date -d "$expiry_date" +%s) - $(date +%s)) / 86400 ))
    echo "$domain: $remaining_days days remaining"
}

For non-standard setups:

  • SNI certificates: Use -servername parameter
  • Self-signed certs: Add -verify_return_error
  • SMTP/IMAP: Adjust port numbers accordingly
  • Client certificates: Use -cert and -key options