SSL Labs A+ HTTPS grade

Getting an A+ grade on (HTTPS Everywhere Series – Part 5)

The SSL Analyzer at SSLLabs analyzes your https setup. You’ll get a security score and a detailed report of your SSL configuration:

  • it verifies if the certificate is valid and trusted.
  • it inspects the server configuration for protocol support, key exchange support and cipher support.


To get an A+ score the default nginx SSL configuration described in our https nginx configuration is not enough. More likely you’ll receive one or more of the following warnings:

Let’s tune the https configuration in the next sections!

Disabling http access to your server

To make your users use the https version of your site by default, you’ll need to redirect all http traffic to the https protocol.
Here is an example server nginx configuration which does this:

server {
        listen <ip_address>:80; # Listen on the HTTP port
        listen [<ip_address>]:80; # Listen on IPv6 address and HTTP 80 port

        return 301 https://$server_name$request_uri;

Fixing Server configuration does not include all intermediate certificates

Actually you should not be receiving this error, as we previously combined all the intermediate certificates with our domain certificate. If the SSLLabs test still reports this error, then you should revisit the previous section.

If you don’t fix this error users may receive strong browser warnings and experience slow performance.

Session can be vulnerable to BEAST / POODLE attacks / SSLv3 is enabled on the server

Sometimes security issues are found in the security protocols or ciphers used for securing websites. Some of these issues get an official name like BEAST or POODLE attacks.

By using the latest version of OpenSSL and properly configuring the nginx SSL settings you can mitigate most of these issues. has an up-to-date list of configuration settings to be used on your server. Actually there are three sets of configurations, a Modern, an Intermediate and Old configuration.

We recommend to at least use the Intermediate or the Modern version as they give you higher levels of security between browsers/clients and your server. The modern version is the most secure, but doesn’t work well with old browsers.

Here are the minimum versions supported for the Modern & Intermediate configuration.

  • Modern: Firefox 27, Chrome 22, IE 11, Opera 14, Safari 7, Android 4.4, Java 8
  • Intermediate: Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7

We’ll use the online tool at to generate an ‘Intermediate’ configuration.

Choose nginx, Intermediate and fill in the nginx version & OpenSSL version. The nginx configuration generated should be like the one in the screenshot above.

In summary these settings will:

  • disable SSL3.0 protocol (even IE6 on Windows XP supports the successor TLSv1 with Windows update) – clients are forced to use at least TLSv1
  • The SSL Ciphersuites nginx/OpenSSL supports server side are ordered: the most secure at the beginning of the list. This will make sure client/servers will try to use the most secure options they both support.
  • Specifies that server ciphers should be preferred over client ciphers when using the TLS protocols (to fix BEAST SSL attack)
  • Enable OSCP stapling (explained in the next section)

For Diffie-Hellman based ciphersuites an extra parameter is needed:

ssl_dhparam /usr/local/nginx/conf/dhparam.pem;

This file can be created by the following OpenSSL command:

$ sudo openssl dhparam -out /usr/local/nginx/conf/dhparam.pem 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time

2048 means the parameter is 2048 bits in size.

OCSP Stapling

OCSP stands for Online Certificate Status Protocol. Let’s explain the context a bit.

Certificates issued by a Certificate Authority can be revoked by the CA. For example because the customer lost their private key or was stolen, or the domain was transferred to a new owner.

The Online Certificate Status Protocol (OCSP) is one method for obtaining certificate revocation information. When presented with a certificate, the browser asks the issuing CA if there are any problems with it. If the certificate is fine, the CA can respond with a signed assertion that the certificate is still valid. If it has been revoked, however, the CA can say so by the same mechanism.

OCSP has a few drawbacks:

  • it slows down new HTTPS connections. When the browser encounters a new certificate, it has to make an additional request to a server operated by the CA.
  • Additionally, if the browser cannot connect to the CA, it must choose between two undesirable options:
    • It can terminate the connection on the assumption that something is wrong, which decreases usability.
    • It can continue the connection, which defeats the purpose of doing this kind of revocation checking.

OCSP stapling solves these problems by having the site itself periodically ask the CA for a signed assertion of status and sending that statement in the handshake at the beginning of new HTTPS connections.

To enable OCSP stapling in nginx; add the following options:

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/nginx/conf/ca.root.crt;

The ssl_trusted_certificate file should only contain the root Certificate Authority certificate. In our case, we created this file like this:

cat AddTrustExternalCARoot.crt > ca.root.crt

When nginx asks for the revocation status of your certificate, it’ll ask the CA this in a secure manner using the root CA certificate (ca.root.crt in our case).

To validate OSCP stapling is working run the following command:

$ openssl s_client -connect -tls1 -tlsextdebug -status < /dev/null| grep OCSP&#91;/x_code&#93;<div id="" class="x-text" style="" ><p>It should give back:</p>
</div>[x_code]OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response

when it is working.

“OCSP response: no response sent” means it is not active yet.

You may need to rerun this command a few times if you just recently started nginx.

Implementing HTTP Strict Transport Security

Suppose a user types in the URL of your website in a browser without any https or http protocol specified. Then the browser will likely choose to load the site via http (the unsecure version). Even if you have configured your server to redirect all http requests to https, the user may will talk to the non-encrypted version of the site before being redirected.

This opens up the potential for a man-in-the-middle attack, where the redirect could be exploited to direct a user to a malicious site instead of the secure version of the original page.

The HTTP Strict Transport Security feature lets a website inform the browser it should never try to load the site using HTTP, and that it should automatically convert all attempts to access the site using HTTP to HTTPs requests.

In your nginx configuration you’ll need to add the following line:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

This adds an HTTP Strict-Transport-Security header, specifiying that all subdomains should also be run on https and that the browser should not try the http version for one year.

Optimizing SSL performance

To further optimize the SSL performance of nginx we can enable some caches.

ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;

The ssl_session_cache will create a shared cache between all the nginx worker processes. We have reserved 50MB for storing SSL sessions (for 1 day). According to the nginx documentation 1MB can store about 4000 sessions. You can reduce or increase the size of the cache based on the traffic you’re expecting.

Wim Bervoets
Follow me

Share this Post

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.