SSL/TLS Troubleshooting Guide - Practical Solutions
SSL/TLS certificate problems can paralyze an application in an instant. This guide will help you quickly diagnose and fix the most common certificate errors.
Diagnostic Tools
OpenSSL - Essential Tool
# Check certificate
openssl s_client -connect example.com:443 -showcerts
# Expiration date
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
# Certificate details
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text
Testssl.sh - Comprehensive Analysis
# Installation
git clone https://github.com/drwetter/testssl.sh.git
cd testssl.sh
# Test
./testssl.sh example.com
Problem 1: Expired Certificate
Symptoms: NET::ERR_CERT_DATE_INVALID
Diagnosis:
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
Solution:
# Let's Encrypt
certbot renew
systemctl reload nginx
# Automatic renewal
echo "0 3 * * * certbot renew --quiet" | crontab -
Problem 2: Incomplete Certificate Chain
Symptoms: unable to get local issuer certificate
Diagnosis:
openssl s_client -connect example.com:443 -showcerts
# You should see certificate + intermediate + root
Nginx Solution:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # fullchain!
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Manual fullchain creation:
cat your-cert.crt intermediate.crt > fullchain.crt
Problem 3: Hostname Mismatch
Symptoms: NET::ERR_CERT_COMMON_NAME_INVALID
Diagnosis:
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep -A2 "Subject Alternative Name"
Solution:
# Add all domains to certificate
certbot certonly --nginx -d example.com -d www.example.com -d api.example.com
Problem 4: Mixed Content
Symptoms: Mixed Content Warning in browser console
Diagnosis:
curl -s https://example.com | grep -o 'http://[^"]*'
Nginx Solution:
add_header Content-Security-Policy "upgrade-insecure-requests;" always;
Code Solution:
<!-- Instead of http:// use // -->
<img src="//example.com/image.jpg">
Problem 5: Self-Signed Certificate
Symptoms: NET::ERR_CERT_AUTHORITY_INVALID
Diagnosis:
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -issuer -subject
# issuer == subject? It's self-signed!
Production Solution:
# Replace with Let's Encrypt
certbot certonly --nginx -d example.com
Problem 6: TLS Version Mismatch
Symptoms: ERR_SSL_VERSION_OR_CIPHER_MISMATCH
Diagnosis:
nmap --script ssl-enum-ciphers -p 443 example.com
Nginx Solution:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
Problem 7: Port 443 Blocked
Symptoms: Timeout, connection refused
Diagnosis:
# Test connection
telnet example.com 443
nc -zv example.com 443
# Check firewall
sudo iptables -L -n | grep 443
Solution:
# Open port 443
sudo ufw allow 443/tcp
sudo firewall-cmd --permanent --add-service=https
Problem 8: SNI Issues
Symptoms: Wrong certificate for domain
Diagnosis:
# Test with SNI
openssl s_client -connect example.com:443 -servername example.com
# Test without SNI
openssl s_client -connect example.com:443 -noservername
Nginx Solution:
# Each domain needs its own server block
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/example.com.crt;
ssl_certificate_key /path/to/example.com.key;
}
Problem 9: OCSP Stapling Issues
Diagnosis:
openssl s_client -connect example.com:443 -status 2>/dev/null | grep -A 17 "OCSP response"
Nginx Solution:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
Problem 10: Certificate Revoked
Symptoms: NET::ERR_CERT_REVOKED
Diagnosis:
openssl ocsp -issuer chain.pem -cert cert.pem -url http://ocsp.example.com
Solution: Certificate has been revoked - you must obtain a new one:
# Generate new key!
openssl genrsa -out new-key.pem 2048
# Get new certificate
certbot certonly --nginx -d example.com --force-renewal
Quick Troubleshooting Checklist
- Expiration date - has the certificate expired?
- Certificate chain - are you using fullchain?
- Hostname - is the domain in SAN?
- Issuer - is the CA trusted?
- TLS version - do you support TLS 1.2+?
- Port 443 - is it open?
- DNS - does the domain point to the correct IP?
- Server logs - what do error logs say?
Online Tools
- SSL Labs: https://www.ssllabs.com/ssltest/ - comprehensive analysis
- Why No Padlock: https://www.whynopadlock.com/ - mixed content debugging
- SSL Checker: https://www.sslchecker.com/ - quick certificate test
Monitoring and Prevention
The best strategy is to prevent problems:
# Monitoring script
#!/bin/bash
DOMAIN="example.com"
DAYS_LEFT=$(echo | openssl s_client -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -checkend $((30*86400)))
if [ $? -ne 0 ]; then
echo "Certificate expires soon!" | mail -s "SSL Alert" [email protected]
fi
Or use a dedicated tool like CrtMgr, which automatically monitors certificates and sends alerts before expiration.
Summary
Most SSL/TLS problems are:
- Expired certificates (automate renewals!)
- Incomplete chain (use fullchain)
- Hostname mismatch (add all domains to SAN)
- Mixed content (CSP: upgrade-insecure-requests)
With the right tools and monitoring, most problems can be detected and fixed in minutes.
Good troubleshooting = methodical approach + right tools