SSL/TLS configuration issues can be frustrating to debug. Here’s a systematic approach to identifying and resolving common SSL certificate problems in Nginx.
Common SSL Certificate Issues
- Certificate Not Found: Nginx cannot locate the certificate files
- Incorrect Certificate Chain: Incomplete or incorrect certificate chain
- Private Key Issues: Mismatched private key or permission problems
- Certificate Expiration: Expired certificates
- Self-Signed Certificate Warnings: Using self-signed certificates in production
- Protocol/Cipher Misconfigurations: Supporting outdated or insecure protocols
Diagnosing SSL Issues
1. Verify Certificate Files
First, ensure your certificate files exist and have correct permissions:
bash# Check if certificate files exist
ls -la /path/to/certificate.crt /path/to/private.key
# Verify file permissions
# Certificate should be readable, private key should be readable only by root/nginx user
chmod 644 /path/to/certificate.crt
chmod 600 /path/to/private.key
chown nginx:nginx /path/to/private.key
2. Test Nginx Configuration
Check for syntax errors in your Nginx configuration:
bashnginx -t
3. Verify Certificate Chain
Check if your certificate chain is complete and in the correct order:
bash# Check certificate details
openssl x509 -in /path/to/certificate.crt -text -noout
# Verify certificate chain
openssl verify -CAfile /path/to/chain.pem /path/to/certificate.crt
A proper full chain certificate should contain:
- Your server certificate
- Intermediate certificates
- Root certificate (optional, as browsers typically have these)
4. Verify Certificate-Key Pair Match
Ensure your private key matches your certificate:
bash# Get modulus of certificate
openssl x509 -noout -modulus -in /path/to/certificate.crt | openssl md5
# Get modulus of private key
openssl rsa -noout -modulus -in /path/to/private.key | openssl md5
# Results should match exactly
5. Test SSL Connection
Use tools like OpenSSL to test your SSL connection:
bash# Test SSL handshake
openssl s_client -connect example.com:443 -servername example.com
# Check for specific TLS versions
openssl s_client -connect example.com:443 -tls1_2
# Check for certificate expiration
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
Resolving Common SSL Issues
1. Certificate Not Found
nginxserver {
listen 443 ssl;
server_name example.com;
# Ensure absolute paths are used
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# Add error logging
error_log /var/log/nginx/ssl-error.log debug;
}
2. Fixing Certificate Chain Issues
Create a proper fullchain.pem:
bash# Concatenate certificates in the correct order
cat server.crt intermediate.crt > fullchain.pem
# Update Nginx configuration
ssl_certificate /path/to/fullchain.pem;
3. Resolving Private Key Issues
bash# Generate a new CSR and private key if needed
openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr
# Update permissions
chmod 600 example.key
chown nginx:nginx example.key
4. Setting Up Auto-Renewal with Certbot
For Let’s Encrypt certificates:
bash# Install Certbot
apt install certbot python3-certbot-nginx
# Obtain and configure certificate
certbot --nginx -d example.com -d www.example.com
# Verify auto-renewal
certbot renew --dry-run
5. Modern SSL Configuration
nginxserver {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# Optimized SSL settings
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Modern configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS (15768000 seconds = 6 months)
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
}
6. Testing Your SSL Configuration
Use online tools to validate your configuration:
By systematically working through these steps, you can diagnose and resolve most SSL certificate issues in your Nginx configuration, ensuring secure and reliable HTTPS connections for your users.