Configuring Apache, Nginx, and OpenSSL for Forward Secrecy

Ivan Ristic

Last updated on: December 22, 2022

Update: This post is obsolete. For guidance on how to deploy TLS securely, please read SSL/TLS Deployment Best Practices, which we always keep up to date.


In my earlier blog post, I gave an overview of Forward Secrecy, as well as some configuration tips. If you’re new to the concept, I suggest that you go and read that post first. This time, I am following up with detailed configuration examples for Apache, Nginx, and OpenSSL.

Software Requirements

To deploy Forward Secrecy, you need to have both your web server and the underlying SSL/TLS library support Elliptic Curve cryptography. For Apache, Nginx, and OpenSSL, the following minimum versions will suffice:

  • OpenSSL 1.0.1c+
  • Apache 2.4.x
  • nginx 1.0.6+ and 1.1.0+

You will probably want to upgrade to the most recent versions wherever possible, because you don’t want to be running old and obsolete and potentially vulnerable software.

You are probably aware that Linux distributions often ship modified packages. The modifications are usually improvements, but could mean feature removal in some cases. For example, Red Hat appears to have no support for Elliptic Curve crypto on their operating systems, because of patent issues. If you’re running CentOS, for example, and wish to support Forward Secrecy, you will need to recompile the key packages to put EC support back in. (There appear to be plenty tutorials on the Web for this.)

Once the correct packages are in place, enabling Forward Secrecy requires two steps:

  1. Configure the web server to actively select suites
  2. Activate the correct OpenSSL suite configuration string

The following configuration advice applies only if you are using compatible software components, as described in the previous section. It is not possible to support Forward Secrecy otherwise.

Apache

To configure Apache, you need to have the following lines in your configuration:

SSLProtocol all -SSLv2 -SSLv3 SSLHonorCipherOrder on SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"

Nginx

To configure Nginx, you need to have the following lines in your configuration:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";

RC4 versus BEAST

Today, only TLS 1.2 with GCM suites offer fully robust security. All other suites suffer from one problem or another (e.g, RC4, Lucky 13, BEAST), but most are difficult to exploit in practice. Because GCM suites are not yet widely supported, most communication today is carried out using one of the slightly flawed cipher suites. It is not possible to do better if you’re running a public web site.

The one choice you can make today is whether to prioritize RC4 in most cases. If you do, you will be safe against the BEAST attack, but vulnerable to the RC4 attacks. On the other hand, if you remove RC4, you will be vulnerable against BEAST, but the risk is quite small. Given that both issues are relatively small, the choice isn’t clear.

However, the trend is clear. Over time, RC4 attacks are going to get better, and the number of users vulnerable to the BEAST attack is going to get smaller.

Configuring OpenSSL (with RC4)

This configuration assumes you wish to deploy best-possible configuration supporting Forward Secrecy, and that you have a preference for GCM suites (resistant to timing attacks) and RC4 (resistant to BEAST). To achieve best performance, the faster ECDHE suites are used whenever possible.

EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS
$ openssl ciphers -V 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS'

The output will be similar to this:

ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384 ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA256 ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384 ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256 ECDHE-RSA-RC4-SHA       SSLv3 Kx=ECDH     Au=RSA  Enc=RC4(128)  Mac=SHA1 ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1 ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1 ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1 ECDHE-ECDSA-AES128-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1 ECDHE-ECDSA-RC4-SHA     SSLv3 Kx=ECDH     Au=ECDSA Enc=RC4(128)  Mac=SHA1 DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256 DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1 DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1 DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(128) Mac=AEAD DHE-RSA-AES128-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA256 DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1 DHE-RSA-SEED-SHA        SSLv3 Kx=DH       Au=RSA  Enc=SEED(128) Mac=SHA1 DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(128) Mac=SHA1 ECDH-RSA-RC4-SHA        SSLv3 Kx=ECDH/RSA Au=ECDH Enc=RC4(128)  Mac=SHA1 ECDH-ECDSA-RC4-SHA      SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=RC4(128)  Mac=SHA1 RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1

If you deploy your configuration, your SSL Labs test results might look like this.

Notes:

  • The list begins with a number of strong TLS 1.2 suites.
  • ECDSA suites are preferred to the RSA ones, giving you a performance edge in a dual-certificate deployment scenario.
  • The main 2 suites (for the current browsers, most of which do not support TLS 1.2) are ECDHE-RSA-RC4-SHA and ECDHE-ECDSA-RC4-SHA, used for RSA and ECDSA certificates, respectively.
  • The DHE suites are there to support those rare browsers that do not support ECDHE. (Opera before version 15 is one such browser. Firefox as shipped on Red Hat systems another.) These suites are slower, but the majority of browsers will offer the faster ECDHE.
  • The RC4-SHA suite at the end is there to support IE8 running on Windows XP. (And possibly IE6, but I have not tested for it.)

Issues:

  • Internet Explorer, in all versions, does not support the ECDHE and RC4 combination (which has the benefit of supporting Forward Secrecy and being resistant to BEAST). But IE has long patched the BEAST vulnerability and so we shouldn’t worry about it.
  • Same comment as above for Firefox on Red Hat systems.
  • It is impossible to support Forward Secrecy for IE8 running on Windows XP, because this browser does not support the necessary suites. The same is probably true for any IE version running on Windows XP. If you’d rather not handshake with such browsers, add !RC4-SHA to the configuration.

Configuring OpenSSL (without RC4)

If you prefer not to use RC4, deploy with the following configuration:

EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4

Alternatively (in order to support a very wide range of browsers, including the IE versions running on Windows XP), you could deploy with RC4 enabled, but used only as a last resort:

EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS +RC4 RC4

Final Remarks

Finally, consider the following:

  • There’s a vast number of SSL/TLS clients in deployment, each potentially supporting a unique list of cipher suites. It is impossible to guarantee consistent results across such a large user base.
  • The Handshake Simulation feature of the SSL Labs test is of great help when choosing cipher suite configuration. It supports a wide range of desktop browsers (including older versions). However, do note that the support for mobile devices is not very good at the moment.
  • Configuring OpenSSL can be tricky. I recommend reading the (free) OpenSSL Cookbook, which describes the configuration in detail.  !DSS

Update (21 August): I have tweaked the suite configuration string to position SHA256 and SHA384 suites (which are TLS 1.2-only) after GCM suites and before RC4 suites. This helps avoid RC4 whenever possible. (This matters now because Google Chrome 29 has just been released, and, for the first time, we have a desktop browser that supports TLS 1.2 by default). Of course, I assume that you have upgraded your OpenSSL to 1.0.1d or better in order to fix the timing issues with CBC suites (the so-called Lucky 13 attack).

Show Comments (52)

Comments

Your email address will not be published. Required fields are marked *

  1. -1-

    "The RC4-SHA suite at the end is there to support IE8 running on Windows XP. (And possibly IE6, but I have not tested for it.)"

    I have tested IE6, IE7 and IE8 on Windows XP all are supporting TLS_RSA_WITH_RC4_128_SHA (name from Wireshark ServerHello command).

    By the way you can install IE collection (browsers from version IE1!!! to IE8) and Firefox collection (from FX2!!! to latest alpha) on the SAME Windows computer – at installation process you select which browser versions would you like to install and you have all of the browser’s versions installed on SINGLE Windows computer and install does not interfere with current browser/s already installed (it installs all of the software in separate directory etc).

    IE collection: http://utilu.com/IECollection/

    Firefox collection: http://utilu.com/UtiluMFC/

    In both cases search for "Download" section.

    -2-

    Configuring OpenSSL can be tricky. I recommend reading the (free) OpenSSL Cookbook, which describes the configuration in detail

    Few days ago I have spotted this book and read it in detail. Excellent book, thanks for sharing such a vital info with community. You rock!

    I did diff between three list of suggested ciphers and spotted some for me unexplainable differences between them (maybe there are OK, just don’t understand why), see bellow 3, 4 and 5. I made tests with openssl v1.0.1c.

    -3-

    In first list of suggestion there is no !DSS compared to second and third list. Is this intentional? As I see adding or removing it has no effect on returned cipher suites list (command: openssl ciphers -V "cipher_suites_filter"), because probably already excluded with some !cipher_suites_filter command. Just for sake of keep it simple, probably add this additional filter also on the first list.

    -4-

    In first list there is definition EECDH+aRSA+EECDH+RC4 Why is there EECDH written two times? I think filter EECDH+aRSA+RC4 does the same thing. If I understand correctly filtering the cipher suites filter EECDH two times with 'AND' condition will return the same result. I have tested both variants with openssl chipher -V "cipher_suites_filter" command and got the same result.

    -5-

    In third list there is "EDH +RC4 RC4 !aNULL" Why using "+RC4" and also "RC4"? Is this intentional or did you mean EDH+RC4 so without space between them?

    In your case EDH +RC4 RC4 bellow ciphers are returned:

    ECDHE-ECDSA-AES256-GCM-SHA384

    ECDHE-ECDSA-AES128-GCM-SHA256

    ECDHE-RSA-AES256-GCM-SHA384

    ECDHE-RSA-AES128-GCM-SHA256

    ECDHE-ECDSA-AES128-SHA256

    ECDHE-RSA-AES128-SHA256

    ECDHE-RSA-AES256-SHA384

    ECDHE-RSA-AES256-SHA

    ECDHE-RSA-AES128-SHA

    DHE-RSA-AES256-GCM-SHA384

    DHE-RSA-AES256-SHA256

    DHE-RSA-AES256-SHA

    DHE-RSA-CAMELLIA256-SHA

    DHE-RSA-AES128-GCM-SHA256

    DHE-RSA-AES128-SHA256

    DHE-RSA-AES128-SHA

    DHE-RSA-SEED-SHA

    DHE-RSA-CAMELLIA128-SHA

    ECDHE-RSA-RC4-SHA

    ECDHE-ECDSA-RC4-SHA

    ECDH-RSA-RC4-SHA

    ECDH-ECDSA-RC4-SHA

    RC4-SHA

    But if adding EDH+RC4 RC4 only bellow ciphers are returned:

    ECDHE-ECDSA-AES256-GCM-SHA384

    ECDHE-ECDSA-AES128-GCM-SHA256

    ECDHE-RSA-AES256-GCM-SHA384

    ECDHE-RSA-AES128-GCM-SHA256

    ECDHE-ECDSA-AES128-SHA256

    ECDHE-RSA-AES128-SHA256

    ECDHE-RSA-AES256-SHA384

    ECDHE-RSA-AES256-SHA

    ECDHE-RSA-AES128-SHA

    ECDHE-RSA-RC4-SHA

    ECDHE-ECDSA-RC4-SHA

    ECDH-RSA-RC4-SHA

    ECDH-ECDSA-RC4-SHA

    RC4-SHA

    Difference is by adding DHE cipher suites. Is this intentional?

    Thanks a lot.

    Regards,

    Jack.

    1. 1. I didn’t test IE6 because it uses a SSLv2-style handshake, and my Handshake Simulator understands only SSLv3-style handshake at this point. Regarding the browser collections, some browsers depend on the underlying operating system, so testing just the programs wouldn’t provide an accurate picture. For IE, Microsoft provides a set of virtual machines for compatibility testing (www.modern.ie); that’s what I used.

      3. I suppose I didn’t add !DSS because no DSS suites appeared while I was developing the configuration. I agree, it should be added everywhere for consistency.

      4. It’s a typo. Once is enough.

      5. The plus at the beginning of a keyword (e.g., +RC4) will match through the suites that are _already_ on the list, and push them to the end of the list. It does not add any new suites. The RC4 keyword selects all RC4 suites and adds them to the list. However, it does not affect any existing suites. The purpose of these 2 keywords is to have all RC4 suites at the end of the list, but with ECDHE and DHE suites first, followed by everything else.

    1. The problem is that even browsers that support TLS 1.2 don’t support GCM suites, or support a small number of them. For example, IE11 supports GCM only in combination with a ECDSA certificate.

      I need to do more research, but it seems that Safari (the other browser that currently supports TLS 1.2) does not support any GCM suites. Chrome 30 (Canary) does not support any GCM suites either.

  2. Thanks for the nice explanations about deploying PFS on Apache!

    Are there anywhere hints how to activate PFS on IIS 7.5?

    According to this article:

    http://technet.microsoft.com/en-us/library/dd560644(v=ws.10).aspx

    Windows 2008 R2 / IIS 7.5 supports two GCM ciphers.

    I setup a test environment and it seems that the offered server protocols depend on the used certificate. I activated TLS 1.2 but this was not enough.

    When i create a certificate with ECC public key algorithm, GCM is offered:

    Public Key Algorithm:

        Algorithm ObjectId: 1.2.840.10045.2.1 ECC

        Algorithm Parameters:

         06 08 2a 86 48 ce 3d 03  01 07

             1.2.840.10045.3.1.7 ECDH_P256

    Using such a certificate I also get this cipher offered:

    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

    Normal certificates with RSA public key algorithm don’t provide GCM under IIS 7.5.

    But actually also certificates with RSA should be able to provide GCM (see http://www.google.com).

    Does anybody have hints for IIS 7.5 / Win 2008 R2?

    A good overview of browser support and ciphers provides this PDF:
    http://www.g-sec.lu/sslharden/SSL_comp_report2011.pdf

    Oh… after digging around I probably found the answer.

    Windows doesnt support any TLS_ECDHE_RSA…GCM… ciphers and thus RSA-certificates dont work with GCM. Thus i can choose between no FPS and BEAST under Windows…

    1. Hi Thomas,

      I haven’t yet looked at Windows (for FS or other things), but I’d recommend that you choose FS (with ECDHE_RSA) over BEAST. SSL Labs is going to drop the BEAST penalty very soon now, as I consider the problem largely mitigated. (And RC4 is getting increasingly weak, too.)

  3. If one is not allowing DHE*, the cipher list on RHEL/CentOS gets pretty short:

    $ openssl ciphers -V 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !DH'
              0x00,0x05 – RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
              0x00,0x20 – KRB5-RC4-SHA            SSLv3 Kx=KRB5     Au=KRB5 Enc=RC4(128)  Mac=SHA1

    If you consider BEAST sufficiently mitigated, or for non-HTTP (where it’s not a concern?), would allowing HIGH make sense?

    openssl ciphers -V 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH HIGH RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !DH'
              0x00,0x35 – AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
              0x00,0x84 – CAMELLIA256-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA1
              0x00,0x2F – AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
              0x00,0x41 – CAMELLIA128-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(128) Mac=SHA1
              0x00,0x05 – RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
              0x00,0x20 – KRB5-RC4-SHA            SSLv3 Kx=KRB5     Au=KRB5 Enc=RC4(128)  Mac=SHA1

    Just for reference, if you disable RC4 and DHE, you have no ciphers left on CentOS.

    * For performance reasons and/or because of "PCI Compliance" concerns. cPanel, for example, disables the DHE ciphers in its recommended PCI Compliance cipher configuration. I’m not sure why; that might actually be the performance concern again too.

  4. Also, is it possible to get a CA to sign an ECDSA key? I haven’t really looked into this much, but nothing promising shows up in a quick Google search.

  5. I’m using nginx, changed ciphers and now I have in Opera 12.16 "TLS v1.2 256 bit AES (1024 bit DHE_RSA/SHA-256)". SSL Server Test shows that Opera 12.15 will handshake with TLS 1.0 and "TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)". Also, before changes I had in my ciphers list "!kEDH" and 100% at Key Exchange score at SSL Server Test. Now if I wil add this, server will not support FS, but  I don’t see anything  that improves score of feistyduck.com in Key Exchange to 90%. What I forgot to add?

    1. You might want to edit the DH-parameters so you are using a keysize of >=2048. I used the following command:

      $ openssl dhparam -out dh4096.pem 4096

      So you see I used a keysize of 4096 (just for the score, a keysize that high is probably impractical on higher traffic websites). For using those I needed to:

      nginx:

      Add a directive ssl_dhparam /etc/nginx/dh4096.pem;

      apache2 (just guessing, unfortunately) (for all the others who might read this):

      Append the content of 4096.pem to your certificate file, maybe like this:

      $ cat /etc/ssl/certs/your-cert.pem 4096.pem > /etc/ssl/certs/your-cert-dhp.pem

      This is untested because I don’t have any applicable apache2-servers for testing. I hope this will work anyway!

  6. I’m not sure whether this is an openssl bug or a bug in the test, but when I queried openssl (1.0.1c, on ubuntu server 13 with nginx) it acted as if it supported all of the ECDHE-ECDSA protocols, but none of them showed up in the test.

    I did, however, still manage to pull off a fairly high A (100-95-90-90) with FS support using only 5 protocols, without cutting out any but SSLv3 (IE6) users: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:DHE-RSA-AES128-SHA:RC4-SHA.  Doing it right meant a longer key for the DHE protocol, which was done as in the above post.  If SSLv3 is enabled, you can include IE6 users, with a slightly lower A..  If deteriorating RC4 bugs you more than the last vestiges of BEAST do, it can be left out.

    @Richard Laager: "cPanel, for example, disables the DHE ciphers in its recommended PCI Compliance cipher configuration. I’m not sure why; that might actually be the performance concern again too."  Some of them default to keys as short as 1024 bits, which is the rough equivalent of an 80 bit key in a symmetrical cipher. Increasing it to 2048 bits only gives ~112 bits of security, but DH is considered about equivalent (per bit) to RSA, and PCI has no problem with 2048 bit site certs. It will be twice as slow as 1024 bits, however.

    PS — Firefox nightly builds now have working TLS 1.1 and 1.2. They still have to be manually enabled, but there’s finally light at the end of that tunnel.

  7. IE on XP (either version) is only supporting RC4-128 and 3DES (besides DSS-DHE, but that will not do). It does not really have to do with the version of the browser, but moreover the version of schannel.dll and that has functionally not evolved through any version of IE on XP.

    And yes, IE6 should leave the table. But as support for XP will stay through 04-2014, it might be something to disable RC4 at that moment as all current OS-es should then have AES ciphers.

    Since you can then still use XP with other browsers that are based on NSS or other security suites you pretty much only killed XP with IE. Percentages for these combined are already low.

  8. Added ssl_dhparam with file generated in openssl (as mentioned by Bastian Schwetzel) and WOW, got 100-95-100-90 score with FS. (Hmm, is possible to got 100-100-100-100? :-) I can improve protocol support by dropping TLSv1 & 1.1, but how can I improve Cipher Strength? Experimented with ciphers list and not got anything better than 90% Maybe I forgot something again..)

    I’m using nginx with SPDY and this SSL settings for 100-95-100-90:

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";

    ssl_prefer_server_ciphers on;

    ssl_dhparam dh4096.pem;

    1. You can improve cipher strength with !MEDIUM, giving you 100-100-100-100 and a B for BEAST.

      On a private server (where I know everyone and can mitigate BEAST by nagging my users to upgrade), I’m running a lot like that, but without dropping TLS1.0 support (yet).  All AES in EECDH or EDH, with 128 bits at the bottom as a fallback.  With my insanely slow 12000-bit DH key, that gets me the highest scores possible without dropping support for any platforms except IE/XP.  And a B, of course.  Gotta say, I love not having to be PCI compliant.

  9. dear ivan

    dear community

    i edited my apache2.conf according to your "default" (ivan ristic variant) suggestion:

    
    SSLHonorCipherOrder On
    SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
    
    

    however i am still not passing ssllabs beast test:

    why is that? what am i missing?

    Protocol Details
    Secure Renegotiation Supported
    Secure Client-Initiated Renegotiation No
    Insecure Client-Initiated Renegotiation No
    BEAST attack Vulnerable INSECURE (more info)
    Compression No
    RC4 Yes NOT DESIRABLE (more info)
    Forward Secrecy (Experimental) No NOT DESIRABLE (more info)
    Next Protocol Negotiation No
    Session resumption Yes
    Session tickets Yes
    OCSP stapling No
    Strict Transport Security No
    Long handshake intolerance No
    TLS extension intolerance No
    TLS version intolerance TLS 2.98
    SSLv2 handshake compatibility Yes

    &

    Protocols
    TLS 1.2 Yes
    TLS 1.1 Yes
    TLS 1.0 Yes
    SSL 3.0 No
    SSL 2.0 No
    Cipher Suites (SSLv3+ suites in server-preferred order, then SSLv2 suites where used)
    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 256
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x6b) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 256
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 256
    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 256
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 128
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x67) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 128
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 128
    TLS_DHE_RSA_WITH_SEED_CBC_SHA (0x9a) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 128
    TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x45) DH 1024 bits (p: 128, g: 1, Ys: 128) FS 128
    SSL_RSA_WITH_RC4_128_SHA (0x5) 128

    you continue by suggesting to:

    To see what suites the above configuration string uses, invoke the following command (all one line):

    
    $ openssl ciphers -V 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS'
    
    

    when i define it as:

    
    SSLCipherSuite ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
    
    

    as suggested (=steve caligo variant) on Mitigating the BEAST attack on TLS the beast vulnerability is not detected anymore.

    right now i set it back to your "default" suggestion.

    i am also a bit confused by the quotation marks and backslashes! while the ivan ristic variant uses both quotation marks and backslashes, the steve caligo variant uses neither!

    1. Your problem seems to be the version of Apache you are using, as I can reproduce the behavior on Ubuntu 12.04 "Precise" with openssl 1.0.1c and 1.0.1e installed. Seems like the mod_ssl version doesn’t support some of the ciphers, leading to the vulnerability. I have not tested using a 2.4 version of Apache, so I don’t know if this will help. If there’s a solution which just needs another cipher list, I would also really appreciate any hints!

      1. when i define it as:

        SSLCipherSuite ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH

        as suggested (=steve caligo variant) onhttps://community.qualys.com/blogs/securitylabs/2011/10/17/mitigating-the-beast-attack-on-tlsthe beast vulnerability is not detected anymore.

                           

        after setting it like this, i passed the beast test.

        disclaimer: i’m a newb. i cannot vouch for the soundness of whatever I propose ;-)

        you sure about my apache version?

        i’m running

        apache2:

          Installed: 2.2.22-1ubuntu1.4

        and

        Ubuntu 12.04.2 LTS (GNU/Linux 3.5.0-39-generic x86_64)

        and

          openssl:

          Installed: 1.0.1-4ubuntu5.10

        is this why ivan ristic’s variant doesn’t work?

        1. I am too using Ubuntu 12.04 (at least on some servers). As I have the same problem with different openSSL versions (1.0.1c and 1.0.1e) and apache2 installed from the repositories, but not when using nginx (1.4.2, from a PPA) I think that apache is the problem in your case. The cipher list you suggested doesn’t have PFS unfortunately, but at least it works around the BEAST vulnerability..

          1. but what can i do to solve it?

            my apache and openssl seem to be the latest available for ubuntu server LTS?

            you can also contact me thru skype, my username:

            r mi pa scal

            (omit all spaces)

          2. They are, in fact, the latest. What I just did to test whether Apache 2.4 solves the problem was adding the PPA https://launchpad.net/~ondrej/+archive/php5 and then installing the Apache version contained in it. This gave me the green PFS bar and a decent score. However it broke my site due to problems with PHP so be careful with that. I have no other solution apart from that, unfortunately..

  10. Just a heads up… with the suggested configuration provided in this article:

    SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 \
    EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 \
    EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"

    Amazon CloudFront servers will not talk to your origin server.  They will report the following error:

    ERROR

    Failed to contact the origin.

    Best I can find right now is that the Amazon forums suggest the following Cipher settings:

    ssl_ciphers ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

    Which is … unfortunate.

      1. So, with Amazon CloudFront currently only supporting:

        RSA_WITH_RC4_128_MD5

        RSA_WITH_AES_128_CBC_SHA

        And assuming Amazon does nothing to update their CDN client ciphers… what’re your thoughts on which of the two to support?

        I noticed that in the suggested cipher configuration in this article, RSA_WITH_RC4_128_SHA appears to have been added to placate IE6 and IE8 on Windows XP.  It appears as though I may have to do similar while I need CloudFront support… :-/

        At the moment, I’m presuming RSA_WITH_AES_128_CBC_SHA is the lesser of the two evils although I would guess that the RC4/MD5 is probably more performant.

        1. I had the same problem as Nathaniel; I deployed a hardened SSL configuration only to discover CloudFront could not connect.

          I didn’t do a wire sniff, but I’m assuming that the CloudFront backend client supports the same ciphersuites as the CloudFront frontend servers:

          https://www.ssllabs.com/ssltest/analyze.html?d=d2agp238gkp7mh.cloudfront.net&s=54.230.194.149&hideResults=on

          Which gives us TLSv1.2, TLSv1.1, TLSv1.0, and SSLv3 with these suites:

          TLS_RSA_WITH_RC4_128_MD5

          TLS_RSA_WITH_AES_128_CBC_SHA

          So I added RSA+AES+SHA to the end of my ciphers list and that took care of that. I don’t want RC4 touching my stuff.

          CloudFront is pretty popular as a low-friction low-cost CDN. Ivan, I’d love to see it in the handshake simulation list along with the googlebot and bing crawler.

          Also, I would love to see Amazon update their docs and specify their SSL capabilities, but I’ll take that up with them. :-)

  11. In trying to set things up for maximally secure ephemeral Diffie-Hellman, I noticed something annoying about older browsers: a DH key >= 2049 bits breaks them, and they can’t connect.  I noticed this using FF/Iceweasel or Seamonkey on various stable/LTS Linux distros, but I’d imagine it applies to older Mozilla-based browsers on other platforms, and possibly to other browsers.

    Iceweasel 17.0.8 on the new Debian Wheezy was fine with keys >4k, however.

    So much for my big DH keys.  :-(

  12. Hi,

    i have use the ciphers and config advice what stand in the posted artical from Ivan but i come only to 80% on the Key Exchange.

    Any Idea?

    regards

    Rolf

  13. Thank you very much for the article.

    I felt bad about all the good stuff not working with Apache 2.2, which is still much more prominent than 2.4. Also, XMPP and mail (SMTP, IMAP, …) servers and many more do provide even less configuration options than Apache.

    I therefore wrote the TLS Interposer (https://netfuture.ch/tools/tls-interposer/), which can be used to tweak most Linux tools using OpenSSL into using more secure settings, as proposed in this post.

    I hope this will prove helpful to those so unfortunate to be stuck with Apache 2.2.

    -Marcel

    1. Hi Marcel,

      That’s a very neat approach! Given how many Apache 2.2.x installations there are and that they don’t support the (now vital) ECDHE cipher suites, your tool is very useful. I’ll give it a try. Perhaps I will be able to revert back to system-installed Apache 2.2.x on my Ubuntu servers :-)

      1. Ivan,

        thanks, please let me know about your success or problems. BTW: Do you have an insight into the ratio between Apache 2.2. and 2.4 in your SSL test?

        -Marcel

        1. We don’t keep any statistics on the SSL Labs web site, but SSL Pulse does collect server signatures. As you probably know, those are not reliable (because the best practice is to hide the server version), but here’s what I have:

          163,587 servers

          78,990 have the word "Apache" in the signature

          2,227 have "Apache/2.0"

          30,196 have "Apache/2.2"

          645 have "Apache/2.4"

          41,039 have "Apache".

  14. Hi, Ivan

    I have 3 questions:

    1) Why you leave DHE-RSA-SEED-SHA?

    2) Why ECDHE-RSA-RC4-SHA and ECDHE-ECDSA-RC4-SHA are not after DHE-RSA-CAMELLIA128-SHA? So, at the end of all others more stronger cipher suits with Forward Secrecy. And if because of BEAST why two GCM-cipher suits DHE-RSA-AES256-GCM-SHA384 and DHE-RSA-AES128-GCM-SHA256 are not higher than these cipher suits with RC4 in your ordered list?

    So, for TLS 1.2 ECDHE-RSA-RC4-SHA and ECDHE-ECDSA-RC4-SHA will be more preferred by server than DHE-RSA-AES256-GCM-SHA384 and DHE-RSA-AES128-GCM-SHA256. Why?

    3) I have openssl 1.0.1e on Win7

    It’s strangely but I have another order of cipher suits with the same command as yours. They are all present but in another order:

    ECDHE-ECDSA-AES256-GCM-SHA384

    ECDHE-ECDSA-AES128-GCM-SHA256

    ECDHE-RSA-AES256-GCM-SHA384

    ECDHE-RSA-AES128-GCM-SHA256

    ECDHE-ECDSA-AES128-SHA256

    ECDHE-RSA-AES128-SHA256

    ECDHE-RSA-RC4-SHA     

    DHE-RSA-AES256-GCM-SHA384

    DHE-RSA-AES256-SHA256  

    DHE-RSA-AES256-SHA     

    DHE-RSA-CAMELLIA256-SHA

    DHE-RSA-AES128-GCM-SHA256

    DHE-RSA-AES128-SHA256  

    DHE-RSA-AES128-SHA     

    DHE-RSA-SEED-SHA       

    DHE-RSA-CAMELLIA128-SHA

    ECDHE-RSA-AES256-SHA384

    ECDHE-ECDSA-AES256-SHA384

    ECDHE-RSA-AES256-SHA   

    ECDHE-ECDSA-AES256-SHA 

    ECDHE-RSA-AES128-SHA   

    ECDHE-ECDSA-AES128-SHA 

    ECDHE-ECDSA-RC4-SHA    

    ECDH-RSA-RC4-SHA       

    ECDH-ECDSA-RC4-SHA     

    RC4-SHA                

  15. What is the relationship between Elliptic Curve Diffie-Hellman and Dual Elliptic Curve Deterministic Random Bit Generator that was revealed to be compromized by the NSA? Does the compromized random bit generator have an impact of using Elliptic Curve Diffie-Hellman for SSL/TLS?

  16. I have an understanding problem… :-?

    The list without RC4 is

    EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4


    Is there a difference between that and

    EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4
  17. Hi Ivan

    What do you think is good or bad in using this method?

    Nginx :

    ssl_protocols -SSLv2 #Original TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DES-CBC3-SHA:!ADH:!aNULL;
    ssl_prefer_server_ciphers on;

    Apache :

    SSLCipherSuite DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DES-CBC3-SHA:!ADH:!aNULL;
    SSLProtocol -SSLv2 #Original TLSv1 TLSv1.1 TLSv1.2

    When I use original SSLProtocol TLSv1 TLSv1.1 TLSv1.2 on Ubuntu 12.04 LTS 32bit, the Webserver Apache/Nginx stop working the output "Failed". So I change SSLProtocol to -SSLv2 -SSLv3

    And the Breakdown:

    Chrome 29 / Win 7             TLS 1.2 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256
    Firefox 10.0.12 ESR / Win 7   TLS 1.0 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)   FS   256
    Firefox 17.0.7 ESR / Win 7    TLS 1.0 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)   FS   256
    Firefox 21 / Fedora 19        TLS 1.0 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)   FS   256
    Firefox 22 / Win 7            TLS 1.0 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)   FS   256
    IE 6 / XP   No FS *           Fail**
    IE 7 / Vistai                 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)   FS    256
    IE 8 / XP   No FS *           TLS 1.0 TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa)   No FS     168
    IE 8-10 / Win 7               TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)   FS    256
    IE 11 / Win 8.1               TLS 1.2 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)   FS    256
    Java 6u45                     TLS 1.0 TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33)   FS    128
    Java 7u25                     TLS 1.0 TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33)   FS    128
    OpenSSL 0.9.8y                TLS 1.0 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256
    OpenSSL 1.0.1e                TLS 1.2 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)   FS   256
    Opera 12.15 / Win 7           TLS 1.0 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256
    Opera 15 / Win 7              TLS 1.1 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)   FS   256
    Safari 5.1.9 / OS X 10.6.8    TLS 1.0 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256
    Safari 6 / iOS 6.0.1          TLS 1.2 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256
    Safari 6.0.4 / OS X 10.8.4    TLS 1.0 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256
    Safari 7 / OS X 10.9          TLS 1.2 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   FS    256

    To fix IE 6 failed i change SSLProtocol to -SSLv2 but im not testing it yet, because my COMODO SSL trial certificate had expired.

    On Apache, I’m using Apache v 2.2

  18. I wanted to enable PFS on Apache/2.2.15 (CentOS6) with the configuration below and get nowhere near the results of what google.com gets – any suggestions? Preferably the google.com equivalent config for HTTP?

    SSLProtocol all -SSLv2 -SSLv3 SSLHonorCipherOrder on SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"

  19. The Nginx configurations won’t work as is, as using a space and \ in the lines causes an error with Nginx 1.6.0, instead the cipher line needs to be:

    ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS";

    using colons instead of spaces, then it’ll start up, otherwise you get the following error:

    nginx: [emerg] SSL_CTX_set_cipher_list("EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384

      EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4

      EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS") failed (SSL: error:140E6118:SSL routines:SSL_CIPHER_PROCESS_RULESTR:invalid command error:140E6118:SSL routines:SSL_CIPHER_PROCESS_RULESTR:invalid command)

    nginx: configuration file /etc/nginx/nginx.conf test failed

    OpenSSL 1.0.1e-3ubuntu1.5 and Nginx 1.6.0 is currently being used.

  20. Any update to this post now that RC4 is no longer recommended? I saw this config Re: RC4 Safe vs RC4 Broken in TLS but seems to not be exactly what you are running on ssllabs.com.

    Here’s the config I’m running which seems to match ssllabs.com config and still allows IE8 (using 3DES instead of RC4):

    SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM \

                    EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 \

                    EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 \

                    EECDH !ECDHE-RSA-DES-CBC3-SHA EDH+aRSA RSA+3DES \

                    !aNULL !eNULL !LOW !SEED !CAMELLIA !MD5 !EXP !PSK !SRP !DSS !RC4"

    BTW In your remove "Configuring OpenSSL (without RC4)" section you I think you incorrectly have RC4 before the !aNULL and then define it again at the end.

    –Edit 17/06/2015

    I removed SEED ciphers and also ECDHE-RSA-DES-CBC3-SHA. Out of interest Ivan why do you prioritise lower level SHAs over higher level (e.g ECDHE-ECDSA-AES128-GCM-SHA256 over ECDHE-ECDSA-AES256-GCM-SHA384) for your ssllabs.com setup?

  21. I got an 'A' grade server with the following in Apache 2.4.16 (Win64) with Open SSL 1.02d :-

    SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA 3DES !RC4 !aNULL !eNULL !LOW !MD5 !EXP !PSK !SRP !DSS"

    By excluding RC4, it seems to use 3DES anywhere it would usually have used RC4. Clever Apache!

    With Apache 2.2, it was impossible to get an A-grade from your tests, so kudos to your testing regime, Qualys!

  22. Please share us the new settings for windows IIS & Linux Apache based machine for only TLS with strong ciphers in order enabled, Forward Secrecy, Session resumption (caching) , ECDH public server param reuse, NS CAA