A valid SSL certificate is only part of a secure HTTPS setup. A complete SSL audit also covers TLS version support, cipher suites, certificate chain completeness, OCSP stapling, and security headers. This guide walks through every check using both the ShowDNS tools and command-line utilities.
What a Good SSL Configuration Looks Like
| Check | Expected Result |
|---|---|
| Certificate validity | Valid, not expired, issued by trusted CA |
| Hostname coverage | Certificate covers all requested domains (SAN) |
| Certificate chain | Complete chain: leaf + intermediate(s) |
| TLS version | TLS 1.2 and 1.3 enabled; TLS 1.0/1.1 disabled |
| Cipher suites | Only strong ciphers (ECDHE, AES-GCM, ChaCha20) |
| OCSP stapling | Enabled for faster revocation checking |
| HSTS header | Present with max-age ≥ 31536000 |
| HTTP→HTTPS redirect | All HTTP requests redirect 301 to HTTPS |
Method 1: ShowDNS SSL Tools
Start with the ShowDNS tools for a quick, comprehensive audit:
- SSL Checker — certificate validity, chain, expiry, and SANs.
- TLS Checker — TLS version support and cipher suites.
- SSL Expiration Checker — days until certificate expires.
- HSTS Checker — HSTS header presence and max-age.
- Security Headers — all HTTP security headers.
Method 2: Command-Line Audit
Check Certificate Details
# Full certificate info
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text
# Quick expiry check
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
# Subject Alternative Names (what domains the cert covers)
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
# Certificate issuer (which CA)
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -issuerCheck Certificate Chain
# Show all certificates in the chain
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | grep "BEGIN CERTIFICATE" | wc -l
# Should return 2 or more (leaf + at least one intermediate)
# Verify chain integrity
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt <(openssl s_client -connect example.com:443 -showcerts 2>/dev/null | openssl x509)Check TLS Versions Supported
# Test TLS 1.3 support (should succeed)
openssl s_client -connect example.com:443 -tls1_3 2>/dev/null | grep "Protocol"
# Test TLS 1.2 support (should succeed)
openssl s_client -connect example.com:443 -tls1_2 2>/dev/null | grep "Protocol"
# Test TLS 1.1 (should FAIL - "handshake failure" is correct)
openssl s_client -connect example.com:443 -tls1_1 2>/dev/null | grep "Protocol"
# Test TLS 1.0 (should FAIL - "handshake failure" is correct)
openssl s_client -connect example.com:443 -tls1 2>/dev/null | grep "Protocol"Check Cipher Suites
# See which cipher was negotiated
openssl s_client -connect example.com:443 2>/dev/null | grep "Cipher is"
# Expected: Cipher is TLS_AES_256_GCM_SHA384 (TLS 1.3)
# or: Cipher is ECDHE-RSA-AES256-GCM-SHA384 (TLS 1.2)
# Use nmap to enumerate all supported ciphers
nmap --script ssl-enum-ciphers -p 443 example.comCheck OCSP Stapling
# Check if OCSP stapling is enabled
openssl s_client -connect example.com:443 -status 2>/dev/null | grep -A20 "OCSP response"
# Good: "OCSP Response Status: successful (0x0)"
# Not configured: "OCSP response: no response sent"Check HTTP to HTTPS Redirect
# Verify HTTP redirects to HTTPS
curl -I http://example.com
# Should show: HTTP/1.1 301 Moved Permanently
# Location: https://example.com/Check HSTS Header
# Check HSTS header
curl -I https://example.com | grep -i "strict-transport"
# Should show: strict-transport-security: max-age=31536000; includeSubDomainsRecommended SSL Configuration for Nginx
A production-ready Nginx SSL configuration:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# Certificate
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# Session caching
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
}Frequently Asked Questions
What is OCSP stapling and should I enable it?
OCSP (Online Certificate Status Protocol) stapling allows the web server to pre-fetch and cache the certificate's revocation status, including it in the TLS handshake. This eliminates the need for clients to query the CA's OCSP server directly, improving privacy and handshake speed. Yes, it should be enabled.
How often should I check my SSL configuration?
Check after any server configuration changes, certificate renewals, or web server updates. Also run quarterly audits to confirm TLS settings are still current with best practices, as recommendations evolve.
Is TLS 1.3 backwards compatible with older clients?
Yes. Servers that support TLS 1.3 automatically negotiate TLS 1.2 with clients that do not support 1.3. Enabling TLS 1.3 does not break compatibility with older clients.