In this update, the recommended baseline is the Mozilla SSL Configuration Generator Intermediate profile. It is the right default for public websites that need a good balance between modern security and real-world client compatibility. If you only support very recent clients, the Mozilla Modern profile is even stricter, but it is no longer the safest default for a general-purpose web server.

The goal is still a clean result on Qualys SSL Labs, but the scanner grade should not be the only target: keep renewals automated, monitor compatibility, and re-test after Apache, OpenSSL, certificate, or CDN changes.

SSL Labs A+ rating

1. Basic Security

Minimizing the amount of data revealed to potential attackers is still useful. Apache should not expose detailed version information on error pages or in the Server header. If your application does not rely on the HTTP TRACE method, disable it too.

# Hide server version on error pages ServerSignature Off # Only return Apache in server header ServerTokens Prod # Disable TRACE unless explicitly required TraceEnable Off

For broad compatibility in 2026, allow TLS 1.2 and TLS 1.3 only. Prefer an explicit allowlist over all -TLSv1 -TLSv1.1, because it makes the intended policy obvious and mirrors the current Mozilla generator output.

SSLProtocol -all +TLSv1.2 +TLSv1.3

If Apache rejects TLSv1.3, check the Apache/OpenSSL versions first. TLS 1.3 requires an OpenSSL build that supports it; removing +TLSv1.3 is a temporary compatibility fallback, not a long-term hardening strategy.

2. Cipher Suite

For TLS 1.2, keep the cipher list short: ECDHE for forward secrecy, AES-GCM or ChaCha20-Poly1305 for authenticated encryption, and ECDSA/RSA depending on your certificate. The current Mozilla Intermediate profile no longer needs finite-field DHE suites for a normal Apache website.

# Mozilla SSL Configuration Generator 6.0, Intermediate, Apache # TLS 1.2 cipher suites 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 # TLS 1.3 cipher suites, if supported by your Apache/OpenSSL build SSLCipherSuite TLSv1.3 TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256

This removes RSA key exchange, static DH, CBC, RC4, 3DES, export ciphers, and old SHA1-based suites. If you need to reason about a particular cipher, ciphersuite.info remains a useful reference.

3. Optimization

The SSLHonorCipherOrder directive no longer needs to be forced on for this profile. With a short list of strong TLS 1.2 suites, allowing the client preference can improve hardware acceleration and ChaCha20 selection without weakening the policy.

SSLHonorCipherOrder off SSLCompression off

The SSLSessionTickets directive disables TLS session tickets. Apache enables tickets by default; if ticket keys are not rotated frequently, session tickets can weaken forward secrecy.

SSLSessionTickets off

The SSLSessionCacheTimeout and SSLSessionCache directives enable SSL session caching to improve performance.

# Enable SSL session caching for improved performance SSLSessionCacheTimeout 300 SSLSessionCache "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"

The SSLUseStapling and SSLStaplingCache directives enable OCSP stapling, which lets Apache include a certificate revocation response during the TLS handshake. It requires a configured stapling cache.

# OCSP stapling SSLUseStapling on SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

4. Security Headers

X-Content-Type-Options tells the browser to respect the MIME types in Content-Type headers, avoiding MIME type sniffing.

Content Security Policy (CSP) helps mitigate XSS, clickjacking, and data injection attacks. Do not publish two alternative enforcing CSP headers at once: browsers enforce all CSP headers they receive. Start with a small enforcing policy, then test stricter script-src rules with Content-Security-Policy-Report-Only.

HTTP Strict-Transport-Security (HSTS) tells browsers to access the site over HTTPS in the future. Use a long max-age only after HTTP to HTTPS redirects and all subdomains are under control. The preload directive should be an explicit opt-in, not a default.

# Security headers ## X-Content-Type-Options: avoid MIME type sniffing Header always set X-Content-Type-Options "nosniff" ## Referrer-Policy: keep full referrers on same-origin requests only Header always set Referrer-Policy "strict-origin-when-cross-origin" ## Optional: disable browser features that this site does not use Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()" ## Small enforcing CSP baseline Header always set Content-Security-Policy "object-src 'none'; base-uri 'self'; frame-ancestors 'self';" ## Test a stricter CSP before enforcing it Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self';" ## Strict Transport Security (HSTS) Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

5. DH Parameters

With the cipher list above, Apache should negotiate ECDHE for TLS 1.2 and TLS 1.3 key exchange groups for TLS 1.3. A custom finite-field Diffie-Hellman parameter file is no longer necessary for the default configuration.

Keep DH parameters only if you intentionally re-enable DHE suites for a legacy or compliance requirement. In that case, use at least 2048 bits, test the performance impact, and document why DHE is still needed.

# Optional: only if your enabled cipher suites include DHE $ openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 $ openssl dh -in /etc/ssl/certs/dhparam.pem -text

Once generated, reference the file in your Apache config only for that DHE-enabled policy:

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

Complete configuration

The complete Apache example is kept in the embedded Gist below. Keep it synchronized with the Mozilla generator and your actual Apache/OpenSSL versions.

Sources

Conclusion

Apache TLS hardening is not a one-time copy-paste task. Use a maintained profile, keep certificates and dependencies current, avoid legacy compatibility unless you have measured demand for it, and test after every meaningful platform change.

Evaluate your configuration: ssllabs.com/ssltest

If you enjoyed this article, feel free to share it or reach out on LinkedIn.