Nginx SSL Ciphers and PCI Compliance

Nginx has clearly established itself as a contender for the dominant next generation web server. However, the road to victory will require some significant improvements to the migration path from Apache and IIS. Online forums and the blogosphere are quickly filling with details on Nginx configuration snippets that share very focused instructions on accomplishing a very specific task. Many of these articles are now wildly out of date as the cycle of Nginx version release accelerates.

My objective is to provide some explanation and context around the configuration of SSL ciphers and protocols within Nginx as they relate to PCI compliance. It goes without saying that I have an eye for performance. When applying this information to your own servers keep in mind that these details apply to the currently stable Nginx release 1.0.14.

Encryption, crypto and SSL are hot topics these days with vulnerabilities, exploits and the discovery of recently compromised SSL authorities eroding the protection SSL provides to both customers and businesses.

Encryption is an expensive, computationally intensive process at any scale, but it is absolutely critical for protecting the sensitive credit card details intrinsic to an ecommerce transaction.

The developers of Nginx have recently changed the default SSL ciphers to include the very strong Diffie-Hellman Ephemeral (DHE) cipher. DHE is used to provide perfect forward secrecy in TLS.

Further reading on Ephermal Diffie-Hellman, PFS and TLS at Wikipedia.org

While I applaud this move on the part of the Nginx dev team there is a tradeoff and that is slower performance. DHE provides stronger encryption which in turn requires more computation but here’s where it gets interesting. To meet today’s PCI DSS crypto standards DHE is not required. Like many things in life there’s a balance to be struck between the risk of compromised encryption and the additional expense or rather the relative loss of connections per second. I’m not a lawyer nor should this be considered legal advice but I prefer things that go fast while meeting the necessary PCI compliance criteria.

In order to disable DHE in the server context of the Nginx configuration add the following line:

ssl_ciphers RC4:HIGH:!aNULL:!MD5:!kEDH;

This line provides the list of openssl cipher suites Nginx will use to negotiate a secure communication channel between client and server. To view the complete list of ciphers available on your server run:

openssl ciphers

An additional component required to meet the PCI DSS standard is the explicit definition of the SSL protocols supported by Nginx. Note the important omission is SSLv2 which enables weak cipher support.

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

In combination with the above directives the ssl_prefer_server_ciphers setting enables protection from Beast attacks.

ssl_prefer_server_ciphers on;

For quick verification of the Nginx SSL encryption configuration the Qualys SSL Labs online tool is great. Consider hiding the results of your server’s analysis the first time you run this tool and also note the recently scanned domains list.

https://www.ssllabs.com/ssldb/index.html

For the security experts I recommend using the openssl client rather than a 3rd party website.

Additional references:

PCI DSS v2.0
https://www.pcisecuritystandards.org/documents/pci_dss_v2.pdf

OpenSSL Cipher List
http://openssl.org/docs/apps/ciphers.html