Insights

Enable Perfect Forward Secrecy for nginx

Photo of the author: Camilo Nova

Camilo Nova

  •  

2 min read.

Recently there have been some security concerns about SSL enabled sites, here I will show you how to make your site stronger to bad people by limiting the requests a user can make and enabling Perfect Forward Secrecy.

First of all we are going to limit the requests to your web server, this will prevent brute force attacks to your site. Nginx has a built-in module to limit the requests from the same IP address, this can be enabled changing your site file, the one is inside sites-available folder, like this:

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
    ...
    location / {
        limit_req      zone=one burst=10 nodelay;
        ...
    }
}

The first line is going to create a zone named one with a 10mb size for a shared memory zone and to limit the requests to 1 per second. Later at the location level, it should useful if you set it just for the application and not in the static content location, you define to limit the requests using the zone we just created before with a burst of 10 and the nodelay option which will show an error page to someone who reach the limit of requests, otherwise it will only delay the response. You can get more information at the official documentation.

Next we are going to set the Perfect Forward Secrecy, this should be a must have when thinking about security, so we are going to add some "randomness" to our key file, the one we use for the SSL certificate; to find which one are you using, just go to your site file and search for the ssl_certificate parameter and there should be the path to your file, let's suppose is named my-key.crt, then we in the command line we issue:

$ openssl dhparam -rand - 2048 >> /path/to/my-key.crt

This is going to add a random data on you key to make it more strong, now we just need to add the ciphers to your nginx.conf file to make it work:

http {
        ...
        ##
        # SSL settings
        ##
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
        # Forward secrecy settings
        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";
        ...

The cipher list is kind of long, but it will work on most older browsers, if you don't need to think about IE 8 then you can use this short one:

ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";

We only need to restart nginx service and see how it works, you can check your site here: https://www.ssllabs.com/ssltest/index.html.

Now your site should have an A+ rating.

Learn more by receiving an email once a month.

Additional Insights

Temas para Sublime Text

Al momento de escribir código de programación que mejor herramienta que Sublime Text , usted puede hacer un sin número ...

Author Carlos Niño Carlos Niño