Every time I run a security audit on a client’s server, weak SSL/TLS ciphers are one of the first things I check for. They’re an easy win for attackers and an easy fix for administrators — yet I still find outdated cipher suites enabled on production servers more often than I’d like. If you’ve landed here because a penetration test flagged “weak ciphers” or you just want to harden your Apache server proactively, I’ll walk you through exactly how I disable them.
What Are Weak Ciphers, and Why Do They Matter?
A cipher suite defines how data gets encrypted during an SSL/TLS handshake. Older cipher suites — things like RC4, DES, 3DES, export-grade ciphers, and anything using MD5 for integrity checks — have known cryptographic weaknesses. Attacks like BEAST, POODLE, SWEET32, and FREAK all exploit weak ciphers or protocols that shouldn’t be in use anymore.
Leaving weak ciphers enabled means:
- Your server may still negotiate a connection using compromised encryption if a client requests it.
- Compliance frameworks like PCI-DSS, HIPAA, and SOC 2 will flag your configuration during audits.
- Automated vulnerability scanners (Qualys SSL Labs, Nessus, OpenVAS) will downgrade your security rating.
Real-World Impact
I once worked with a client whose SSL Labs grade was stuck at a “C” purely because of legacy RC4 and 3DES ciphers left over from an old load balancer migration. Disabling them took fifteen minutes and pushed the grade to an “A” instantly — no other changes needed.
Prerequisites
- Apache 2.4+ with
mod_sslenabled. - Root/sudo access to edit Apache configuration files.
- OpenSSL installed for testing (usually bundled by default).
- A valid SSL certificate already installed (if you haven’t set this up yet, that’s a separate step from disabling ciphers).
Step 1: Locate Your SSL Configuration File
Depending on your distro, this is typically:
- Debian/Ubuntu:
/etc/apache2/mods-available/ssl.confor inside your virtual host’s SSL block. - CentOS/RHEL:
/etc/httpd/conf.d/ssl.conf.
I always make a backup before touching it:
sudo cp /etc/apache2/mods-available/ssl.conf /etc/apache2/mods-available/ssl.conf.bak
Step 2: Check Your Current Cipher Configuration
I run this to see what’s currently negotiable on the server:
nmap --script ssl-enum-ciphers -p 443 yourdomain.com
Or with testssl.sh, which I prefer for a more detailed breakdown:
./testssl.sh yourdomain.com
This tells me exactly which weak ciphers are currently accepted so I know what I’m fixing.
Step 3: Define a Strong Cipher Suite
Inside the SSL configuration block (or your <VirtualHost> for port 443), I set the SSLCipherSuite and SSLProtocol directives. Here’s a configuration I commonly deploy that balances strong security with broad compatibility:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
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
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
If you want a much stricter, modern-only configuration (dropping support for older clients), I use:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLCipherSuite TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
SSLHonorCipherOrder on
That second block is TLS 1.3-only, which drops compatibility with a lot of older browsers and clients — I only use it when I know exactly who’s connecting (internal APIs, modern-browser-only sites).
Breaking Down What Changed
SSLProtocol— disables SSLv3, TLS 1.0, and TLS 1.1, all of which have known vulnerabilities (POODLE, BEAST).SSLCipherSuite— explicitly lists only strong, forward-secrecy-capable ciphers using AES-GCM or ChaCha20-Poly1305.SSLHonorCipherOrder on— forces the server (not the client) to pick the cipher order, preventing a malicious client from forcing a weak cipher.SSLCompression off— mitigates the CRIME attack.SSLSessionTickets off— reduces some forward-secrecy risks associated with session ticket reuse.
Step 4: Apply Changes to All Virtual Hosts
If you run multiple <VirtualHost> blocks for port 443, make sure each one either includes the same directives or references a shared SSL configuration file with an Include directive:
<VirtualHost *:443>
ServerName example.com
Include /etc/apache2/ssl-hardening.conf
...
</VirtualHost>
I like centralizing this in one include file so I only need to update cipher policy in one place.
Step 5: Test the Configuration
Always test syntax before reloading:
sudo apachectl configtest
Then reload Apache:
sudo systemctl reload apache2
Understanding Which Ciphers to Avoid
Over the years I’ve built a mental blacklist of cipher components that should never appear in a modern SSLCipherSuite directive:
- NULL ciphers — provide no encryption at all; somehow still show up in default OpenSSL builds occasionally.
- EXPORT ciphers — deliberately weakened for old export regulations; trivially breakable today.
- RC4 — has known statistical biases that make it feasible to recover plaintext given enough traffic.
- DES and 3DES — vulnerable to the SWEET32 birthday attack due to a 64-bit block size.
- MD5-based MACs — MD5 is cryptographically broken for collision resistance.
- Anonymous Diffie-Hellman (ADH) — provides encryption without authentication, making it trivially vulnerable to man-in-the-middle attacks.
I explicitly exclude these using a negative cipher string if I want a shorter directive, though I still prefer an explicit allow-list for clarity:
SSLCipherSuite HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4
That said, I generally trust the explicit allow-list approach shown earlier more than a deny-list, since new weak ciphers occasionally get added to OpenSSL’s HIGH category over time, and a deny-list has to keep chasing them.
Step 6: Verify Weak Ciphers Are Gone
I re-run the same scan from Step 2 and confirm the weak ciphers no longer appear:
nmap --script ssl-enum-ciphers -p 443 yourdomain.com
I also check with the SSL Labs Server Test for an independent, publicly trusted grade — it’s the tool I most often send to clients as proof of remediation.
Common Mistakes I See
- Disabling TLS 1.2 too aggressively — a surprising number of enterprise clients and older mobile devices still rely on TLS 1.2; don’t drop it unless you’re certain.
- Forgetting
SSLHonorCipherOrder on— without this, a client can still request a weaker cipher from your allowed list even if you’ve trimmed it down. - Not restarting/reloading after config changes — Apache won’t apply new SSL settings until reloaded.
- Only fixing the default site and forgetting cipher settings need to apply to every SSL-enabled virtual host.
Security Best Practices
- Disable SSLv2, SSLv3, TLS 1.0, and TLS 1.1 entirely — none of them are considered secure anymore.
- Prioritize AEAD ciphers (AES-GCM, ChaCha20-Poly1305) over CBC-mode ciphers.
- Enable
SSLHonorCipherOrder onso the server dictates cipher negotiation. - Periodically re-scan your server — cipher recommendations evolve as new vulnerabilities are discovered.
- Pair cipher hardening with HSTS (
Strict-Transport-Security) to prevent protocol downgrade attacks entirely.
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Performance Optimization Tips
Modern AEAD ciphers like AES-GCM and ChaCha20-Poly1305 aren’t just more secure — they’re also faster than older CBC-mode ciphers on hardware with AES-NI support. So hardening your cipher suite often improves performance as a side effect, not just security.
I also recommend enabling OCSP stapling alongside cipher hardening to reduce TLS handshake latency (I cover this in a separate, dedicated guide on OCSP stapling).
Keeping Cipher Policy Current Over Time
Cipher hardening isn’t a one-time task. I schedule a recurring reminder (quarterly, at minimum) to:
- Re-run an SSL Labs or
testssl.shscan against every production domain. - Check for newly disclosed vulnerabilities affecting cipher suites I currently allow.
- Compare my configuration against the latest Mozilla SSL Configuration Generator recommendations for “Intermediate” or “Modern” compatibility profiles.
- Review access logs for any clients still connecting with protocols I’m considering deprecating, so I can gauge the real-world impact before making a change.
I’ve found that automating this check with a simple cron job that emails me the testssl.sh output saves a lot of manual effort and catches configuration drift after unrelated changes (like a package upgrade resetting a config file).
Troubleshooting
Problem: Older clients can’t connect anymore This usually means you’ve dropped TLS 1.0/1.1 or a cipher an old client depends on. Check your access logs for handshake failures and weigh compatibility against security needs.
Problem: apachectl configtest fails after editing SSLCipherSuite Double-check for typos or stray colons in the cipher list — a single malformed entry breaks the whole directive.
Problem: SSL Labs still shows weak ciphers after reload Clear any CDN or reverse proxy cache in front of your server, since it might be terminating TLS itself with its own cipher policy.
FAQs
Will disabling weak ciphers break my website for users? For the vast majority of modern users on updated browsers, no. It’s a small percentage of users on very old software who might be affected, and honestly, they’re the ones most at risk from weak encryption anyway.
How often should I review my cipher suite? I recommend reviewing it at least once a year, or immediately after any major TLS-related vulnerability disclosure.
Should I disable TLS 1.2? Not unless you have a specific reason to require TLS 1.3 only. TLS 1.2 with strong ciphers is still considered secure.
Summary and Key Takeaways
Disabling weak ciphers in Apache is one of the highest-value, lowest-effort security improvements you can make. By explicitly defining a strong SSLCipherSuite, disabling outdated protocols, and enforcing server-side cipher order, you close off a whole category of downgrade and eavesdropping attacks.
Key takeaways:
- Disable SSLv3, TLS 1.0, and TLS 1.1 — none are secure.
- Use an explicit
SSLCipherSuitewith only AEAD ciphers. - Set
SSLHonorCipherOrder onto prevent client-forced downgrades. - Test with
testssl.shor SSL Labs after every change.