Disabling RC4 in the SSL cipher suite of an Apache server

Please, see the EDIT sections in my own answer; they contain an explanation to this conundrum.

I'm trying to disable RC4 for an Apache 2.2.9 server running on a CentOS 6.5 VPS and I can't seem to succeed.

A recently purchased business-validated certificate is installed and SSL connections are running fine but I wanted to configure things as well as possible, to "harden the security" as some tutorials put it.

Checking the configuration with Qualys SSL Labs, the results page shows "This server accepts the RC4 cipher, which is weak. Grade capped to B."

However, I have put this in ssl.conf:

 SSLCipherSuite HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!SSLv2:!SSLv3

I have saved the script given in the answer to this question in a file named test-ssl-ciphers.sh and changed the IP address to a loopback address. This is the result of ./test-ssl-ciphers.sh | grep -i "RC4":

Testing ECDHE-RSA-RC4-SHA...NO (sslv3 alert handshake failure)
Testing ECDHE-ECDSA-RC4-SHA...NO (sslv3 alert handshake failure)
Testing AECDH-RC4-SHA...NO (sslv3 alert handshake failure)
Testing ADH-RC4-MD5...NO (sslv3 alert handshake failure)
Testing ECDH-RSA-RC4-SHA...NO (sslv3 alert handshake failure)
Testing ECDH-ECDSA-RC4-SHA...NO (sslv3 alert handshake failure)
Testing RC4-SHA...NO (sslv3 alert handshake failure)
Testing RC4-MD5...NO (sslv3 alert handshake failure)
Testing RC4-MD5...NO (sslv3 alert handshake failure)
Testing PSK-RC4-SHA...NO (no ciphers available)
Testing KRB5-RC4-SHA...NO (no ciphers available)
Testing KRB5-RC4-MD5...NO (no ciphers available)
Testing EXP-ADH-RC4-MD5...NO (sslv3 alert handshake failure)
Testing EXP-RC4-MD5...NO (sslv3 alert handshake failure)
Testing EXP-RC4-MD5...NO (sslv3 alert handshake failure)
Testing EXP-KRB5-RC4-SHA...NO (no ciphers available)
Testing EXP-KRB5-RC4-MD5...NO (no ciphers available)

Each of these lines contains "NO", which, according to the script, means that the server does not support the specified cipher combination.

Moreover, the command grep -i -r "RC4" /etc/httpd gives me only the above-mentioned ssl.conf file.

Also, running openssl ciphers -V on my cipher suite shows no RC4 ciphers at all, which makes sense given the configuration string.

I am therefore somehow lost as to why the SSL check websites are telling me that "the server accepts RC4". They even list the following ciphers as being accepted:

TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_RC4_128_SHA
TLS_ECDHE_RSA_WITH_RC4_128_SHA

Does anyone have a possible explanation? What am I doing something wrong? Maybe there's another place where that support of RC4 or "acceptance" be configured?

Thanks.

[EDIT] Using a CentOS 6.6 in a virtual machine at home, I ran the script again against my VPS using its domain name instead of the loopback address. This setup implies that the list of ciphers is provided by the openssl instance in the VM: I still don't have RC4 among the ciphers that yield YES.


Solution 1:

While installing the renewed certificate, I discovered that the problem was caused by specifying (for the domain and for each subdomain) in ISPConfig the entire set of data necessary for HTTPS: certificate, private key, CA chain, etc.

Put differently, removing the set of data led to the Qualys test to grade the domain A and at the same time remove the warnings about RC4. Putting the details back leads to the warnings coming back and the grade being capped at B again, which leaves no place for doubts as to the causality link.

It's as if the giving of the details for each vhost somehow created a new environment in which some defaults have overridden the cipher suite that I've specified in ssl.conf. Weird.

The solution is to add the SSLCipherSuite specification in the Apache Directives textarea for each vhost. This is what I have in the configuration that gets me an A grade:

SSLProtocol ALL -SSLv2 -SSLv3
SSLHonorCipherOrder on
# Compression is disabled by default on my distribution (CentOS 6)
# SSLCompression off 
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

EDIT (2017-05-16): An additional finding about this problem: the specifying of SSLCipherSuite is mandatory. I can't fathom why that specific directive, although specified at the server level does not automatically apply to virtual host configurations. I am running Apache 2.2.15 on CentOS 6.9.

EDIT (2018-06-18): More information. I've just discovered that the SSLCipherSuite directive can be specified a single time and it will apply to all virtual hosts: in the base mod_ssl configuration file (on CentOS 6, the file is found at /etc/httpd/conf.d/ssl.conf), you simply have to specify the directive outside of the default virtualhost. The Apache 2.2 documentation states that the default value of this directive is SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP. I reckon that this is where the RC4 cipher comes from: in the absence of any specification, which was the case for me since no specification was in the "global" context, the default value applies. This understanding ends what has been a mystery for me. Ironically, I'm about to switch to CentOS 7 when I find this explanation! HTH.

Solution 2:

SSLCipherSuite HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!SSLv2:!SSLv3
                                                                    ^^^^^^^

Bad idea. Disabling all SSLv3 ciphers results in disabling the ciphers usable with TLS1.0 and TLS1.1 and leaves only a few ciphers newly introduced with TLS1.2 (if your server supports TLS1.2)

I am therefore somehow lost as to why the SSL check websites are telling me that "the server accepts RC4". They even list the following ciphers as being accepted:

Make sure that you local and the external tests both access the same server (IP address). I've seen lots of sites where example.com is on a different host than www.example.com and thus the tests differ.