nginx enables many additional features over Apache’s httpd server, which allows a much more secure SSL configuration, enabling features such as Perfect Forward Secrecy (PFS) which cannot be enabled using default Apache installs from repository.
Below is a guide on how to enable a very secure SSL configuration for your nginx server, including using Diffie–Hellman for key exchange, enabling Online Certificate Status Protocol (OCSP) features and making use of higher security ciphers and protocols only.
**In order to achieve this level of security we have made some trade-offs with usability which must be accepted. **To achieve this level of security, we have enforced TLS only protocols, cipher protocols and Diffie-Hellman parameters that mean clients such as IE6 on Windows XP, older versions of Java and some smaller search engine crawlers may no longer be able to access your site. The trade-off decision has been made to be more secure for the majority, rather than support out of date software packages which may, possibly, somewhere, be used. You need to decide for yourself how to proceed, but the internet would be a much better place being secure for the majority than supporting those who are more likely to be running compromised/vulnerable equipment…
Adding SSL configuration to nginx
The below outlines SSL best practice for nginx, including using Diffie-Hellman to achieve Perfect Forward Secrecy. It assumes that you have already installed nginx (such as detailed in my previous article) and have purchased a SSL certificate from a trusted Certificate Authority (CA).
The first step is to add server wide SSL parameters that will be used in the configuration of all sites hosted using nginx. The below contents should be added in the http section of your nginx configuration file, normally located in the /etc/nginx/nginx.conf location and enables: TLS protocol support; a range of secure ciphers in a security preferred order and also SSL session caching for performance benefits.
Update: The below is not going to be kept updated, so I recommend using CloudFlare’s configuration which is regularly updated.
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 EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;
Adding Diffie-Hellman support
In order to add support for Perfect Forward Secrecy, we need to create a safe randomised seed for use which can be done as follows:
# openssl dhparam -out /pathtoyourcerts/dhparam.pem 2048 # 600 dhparam.pem
Once the file has been created and secured, it can then be referenced in your nginx configuration by adding the following line immediately below the content added to the /etc/nginx/nginx.conf file above:
ssl_dhparam /pathtoyourcerts/dhparam.pem;
Adding OCSP stapling
Certificate revocation checking became a very discussed topic in the wake of the Heartbleed vulnerability due to the security and privacy issues that suddenly became more plausible very quickly. OCSP stapling is the industry best practice solution to addressing the issues raised and can be added into your nginx server configuration file in /etc/nginx/nginx.conf using the following configuration. You will need to ensure that the certificates of your Certificate Authority used for the OCSP check are present added to the “ocsp.crt” file referenced in the below configuration.
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /pathtoyourcerts/ocsp.crt; resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s;
Now that the server SSL configuration has been completed, you can create the per site configuration.
Adding SSL support to sites
To enable SSL support for each site individually, the below should be completed for each individual site/configuration file within the /etc/nginx/conf.d/ directory, with the applicable configuration for each substituted as applicable. The configuration assumes that your certificate file contains the chain for your certificate provider in addition to your individual certificate.
listen 443 ssl; ssl_certificate /pathtoyourcerts/site.tld.crt; ssl_certificate_key /pathtoyourcerts/site.tld.key;
Once the above configuration has been completed, you can now test your configuration (service nginx configtest) and fix any errors that are noted. Assuming there are none, your server can be reloaded and then your configuration can be tested against services such as Qualys’ SSL Labs Tester.
Image credit: Yuri Samoilov