Enable Perfect Forward Secrecy for nginx
Camilo Nova
CEORecently 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.
Written by Camilo Nova
As the Axiacore CEO, Camilo writes about the intersection of technology, design, and business. With a strategic mindset and a deep understanding of the industry, he is dedicated to helping companies grow.