SSL Setup on Laravel Forge

on September 19, 2014 Technical with 0 comments

A interesting set of statistics and analysis for SSL standards across the web is reported by SSL Pulse. This shows that of the top 150,000 SSL enabled web sites examined 30.6% have SSL configured correctly.

This means that an amazing 69.4% of the top sites do not have SSL configured correctly!

Laravel Forge (forge.laravel.com) makes it incredibly easy for you to set up a Laravel (or other framework) website in the cloud. It also provides a simple means to configure an SSL site – just enter your private key and certificate and Forge does the rest.

As with any configuration process it is important to validate the configuration. Sauve Solutions uses the free online SSL configuration testing tool from Qualsys – Qualsys also provide solutions to automate the testing to ensure the configuration remains valid which can protect you against inadvertent configuration changes.

Running this tool against a fresh Laravel Forge configured site shows that the default setup provides an A- rating. This is better than almost 70% of the SSL sites out there – but we can do better.

Improving SSL Security

In reality it is quite easy to improve the SSL setup of an Nginx site. There are 4 things that need to be added to the Nginx configuration file. The file can be accessed in Forge by clicking on the ‘Edit Nginx Configuration’ on the bottom right of the Site Details page.

nginxconfig

As you can see we place these just before the # FORGE SSL line.

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

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_dhparam /etc/nginx/ssl/dh2048conf.pem;

ssl_ciphers “ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA”;

# FORGE SSL (DO NOT REMOVE!)

Examining these lines in turn

Strict-Transport-Security

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

This line inserts a header in every response that instructs the browser to follow the Strict Transport Security policy. This prevents a number of vulnerabilities, for example browsers submitting requests to insecure resources on a web page, e.g. an image. This can accidentally leak session keys and other confidential information. For a full explanation see Wikipedia.

Protocols

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

This line tells NGINX which SSL protocols to use. Best practice currently is to disable the older protocols SSLV1, SSLV2 and SSLV3. All modern browsers can use the new TLS protocols which offer substantially improved security.

Diffie-Hellman Key Exchange Parameters

ssl_dhparam /etc/nginx/ssl/dh2048conf.pem;

The Diffie Hellman Key exchange is used during the set up of the SSL communication to establish a shared secret key which is used for encrypting the data between client and server. Wikipedia again has a good explanation. The standard NGINX configuration relies on the defaults in OpenSSL for the length of the key used for Ephemeral Diffie Hellman Key Exchange. Longer keys result in improved security. By default OpenSSL will use a 1024 bit key. It is good practice to increase this to 2048 bits.

This is achieved by using OpenSSL to create configuration file which is read by Nginx.

Create a configuration file on the command line – using openssl dhparam -out dh2048conf.pem 2048 then move the resultant file to some accessible directory. We recommend /etc/nginx/ssl/ which is the directory that contains all of the SSL configurations for the different sites.

Ciphers

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA";

Note:This should all be on one line in the configuration file.

The ciphers section defines how Nginx will negotiate with the client to establish a secure connection. The ssl_ciphers line defines the valid cipher suites that the server will offer to clients. The order is important – and the suites specified first will be preferred over those at the end. The key element of this configuration is that we are preferring those cipher suites that support “Perfect forward Secrecy” – once again Wikipedia will explain.

Enabling Perfect Forward Secrecy is one of the biggest improvements you can make to the configuration.

This set of ciphers is recommended by Ivan Ristic from SSL Labs – he has recently published a fantastic book on the whole subject of SSL configuration – see Bulletproof TLS/SSL Configuration – which should be read by everyone who is involved in configuring secure servers.

The above will work on all modern browsers – however be aware that IE6 on XP will be left in the cold. There are also some reports of IE8 on XP not working as well. Since the limitation is imposed by SCHANNEL.DLL in Windows, it is recommended that you utilise Chrome or Firefox as an alternative browser which implement their own SSL solution.

Conclusion

Implementing these configuration changes will improve the security of your SSL configuration – moving the site to an A grade according to SSLLabs testing.

Don’t forget to restart Nginx to read the configuration changes.

These simple changes will put your site in the top few percent of internet sites in terms of SSL configuration. This is becoming increasingly important as search engines prioritise SSL sites. Google is also taking a strong stance on SSL security – see their recent blog post regarding updates to Chrome which will start to issue certificate warnings for SSL certificates which use a SHA1 signature.