Doing the ChaCha with Nginx

ChaCha20-Poly1305 is the combination of a new cipher, ChaCha20, and a new MAC, Poly1305, to give us a new AEAD cipher suite. AEADs will be the only option that will be available going forwards in TLSv1.3 so alongside AES-GCM, ChaCha20-Poly1305 will be our only other choice. There are also some nice performance benefits to be had.


The basics

This blog will focus less on the specific details and benefits of the new cipher suite and more on how to add support in Nginx. ChaCha20 is a a very fast cipher and has a significant performance advantage over AES when implemented in software. This means that devices that don't have hardware AES acceleration, typically mobile devices, will see a ~200% increase in performance when using ChaCha20. If the device does have AES hardware acceleration and negotiates a suite using ChaCha20, it can expect to see a ~50% decrease in performance. Poly1305 authenticator is a high-speed Message Authentication Code (MAC) and is used for integrity checking and combined with ChaCha20 gives us Authenticated Encryption with Associated Data (AEAD). Cloudflare have a nice blog with more details and of course you can always read the RFC if you're feeling brave!


Adding support in Nginx

I already build Nginx from source so adding support for ChaCha20-Poly1305 wasn't too difficult for me but I'm going to share my build script so you can hopefully have a much easier time doing the same. The first thing you need to do is create a folder to download the various components we're going to need.

cd ~
mkdir nginx
cd nginx

Next download and prepare the latest version of Nginx, which you can find here, updating the version numbers as appropriate.

wget http://nginx.org/download/nginx-1.11.7.tar.gz
tar -xzvf nginx-1.11.7.tar.gz
rm nginx-1.11.7.tar.gz

The next step is to download the latest version of OpenSSL so we can get support for ChaCha20-Poly1305, again, grab the latest version from here and update the version as appropriate.

wget https://www.openssl.org/source/openssl-1.1.0c.tar.gz
tar -xzvf openssl-1.1.0c.tar.gz
rm openssl-1.1.0c.tar.gz

We will be building Nginx with a custom version of OpenSSL and not altering the system version. Now is also a great time to add PageSpeed if you'd like some extra performance boosts and Brotli support if you want better compression so check the linked articles and incorporate them into this process if you wish. You're now ready to build Nginx with the changes we made and you need your existing configure arguments. Use the following command to get them.

nginx -V

Once you have those change into the directory where you downloaded the latest version of Nginx and we can configure it.

cd nginx-1.11.7
./configure (existing configure arguments) --with-openssl=/home/scott/nginx/openssl-1.1.0c

For the ./configure command you need to paste in your existing configure arguments and then add the additional one to point to the location that you downloaded the new version of OpenSSL. Once that's finished the remainder of the process is fairly simple.

make
sudo make install
sudo service nginx restart

This will make and install the new version of Nginx and then restart the process to kill the old version and start the new version. You can check your version with the following command that should give you the information you need.

nginx -V

nginx version: nginx/1.11.7
built by gcc 4.8.4 (Ubuntu 4.8.4-0ubuntu1~12.04.1)
built with OpenSSL 1.1.0c  10 Nov 2016
configure arguments: (your new configure arguments here)

You want to see the versions of Nginx and OpenSSL that you downloaded, that means the process worked and you're ready to start using ChaCha20-Poly1305. The last thing to do now is update your cipher suites to add support in Nginx. In your ssl_ciphers directive you can now add the appropriate suites.

ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305";

Where and how you add this will depend on your configuration but those are the appropriate values. I use hybrid RSA and ECDSA certificates so have both suites listed above but you will only need one unless you add support for that yourself. Depending on your audience, desktop or mobile, it will also be more or less appropriate for your to prioritise these new suites above all others until we have the ability to choose the suite based on the client. The last thing to do now is test your site with SSL Labs to see if everything worked as expected!

A+ on SSL Labs


suite config on SSL Labs


You can see my SSL Labs grade above and the new cipher suites at the top of my config. If you get ChaCha20-Poly1305 setup on your site then link the SSL Labs scan results below!

Author image
About Scott Helme
United Kingdom Website
Security researcher, entrepreneur and international speaker who specialises in web technologies.