How to Disable Weak Ciphers in Apache

How to disable weak ciphers in Apache

How to disable weak ciphers in Apache

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:

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

Step 1: Locate Your SSL Configuration File

Depending on your distro, this is typically:

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

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:

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

Security Best Practices

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:

  1. Re-run an SSL Labs or testssl.sh scan against every production domain.
  2. Check for newly disclosed vulnerabilities affecting cipher suites I currently allow.
  3. Compare my configuration against the latest Mozilla SSL Configuration Generator recommendations for “Intermediate” or “Modern” compatibility profiles.
  4. 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:

References

Exit mobile version