🎯 Introduction
Secure communication is one of the cornerstones of modern web infrastructure.\ To protect the confidentiality and integrity of data exchanged over the internet, we rely on SSL (Secure Sockets Layer) and its successor TLS (Transport Layer Security).
Unfortunately, many systems are still misconfigured or use outdated cipher suites, exposing both user data and server integrity.
In this guide, you'll learn how to build a modern SSL/TLS setup --- from enabling TLS 1.3 and forward secrecy to implementing HSTS, OCSP stapling, and automated certificate renewal.
🧰 Prerequisites
This guide assumes the following environment:
- Server: Ubuntu 22.04 LTS (or similar)\
- Web Server: Nginx 1.24+ or Apache 2.4.58+\
- Tools:
openssl,curl,testssl.sh\ - Certificate Authority: Let's Encrypt (free) or any commercial CA
You should be familiar with: - Basic Linux command line - SSL
certificate structure (/etc/letsencrypt/live/) - Basic understanding
of Nginx or Apache configuration files
🧩 1. Choose the Right TLS Version
Today, TLS 1.2 and TLS 1.3 are considered secure.\ However, whenever possible, enable only TLS 1.3.\ Older protocols like TLS 1.0, 1.1, and SSLv3 are deprecated and must be disabled.
🔧 Example (Nginx)
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
💡 Tip:\ TLS 1.3 automatically selects strong cipher suites, so you don't need to define them manually unless TLS 1.2 is enabled for compatibility.
🔒 Example (Apache)
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLHonorCipherOrder on
🧠 2. Use Strong Cipher Suites
Cipher suites define how your server encrypts traffic.\ Outdated or weak algorithms like RC4, DES, and 3DES should never be used.
Recommended Cipher List (for TLS 1.2)
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:
ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:
ECDHE-RSA-CHACHA20-POLY1305:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-GCM-SHA256';
This list: - Supports Perfect Forward Secrecy (PFS)\
- Uses modern algorithms like AES-GCM and CHACHA20\
- Ensures strong key exchange (ECDHE)
🧩 Note:\ PFS ensures that even if a future key is compromised, past sessions remain confidential.
🧱 3. Provide a Complete Certificate Chain
Browsers must receive the full certificate chain, including intermediate certificates.\ Missing intermediates will result in SSL warnings or reduced SSL Labs scores.
Nginx Example
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Apache Example
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
💡 Let's Encrypt automatically provides a
fullchain.pemfile containing both the leaf and intermediate certificates.
🧭 4. Enable HSTS (HTTP Strict Transport Security)
HSTS forces browsers to use HTTPS only, preventing SSL-stripping attacks.
Nginx Configuration
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
This tells browsers to: - Enforce HTTPS for one year\
- Include subdomains\
- Register for browser preload lists
Check preload status:\ 👉
🔁 5. Enable OCSP Stapling
OCSP Stapling improves TLS handshake speed by caching the certificate validation response from the CA.
Nginx Configuration
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
⚙️ Without stapling, each client queries the CA directly --- slower and less private.
🔐 6. Perfect Forward Secrecy (PFS)
Perfect Forward Secrecy ensures that compromising one key does not expose past sessions.
Test It
openssl s_client -connect example.com:443 -tls1_2 | grep "Cipher"
If you see ECDHE or DHE in the output, PFS is enabled.
🔄 7. Automate Certificate Renewal
Manual certificate renewal is risky.\
Let's Encrypt supports automation through cron or systemd timers.
Cron Example
sudo crontab -e
Add this line:
0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
🧠 Test it safely using:
sudo certbot renew --dry-run
🧪 8. Test and Validate SSL Configuration
1️⃣ SSL Labs Test
Visit\ 👉
Input your domain and review your score (A+ recommended).
2️⃣ testssl.sh
git clone https://github.com/drwetter/testssl.sh.git
cd testssl.sh
./testssl.sh https://example.com
This script tests: - Protocol support\
- Cipher strength\
- HSTS and OCSP configuration
📋 9. Performance Optimizations
TLS security doesn't have to slow down your site.
To boost performance: - Enable HTTP/2 and HTTP/3 (QUIC)\
- Use TLS 1.3 session resumption (0-RTT)\
- Prefer ECC (P-256) certificates for faster handshakes\
- Use caching and reverse proxies (e.g., Cloudflare, Nginx Proxy Manager)
Enable HTTP/2
listen 443 ssl http2;
⚡ Multiplexing allows multiple requests over one connection --- significantly faster page loads.
🧱 10. Secure Redirects
Always redirect HTTP to HTTPS with a single clean rule.
Nginx Example
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
💡
301is a permanent redirect, improving SEO and caching behavior.
🧰 11. Add Security Headers
Complement your SSL setup with modern browser security headers:
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin";
add_header Permissions-Policy "geolocation=(), microphone=()";
add_header Content-Security-Policy "default-src 'self';";
These help mitigate: - Clickjacking\
- MIME-sniffing\
- Cross-site tracking and data leaks
🧮 12. Certificate Types and Use Cases
Type Usage Description
DV (Domain Blogs, personal Fast, automatic issuance Validation) sites
OV Corporate websites Includes company verification
(Organization
Validation)
EV (Extended Finance, e-commerce Strong identity validation Validation)
Wildcard *.example.com Covers all subdomains
SAN (Subject Multi-domain Single certificate for many domains Alt Name)
🔍 Recommendation:\ Use OV/EV for enterprise and finance; Let's Encrypt DV for automation and simplicity.
🔎 13. Logging and Monitoring
Monitor SSL errors proactively:
tail -f /var/log/nginx/error.log | grep ssl
Check renewal logs:
sudo cat /var/log/letsencrypt/letsencrypt.log
Use Prometheus or Grafana to track certificate expiration metrics.
🧩 14. Complete Nginx Configuration Example
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:
ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:
ECDHE-RSA-CHACHA20-POLY1305:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-GCM-SHA256';
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin";
add_header Content-Security-Policy "default-src 'self';";
root /var/www/html;
index index.html index.php;
}
🧭 Conclusion
A well-configured SSL/TLS setup not only encrypts traffic but also strengthens trust, SEO, and overall system reliability.
In this guide, you learned to: - Enforce TLS 1.3 and modern ciphers\
- Implement HSTS, OCSP, and Forward Secrecy\
- Automate renewals and perform SSL audits
Your infrastructure now meets A+ grade standards for both performance and security.