SSL PFS on Nginx

Update: 3/10/2016: Cipher list matches recommendations from https://wiki.mozilla.org/Security/Server_Side_TLS.

Update: 5/29/2015: Modified cipher list for high security.

Update: 12/9/2014: RC4 has been identified by SSL Labs as a weak point in SSL implementations so the example nginx configuration below now includes disabling of RC4 ciphers. This updated configuration means that the horribly outdated browsers IE6 on Windows XP and IE8 on Windows XP will no longer work with your site.

Also, please upgrade to the latest OpenSSL to ensure that TLS POODLE is mitigated via TLS_FALLBACK_SCSV downgrade attack prevention.


August 2, 2014

Doing this in your nginx configuration will make your SSL web server much more robust. Some parts of this, such as the OCSP stapling directives require nginx version 1.3.7+.

Straight to the point: Here is a nginx configuration snippet with HSTS, OCSP, and PFS ciphers:

server {

    listen 443;
    server_name www.yoursitename.com;
    ssl on;

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

    # hide server version
    server_tokens off;

    ssl_certificate ssl-cert-with-ca-chain.crt;
    ssl_certificate_key yourserver.key;

    # OCSP stapling caches OCSP records from URL in ssl-cert-with-ca-chain
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate ssl-cert-with-ca-chain.crt;
    resolver 8.8.8.8 4.2.2.2;

    # Enables session resumption
    ssl_session_timeout 5m;
    ssl_session_cache shared:nginxSSL:10m;

    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;

    # ... the rest of your configuration

}

SSL Perfect Forward Secrecy (PFS)

The perfect forward secrecy cipher list defined in ssl_ciphers enables reference browsers to generate session keys in a way that only the client and server can obtain them. If someone collects and saves your SSL traffic, he or she cannot later steal the server's private key and decrypt the past communications. Traffic sent in the past is still safe. (Note: Man-in-the-middle attacks are still a threat if the private key is stolen.)

PFS future-proofs your SSL web server.

HTTP Strict Transport Security (HSTS)

add_header Strict-Transport-Security tells the browser to use HTTP Strict Transport Security. It tells client browsers to only use HTTPS connections. This, coupled with a nginx permanent redirect of all HTTP traffic to HTTPS, ensures an SSL server that is resistant to spoofing.

server {
    listen 80;

    location / {
        rewrite     ^(.*)   https://yoursitename.com$1 permanent;
    }

    # ...
}

Online Certificate Status Protocol Stapling (OCSP Stapling)

The ssl_stapling directive, with its 3 subsequent lines in the above config, enables server caching of OCSP information. It is not going to work if a trusted Certificate Authority has not signed your SSL certificate. OCSP stapling allows an alternative to pinging your CA for certificate status. The web server caches the response from the CA that issued the certificate. By enabling this in nginx, you must include the CA certificate chain in your certificate file.

Test your SSL

You can always see how secure your web site SSL implementation is by running the Qualys SSL Labs SSL Server Test.