SSL/TLS Security Hardening

Configuration checklist for secure HTTPS

SSL/TLS encryption and HTTPS security
Why SSL/TLS Matters: Proper SSL/TLS configuration protects data in transit, prevents man-in-the-middle attacks, and builds user trust. Weak configurations can be exploited despite having a certificate.

Essential SSL/TLS Hardening Steps

1. Get a Valid SSL Certificate

Free Option: Let's Encrypt

# Install Certbot sudo apt install certbot python3-certbot-apache -y # For Apache sudo apt install certbot python3-certbot-nginx -y # For Nginx # Get certificate (Apache) sudo certbot --apache -d example.com -d www.example.com # Get certificate (Nginx) sudo certbot --nginx -d example.com -d www.example.com # Test auto-renewal sudo certbot renew --dry-run

Commercial Certificates

• DigiCert, Sectigo, GlobalSign for OV/EV certificates
• Install using CSR (Certificate Signing Request)

See detailed certificate installation guide →

2. Disable Weak SSL/TLS Protocols

Apache Configuration

# Edit /etc/apache2/sites-available/your-site-ssl.conf or ssl.conf # Disable SSLv2, SSLv3, TLS 1.0, TLS 1.1 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 # Or only enable TLS 1.2 and 1.3 SSLProtocol TLSv1.2 TLSv1.3 # Restart Apache sudo systemctl restart apache2

Nginx Configuration

# Edit /etc/nginx/sites-available/your-site or nginx.conf server { listen 443 ssl http2; # Only allow TLS 1.2 and 1.3 ssl_protocols TLSv1.2 TLSv1.3; # Certificate paths ssl_certificate /path/to/fullchain.pem; ssl_certificate_key /path/to/privkey.pem; } # Restart Nginx sudo systemctl restart nginx

3. Use Strong Cipher Suites

Apache

# Strong cipher configuration SSLCipherSuite 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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 # Prefer server cipher order SSLHonorCipherOrder on

Nginx

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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on;

4. Enable HSTS (HTTP Strict Transport Security)

Apache

# Enable headers module sudo a2enmod headers # Add to VirtualHost Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Nginx

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Important: Start with shorter max-age (e.g., 300 seconds) for testing. Once confident, increase to 31536000 (1 year) and submit to HSTS Preload List.

5. Enable OCSP Stapling

Why: Improves performance and privacy by bundling certificate validity status with TLS handshake.

Apache

SSLUseStapling on SSLStaplingCache "shmcb:logs/stapling-cache(150000)"

Nginx

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 5s;

6. Use Strong Diffie-Hellman Parameters

Generate DH Parameters

# Generate 2048-bit (faster, still secure) sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 # Or 4096-bit (slower, more secure - takes ~10 minutes) sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Configure Apache

SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"

Configure Nginx

ssl_dhparam /etc/ssl/certs/dhparam.pem;

7. Enable Session Resumption

Apache

SSLSessionCache "shmcb:/var/cache/apache2/ssl_scache(512000)" SSLSessionCacheTimeout 300

Nginx

ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;

8. Redirect HTTP to HTTPS

Apache

<VirtualHost *:80> ServerName example.com ServerAlias www.example.com Redirect permanent / https://example.com/ </VirtualHost> # Or using mod_rewrite RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Nginx

server { listen 80; server_name example.com www.example.com; return 301 https://$server_name$request_uri; }

Complete Secure Configuration Examples

Apache Complete SSL Configuration

<VirtualHost *:443> ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/html # SSL Certificate SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem # Strong protocols only SSLProtocol TLSv1.2 TLSv1.3 # Strong ciphers SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder on # DH parameters SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem" # OCSP Stapling SSLUseStapling on SSLStaplingCache "shmcb:logs/stapling-cache(150000)" # Session cache SSLSessionCache "shmcb:/var/cache/apache2/ssl_scache(512000)" SSLSessionCacheTimeout 300 # Security headers Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" Header always set X-Frame-Options "DENY" Header always set X-Content-Type-Options "nosniff" # HTTP/2 Protocols h2 http/1.1 </VirtualHost>

Nginx Complete SSL Configuration

server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com www.example.com; root /var/www/html; # SSL Certificate ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # Strong protocols only ssl_protocols TLSv1.2 TLSv1.3; # Strong ciphers ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on; # DH parameters ssl_dhparam /etc/ssl/certs/dhparam.pem; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Session cache ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; # Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "0" always; location / { try_files $uri $uri/ =404; } }

Testing Your SSL/TLS Configuration

Online Testing Tools:

SSL Labs Server Test - Comprehensive SSL analysis (aim for A+ rating)
Security Headers - Check HTTP security headers
testssl.sh - Command-line SSL testing tool

Command-Line Testing

# Test SSL connection openssl s_client -connect example.com:443 # Check certificate expiration echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates # Test specific TLS version openssl s_client -connect example.com:443 -tls1_2 openssl s_client -connect example.com:443 -tls1_3 # Using testssl.sh git clone https://github.com/drwetter/testssl.sh.git cd testssl.sh ./testssl.sh example.com

Common SSL/TLS Vulnerabilities to Fix

Vulnerability Impact Fix
POODLE High Disable SSLv3
BEAST Medium Disable TLS 1.0, prefer server ciphers
CRIME Medium Disable SSL compression
Heartbleed Critical Update OpenSSL to 1.0.1g+
FREAK High Disable export ciphers
Logjam High Use 2048-bit DH parameters
DROWN High Disable SSLv2

Security Checklist

☐ Valid SSL certificate installed
☐ SSLv2, SSLv3, TLS 1.0, TLS 1.1 disabled
☐ Strong cipher suites configured
☐ HSTS enabled with long max-age
☐ OCSP Stapling enabled
☐ Strong DH parameters (2048-bit minimum)
☐ HTTP redirects to HTTPS
☐ Certificate auto-renewal configured
☐ SSL Labs test shows A or A+ rating
☐ Regular security monitoring enabled

Important: After making SSL configuration changes, always test in staging first and verify that your site remains accessible before applying to production.

🔒 Protect Your Connection

Even with perfect SSL/TLS configuration, your connection can be compromised on untrusted networks. Use a VPN for an additional layer of encryption:

Get NordVPN (2-Year Plan)

Military-grade encryption • No-logs policy • 30-day money-back guarantee

← Back to Tools