Article 6 of 6: Understanding TLS Security Series
This final article provides actionable configuration guidance for hardening TLS on web servers, load balancers, and applications. We cover protocol versions, cipher suites, certificates, security headers, and testing tools.
Each section includes the theory (why it matters), practical configuration (copy-paste ready), and common mistakes to avoid.
Quick Reference Checklist
| Configuration | Minimum | Recommended |
|---|---|---|
| TLS Version | TLS 1.2 | TLS 1.3 only |
| Key Exchange | ECDHE | X25519 + ML-KEM |
| Cipher Mode | AEAD (GCM) | AES-256-GCM |
| Certificate Key | RSA 2048 | ECDSA P-256 |
| Certificate Validity | 200 days | 90 days (ACME) |
| HSTS | Enabled | Preloaded |
| OCSP Stapling | Enabled | Must-Staple |
2026 Certificate Lifetime Changes
Starting March 2026, maximum certificate validity periods are decreasing significantly. Automate your certificate renewal now.
| Date | Max Validity | Action Required |
|---|---|---|
| Before Mar 2026 | 398 days | Current standard |
| Mar 15, 2026 | 200 days | Update automation |
| Mar 15, 2027 | 100 days | Quarterly renewal |
| Mar 15, 2029 | 47 days | ~Monthly renewal |
1. Protocol Version Configuration
Theory: Why This Matters
| Version | Status | Action |
|---|---|---|
| SSL 2.0 | BROKEN | Disable immediately, many critical vulnerabilities |
| SSL 3.0 | BROKEN | Disable. POODLE attack, RFC 7568 prohibits |
| TLS 1.0 | DEPRECATED | Disable. BEAST, RFC 8996 deprecates |
| TLS 1.1 | DEPRECATED | Disable. No benefits over 1.0, RFC 8996 deprecates |
| TLS 1.2 | SUPPORTED | Enable with strong ciphers only |
| TLS 1.3 | RECOMMENDED | Enable, best security and performance |
Practical: Configuration
Nginx:
# Enable only TLS 1.2 and 1.3
ssl_protocols TLSv1.2 TLSv1.3;
Apache:
# Enable only TLS 1.2 and 1.3
SSLProtocol -all +TLSv1.2 +TLSv1.3
HAProxy:
# In bind line
bind *:443 ssl crt /path/cert.pem ssl-min-ver TLSv1.2
Reality: Common Mistakes
- Enabling TLS 1.0 “for compatibility” when most clients support 1.2+
- Not testing after changes. Use SSL Labs to verify.
- Forgetting to restart service after config change
2. Cipher Suite Configuration
Theory: Why This Matters
Cipher Suite Priority:
- TLS 1.3 ciphers (all secure, automatic)
- ECDHE + AESGCM (forward secrecy + AEAD)
- ECDHE + CHACHA20 (mobile-friendly)
- DHE + AESGCM (if ECDHE unavailable)
Must Disable:
- RSA key exchange (no forward secrecy)
- CBC mode ciphers (padding oracles)
- 3DES (Sweet32 attack)
- RC4 (broken)
- Export ciphers (Logjam, FREAK)
Practical: Configuration
Nginx, Recommended Cipher Suite:
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_prefer_server_ciphers on;
ssl_ecdh_curve X25519:secp384r1;
Apache, Recommended Cipher Suite:
SSLCipherSuite 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
SSLHonorCipherOrder on
Reality: Common Mistakes
- Using
HIGHorALLcipher strings, which are too permissive - Not setting server cipher preference. Client might choose weak cipher.
- Forgetting to specify curves, which may use weak DH params
3. Certificate Configuration
Theory: Why This Matters
- Use automated certificate management (Let’s Encrypt/ACME)
- Short validity (90 days) with automated renewal
- ECDSA P-256 preferred over RSA (smaller, faster)
- Include full certificate chain (not just leaf)
- Enable OCSP stapling for revocation checking
Practical: Configuration
Let’s Encrypt with Certbot:
# Install certbot
apt install certbot python3-certbot-nginx
# Get certificate (ECDSA)
certbot --nginx -d example.com --key-type ecdsa --elliptic-curve secp256r1
# Auto-renewal (cron)
0 0 * * * certbot renew --quiet
OCSP Stapling (Nginx):
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/chain.pem;
Verify Certificate Chain:
# Check certificate chain is complete
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | \
grep 'Certificate chain' -A 20
Reality: Common Mistakes
- Missing intermediate certificate, which causes trust errors on some clients
- Manual renewal process that leads to expired certificates
- Using self-signed in production with no trust and no revocation
4. Security Headers
Theory: Why This Matters
Security headers complement TLS by providing additional browser-enforced protections.
| Header | Purpose |
|---|---|
| Strict-Transport-Security | Forces HTTPS, prevents SSL stripping |
| X-Frame-Options | Prevents clickjacking attacks |
| X-Content-Type-Options | Prevents MIME type sniffing |
| Content-Security-Policy | Controls resource loading, prevents XSS |
| Referrer-Policy | Controls referrer information leakage |
Practical: Configuration
Complete Security Headers (Nginx):
# HSTS - Force HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Prevent clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# Prevent MIME sniffing
add_header X-Content-Type-Options "nosniff" always;
# XSS protection (legacy browsers)
add_header X-XSS-Protection "1; mode=block" always;
# Referrer policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Content Security Policy (customize for your app)
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
Reality: Common Mistakes
- CSP too restrictive, breaks application functionality
- Missing
always, headers not sent on error pages - HSTS without testing can lock out users if HTTPS breaks
5. Testing & Validation
Theory: Why This Matters
Always test TLS configuration after changes. Use multiple tools to catch different issues.
Practical: Tools
Online Testing Tools:
| Tool | Purpose |
|---|---|
| SSL Labs | Comprehensive, industry standard |
| Security Headers | securityheaders.com, HTTP header analysis |
| Mozilla Observatory | observatory.mozilla.org, overall security check |
| Hardenize | hardenize.com, email + web security |
Command-Line Testing:
# testssl.sh - comprehensive local testing
testssl.sh example.com
# Check specific vulnerability
testssl.sh --heartbleed --poodle --beast example.com
# nmap SSL scripts
nmap --script ssl-enum-ciphers,ssl-cert -p 443 example.com
# Quick OpenSSL check
openssl s_client -connect example.com:443 -tls1_3 -brief
SSL Labs Grade Requirements:
| Grade | Requirements |
|---|---|
| A+ | A grade + HSTS with long max-age |
| A | TLS 1.2+, strong ciphers, no vulnerabilities, valid cert |
| B | Minor issues like weak DH, missing features |
| C-F | Vulnerable to known attacks, weak protocols enabled |
Reality: Common Mistakes
- Testing only once when configurations drift over time
- Not testing after certificate renewal, which causes chain issues
- Automate testing in CI/CD pipeline
6. Complete Server Configuration
Complete Nginx TLS Configuration (2026 Recommended):
server {
listen 443 ssl http2;
server_name example.com;
# Certificates
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Protocols - TLS 1.3 only (2026 recommendation)
ssl_protocols TLSv1.3;
# Ciphers
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_prefer_server_ciphers on;
ssl_ecdh_curve X25519:secp384r1;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# Session
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off; # Forward secrecy
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
}
Reference: Use ssl-config.mozilla.org (Modern profile) for the latest recommended configurations.
Series Summary
This 6-article series covered everything you need to understand and implement secure TLS:
- Cryptography Fundamentals: Symmetric, asymmetric, hashing, key exchange, post-quantum
- TLS 1.2 Deep Dive: Handshake, key derivation, certificate trust model
- TLS 1.3: The Modern Standard: 1-RTT, HKDF, ECH, hybrid post-quantum
- TLS Attacks & Vulnerabilities: POODLE, Heartbleed, BEAST, Logjam, DROWN, ROBOT
- MITM Attacks: Interception, SSL stripping, HSTS, certificate pinning
- TLS Hardening Guide (this article): Configuration, testing, best practices
Key Takeaways
- Use TLS 1.3 where possible, TLS 1.2 as fallback only
- AEAD ciphers only: AES-256-GCM or ChaCha20-Poly1305
- Automate certificate management with Let’s Encrypt and ACME
- Prepare for shorter certificate lifetimes (200 days in 2026)
- Enable HSTS with preload for SSL stripping defense
- Test regularly with SSL Labs, testssl.sh, and nmap
- Prepare for post-quantum with X25519 + ML-KEM hybrid
Previous: Article 5: MITM Attacks
This concludes our 6-article series on Understanding TLS Security.
Want to verify your TLS hardening is actually effective? We validate TLS configuration as part of our Web Application Pentest and IoT Pentest engagements. Get a free external security snapshot to see what’s exposed, or view our pricing.